Checking the contents of a char list list in sml - list

My question is like the one here.
I'm working on a char list list and I need to check that 1-9 are used once in every list, but also once in every position in the list.
My code looks like this:
infix member
fun x member [] = false
| x member (y::ys) = x = y orelse x member ys;
fun rscheck xs =
let
val ys = [#"1",#"2",#"3",#"4",#"5",#"6",#"7",#"8",#"9"]
in
ys member xs
end;
but this only checks if 1-9 are members of the lists, not if they're on the same position in different lists.
I had the idea to use this function:
fun poslist xs n = map (fn x => List.nth (x , n)) xs;
(the function poslist is supposed to return whatever is in position n of the list xs, so I can isolate the individual lists in the char list list), but since poslist returns a char list rscheck can't work with it as it needs a char list list.
1) Can I improve poslist?
2) How do I fix rscheck?
Edit
infix member
fun x member [] = false
| x member (y::ys) = x = y orelse x member ys;
fun samelist (x::xs) ys = x member ys andalso samelist xs ys
| samelist [] _ = true;
fun takelist xs n = map (fn x => List.nth (x , n)) xs;
fun reverse xs = List.tabulate (9 , fn x => takelist xs x);
fun rscheck xs =
let
val s = [#"1",#"2",#"3",#"4",#"5",#"6",#"7",#"8",#"9"]
in
List.all (fn x => samelist s x) xs
end andalso rscheck (reverse xs);

Your rscheck method just checks whether one of the rows is equal to [#"1",#"2",#"3",#"4",#"5",#"6",#"7",#"8",#"9"]. What it should do is check that all the rows contain the numbers in any order. Once you fix that you can solve the rest of the problem as follows:
The easiest way to check whether a matrix is a valid sudoku solution is to use your rscheck function on it, then transpose it (i.e. switch its rows and columns) and then use your rscheck on the transposed matrix. If it returns true both times, it's a valid sudoku solution.
To transpose the matrix you can either translate this OCaml code to SML, or simply use your poslist function for all indices from 0 to 8.

Related

Creating an intersection and difference in ML New Jersey

Using the function contains constructed earlier, write a function intersection that takes two list (modeling sets) and returns a list that comes up with the intersection of two sets. So
intersection([1, 2, 3], [1, 3])
would return [1, 3].
Using the function contains constructed earlier, write a function difference which takes two list and returns a list modeling the difference of the first set from the second set (Set A – Set B).
I've created this code contains which is down below, now my goal is to create both an intersection and difference function.
fun contains(x, []) = false
| contains(x, y::rest) =
if x = y
then true
else contains(x, rest);
fun intersection([], y) = []
| intersection(x, y) = if x = y
then [x,y]
else [];;
Trying it:
- intersection([1, 2], [2, 3]);
val it = [] : int list list
As for your contains function, it can be improved slightly:
fun contains(x, []) = false
| contains(x, y::rest) =
x = y orelse contains(x, rest)
That is, if P then true else Q is the same as P orelse Q.
The higher-order standard-library solution is to write
fun contains (x, ys) = List.exists (fn y => x = y) ys
But the former is preferrable if the exercise is to demonstrate understanding of basic recursion.
As for your intersection function, it seems that however you managed to make contains, you are not applying the same principles of list recursion. You compare x = y, but here x and y are lists, not individual elements. Whereas in contains, x is a single value within a list/set, and y is the first element of the list/set y::rest.
So you should probably start to either annotate each argument with a type, or name it in such a way that you're not in doubt about what it's supposed to represent. For intersection the rule is that you only want elements that are members of both lists/sets.
For example:
fun intersection (xs, ys) = ...
Or with types annotated:
fun intersection (xs : ''a list, ys : ''a list) = ...
And you may think that you need to use recursion on lists by pattern matching on the empty/non-empty lists on either xs or ys. I've picked xs here because it happened to be the first argument, but this is arbitrary:
fun intersection ([], ys) = ...
| intersection (x::xs, ys) = ...
Or with types annotated:
fun intersection ([] : ''a list, ys : ''a list) = ...
| intersection (x::xs : ''a list, ys : ''a list) = ...
Then you can ask yourself:
What is the intersection between the empty list/set and ys?
Is x a part of the intersection of x::xs and ys?
What other elements might be part of this intersection (recursively)?

How to recursively multiply all elements of a list with itself to create a matrix? OCaml

I need to create a weight matrix essentially by multiplying all the elements of a list with themselves.
for example if my list is [1;-1;1;-1], the resulting matrix would be
[[0;-1;1;-1],
[-1;0;-1;1],
[1;-1;0;-1],
[-1;1;-1;0]]
(diagonal is filled with 0's because a node shouldn't be able to lead to itself)
This would be a piece of cake, but it has to be done recursively, with the following constraints:
only List.hd, List.tl and List.nth can be used, and as a parameter, I can only pass in the list:
let rec listMatrix = fun(myList)->...
Is there any way to do this? Or should I just try to find some fundamentally different way to solve this problem?
Also, only functional approach is allowed, no global variables.
One way to do it recursively is as follows:
let l = [1;-1;1;-1];;
let rec index xs =
let idx xs i = match xs with
[] -> []
| (x::xss) -> (i,x) :: idx xss (i+1)
in idx xs 0
fst (x,y) = x
snd (x,y) = y
let rec mult xs ys = match xs with
[] -> []
| (x::xss) -> (List.map (fun y->if (fst x == fst y) then 0 else (snd y*snd x)) ys) :: (mult xss ys)
let mult0 xs = mult (index xs) (index xs)
What the code does is, as asked, multiplying a vector with itself. The vector is indexed with numbers in order to handle diagonal elements specially.
The output is:
# mult0 l;;
- : int list list =
[[0; -1; 1; -1]; [-1; 0; -1; 1]; [1; -1; 0; -1]; [-1; 1; -1; 0]]

Haskell Function that Takes A Pair of Values and a List

My homework has been driving me up the wall. I am supposed to write a function called myRepl that takes a pair of values and a list and returns a new list such that each occurrence of the first value of the pair in the list is replaced with the second value.
Example:
ghci> myRepl (2,8) [1,2,3,4]
> [1,8,3,4].
So far I have something like this (but its very rough and not working well at all. I need help with the algorithm:
myRep1 (x,y) (z:zs) =
if null zs then []
else (if x == z then y : myRep1 zs
else myRep1 zs )
I don't know how to create a function that takes a pair of values and a list. I'm not sure what the proper syntax is for that, and I'm not sure how to go about the algorithm.
Any help would be appreciated.
How about something like:
repl (x,y) xs = map (\i -> if i==x then y else i) xs
Explanation
map is a function that takes a function, applies it to each value in the list, and combines all the return values of that function into a new list.
The \i -> notation is a shortcut for writing the full function definition:
-- Look at value i - if it's the same as x, replace it with y, else do nothing
replacerFunc x y i = if x == y then y else i
then we can rewrite the repl function:
repl (x, y) xs = map (replacerFunc x y) xs
I'm afraid the map function you just have to know - it is relatively easy to see how it works. See the docs:
http://www.haskell.org/hoogle/?hoogle=map
How to write this without map? Now, a good rule of thumb is to get the base case of the recursion out of the way first:
myRep1 _ [] = ???
Now you need a special case if the list element is the one you want to replace. I would recommend a guard for this, as it reads much better than if:
myRep1 (x,y) (z:zs)
| x == z = ???
| otherwise = ???
As this is home work, I left a few blanks for you to fill in :-)
myRepl :: Eq a => (a, a) -> [a] -> [a]
myRepl _ [] = []
myRepl (v, r) (x : xs) | x == v = r : myRepl (v, r) xs
| otherwise = x : myRepl (v, r) xs
Untupled arguments, pointfree, in terms of map:
replaceOccs :: Eq a => a -> a -> [a] -> [a]
replaceOccs v r = map (\ x -> if x == v then r else x)

SML function to with 2 lists that returns the XOR---fixed

Anyone able to offer any advice for a function in SML that will take 2 lists and return the XOR of them, so that if you have the lists [a,b,c,d], [c,d,e,f] the function returns [a,b,e,f] ?
I have tried to do it with 2 functions, but even that does not work properly.
fun del(nil,L2) = nil
|del(x::xs,L2)=
if (List.find (fn y => y = x) L2) <> (SOME x) then
del(xs, L2) # [x]
else
del(xs, L2);
fun xor(L3,L4) =
rev(del(L3,L4)) # rev(del(L4,L3));
Your attempt seems almost correct, except that fn x => x = x does not make sense, since it always returns true. I think you want fn y => y = x instead.
A couple of other remarks:
You can replace your use of List.find with List.filter which is closer to what you want.
Don't do del(xs,L) # [x] for the recursive step. Appending to the end of the list has a cost linear to the length of the first list, so if you do it in every step, your function will have quadratic runtime. Do x :: del(xs,L) instead, which also allows you to drop the list reversals in the end.
What you call "XOR" here is usually called the symmetric difference, at least for set-like structures.
The simplest way would be to filter out duplicates from each list and then concatenate the two resulting lists. Using List.filter you can remove any element that is a member (List.exists) of the other list.
However that is quite inefficient, and the below code is more an example of how not to do it in real life, though it is "functionally" nice to look at :)
fun symDiff a b =
let
fun diff xs ys =
List.filter (fn x => not (List.exists ( fn y => x = y) ys)) xs
val a' = diff a b
val b' = diff b a
in
a' # b'
end
This should be a better solution, that is still kept simple. It uses the SML/NJ specific ListMergeSort module for sorting the combined list a # b.
fun symDiff1 a b =
let
val ab' = ListMergeSort.sort op> (a # b)
(* Remove elements if they occur more than once. Flag indicates whether x
should be removed when no further matches are found *)
fun symDif' (x :: y :: xs) flag =
(case (x = y, flag) of
(* Element is not flagged for removal, so keep it *)
(false, false) => x :: symDif' (y :: xs) false
(* Reset the flag and remove x as it was marked for removal *)
| (false, true) => symDif' (y::xs) false
(* Remove y and flag x for removal if it wasn't already *)
| (true, _) => symDif' (x::xs) true)
| symDif' xs _ = xs
in
symDif' ab' false
end
However this is still kind of stupid. As the sorting function goes through all elements in the combined list, and thus it also ought to be the one that is "responsible" for removing duplicates.

haskell list and functional

This is homework that has been driving crazy for the last couple of days.
I got a list that I am applying a function to - pushing each element to the right if the element next to it is smaller then the previous one.
My function to pass over the list once and sort the head of the list:
sortEm lis#(x:y:xs) = if x > y then y: sortEm (x:xs) else lis
sortEm [x] = [x]
sortEm [] = []
myList (x:y:xs) = if x > y then sortEm lis else x:myList(y:xs)
myList [] = []
myList [x] = [x]
But my problem is that once that sortem has finished it returns either an empty list or a list containing one element, how would i design this the functional way?
I was thinking about foldl and some haskell magic to go along with that but currently I am stuck.
Thanks in advance
First of, your sortEm function name is misleading, it doesn't sort its argument list but inserts its head element into its tail. As it happens, there is an insert function already in Data.List module that inserts its first argument into the 2nd, so there's an equivalency
sortEm (x:xs) === Data.List.insert x xs
Now, inserting an item will only get you a sorted list back if you're inserting it into a list that is already sorted. Since empty list is sorted, that's what myList function does that you got in dave4420's answer. That is an "insertion" sort, progressively inserting elements of list into an auxiliary list, initially empty. And that's what the 2nd function does that you got in dave4420 answer:
insertionSort xs = foldr Data.List.insert [] xs
This does "apply sortem" i.e. inserts, "each element" only once. For a list [a,b,c,...,z] it's equivalent to
insert a (insert b (insert c (... (insert z []) ...)))
What you probably meant in your comment, i.e. comparing (and possibly swapping) two neighboring elements "only once", is known as bubble sort. Of course making only one pass through the list won't get it sorted, in a general case:
bubbleOnce xs = foldr g [] xs where
g x [] = [x]
g x xs#(y:ys) | x>y = y:x:ys -- swap x and y in the output
| otherwise = x:xs -- keep x before y in the output
Now, bubbleOnce [4,2,6,1,8] ==> [1,4,2,6,8]. The value that you expected, [2,4,1,6,8], would result from applying the folding function g in an opposite direction, from the left to the right. But that's much less natural to do here with Haskell lists:
bubbleOnce' [] = []
bubbleOnce' (x:xs) = let (z,h)=foldl g (x,id) xs in (h [z]) where
g (x,f) y | x>y = (x, f.(y:)) -- swap x and y in the output
| otherwise = (y, f.(x:)) -- keep x before y in the output
(edit:) see jimmyt's answer for the equivalent, but simple and nice version using straightforward recursion. It is also lazier (less strict) than both the fodlr and foldl versions here.
myList [] = []
myList (x : xs) = sortEm (x : myList xs)
(untested)
Or in terms of a fold:
myList = foldr cons []
where cons x xs = sortEm (x : xs)
(also untested)
-- if..then..else version
sortEM :: Ord a => [a] -> [a]
sortEM (x:y:xs) = if x < y
then x : sortEM (y:xs)
else y : sortEM (x:xs)
sortEM b = b
-- guard version
sortEM_G :: Ord a => [a] -> [a]
sortEM_G (x:y:xs)
| x < y = x : sortEM_G (y:xs)
| otherwise = y : sortEM_G (x:xs)
sortEM_G b = b