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
infi开发者_Python百科x 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.
精彩评论