From 1affcc2138d3adb78d2c4c8eef7e81bdf56f017a Mon Sep 17 00:00:00 2001 From: MartinMayr Date: Tue, 15 Mar 2011 22:13:17 +0100 Subject: [PATCH 1/4] fillFirstEmptyPosition mit ReferenceCell implementiert --- Source/SudokuSolver/Program.fs | 50 +++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/Source/SudokuSolver/Program.fs b/Source/SudokuSolver/Program.fs index b70e919..83257a7 100644 --- a/Source/SudokuSolver/Program.fs +++ b/Source/SudokuSolver/Program.fs @@ -28,7 +28,22 @@ let isComplete matrix = matrix |> Seq.exists listContainsZero -let fillFirstEmptyPosition matrix = [matrix] // TODO: Homework +let rec fillFirstEmptyPositionWith matrix number = + let m = ref number + let replaceZero z = + match z with + | 0 -> + let g = !m + m := 0 + g + | f -> id f + let changeList = List.map replaceZero + List.map changeList matrix + +let fillFirstEmptyPosition (matrix : int list list) = + let replaceFunction = fillFirstEmptyPositionWith matrix + [ 1 .. 9 ] + |> List.map replaceFunction let rec solve matrix = if isComplete matrix then [matrix] else @@ -37,27 +52,24 @@ let rec solve matrix = |> List.filter isMatrixValid |> List.map solve |> List.concat + +let testData = + [[ 1; 2; 3; 4] + [ 5; 6; 7; 8] + [ 9; 10; 11; 12] + [13; 14; 15; 16]] +let printData l = + l + |> Seq.iter (fun n -> printfn "%A" n) +let transform (l : int list list) = + l +testData + |> transform + |> printData - - - - - - - - - - - - - - - - - - +System.Console.ReadKey() |> ignore \ No newline at end of file From fdaa001f57d069a6a4c30233faae33b99d840dbf Mon Sep 17 00:00:00 2001 From: MartinMayr Date: Sun, 27 Mar 2011 20:19:05 +0200 Subject: [PATCH 2/4] Beschreibung des Algorithmus hinzugefuegt --- Source/SudokuSolver/AlgorithmusBeschreibung.txt | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 Source/SudokuSolver/AlgorithmusBeschreibung.txt diff --git a/Source/SudokuSolver/AlgorithmusBeschreibung.txt b/Source/SudokuSolver/AlgorithmusBeschreibung.txt new file mode 100644 index 0000000..a7b5096 --- /dev/null +++ b/Source/SudokuSolver/AlgorithmusBeschreibung.txt @@ -0,0 +1,6 @@ +Kernstück der Lösung ist eine rekursive Methode die ihre Endbedingung erreicht +sobald die Matrix vollständig ausgefüllt ist und keine Regelverstöße enthält. +Die Methode übernimmt eine Matrix und ersetzt die erste freie Position durch alle möglichen Zaheln (1-9). +Aus den dadurch entstanden neuen Matrizen werden die gefiltert, die gegen die Regeln verstoßen. +Die übrigen Matrizen gehen in das nächste Rekursionslevel um die nächste freie Position auszufüllen. +Die "Root"-Methode liefert eine Liste aller möglichen Lösungen zurück. \ No newline at end of file From 92bb958f935c681ef2f634fafb2a338de420b709 Mon Sep 17 00:00:00 2001 From: MartinMayr Date: Sun, 27 Mar 2011 20:29:19 +0200 Subject: [PATCH 3/4] CSharp-Implementierung der Transpose-Methode --- Source/SudokuSolver/SudokuSolver.sln | 7 +++ Source/SudokuSolverCSharp/Program.cs | 52 +++++++++++++++++ .../Properties/AssemblyInfo.cs | 36 ++++++++++++ .../SudokuSolverCSharp.csproj | 57 +++++++++++++++++++ 4 files changed, 152 insertions(+) create mode 100644 Source/SudokuSolverCSharp/Program.cs create mode 100644 Source/SudokuSolverCSharp/Properties/AssemblyInfo.cs create mode 100644 Source/SudokuSolverCSharp/SudokuSolverCSharp.csproj diff --git a/Source/SudokuSolver/SudokuSolver.sln b/Source/SudokuSolver/SudokuSolver.sln index 2064c96..2d2dc94 100644 --- a/Source/SudokuSolver/SudokuSolver.sln +++ b/Source/SudokuSolver/SudokuSolver.sln @@ -5,9 +5,12 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "SudokuSolver", "SudokuSolve EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{48312B1C-323F-41DF-9D51-5F5C06E6F34B}" ProjectSection(SolutionItems) = preProject + AlgorithmusBeschreibung.txt = AlgorithmusBeschreibung.txt ..\..\README.markdown = ..\..\README.markdown EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SudokuSolverCSharp", "..\SudokuSolverCSharp\SudokuSolverCSharp.csproj", "{0F2E3C11-483C-43E9-9645-3A4A34FCDDAA}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x86 = Debug|x86 @@ -18,6 +21,10 @@ Global {F37F8189-F2BC-415D-99DE-E9F692B5AA70}.Debug|x86.Build.0 = Debug|x86 {F37F8189-F2BC-415D-99DE-E9F692B5AA70}.Release|x86.ActiveCfg = Release|x86 {F37F8189-F2BC-415D-99DE-E9F692B5AA70}.Release|x86.Build.0 = Release|x86 + {0F2E3C11-483C-43E9-9645-3A4A34FCDDAA}.Debug|x86.ActiveCfg = Debug|x86 + {0F2E3C11-483C-43E9-9645-3A4A34FCDDAA}.Debug|x86.Build.0 = Debug|x86 + {0F2E3C11-483C-43E9-9645-3A4A34FCDDAA}.Release|x86.ActiveCfg = Release|x86 + {0F2E3C11-483C-43E9-9645-3A4A34FCDDAA}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Source/SudokuSolverCSharp/Program.cs b/Source/SudokuSolverCSharp/Program.cs new file mode 100644 index 0000000..2eef3f0 --- /dev/null +++ b/Source/SudokuSolverCSharp/Program.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace SudokuSolverCSharp +{ + class Program + { + private static readonly List> Original = new List> + { + new List{1,5,9,13}, + new List{2,6,10,14}, + new List{3,7,11,15}, + new List{4,8,12,16} + }; + + private static readonly List> Rsesult = new List> + { + new List{1,2,3,4}, + new List{5,6,7,8}, + new List{9,10,11,12}, + new List{13,14,15,16} + }; + + static void Main(string[] args) + { + PrintResult(Transpose(Original)); + Console.ReadKey(); + } + + private static List> Transpose(List> original) + { + List> result = new List>(); + + for (int i = 0; i < original[0].Count; i++) + { + result.Add(new List()); + foreach (List number in original) + { + result[i].Add(number[i]); + } + } + + return result; + } + + private static void PrintResult(List> data) + { + data.ForEach(l => Console.WriteLine(string.Join("; ", l.Select(z => z.ToString())))); + } + } +} diff --git a/Source/SudokuSolverCSharp/Properties/AssemblyInfo.cs b/Source/SudokuSolverCSharp/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..88270cd --- /dev/null +++ b/Source/SudokuSolverCSharp/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("SudokuSolverCSharp")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("SudokuSolverCSharp")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2011")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("558dd987-cc07-4d7e-a2d5-55f10507f706")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Source/SudokuSolverCSharp/SudokuSolverCSharp.csproj b/Source/SudokuSolverCSharp/SudokuSolverCSharp.csproj new file mode 100644 index 0000000..73e0186 --- /dev/null +++ b/Source/SudokuSolverCSharp/SudokuSolverCSharp.csproj @@ -0,0 +1,57 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {0F2E3C11-483C-43E9-9645-3A4A34FCDDAA} + Exe + Properties + SudokuSolverCSharp + SudokuSolverCSharp + v4.0 + Client + 512 + + + x86 + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + x86 + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + \ No newline at end of file From 7436fdd72c1f4244688f488f20d2debd5468550f Mon Sep 17 00:00:00 2001 From: MartinMayr Date: Mon, 28 Mar 2011 20:19:39 +0200 Subject: [PATCH 4/4] Extrahieren der Boxen implementiert --- Source/SudokuSolver/Program.fs | 85 ++++++++++++++++++++++++------- Source/SudokuSolver/SampleData.fs | 15 +++++- 2 files changed, 81 insertions(+), 19 deletions(-) diff --git a/Source/SudokuSolver/Program.fs b/Source/SudokuSolver/Program.fs index 83257a7..604cec8 100644 --- a/Source/SudokuSolver/Program.fs +++ b/Source/SudokuSolver/Program.fs @@ -4,9 +4,39 @@ let rec transpose = function | (_::_)::_ as M -> List.map List.head M :: transpose (List.map List.tail M) | _ -> [] +let removeElements l count = + let rec r = fun counter list -> + if counter = count then + list + else + list |> List.tail |> r (counter + 1) + r 0 l + +let rec buildTuples (l : int list list) = + if l.Length = 0 then + [] + else + let f = List.zip3 (List.head l) (List.nth l 1) (List.nth l 2) + List.append f (buildTuples (removeElements l 3)) + +let buildListFromTupel (a, b, c) = + [a ; b; c] + +let rec combineTuples (l : (int * int * int) list) = + if l.Length = 0 then + [] + else + let f = List.head l + let s = List.nth l 1 + let t = List.nth l 2 + (buildListFromTupel f @ buildListFromTupel s @ buildListFromTupel t) :: combineTuples(removeElements l 3) + let GetRows = id let GetCols = transpose -let GetBoxes = id // Homework +let GetBoxes l = + l + |> buildTuples + |> combineTuples let isAllUnique numbers = let set = new HashSet<_>() @@ -22,11 +52,12 @@ let isMatrixValid matrix = rows @ cols @ boxes |> Seq.forall isAllUnique -let listContainsZero = List.forall ((<>) 0) +let listContainsZero = List.exists ((=) 0) let isComplete matrix = matrix |> Seq.exists listContainsZero + |> not let rec fillFirstEmptyPositionWith matrix number = let m = ref number @@ -46,30 +77,48 @@ let fillFirstEmptyPosition (matrix : int list list) = |> List.map replaceFunction let rec solve matrix = - if isComplete matrix then [matrix] else - matrix - |> fillFirstEmptyPosition - |> List.filter isMatrixValid - |> List.map solve - |> List.concat - + if isComplete matrix then [matrix] + else + matrix + |> fillFirstEmptyPosition + |> List.filter isMatrixValid + |> List.map solve + |> List.concat let testData = - [[ 1; 2; 3; 4] - [ 5; 6; 7; 8] - [ 9; 10; 11; 12] - [13; 14; 15; 16]] + [[0; 0; 8; 3; 0; 0; 6; 0; 0] + [0; 0; 4; 0; 0; 0; 0; 1; 0] + [6; 7; 0; 0; 8; 0; 0; 0; 0] -let printData l = - l - |> Seq.iter (fun n -> printfn "%A" n) + [0; 1; 6; 4; 3; 0; 0; 0; 0] + [0; 0; 0; 7; 9; 0; 0; 2; 0] + [0; 9; 0; 0; 0; 0; 4; 0; 1] -let transform (l : int list list) = + [0; 0; 0; 9; 1; 0; 0; 0; 5] + [0; 0; 3; 0; 5; 0; 0; 0; 2] + [0; 5; 0; 0; 0; 0; 0; 7; 4]] +let printCell i cell = + printf "%A " cell + if (i % 3) = 2 then printf " " + +let printRow i row = + Seq.iteri printCell row + + printfn "" + if (i % 3) = 2 then printfn "" + +let printGrid grid = + grid + |> Seq.iteri printRow + printfn "" + +let printData l = l + |> Seq.iter printGrid testData - |> transform + |> solve |> printData System.Console.ReadKey() |> ignore \ No newline at end of file diff --git a/Source/SudokuSolver/SampleData.fs b/Source/SudokuSolver/SampleData.fs index 95e9275..e77e794 100644 --- a/Source/SudokuSolver/SampleData.fs +++ b/Source/SudokuSolver/SampleData.fs @@ -23,4 +23,17 @@ let field2 = [0; 0; 0; 9; 1; 0; 0; 0; 5] [0; 0; 3; 0; 5; 0; 0; 0; 2] - [0; 5; 0; 0; 0; 0; 0; 7; 4]] \ No newline at end of file + [0; 5; 0; 0; 0; 0; 0; 7; 4]] + +let field3 = + [[6; 5; 0; 0; 7; 1; 0; 0; 4] + [7; 9; 8; 2; 0; 4; 0; 0; 6] + [0; 0; 4; 6; 0; 0; 3; 0; 0] + + [0; 0; 0; 0; 2; 0; 8; 0; 0] + [1; 0; 2; 0; 4; 0; 6; 0; 5] + [0; 0; 9; 0; 1; 0; 0; 0; 0] + + [0; 0; 6; 0; 0; 2; 1; 0; 0] + [9; 0; 0; 3; 0; 5; 7; 8; 2] + [8; 0; 0; 1; 9; 0; 0; 6; 3]]