├── Inputs ├── in_1.json ├── in_10.json ├── in_2.json ├── in_3.json ├── in_4.json ├── in_5.json ├── in_6.json ├── in_7.json ├── in_8.json └── in_9.json ├── LICENSE ├── README.md ├── Squares.sln ├── SquaresFrontEnd ├── App.config ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── PuzzleDTOs.cs ├── SolverHelper.cs ├── SquareSolverForm.Designer.cs ├── SquareSolverForm.cs ├── SquareSolverForm.resx ├── SquaresFrontEnd.csproj └── packages.config ├── SquaresService ├── App.config ├── CleanupService.cs ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── SquareSolverService.cs ├── SquaresService.csproj └── packages.config ├── SquaresServiceInterface ├── CleanupService.cs ├── Properties │ └── AssemblyInfo.cs ├── SquaresServiceInterface.csproj └── SquaresSolverService.cs ├── SquaresSolver ├── Configuration.cs ├── FastDictionary.cs ├── Fnv1a64.cs ├── PathStateLarge.cs ├── PathStateMedium.cs ├── PathStateShort.cs ├── Properties │ └── AssemblyInfo.cs ├── SquareTilingBase.cs ├── SquareTilingCombinatorics.cs ├── SquareTilingHeuristic.cs ├── SquareTilingHeuristicLarge.cs ├── SquareTilingOptimal.cs └── SquaresSolver.csproj ├── SquaresSolverTypes ├── Properties │ └── AssemblyInfo.cs ├── Square.cs └── SquaresSolverTypes.csproj └── packages └── repositories.config /Inputs/in_1.json: -------------------------------------------------------------------------------- 1 | {"width":35,"height":23,"puzzle":[[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,false,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,false,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,false,true,true,false,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true],[true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false],[true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,false,true,true,false,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,false,true,true,true,true,true,true,true,true,true,false,true,false,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]],"id":"43bf67a1263f47b1b22028ca2d8bb6f7-14324325136181883"} -------------------------------------------------------------------------------- /Inputs/in_10.json: -------------------------------------------------------------------------------- 1 | {"width":26,"height":24,"puzzle":[[true,true,false,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[false,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,false,true,true,true],[true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true],[true,true,true,true,false,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,false,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true]],"id":"857de503e3b34e1fbfd7b37819a707b3-14324326279932558"} -------------------------------------------------------------------------------- /Inputs/in_2.json: -------------------------------------------------------------------------------- 1 | {"width":34,"height":26,"puzzle":[[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false],[true,true,true,true,true,true,true,false,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,false,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]],"id":"cc2729b9d1c64581a936913a0478cdbd-14324325388995174"} -------------------------------------------------------------------------------- /Inputs/in_3.json: -------------------------------------------------------------------------------- 1 | {"width":33,"height":29,"puzzle":[[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,false,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,false,true,false,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,false,true,true,true,true,true,true,true,true,false,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,false,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,false,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,false,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,false,true,true,true,true,false,true,true,true,true,true]],"id":"4fc8ebfb9eb7493baf134f60d8cf18e3-14324325512431923"} -------------------------------------------------------------------------------- /Inputs/in_4.json: -------------------------------------------------------------------------------- 1 | {"width":28,"height":31,"puzzle":[[true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true],[true,false,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,false,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,false,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,false,false,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true],[true,true,true,false,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true]],"id":"9d586c6bd62a4ed59c74f40defa541e9-14324325612119579"} -------------------------------------------------------------------------------- /Inputs/in_5.json: -------------------------------------------------------------------------------- 1 | {"width":37,"height":33,"puzzle":[[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,false,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true],[true,false,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true],[false,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,false,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]],"id":"aff9146ee3e54207aee6bbd07cba431f-14324325703994873"} -------------------------------------------------------------------------------- /Inputs/in_6.json: -------------------------------------------------------------------------------- 1 | {"width":25,"height":35,"puzzle":[[true,true,true,true,true,true,true,true,true,true,false,true,false,true,true,true,true,true,true,false,true,true,true,true,true],[true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true],[true,false,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true],[false,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,false,true,true,true,true,true,false,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[false,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true],[true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true],[true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false],[true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true],[true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true],[true,true,true,false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,false,true],[true,true,true,true,true,false,true,true,true,false,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true],[true,true,false,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]],"id":"ec8ce846678b40e48c2a18e68be979dc-14324325909932628"} -------------------------------------------------------------------------------- /Inputs/in_7.json: -------------------------------------------------------------------------------- 1 | {"width":27,"height":32,"puzzle":[[true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,false,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true],[true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,false,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true],[false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,false,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false]],"id":"233524733c8c46108f5dc5b635ef5c73-14324326008213440"} -------------------------------------------------------------------------------- /Inputs/in_8.json: -------------------------------------------------------------------------------- 1 | {"width":31,"height":21,"puzzle":[[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,false,false,false,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,false,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true],[false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true],[true,true,false,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true],[true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true],[true,true,true,false,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[false,true,true,true,false,true,true,false,true,false,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,false,false,false,true,true,true,false,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,false,true,true,true,true,false,true,true,true,false,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true],[true,false,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true]],"id":"91366c238218488d96c759da94077adc-14324326115557359"} -------------------------------------------------------------------------------- /Inputs/in_9.json: -------------------------------------------------------------------------------- 1 | {"width":25,"height":27,"puzzle":[[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true],[true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,false,true,false,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,false,true,true,true,false,true,true,true,true,true,true,true,true,true,false],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true],[true,true,true,true,true,true,true,true,true,true,true,true,false,true,true,true,true,true,true,true,true,true,true,true,true]],"id":"9bc693903677452eaadb629ce086765a-14324326189463589"} -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Dimitar Blagoev Blagoev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Squares.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SquaresFrontEnd", "SquaresFrontEnd\SquaresFrontEnd.csproj", "{3066047D-5777-46B0-9727-653238F4C700}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SquaresService", "SquaresService\SquaresService.csproj", "{43C0FE8D-98D5-4A2E-8C1E-21CB5D30653A}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B8EA0214-4BDD-4CEF-95A1-B674F86A4014}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SquaresSolver", "SquaresSolver\SquaresSolver.csproj", "{3501B846-E1D2-4253-A786-48E324E50C27}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SquaresServiceInterface", "SquaresServiceInterface\SquaresServiceInterface.csproj", "{F4DFE510-B82F-4EF2-9181-A9D3546AB49E}" 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SquaresSolverTypes", "SquaresSolverTypes\SquaresSolverTypes.csproj", "{3C668274-B94A-487E-AF47-970D3A0515E5}" 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug|Any CPU = Debug|Any CPU 21 | Debug|Mixed Platforms = Debug|Mixed Platforms 22 | Debug|Win32 = Debug|Win32 23 | Debug|x64 = Debug|x64 24 | Release|Any CPU = Release|Any CPU 25 | Release|Mixed Platforms = Release|Mixed Platforms 26 | Release|Win32 = Release|Win32 27 | Release|x64 = Release|x64 28 | EndGlobalSection 29 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 30 | {43C0FE8D-98D5-4A2E-8C1E-21CB5D30653A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {43C0FE8D-98D5-4A2E-8C1E-21CB5D30653A}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {43C0FE8D-98D5-4A2E-8C1E-21CB5D30653A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 33 | {43C0FE8D-98D5-4A2E-8C1E-21CB5D30653A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 34 | {43C0FE8D-98D5-4A2E-8C1E-21CB5D30653A}.Debug|Win32.ActiveCfg = Debug|Any CPU 35 | {43C0FE8D-98D5-4A2E-8C1E-21CB5D30653A}.Debug|x64.ActiveCfg = Debug|x64 36 | {43C0FE8D-98D5-4A2E-8C1E-21CB5D30653A}.Debug|x64.Build.0 = Debug|x64 37 | {43C0FE8D-98D5-4A2E-8C1E-21CB5D30653A}.Release|Any CPU.ActiveCfg = Release|Any CPU 38 | {43C0FE8D-98D5-4A2E-8C1E-21CB5D30653A}.Release|Any CPU.Build.0 = Release|Any CPU 39 | {43C0FE8D-98D5-4A2E-8C1E-21CB5D30653A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 40 | {43C0FE8D-98D5-4A2E-8C1E-21CB5D30653A}.Release|Mixed Platforms.Build.0 = Release|Any CPU 41 | {43C0FE8D-98D5-4A2E-8C1E-21CB5D30653A}.Release|Win32.ActiveCfg = Release|Any CPU 42 | {43C0FE8D-98D5-4A2E-8C1E-21CB5D30653A}.Release|x64.ActiveCfg = Release|x64 43 | {43C0FE8D-98D5-4A2E-8C1E-21CB5D30653A}.Release|x64.Build.0 = Release|x64 44 | {3066047D-5777-46B0-9727-653238F4C700}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 45 | {3066047D-5777-46B0-9727-653238F4C700}.Debug|Any CPU.Build.0 = Debug|Any CPU 46 | {3066047D-5777-46B0-9727-653238F4C700}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 47 | {3066047D-5777-46B0-9727-653238F4C700}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 48 | {3066047D-5777-46B0-9727-653238F4C700}.Debug|Win32.ActiveCfg = Debug|Any CPU 49 | {3066047D-5777-46B0-9727-653238F4C700}.Debug|x64.ActiveCfg = Debug|x64 50 | {3066047D-5777-46B0-9727-653238F4C700}.Debug|x64.Build.0 = Debug|x64 51 | {3066047D-5777-46B0-9727-653238F4C700}.Release|Any CPU.ActiveCfg = Release|Any CPU 52 | {3066047D-5777-46B0-9727-653238F4C700}.Release|Any CPU.Build.0 = Release|Any CPU 53 | {3066047D-5777-46B0-9727-653238F4C700}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 54 | {3066047D-5777-46B0-9727-653238F4C700}.Release|Mixed Platforms.Build.0 = Release|Any CPU 55 | {3066047D-5777-46B0-9727-653238F4C700}.Release|Win32.ActiveCfg = Release|Any CPU 56 | {3066047D-5777-46B0-9727-653238F4C700}.Release|x64.ActiveCfg = Release|x64 57 | {3066047D-5777-46B0-9727-653238F4C700}.Release|x64.Build.0 = Release|x64 58 | {3501B846-E1D2-4253-A786-48E324E50C27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 59 | {3501B846-E1D2-4253-A786-48E324E50C27}.Debug|Any CPU.Build.0 = Debug|Any CPU 60 | {3501B846-E1D2-4253-A786-48E324E50C27}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 61 | {3501B846-E1D2-4253-A786-48E324E50C27}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 62 | {3501B846-E1D2-4253-A786-48E324E50C27}.Debug|Win32.ActiveCfg = Debug|Any CPU 63 | {3501B846-E1D2-4253-A786-48E324E50C27}.Debug|x64.ActiveCfg = Debug|x64 64 | {3501B846-E1D2-4253-A786-48E324E50C27}.Debug|x64.Build.0 = Debug|x64 65 | {3501B846-E1D2-4253-A786-48E324E50C27}.Release|Any CPU.ActiveCfg = Release|Any CPU 66 | {3501B846-E1D2-4253-A786-48E324E50C27}.Release|Any CPU.Build.0 = Release|Any CPU 67 | {3501B846-E1D2-4253-A786-48E324E50C27}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 68 | {3501B846-E1D2-4253-A786-48E324E50C27}.Release|Mixed Platforms.Build.0 = Release|Any CPU 69 | {3501B846-E1D2-4253-A786-48E324E50C27}.Release|Win32.ActiveCfg = Release|Any CPU 70 | {3501B846-E1D2-4253-A786-48E324E50C27}.Release|x64.ActiveCfg = Release|x64 71 | {3501B846-E1D2-4253-A786-48E324E50C27}.Release|x64.Build.0 = Release|x64 72 | {F4DFE510-B82F-4EF2-9181-A9D3546AB49E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 73 | {F4DFE510-B82F-4EF2-9181-A9D3546AB49E}.Debug|Any CPU.Build.0 = Debug|Any CPU 74 | {F4DFE510-B82F-4EF2-9181-A9D3546AB49E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 75 | {F4DFE510-B82F-4EF2-9181-A9D3546AB49E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 76 | {F4DFE510-B82F-4EF2-9181-A9D3546AB49E}.Debug|Win32.ActiveCfg = Debug|Any CPU 77 | {F4DFE510-B82F-4EF2-9181-A9D3546AB49E}.Debug|x64.ActiveCfg = Debug|x64 78 | {F4DFE510-B82F-4EF2-9181-A9D3546AB49E}.Debug|x64.Build.0 = Debug|x64 79 | {F4DFE510-B82F-4EF2-9181-A9D3546AB49E}.Release|Any CPU.ActiveCfg = Release|Any CPU 80 | {F4DFE510-B82F-4EF2-9181-A9D3546AB49E}.Release|Any CPU.Build.0 = Release|Any CPU 81 | {F4DFE510-B82F-4EF2-9181-A9D3546AB49E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 82 | {F4DFE510-B82F-4EF2-9181-A9D3546AB49E}.Release|Mixed Platforms.Build.0 = Release|Any CPU 83 | {F4DFE510-B82F-4EF2-9181-A9D3546AB49E}.Release|Win32.ActiveCfg = Release|Any CPU 84 | {F4DFE510-B82F-4EF2-9181-A9D3546AB49E}.Release|x64.ActiveCfg = Release|x64 85 | {F4DFE510-B82F-4EF2-9181-A9D3546AB49E}.Release|x64.Build.0 = Release|x64 86 | {3C668274-B94A-487E-AF47-970D3A0515E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 87 | {3C668274-B94A-487E-AF47-970D3A0515E5}.Debug|Any CPU.Build.0 = Debug|Any CPU 88 | {3C668274-B94A-487E-AF47-970D3A0515E5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 89 | {3C668274-B94A-487E-AF47-970D3A0515E5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 90 | {3C668274-B94A-487E-AF47-970D3A0515E5}.Debug|Win32.ActiveCfg = Debug|Any CPU 91 | {3C668274-B94A-487E-AF47-970D3A0515E5}.Debug|x64.ActiveCfg = Debug|x64 92 | {3C668274-B94A-487E-AF47-970D3A0515E5}.Debug|x64.Build.0 = Debug|x64 93 | {3C668274-B94A-487E-AF47-970D3A0515E5}.Release|Any CPU.ActiveCfg = Release|Any CPU 94 | {3C668274-B94A-487E-AF47-970D3A0515E5}.Release|Any CPU.Build.0 = Release|Any CPU 95 | {3C668274-B94A-487E-AF47-970D3A0515E5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 96 | {3C668274-B94A-487E-AF47-970D3A0515E5}.Release|Mixed Platforms.Build.0 = Release|Any CPU 97 | {3C668274-B94A-487E-AF47-970D3A0515E5}.Release|Win32.ActiveCfg = Release|Any CPU 98 | {3C668274-B94A-487E-AF47-970D3A0515E5}.Release|x64.ActiveCfg = Release|x64 99 | {3C668274-B94A-487E-AF47-970D3A0515E5}.Release|x64.Build.0 = Release|x64 100 | EndGlobalSection 101 | GlobalSection(SolutionProperties) = preSolution 102 | HideSolutionNode = FALSE 103 | EndGlobalSection 104 | EndGlobal 105 | -------------------------------------------------------------------------------- /SquaresFrontEnd/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /SquaresFrontEnd/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms; 6 | 7 | namespace Squares 8 | { 9 | static class Program 10 | { 11 | /// 12 | /// The main entry point for the application. 13 | /// 14 | [STAThread] 15 | static void Main() 16 | { 17 | Application.EnableVisualStyles(); 18 | Application.SetCompatibleTextRenderingDefault(false); 19 | Application.Run(new SquareSolverForm()); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /SquaresFrontEnd/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Squares")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("Squares")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("35957353-38e0-41cf-b316-0dea3dc3ddfa")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /SquaresFrontEnd/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.0 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Squares.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Squares.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /SquaresFrontEnd/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /SquaresFrontEnd/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.0 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Squares.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SquaresFrontEnd/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SquaresFrontEnd/PuzzleDTOs.cs: -------------------------------------------------------------------------------- 1 | using SquaresSolverTypes; 2 | using System; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Squares 10 | { 11 | public class PuzzleRequest 12 | { 13 | public int width { get; set; } 14 | public int height { get; set; } 15 | 16 | public List puzzle { get; set; } 17 | 18 | public string id { get; set; } 19 | } 20 | 21 | public class PuzzleResponse 22 | { 23 | public string id { get; set; } 24 | 25 | public List squares { get; set; } 26 | 27 | public void SetSquares(List p_squares) 28 | { 29 | squares = new List(); 30 | foreach (var square in p_squares) 31 | { 32 | squares.Add(new PuzzleResponseSquare(square)); 33 | } 34 | } 35 | } 36 | 37 | public class PuzzleResponseSquare 38 | { 39 | public int X { get; set; } 40 | public int Y { get; set; } 41 | public int Size { get; set; } 42 | 43 | public PuzzleResponseSquare(Square square) 44 | { 45 | X = square.x; 46 | Y = square.y; 47 | Size = square.size; 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /SquaresFrontEnd/SolverHelper.cs: -------------------------------------------------------------------------------- 1 | using ServiceStack.Text; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Net; 6 | using ServiceStack; 7 | using SquaresSolverTypes; 8 | 9 | namespace Squares 10 | { 11 | public class SolverHelper 12 | { 13 | private const string puzzleServerUrl = "http://techchallenge.cimpress.com/"; 14 | private const string registrationKey = "yourCimpressTechChallengeRegistrationKey"; 15 | 16 | private const string outputFolder = @".\\puzzles\\"; 17 | 18 | public static PuzzleRequest FetchOnlinePuzzle(string mode) 19 | { 20 | PuzzleRequest pr; 21 | 22 | Directory.CreateDirectory(outputFolder + mode); 23 | 24 | string puzzleUrl = puzzleServerUrl + registrationKey + "/" + mode + "/puzzle"; 25 | 26 | WebRequest wrPuzzle = WebRequest.Create(puzzleUrl); 27 | 28 | string puzzle = new StreamReader(wrPuzzle.GetResponse().GetResponseStream()).ReadToEnd(); 29 | 30 | pr = JsonSerializer.DeserializeFromString(puzzle); 31 | 32 | string outputFileName = outputFolder + mode + "\\" + pr.id + ".json"; 33 | 34 | using (var output = new StreamWriter(new FileStream(outputFileName, FileMode.Append))) 35 | { 36 | output.Write(puzzle); 37 | } 38 | 39 | return pr; 40 | } 41 | 42 | public static PuzzleRequest FetchLocalPuzzle(string fileName) 43 | { 44 | PuzzleRequest pr; 45 | 46 | using (var inputStream = new FileStream(fileName, FileMode.Open)) 47 | { 48 | pr = JsonSerializer.DeserializeFromStream(inputStream); 49 | } 50 | 51 | return pr; 52 | } 53 | 54 | public static string SendOnlineResponse(PuzzleRequest pr, string mode, List solution) 55 | { 56 | PuzzleResponse response = new PuzzleResponse(); 57 | 58 | response.id = pr.id; 59 | response.SetSquares(solution); 60 | 61 | string postData = JsonSerializer.SerializeToString(response); 62 | 63 | string solutionUrl = puzzleServerUrl + registrationKey + "/" + mode + "/solution"; 64 | 65 | var wrSolution = (HttpWebRequest)WebRequest.Create(solutionUrl); 66 | 67 | wrSolution.Method = "POST"; 68 | wrSolution.ContentType = "application/json"; 69 | wrSolution.Accept = "application/json"; 70 | Stream dataStream = wrSolution.GetRequestStream(); 71 | dataStream.Write(postData); 72 | dataStream.Flush(); 73 | dataStream.Close(); 74 | 75 | WebResponse solutionResponse; 76 | 77 | solutionResponse = wrSolution.GetResponse(); 78 | 79 | dataStream = solutionResponse.GetResponseStream(); 80 | StreamReader reader = new StreamReader(dataStream); 81 | string responseFromServer = reader.ReadToEnd(); 82 | 83 | Console.WriteLine(responseFromServer); 84 | 85 | reader.Close(); 86 | dataStream.Close(); 87 | solutionResponse.Close(); 88 | return responseFromServer; 89 | } 90 | 91 | public static string LogOnlineResult(string mode, string responseFromServer, int resultsCount, int internalTotalTime, int totalTime) 92 | { 93 | string logLine = responseFromServer + "," + totalTime.ToString() + "," + internalTotalTime.ToString() + "," + resultsCount.ToString(); 94 | 95 | var logFileName = outputFolder + mode + "_run.log"; 96 | 97 | using (var output = new StreamWriter(new FileStream(logFileName, FileMode.Append))) 98 | { 99 | output.WriteLine(logLine); 100 | } 101 | return logLine; 102 | } 103 | 104 | public static string LogLocalResult(string fileName, int squaresCount, int resultsCount, int internalTotalTime, int totalTime) 105 | { 106 | string logLine = Path.GetFileNameWithoutExtension(fileName) + "," + squaresCount.ToString() + "," + totalTime.ToString() + "," + internalTotalTime.ToString() + "," + resultsCount.ToString(); 107 | 108 | Directory.CreateDirectory(outputFolder); 109 | 110 | var logFileName = outputFolder + new DirectoryInfo(Path.GetDirectoryName(fileName)).Name + "_run.log"; 111 | 112 | using (var output = new StreamWriter(new FileStream(logFileName, FileMode.Append))) 113 | { 114 | output.WriteLine(logLine); 115 | } 116 | return logLine; 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /SquaresFrontEnd/SquareSolverForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace Squares 2 | { 3 | partial class SquareSolverForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.btnSolveOnline = new System.Windows.Forms.Button(); 32 | this.btnSolveLocal = new System.Windows.Forms.Button(); 33 | this.pictureBox1 = new System.Windows.Forms.PictureBox(); 34 | this.panel1 = new System.Windows.Forms.Panel(); 35 | this.mtbPuzzleCount = new System.Windows.Forms.MaskedTextBox(); 36 | this.labelSolve = new System.Windows.Forms.Label(); 37 | this.cbMode = new System.Windows.Forms.CheckBox(); 38 | this.lbLog = new System.Windows.Forms.ListBox(); 39 | this.cbInverseY = new System.Windows.Forms.CheckBox(); 40 | this.cbInverseX = new System.Windows.Forms.CheckBox(); 41 | this.cbTranspose = new System.Windows.Forms.CheckBox(); 42 | this.labelResultsProcessed = new System.Windows.Forms.Label(); 43 | this.labelSquareCount = new System.Windows.Forms.Label(); 44 | this.openLocalFileDialog = new System.Windows.Forms.OpenFileDialog(); 45 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); 46 | this.panel1.SuspendLayout(); 47 | this.SuspendLayout(); 48 | // 49 | // btnSolveOnline 50 | // 51 | this.btnSolveOnline.Location = new System.Drawing.Point(168, 12); 52 | this.btnSolveOnline.Name = "btnSolveOnline"; 53 | this.btnSolveOnline.Size = new System.Drawing.Size(146, 23); 54 | this.btnSolveOnline.TabIndex = 0; 55 | this.btnSolveOnline.Text = "Solve Online Puzzles"; 56 | this.btnSolveOnline.UseVisualStyleBackColor = true; 57 | this.btnSolveOnline.Click += new System.EventHandler(this.btnSolveOnline_Click); 58 | // 59 | // btnSolveLocal 60 | // 61 | this.btnSolveLocal.Location = new System.Drawing.Point(425, 12); 62 | this.btnSolveLocal.Name = "btnSolveLocal"; 63 | this.btnSolveLocal.Size = new System.Drawing.Size(146, 23); 64 | this.btnSolveLocal.TabIndex = 1; 65 | this.btnSolveLocal.Text = "Re-Solve Local Puzzles"; 66 | this.btnSolveLocal.UseVisualStyleBackColor = true; 67 | this.btnSolveLocal.Click += new System.EventHandler(this.btnSolveLocal_Click); 68 | // 69 | // pictureBox1 70 | // 71 | this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill; 72 | this.pictureBox1.Location = new System.Drawing.Point(0, 127); 73 | this.pictureBox1.Name = "pictureBox1"; 74 | this.pictureBox1.Size = new System.Drawing.Size(944, 795); 75 | this.pictureBox1.TabIndex = 2; 76 | this.pictureBox1.TabStop = false; 77 | this.pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint); 78 | // 79 | // panel1 80 | // 81 | this.panel1.Controls.Add(this.mtbPuzzleCount); 82 | this.panel1.Controls.Add(this.labelSolve); 83 | this.panel1.Controls.Add(this.cbMode); 84 | this.panel1.Controls.Add(this.lbLog); 85 | this.panel1.Controls.Add(this.cbInverseY); 86 | this.panel1.Controls.Add(this.cbInverseX); 87 | this.panel1.Controls.Add(this.cbTranspose); 88 | this.panel1.Controls.Add(this.labelResultsProcessed); 89 | this.panel1.Controls.Add(this.labelSquareCount); 90 | this.panel1.Controls.Add(this.btnSolveOnline); 91 | this.panel1.Controls.Add(this.btnSolveLocal); 92 | this.panel1.Dock = System.Windows.Forms.DockStyle.Top; 93 | this.panel1.Location = new System.Drawing.Point(0, 0); 94 | this.panel1.Name = "panel1"; 95 | this.panel1.Size = new System.Drawing.Size(944, 127); 96 | this.panel1.TabIndex = 3; 97 | // 98 | // mtbPuzzleCount 99 | // 100 | this.mtbPuzzleCount.Location = new System.Drawing.Point(52, 14); 101 | this.mtbPuzzleCount.Mask = "00000"; 102 | this.mtbPuzzleCount.Name = "mtbPuzzleCount"; 103 | this.mtbPuzzleCount.Size = new System.Drawing.Size(42, 20); 104 | this.mtbPuzzleCount.TabIndex = 13; 105 | this.mtbPuzzleCount.Text = "1"; 106 | this.mtbPuzzleCount.ValidatingType = typeof(int); 107 | // 108 | // labelSolve 109 | // 110 | this.labelSolve.AutoSize = true; 111 | this.labelSolve.Location = new System.Drawing.Point(12, 17); 112 | this.labelSolve.Name = "labelSolve"; 113 | this.labelSolve.Size = new System.Drawing.Size(34, 13); 114 | this.labelSolve.TabIndex = 12; 115 | this.labelSolve.Text = "Solve"; 116 | // 117 | // cbMode 118 | // 119 | this.cbMode.AutoSize = true; 120 | this.cbMode.Location = new System.Drawing.Point(100, 16); 121 | this.cbMode.Name = "cbMode"; 122 | this.cbMode.Size = new System.Drawing.Size(62, 17); 123 | this.cbMode.TabIndex = 10; 124 | this.cbMode.Text = "Contest"; 125 | this.cbMode.UseVisualStyleBackColor = true; 126 | // 127 | // lbLog 128 | // 129 | this.lbLog.Dock = System.Windows.Forms.DockStyle.Bottom; 130 | this.lbLog.FormattingEnabled = true; 131 | this.lbLog.Location = new System.Drawing.Point(0, 45); 132 | this.lbLog.Name = "lbLog"; 133 | this.lbLog.Size = new System.Drawing.Size(944, 82); 134 | this.lbLog.TabIndex = 9; 135 | // 136 | // cbInverseY 137 | // 138 | this.cbInverseY.AutoSize = true; 139 | this.cbInverseY.Location = new System.Drawing.Point(857, 16); 140 | this.cbInverseY.Name = "cbInverseY"; 141 | this.cbInverseY.Size = new System.Drawing.Size(71, 17); 142 | this.cbInverseY.TabIndex = 7; 143 | this.cbInverseY.Text = "Inverse Y"; 144 | this.cbInverseY.UseVisualStyleBackColor = true; 145 | // 146 | // cbInverseX 147 | // 148 | this.cbInverseX.AutoSize = true; 149 | this.cbInverseX.Location = new System.Drawing.Point(780, 16); 150 | this.cbInverseX.Name = "cbInverseX"; 151 | this.cbInverseX.Size = new System.Drawing.Size(71, 17); 152 | this.cbInverseX.TabIndex = 6; 153 | this.cbInverseX.Text = "Inverse X"; 154 | this.cbInverseX.UseVisualStyleBackColor = true; 155 | // 156 | // cbTranspose 157 | // 158 | this.cbTranspose.AutoSize = true; 159 | this.cbTranspose.Location = new System.Drawing.Point(698, 16); 160 | this.cbTranspose.Name = "cbTranspose"; 161 | this.cbTranspose.Size = new System.Drawing.Size(76, 17); 162 | this.cbTranspose.TabIndex = 5; 163 | this.cbTranspose.Text = "Transpose"; 164 | this.cbTranspose.UseVisualStyleBackColor = true; 165 | // 166 | // labelResultsProcessed 167 | // 168 | this.labelResultsProcessed.AutoSize = true; 169 | this.labelResultsProcessed.Location = new System.Drawing.Point(649, 17); 170 | this.labelResultsProcessed.Name = "labelResultsProcessed"; 171 | this.labelResultsProcessed.Size = new System.Drawing.Size(13, 13); 172 | this.labelResultsProcessed.TabIndex = 4; 173 | this.labelResultsProcessed.Text = "1"; 174 | // 175 | // labelSquareCount 176 | // 177 | this.labelSquareCount.AutoSize = true; 178 | this.labelSquareCount.Location = new System.Drawing.Point(599, 17); 179 | this.labelSquareCount.Name = "labelSquareCount"; 180 | this.labelSquareCount.Size = new System.Drawing.Size(13, 13); 181 | this.labelSquareCount.TabIndex = 2; 182 | this.labelSquareCount.Text = "1"; 183 | // 184 | // openLocalFileDialog 185 | // 186 | this.openLocalFileDialog.Filter = "Json Puzzles|*.json"; 187 | this.openLocalFileDialog.InitialDirectory = "."; 188 | this.openLocalFileDialog.Multiselect = true; 189 | // 190 | // SquareSolverForm 191 | // 192 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 193 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 194 | this.ClientSize = new System.Drawing.Size(944, 922); 195 | this.Controls.Add(this.pictureBox1); 196 | this.Controls.Add(this.panel1); 197 | this.Name = "SquareSolverForm"; 198 | this.Text = "Square Solver"; 199 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); 200 | this.panel1.ResumeLayout(false); 201 | this.panel1.PerformLayout(); 202 | this.ResumeLayout(false); 203 | 204 | } 205 | 206 | #endregion 207 | 208 | private System.Windows.Forms.Button btnSolveOnline; 209 | private System.Windows.Forms.Button btnSolveLocal; 210 | private System.Windows.Forms.PictureBox pictureBox1; 211 | private System.Windows.Forms.Panel panel1; 212 | private System.Windows.Forms.Label labelSquareCount; 213 | private System.Windows.Forms.Label labelResultsProcessed; 214 | private System.Windows.Forms.CheckBox cbInverseY; 215 | private System.Windows.Forms.CheckBox cbInverseX; 216 | private System.Windows.Forms.CheckBox cbTranspose; 217 | private System.Windows.Forms.ListBox lbLog; 218 | private System.Windows.Forms.MaskedTextBox mtbPuzzleCount; 219 | private System.Windows.Forms.Label labelSolve; 220 | private System.Windows.Forms.CheckBox cbMode; 221 | private System.Windows.Forms.OpenFileDialog openLocalFileDialog; 222 | } 223 | } 224 | 225 | -------------------------------------------------------------------------------- /SquaresFrontEnd/SquareSolverForm.cs: -------------------------------------------------------------------------------- 1 | using ServiceStack.Text; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Drawing; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | using System.Windows.Forms; 9 | using System.Threading; 10 | using System.Diagnostics; 11 | using ServiceStack; 12 | using SquaresServiceInterface; 13 | using SquaresSolverTypes; 14 | using SquaresSolver; 15 | 16 | namespace Squares 17 | { 18 | public partial class SquareSolverForm : Form 19 | { 20 | public SquareSolverForm() 21 | { 22 | InitializeComponent(); 23 | 24 | for (int i = 1; i <= 40; i++) 25 | { 26 | Console.WriteLine(i.ToString() + "," + SquareTilingCombinatorics.UniqueTilings(i) + "," + SquareTilingCombinatorics.DerivedTilings(i)); 27 | } 28 | } 29 | 30 | private async Task OnlineSolverTask(string mode) 31 | { 32 | DateTime timeStarted = DateTime.UtcNow; 33 | 34 | PuzzleRequest pr; 35 | 36 | try 37 | { 38 | pr = SolverHelper.FetchOnlinePuzzle(mode); 39 | } 40 | catch (Exception ex) 41 | { 42 | MessageBox.Show("An error occured while retrieving a puzzle from the puzzle server: \n" + ex.Message); 43 | return false; 44 | } 45 | 46 | int resultsCount; 47 | int bestApproach; 48 | 49 | DateTime internalTimeStarted = DateTime.UtcNow; 50 | 51 | var solution = findBestTiling(pr, out resultsCount, out bestApproach); 52 | 53 | int internalTotalTime = (int)(DateTime.UtcNow - internalTimeStarted).TotalMilliseconds; 54 | 55 | string responseFromServer; 56 | 57 | try 58 | { 59 | responseFromServer = SolverHelper.SendOnlineResponse(pr, mode, solution); 60 | } 61 | catch (Exception ex) 62 | { 63 | MessageBox.Show("An error occured while retrieving a puzzle from the puzzle server: \n" + ex.Message); 64 | return false; 65 | } 66 | 67 | int totalTime = (int)(DateTime.UtcNow - timeStarted).TotalMilliseconds; 68 | 69 | string logLine = SolverHelper.LogOnlineResult(mode, responseFromServer, resultsCount, internalTotalTime, totalTime); 70 | 71 | UpdateGUI(pr, resultsCount, bestApproach, solution, logLine); 72 | 73 | return await CleanupWorkers(); 74 | } 75 | 76 | private async Task LocalSolverTask(string fileName) 77 | { 78 | DateTime timeStarted = DateTime.UtcNow; 79 | 80 | PuzzleRequest pr; 81 | 82 | try 83 | { 84 | pr = SolverHelper.FetchLocalPuzzle(fileName); 85 | } 86 | catch (Exception ex) 87 | { 88 | MessageBox.Show("An error occured while retrieving a local puzzle: \n" + ex.Message); 89 | return false; 90 | } 91 | 92 | int resultsCount; 93 | int bestApproach; 94 | 95 | DateTime internalTimeStarted = DateTime.UtcNow; 96 | 97 | var solution = findBestTiling(pr, out resultsCount, out bestApproach); 98 | 99 | int internalTotalTime = (int)(DateTime.UtcNow - internalTimeStarted).TotalMilliseconds; 100 | 101 | int totalTime = (int)(DateTime.UtcNow - timeStarted).TotalMilliseconds; 102 | 103 | string logLine = SolverHelper.LogLocalResult(fileName, solution.Count, resultsCount, internalTotalTime, totalTime); 104 | 105 | UpdateGUI(pr, resultsCount, bestApproach, solution, logLine); 106 | 107 | return await CleanupWorkers(); 108 | } 109 | 110 | private async Task CleanupWorkers() 111 | { 112 | foreach (var thread in threads) 113 | { 114 | thread.Join(); 115 | } 116 | 117 | try 118 | { 119 | List> cleanupTasks = new List>(); 120 | 121 | for (int i = 0; i < 9; i++) 122 | { 123 | var client = new JsonServiceClient("http://localhost:" + (8900 + i).ToString() + "/"); 124 | 125 | var cleanup = client.PostAsync(new CleanupRequest()); 126 | cleanupTasks.Add(cleanup); 127 | } 128 | 129 | foreach (var task in cleanupTasks) 130 | { 131 | var result = await task; 132 | 133 | if (result.success != true) 134 | { 135 | MessageBox.Show("Something Strange Happened"); 136 | return false; 137 | } 138 | } 139 | 140 | return true; 141 | } 142 | catch 143 | { 144 | MessageBox.Show("Something Bad Happened"); 145 | return false; 146 | } 147 | } 148 | 149 | private void UpdateGUI(PuzzleRequest pr, int resultsCount, int bestApproach, List solution, string logLine) 150 | { 151 | this.Invoke((MethodInvoker)delegate 152 | { 153 | int n = pr.width; 154 | int m = pr.height; 155 | 156 | map = new bool[n, m]; 157 | 158 | for (int y = 0; y < m; y++) 159 | { 160 | for (int x = 0; x < n; x++) 161 | { 162 | int ix = x; 163 | int iy = y; 164 | 165 | map[ix, iy] = pr.puzzle[y][x]; 166 | } 167 | } 168 | 169 | shownSolution = solution; 170 | 171 | this.labelSquareCount.Text = shownSolution.Count.ToString(); 172 | 173 | this.labelResultsProcessed.Text = resultsCount.ToString(); 174 | 175 | Console.WriteLine(logLine); 176 | 177 | lbLog.Items.Add(logLine); 178 | 179 | int visibleItems = lbLog.ClientSize.Height / lbLog.ItemHeight; 180 | lbLog.TopIndex = Math.Max(lbLog.Items.Count - visibleItems + 1, 0); 181 | 182 | this.cbTranspose.Checked = (bestApproach >> 2) % 2 == 1; 183 | this.cbInverseX.Checked = (bestApproach >> 1) % 2 == 1; 184 | this.cbInverseY.Checked = bestApproach % 2 == 1; 185 | 186 | pictureBox1.Refresh(); 187 | }); 188 | } 189 | 190 | private void btnSolveOnline_Click(object sender, EventArgs e) 191 | { 192 | var ProcessPool = StartServices(); 193 | 194 | ThreadPool.QueueUserWorkItem(async arg => 195 | { 196 | // Always do one trial run to warm up the services 197 | if (!await OnlineSolverTask("trial")) 198 | { 199 | StopServices(ProcessPool); 200 | return; 201 | } 202 | 203 | int count = 0; 204 | 205 | Int32.TryParse(mtbPuzzleCount.Text, out count); 206 | 207 | string mode = cbMode.Checked ? "contest" : "trial"; 208 | 209 | for (int i = 0; i < count; i++) 210 | { 211 | if (!await OnlineSolverTask(mode)) break; 212 | } 213 | 214 | MessageBox.Show("Puzzle solving complete. You can review the services' console output. Click OK to clean-up."); 215 | 216 | StopServices(ProcessPool); 217 | }); 218 | } 219 | 220 | private static void StopServices(List ProcessPool) 221 | { 222 | Thread.Sleep(2000); 223 | 224 | foreach (var process in ProcessPool) 225 | { 226 | try 227 | { 228 | process.Kill(); 229 | } 230 | catch 231 | { 232 | } 233 | } 234 | } 235 | 236 | private static List StartServices() 237 | { 238 | var ProcessPool = new List(); 239 | 240 | for (int i = 0; i < 9; i++) 241 | { 242 | ProcessPool.Add(Process.Start(@"SquaresService.exe", i.ToString())); 243 | } 244 | 245 | Thread.Sleep(3000); 246 | return ProcessPool; 247 | } 248 | 249 | bool[,] map; 250 | 251 | List shownSolution; 252 | 253 | List threads; 254 | 255 | private List findBestTiling(PuzzleRequest pr, out int results, out int best) 256 | { 257 | List bestSolution = new List(); 258 | 259 | var solutions = new List[9]; 260 | 261 | threads = new List(); 262 | 263 | int Directions = 8; 264 | 265 | DateTime begin = DateTime.UtcNow; 266 | 267 | threads.Add(new Thread( 268 | arg => 269 | { 270 | int index = (int)arg; 271 | 272 | var solution = findMinRemoteFast(pr); 273 | //List solution = null; 274 | 275 | lock (solutions) 276 | { 277 | if (solution != null && (solutions[index] == null || solution.Count < solutions[index].Count)) 278 | { 279 | solutions[index] = solution; 280 | } 281 | } 282 | 283 | })); 284 | 285 | threads[0].Start(8); 286 | 287 | for (int i = 0; i < Directions; i++) 288 | { 289 | threads.Add(new Thread( 290 | arg => 291 | { 292 | int index = (int)arg; 293 | 294 | var solution = findMinRemote(pr, (index >> 2) % 2 == 1, (index >> 1) % 2 == 1, index % 2 == 1); 295 | 296 | lock (solutions) 297 | { 298 | if (solution != null && (solutions[index] == null || solution.Count < solutions[index].Count)) 299 | { 300 | solutions[index] = solution; 301 | } 302 | } 303 | 304 | })); 305 | 306 | threads[threads.Count - 1].Start(i); 307 | } 308 | 309 | bool stillWaiting; 310 | 311 | var bestSolutionCount = Int32.MaxValue; 312 | var bestSolutionIndex = 0; 313 | 314 | var sleeper = new System.Threading.ManualResetEvent(false); 315 | 316 | for (int index = 0; index < Directions; index++) 317 | { 318 | var solution = findMin(pr, (index >> 2) % 2 == 1, (index >> 1) % 2 == 1, index % 2 == 1); 319 | 320 | lock (solutions) 321 | { 322 | if (solution != null && (solutions[index] == null || solution.Count < solutions[index].Count)) 323 | { 324 | solutions[index] = solution; 325 | } 326 | } 327 | } 328 | 329 | do 330 | { 331 | sleeper.WaitOne(50); 332 | 333 | stillWaiting = false; 334 | 335 | foreach (var thread in threads) 336 | { 337 | if (thread.IsAlive) stillWaiting = true; 338 | } 339 | 340 | lock (solutions) 341 | { 342 | results = 0; 343 | 344 | for (int i = 0; i <= Directions; i++) 345 | { 346 | if (solutions[i] == null) continue; 347 | 348 | if (solutions[i].Count < bestSolutionCount) 349 | { 350 | bestSolutionIndex = i; 351 | bestSolutionCount = solutions[i].Count; 352 | } 353 | 354 | results++; 355 | } 356 | } 357 | 358 | if ((DateTime.UtcNow - begin).TotalMilliseconds > RunTimeConfiguration.TaskTimeout) break; 359 | 360 | } while (stillWaiting); 361 | 362 | best = bestSolutionIndex; 363 | 364 | bool transpose = (bestSolutionIndex >> 2) % 2 == 1; 365 | bool invertX = (bestSolutionIndex >> 1) % 2 == 1; 366 | bool invertY = bestSolutionIndex % 2 == 1; ; 367 | 368 | int N = transpose ? pr.height : pr.width; 369 | int M = transpose ? pr.width : pr.height; 370 | 371 | foreach (var square in solutions[bestSolutionIndex]) 372 | { 373 | var newSquare = new Square() 374 | { 375 | x = invertX ? N - square.x - square.size : square.x, 376 | y = invertY ? M - square.y - square.size : square.y, 377 | size = square.size 378 | }; 379 | 380 | if (transpose) 381 | { 382 | int temp = newSquare.x; 383 | newSquare.x = newSquare.y; 384 | newSquare.y = temp; 385 | } 386 | 387 | bestSolution.Add(newSquare); 388 | } 389 | 390 | return bestSolution; 391 | } 392 | 393 | List findMinRemote(PuzzleRequest pr, bool transpose, bool invX, bool invY) 394 | { 395 | int n = transpose ? pr.height : pr.width; 396 | int m = transpose ? pr.width : pr.height; 397 | 398 | var map = new List(); 399 | 400 | for (int y = 0; y < m; y++) 401 | { 402 | map.Add(new bool[n]); 403 | } 404 | 405 | for (int y = 0; y < m; y++) 406 | { 407 | for (int x = 0; x < n; x++) 408 | { 409 | int ix = invX ? n - x - 1 : x; 410 | int iy = invY ? m - y - 1 : y; 411 | 412 | map[iy][ix] = transpose ? pr.puzzle[x][y] : pr.puzzle[y][x]; 413 | } 414 | } 415 | 416 | var client = new JsonServiceClient("http://localhost:" + (8900 + (transpose ? 4 : 0) + (invX ? 2 : 0) + (invY ? 1 : 0)).ToString() + "/"); 417 | 418 | int costMargin = 5; // pr.height > 30 ? 4 : 5; 419 | 420 | try 421 | { 422 | SquareSolverResponse response = client.Post(new SquareSolver { Map = map, CostMargin = costMargin }); 423 | 424 | return response.Solution; 425 | } 426 | catch 427 | { 428 | return null; 429 | } 430 | } 431 | 432 | List findMinRemoteFast(PuzzleRequest pr) 433 | { 434 | int n = pr.width; 435 | int m = pr.height; 436 | 437 | var map = new List(); 438 | 439 | for (int y = 0; y < m; y++) 440 | { 441 | map.Add(new bool[n]); 442 | } 443 | 444 | for (int y = 0; y < m; y++) 445 | { 446 | for (int x = 0; x < n; x++) 447 | { 448 | int ix = x; 449 | int iy = y; 450 | 451 | map[iy][ix] = pr.puzzle[y][x]; 452 | } 453 | } 454 | 455 | var client = new JsonServiceClient("http://localhost:" + (8900 + 8).ToString() + "/"); 456 | 457 | try 458 | { 459 | SquareSolverResponse response = client.Post(new SquareSolver { Map = map, CostMargin = 0 }); 460 | 461 | return response.Solution; 462 | } 463 | catch 464 | { 465 | return null; 466 | } 467 | } 468 | 469 | List findMin(PuzzleRequest pr, bool transpose, bool invX, bool invY) 470 | { 471 | int n = transpose ? pr.height : pr.width; 472 | int m = transpose ? pr.width : pr.height; 473 | 474 | var map = new bool[n, m]; 475 | 476 | for (int y = 0; y < m; y++) 477 | { 478 | for (int x = 0; x < n; x++) 479 | { 480 | int ix = invX ? n - x - 1 : x; 481 | int iy = invY ? m - y - 1 : y; 482 | 483 | map[ix, iy] = transpose ? pr.puzzle[x][y] : pr.puzzle[y][x]; 484 | } 485 | } 486 | 487 | int costMargin = 0; 488 | 489 | SquareTilingBase squareTiling; 490 | 491 | if (m <= 40) 492 | { 493 | squareTiling = new SquareTilingHeuristic(map, false, costMargin); 494 | } 495 | else 496 | { 497 | squareTiling = new SquareTilingHeuristicLarge(map, false, costMargin, 0); 498 | } 499 | 500 | var solution = squareTiling.Solve(); 501 | 502 | return solution; 503 | } 504 | 505 | private void workerThread(Object o) 506 | { 507 | } 508 | 509 | private void btnSolveLocal_Click(object sender, EventArgs e) 510 | { 511 | DialogResult result = openLocalFileDialog.ShowDialog(); 512 | 513 | if (result != System.Windows.Forms.DialogResult.OK || openLocalFileDialog.FileNames.Count() == 0) return; 514 | 515 | string[] fileNames = openLocalFileDialog.FileNames; 516 | 517 | var ProcessPool = StartServices(); 518 | 519 | ThreadPool.QueueUserWorkItem(async arg => 520 | { 521 | foreach (string fileName in openLocalFileDialog.FileNames) 522 | { 523 | if (!await LocalSolverTask(fileName)) break; 524 | } 525 | 526 | MessageBox.Show("Puzzle solving complete. You can review the services' console output. Click OK to clean-up."); 527 | 528 | StopServices(ProcessPool); 529 | }); 530 | } 531 | 532 | private void pictureBox1_Paint(object sender, PaintEventArgs e) 533 | { 534 | e.Graphics.Clear(Color.White); 535 | 536 | Pen p = new Pen(Color.Black); 537 | 538 | Brush b = new SolidBrush(Color.Black); 539 | 540 | int rs = 20; 541 | 542 | if (map == null) return; 543 | 544 | for (int y = 0; y < map.GetLength(1); y++) 545 | { 546 | for (int x = 0; x < map.GetLength(0); x++) 547 | { 548 | if (map[x, y]) 549 | { 550 | e.Graphics.DrawRectangle(p, rs + x * rs, rs + y * rs, rs, rs); 551 | } 552 | else 553 | { 554 | e.Graphics.FillRectangle(b, rs + x * rs, rs + y * rs, rs, rs); 555 | } 556 | } 557 | } 558 | 559 | if (shownSolution == null) return; 560 | 561 | Random r = new Random(0); 562 | 563 | for (int i = 0; i < shownSolution.Count(); i++) 564 | { 565 | Brush b1 = new SolidBrush(Color.FromArgb((1280 - shownSolution[i].x * 10) % 128 + 128, (shownSolution[i].y * 10) % 128 + 128, (shownSolution[i].size * 40) % 128 + 128)); 566 | 567 | e.Graphics.FillRectangle(b1, rs + shownSolution[i].x * rs, rs + shownSolution[i].y * rs, shownSolution[i].size * rs, shownSolution[i].size * rs); 568 | 569 | e.Graphics.DrawRectangle(p, rs + shownSolution[i].x * rs, rs + shownSolution[i].y * rs, shownSolution[i].size * rs, shownSolution[i].size * rs); 570 | } 571 | } 572 | } 573 | } 574 | -------------------------------------------------------------------------------- /SquaresFrontEnd/SquareSolverForm.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | -------------------------------------------------------------------------------- /SquaresFrontEnd/SquaresFrontEnd.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {3066047D-5777-46B0-9727-653238F4C700} 8 | WinExe 9 | Properties 10 | Squares 11 | Squares 12 | v4.6 13 | 512 14 | 15 | publish\ 16 | true 17 | Disk 18 | false 19 | Foreground 20 | 7 21 | Days 22 | false 23 | false 24 | true 25 | 0 26 | 1.0.0.%2a 27 | false 28 | false 29 | true 30 | 31 | 32 | x64 33 | true 34 | full 35 | false 36 | bin\Debug\ 37 | DEBUG;TRACE 38 | prompt 39 | 4 40 | true 41 | 42 | 43 | x86 44 | pdbonly 45 | true 46 | bin\Release\ 47 | TRACE 48 | prompt 49 | 4 50 | false 51 | 52 | 53 | true 54 | bin\x64\Debug\ 55 | DEBUG;TRACE 56 | full 57 | x64 58 | prompt 59 | MinimumRecommendedRules.ruleset 60 | 61 | 62 | bin\x64\Release\ 63 | 64 | 65 | true 66 | pdbonly 67 | x64 68 | prompt 69 | MinimumRecommendedRules.ruleset 70 | 71 | 72 | 73 | ..\packages\ServiceStack.Client.4.0.40\lib\net40\ServiceStack.Client.dll 74 | 75 | 76 | ..\packages\ServiceStack.Interfaces.4.0.40\lib\portable-wp80+sl5+net40+win8+monotouch+monoandroid+xamarin.ios10\ServiceStack.Interfaces.dll 77 | 78 | 79 | ..\packages\ServiceStack.Text.4.0.40\lib\net40\ServiceStack.Text.dll 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | Form 96 | 97 | 98 | SquareSolverForm.cs 99 | 100 | 101 | 102 | 103 | 104 | SquareSolverForm.cs 105 | 106 | 107 | ResXFileCodeGenerator 108 | Resources.Designer.cs 109 | Designer 110 | 111 | 112 | True 113 | Resources.resx 114 | True 115 | 116 | 117 | 118 | SettingsSingleFileGenerator 119 | Settings.Designer.cs 120 | 121 | 122 | True 123 | Settings.settings 124 | True 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | False 133 | Microsoft .NET Framework 4.5.1 %28x86 and x64%29 134 | true 135 | 136 | 137 | False 138 | .NET Framework 3.5 SP1 Client Profile 139 | false 140 | 141 | 142 | False 143 | .NET Framework 3.5 SP1 144 | false 145 | 146 | 147 | 148 | 149 | {f4dfe510-b82f-4ef2-9181-a9d3546ab49e} 150 | SquaresServiceInterface 151 | 152 | 153 | {43c0fe8d-98d5-4a2e-8c1e-21cb5d30653a} 154 | SquaresService 155 | 156 | 157 | {3c668274-b94a-487e-af47-970d3a0515e5} 158 | SquaresSolverTypes 159 | 160 | 161 | {3501b846-e1d2-4253-a786-48e324e50c27} 162 | SquaresSolver 163 | 164 | 165 | 166 | 173 | -------------------------------------------------------------------------------- /SquaresFrontEnd/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SquaresService/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /SquaresService/CleanupService.cs: -------------------------------------------------------------------------------- 1 | using ServiceStack; 2 | using SquaresServiceInterface; 3 | using System; 4 | 5 | namespace SquaresService 6 | { 7 | public class CleanupService : Service 8 | { 9 | public object Any(CleanupRequest request) 10 | { 11 | GC.Collect(); 12 | GC.WaitForPendingFinalizers(); 13 | GC.WaitForFullGCComplete(); 14 | GC.Collect(); 15 | 16 | Console.WriteLine("Cleanup Complete."); 17 | 18 | return new CleanupRequestResponse() { success = true }; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /SquaresService/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using ServiceStack; 4 | using SquaresServiceInterface; 5 | using SquaresSolver; 6 | 7 | namespace SquaresService 8 | { 9 | class Program 10 | { 11 | //Define the Web Services AppHost 12 | public class AppHost : AppSelfHostBase 13 | { 14 | public AppHost() 15 | : base("HttpListener Self-Host", typeof(SquareSolverService).Assembly) { } 16 | 17 | public override void Configure(Funq.Container container) { } 18 | } 19 | 20 | //Run it! 21 | static void Main(string[] args) 22 | { 23 | SquareTilingCombinatorics.Init(); 24 | 25 | var listeningOn = args.Length == 0 ? "http://localhost:1330/" : "http://localhost:890" + args[0] + "/"; 26 | var appHost = new AppHost().Init(); 27 | 28 | try { appHost.Start(listeningOn); 29 | } 30 | catch (Exception ex) 31 | { 32 | Console.WriteLine("Service was unable to start."); 33 | Console.WriteLine(ex.Message); 34 | return; 35 | } 36 | 37 | Console.WriteLine("AppHost Created at {0}, listening on {1}", 38 | DateTime.Now, listeningOn); 39 | 40 | var map = new List(); 41 | 42 | map.Add(new bool[1]); 43 | 44 | map[0][0] = true; 45 | 46 | var client = new JsonServiceClient(listeningOn); 47 | 48 | SquareSolverResponse response = client.Post(new SquareSolver { Map = map, CostMargin = 1 }); 49 | 50 | Console.WriteLine(response.Solution.Count); 51 | 52 | Console.ReadLine(); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /SquaresService/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SquaresService")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("SquaresService")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("0b9c3658-4c8f-4487-a2d0-30a750fffeff")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /SquaresService/SquareSolverService.cs: -------------------------------------------------------------------------------- 1 | using ServiceStack; 2 | using SquaresServiceInterface; 3 | using SquaresSolver; 4 | 5 | namespace SquaresService 6 | { 7 | public class SquareSolverService : Service 8 | { 9 | public object Any(SquareSolver request) 10 | { 11 | int N = request.Map[0].Length; 12 | int M = request.Map.Count; 13 | var map = new bool[N, M]; 14 | 15 | for (int x = 0; x < N; x++) 16 | { 17 | for (int y = 0; y < M; y++) 18 | { 19 | map[x, y] = request.Map[y][x]; 20 | } 21 | } 22 | 23 | SquareTilingBase solver; 24 | 25 | if (M <= 15) 26 | { 27 | solver = new SquareTilingOptimal(map); 28 | } 29 | else if (M <= 40) 30 | { 31 | solver = new SquareTilingHeuristic(map, true, request.CostMargin); 32 | } 33 | else 34 | { 35 | if (N >= M) 36 | { 37 | solver = new SquareTilingHeuristicLarge(map, true, request.CostMargin); 38 | } 39 | else 40 | { 41 | solver = new SquareTilingHeuristicLarge(map, true, 0, 0); 42 | } 43 | } 44 | 45 | return new SquareSolverResponse { Solution = solver.Solve() }; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /SquaresService/SquaresService.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {43C0FE8D-98D5-4A2E-8C1E-21CB5D30653A} 8 | Exe 9 | Properties 10 | SquaresService 11 | SquaresService 12 | v4.6 13 | 512 14 | true 15 | 16 | 17 | 18 | x64 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | x86 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | true 38 | bin\x64\Debug\ 39 | DEBUG;TRACE 40 | full 41 | x64 42 | prompt 43 | MinimumRecommendedRules.ruleset 44 | true 45 | 46 | 47 | bin\x64\Release\ 48 | 49 | 50 | true 51 | pdbonly 52 | x64 53 | prompt 54 | MinimumRecommendedRules.ruleset 55 | true 56 | 57 | 58 | 59 | ..\packages\ServiceStack.4.0.40\lib\net40\ServiceStack.dll 60 | 61 | 62 | ..\packages\ServiceStack.Client.4.0.40\lib\net40\ServiceStack.Client.dll 63 | 64 | 65 | ..\packages\ServiceStack.Common.4.0.40\lib\net40\ServiceStack.Common.dll 66 | 67 | 68 | ..\packages\ServiceStack.Interfaces.4.0.40\lib\portable-wp80+sl5+net40+win8+monotouch+monoandroid+xamarin.ios10\ServiceStack.Interfaces.dll 69 | 70 | 71 | ..\packages\ServiceStack.Text.4.0.40\lib\net40\ServiceStack.Text.dll 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | {f4dfe510-b82f-4ef2-9181-a9d3546ab49e} 94 | SquaresServiceInterface 95 | 96 | 97 | {3c668274-b94a-487e-af47-970d3a0515e5} 98 | SquaresSolverTypes 99 | 100 | 101 | {3501b846-e1d2-4253-a786-48e324e50c27} 102 | SquaresSolver 103 | 104 | 105 | 106 | 113 | -------------------------------------------------------------------------------- /SquaresService/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SquaresServiceInterface/CleanupService.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace SquaresServiceInterface 3 | { 4 | public class CleanupRequest 5 | { 6 | } 7 | 8 | public class CleanupRequestResponse 9 | { 10 | public bool success { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /SquaresServiceInterface/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SquaresServiceInterface")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("SquaresServiceInterface")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("25ebb62b-7c0d-4ec1-a8c9-9b042bce005d")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /SquaresServiceInterface/SquaresServiceInterface.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {F4DFE510-B82F-4EF2-9181-A9D3546AB49E} 8 | Library 9 | Properties 10 | SquaresServiceInterface 11 | SquaresServiceInterface 12 | v4.6 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | true 35 | bin\x64\Debug\ 36 | DEBUG;TRACE 37 | full 38 | x64 39 | prompt 40 | MinimumRecommendedRules.ruleset 41 | 42 | 43 | bin\x64\Release\ 44 | 45 | 46 | true 47 | pdbonly 48 | x64 49 | prompt 50 | MinimumRecommendedRules.ruleset 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | {3c668274-b94a-487e-af47-970d3a0515e5} 69 | SquaresSolverTypes 70 | 71 | 72 | {3501b846-e1d2-4253-a786-48e324e50c27} 73 | SquaresSolver 74 | 75 | 76 | 77 | 84 | -------------------------------------------------------------------------------- /SquaresServiceInterface/SquaresSolverService.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using SquaresSolverTypes; 3 | 4 | namespace SquaresServiceInterface 5 | { 6 | public class SquareSolver 7 | { 8 | public List Map { get; set; } 9 | public int CostMargin { get; set; } 10 | } 11 | 12 | public class SquareSolverResponse 13 | { 14 | public List Solution { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /SquaresSolver/Configuration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace SquaresSolver 8 | { 9 | public class RunTimeConfiguration 10 | { 11 | // Total time in seconds we have to solve the task 12 | private const int TotalTimeThreshold = 10; 13 | 14 | // Max number of unique states when generating derived tiles in heuristic mode 15 | public const int HeuristicsMaxUniqueTiles = 1000000; 16 | 17 | // Time gates and optimizations in milliseconds - derived from the total time 18 | public const int HeuristicsCostReductionGate1 = TotalTimeThreshold * 400; 19 | public const int HeuristicsCostReductionGate2 = TotalTimeThreshold * 600; 20 | public const int HeuristicsCostReductionGate3 = TotalTimeThreshold * 700; 21 | 22 | public const int HeuristicsTurnOnGreedy = TotalTimeThreshold * 750; 23 | 24 | public const int HeuristicsStopOptimizing = TotalTimeThreshold * 990 - 1400; 25 | 26 | public const int TaskTimeout = TotalTimeThreshold * 1000 - 500; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /SquaresSolver/Fnv1a64.cs: -------------------------------------------------------------------------------- 1 | // A modified and stripped-down FNV-1a 64-bit hashing implementation for computing a 64-bit hash of a 32-bit integer array. 2 | // This class is used internally by the SquareTilingHeuristicLarge square tiling algorithm and does not implement the HashAlgorithm interface. 3 | // Inspired by https://github.com/jslicer/FNV-1a 4 | 5 | namespace SquaresSolver 6 | { 7 | public sealed class Fnv1a64 8 | { 9 | private const ulong FnvPrime = unchecked(1099511628211); 10 | 11 | private const ulong FnvOffsetBasis = unchecked(14695981039346656037); 12 | 13 | public static ulong GetHash(int[] array) 14 | { 15 | ulong hash = FnvOffsetBasis; 16 | 17 | int end = array.Length; 18 | for (var i = 0; i < end; i++) 19 | { 20 | unchecked 21 | { 22 | hash ^= (ulong)(array[i] >> 24); 23 | hash *= FnvPrime; 24 | hash ^= (ulong)((array[i] >> 16) % 256); 25 | hash *= FnvPrime; 26 | hash ^= (ulong)((array[i] >> 8) % 256); 27 | hash *= FnvPrime; 28 | hash ^= (ulong)(array[i] % 256); 29 | hash *= FnvPrime; 30 | } 31 | } 32 | 33 | return hash; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /SquaresSolver/PathStateLarge.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | 4 | namespace SquaresSolver 5 | { 6 | internal class PathStateLarge 7 | { 8 | public int cost; 9 | 10 | public int[] state; 11 | 12 | public PathStateLarge prev = null; 13 | 14 | public PathStateLarge() { } 15 | 16 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 17 | public PathStateLarge(PathStateLarge p) 18 | { 19 | this.cost = p.cost; 20 | 21 | var l = p.state.Length; 22 | this.state = new int[l]; 23 | Array.Copy(p.state, this.state, l); 24 | 25 | this.prev = p.prev; 26 | } 27 | 28 | public void Copy(PathStateLarge p) 29 | { 30 | this.cost = p.cost; 31 | 32 | var l = p.state.Length; 33 | this.state = new int[l]; 34 | Array.Copy(p.state, this.state, l); 35 | 36 | this.prev = p.prev; 37 | } 38 | 39 | public int this[int index] 40 | { 41 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 42 | get 43 | { 44 | return state[index]; 45 | } 46 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 47 | set 48 | { 49 | state[index] = value; 50 | } 51 | } 52 | 53 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 54 | public void Dec(int index) 55 | { 56 | state[index]--; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /SquaresSolver/PathStateMedium.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | namespace SquaresSolver 4 | { 5 | internal class PathStateMedium 6 | { 7 | public int cost; 8 | 9 | public ulong s1; 10 | public ulong s2; 11 | public ulong s3; 12 | public ulong s4; 13 | 14 | public PathStateMedium prev = null; 15 | 16 | public PathStateMedium() { } 17 | 18 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 19 | public PathStateMedium(PathStateMedium p) 20 | { 21 | this.cost = p.cost; 22 | 23 | this.s1 = p.s1; 24 | this.s2 = p.s2; 25 | this.s3 = p.s3; 26 | this.s4 = p.s4; 27 | 28 | this.prev = p.prev; 29 | } 30 | 31 | public void Copy(PathStateMedium p) 32 | { 33 | this.cost = p.cost; 34 | 35 | this.s1 = p.s1; 36 | this.s2 = p.s2; 37 | this.s3 = p.s3; 38 | this.s4 = p.s4; 39 | 40 | this.prev = p.prev; 41 | } 42 | 43 | public int this[int index] 44 | { 45 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 46 | get 47 | { 48 | if (index < 10) 49 | { 50 | return (int)((s1 >> ((index << 2) + (index << 1))) % 64); 51 | } 52 | else if (index < 20) 53 | { 54 | index -= 10; 55 | return (int)((s2 >> ((index << 2) + (index << 1))) % 64); 56 | } 57 | else if (index < 30) 58 | { 59 | index -= 20; 60 | return (int)((s3 >> ((index << 2) + (index << 1))) % 64); 61 | } 62 | else 63 | { 64 | index -= 30; 65 | return (int)((s4 >> ((index << 2) + (index << 1))) % 64); 66 | } 67 | } 68 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 69 | set 70 | { 71 | if (index < 10) 72 | { 73 | s1 &= ~(63UL << ((index << 2) + (index << 1))); 74 | s1 |= ((ulong)value << ((index << 2) + (index << 1))); 75 | } 76 | else if (index < 20) 77 | { 78 | index -= 10; 79 | s2 &= ~(63UL << ((index << 2) + (index << 1))); 80 | s2 |= ((ulong)value << ((index << 2) + (index << 1))); 81 | } 82 | else if (index < 30) 83 | { 84 | index -= 20; 85 | s3 &= ~(63UL << ((index << 2) + (index << 1))); 86 | s3 |= ((ulong)value << ((index << 2) + (index << 1))); 87 | } 88 | else 89 | { 90 | index -= 30; 91 | s4 &= ~(63UL << ((index << 2) + (index << 1))); 92 | s4 |= ((ulong)value << ((index << 2) + (index << 1))); 93 | } 94 | } 95 | } 96 | 97 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 98 | public void Dec(int index) 99 | { 100 | if (index < 10) 101 | { 102 | s1 -= 1UL << ((index << 2) + (index << 1)); 103 | } 104 | else if (index < 20) 105 | { 106 | index -= 10; 107 | s2 -= 1UL << ((index << 2) + (index << 1)); 108 | } 109 | else if (index < 30) 110 | { 111 | index -= 20; 112 | s3 -= 1UL << ((index << 2) + (index << 1)); 113 | } 114 | else 115 | { 116 | index -= 30; 117 | s4 -= 1UL << ((index << 2) + (index << 1)); 118 | } 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /SquaresSolver/PathStateShort.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | 3 | namespace SquaresSolver 4 | { 5 | internal class PathStateShort 6 | { 7 | public int cost; 8 | 9 | public ulong s1; 10 | 11 | public PathStateShort prev = null; 12 | 13 | public PathStateShort() { } 14 | 15 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 16 | public PathStateShort(PathStateShort p) 17 | { 18 | this.cost = p.cost; 19 | 20 | this.s1 = p.s1; 21 | 22 | this.prev = p.prev; 23 | } 24 | 25 | public void Copy(PathStateShort p) 26 | { 27 | this.cost = p.cost; 28 | 29 | this.s1 = p.s1; 30 | 31 | this.prev = p.prev; 32 | } 33 | 34 | public int this[int index] 35 | { 36 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 37 | get 38 | { 39 | return (int)((s1 >> (index << 2)) % 16); 40 | } 41 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 42 | set 43 | { 44 | s1 &= ~(15UL << (index << 2)); 45 | s1 |= ((ulong)value << (index << 2)); 46 | } 47 | } 48 | 49 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 50 | public void Dec(int index) 51 | { 52 | s1 -= 1UL << (index << 2); 53 | } 54 | 55 | public ulong Key 56 | { 57 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 58 | get 59 | { 60 | return s1; 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /SquaresSolver/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SquaresSolver")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("SquaresSolver")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("fe36aea0-2edd-4d55-aed1-4732f1c3f8ab")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /SquaresSolver/SquareTilingBase.cs: -------------------------------------------------------------------------------- 1 | using SquaresSolverTypes; 2 | using System; 3 | using System.Collections.Generic; 4 | 5 | namespace SquaresSolver 6 | { 7 | public abstract class SquareTilingBase 8 | { 9 | protected int N; 10 | protected int M; 11 | 12 | protected bool[,] Map; 13 | 14 | protected int[,] MaxSquare; 15 | 16 | protected int[] MaxSize; 17 | protected int[] JumpTo; 18 | 19 | public SquareTilingBase(bool[,] map) 20 | { 21 | N = map.GetLength(0); 22 | M = map.GetLength(1); 23 | Map = map; 24 | 25 | MaxSquare = new int[N + 1, M + 1]; 26 | MaxSize = new int[M + 1]; 27 | JumpTo = new int[M + 1]; 28 | } 29 | 30 | protected void CalculateMaxSquares() 31 | { 32 | MaxSquare = new int[N, M]; 33 | 34 | for (int x = N - 1; x >= 0; x--) 35 | { 36 | for (int y = M - 1; y >= 0; y--) 37 | { 38 | if (!Map[x, y]) 39 | { 40 | MaxSquare[x, y] = 0; 41 | } 42 | else if (x == N - 1 || y == M - 1) 43 | { 44 | MaxSquare[x, y] = 1; 45 | } 46 | else 47 | { 48 | MaxSquare[x, y] = 1 + Math.Min(MaxSquare[x + 1, y + 1], Math.Min(MaxSquare[x + 1, y], MaxSquare[x, y + 1])); 49 | } 50 | } 51 | } 52 | } 53 | 54 | public abstract List Solve(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /SquaresSolver/SquareTilingCombinatorics.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | 4 | namespace SquaresSolver 5 | { 6 | public class SquareTilingCombinatorics 7 | { 8 | public const int MaxN = 41; 9 | 10 | public static void Init() 11 | { 12 | for (int n = 2; n <= MaxN; n++) 13 | { 14 | for (int w = 2; w <= n; w++) 15 | { 16 | for (int p = 2; p <= w; p++) 17 | { 18 | CombinationsBefore(n, w, p); 19 | } 20 | } 21 | } 22 | } 23 | 24 | // How many combinations for a given height before we reach a top square of a given size and position offset 25 | 26 | static ulong[] m_combinationsBeforeCache = new ulong[MaxN * MaxN * MaxN]; 27 | 28 | // Since the cache is pre-initialized we can inline the cached result function 29 | 30 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 31 | public static ulong CombinationsBefore(int height, int topSquareSize, int topSquarePosition) 32 | { 33 | if (topSquarePosition <= 1 || height <= 1) 34 | { 35 | return 0; 36 | } 37 | 38 | int index = height * MaxN * MaxN + topSquareSize * MaxN + topSquarePosition - MaxN * MaxN - MaxN - 1; 39 | 40 | if (m_combinationsBeforeCache[index] > 0) return m_combinationsBeforeCache[index]; 41 | 42 | return CombinationsBeforeCalculator(index, height, topSquareSize, topSquarePosition); 43 | } 44 | 45 | private static ulong CombinationsBeforeCalculator(int index, int height, int topSquareSize, int topSquarePosition) 46 | { 47 | ulong result = UniqueTilings(height - 1, 1); 48 | 49 | for (int i = 2; i < topSquareSize; i++) 50 | { 51 | for (int j = 2; j <= i; j++) 52 | { 53 | result += UniqueTilings(height - i, j); 54 | } 55 | } 56 | 57 | for (int j = 2; j < topSquarePosition; j++) 58 | { 59 | result += UniqueTilings(height - topSquareSize, j); 60 | } 61 | 62 | m_combinationsBeforeCache[index] = result; 63 | 64 | return result; 65 | } 66 | 67 | 68 | // How many unique tiling combinations are there given the remaining height of the puzzle and the previous block width 69 | 70 | static ulong[] m_uniqueTilingsCache = new ulong[MaxN * MaxN]; 71 | 72 | public static ulong UniqueTilings(int height, int previous = 0) 73 | { 74 | if (height <= 1) 75 | { 76 | return 1; 77 | } 78 | 79 | int index = height * MaxN + previous; 80 | 81 | if (m_uniqueTilingsCache[index] > 0) return m_uniqueTilingsCache[index]; 82 | 83 | ulong result = UniqueTilings(height - 1, 1); 84 | 85 | for (int i = 2; i <= height; i++) 86 | { 87 | for (int j = 2; j <= i; j++) 88 | { 89 | if (j == previous) continue; 90 | 91 | result += UniqueTilings(height - i, j); 92 | } 93 | } 94 | 95 | m_uniqueTilingsCache[index] = result; 96 | 97 | return result; 98 | } 99 | 100 | // How many derived tiling combinations are there given the remaining height of the puzzle and the previous block width 101 | 102 | static ulong[] m_derivedTilingsCache = new ulong[MaxN * MaxN * MaxN]; 103 | 104 | public static ulong DerivedTilings(int height, int previous = 0, int length = 0) 105 | { 106 | if (height <= 1) 107 | { 108 | return UniqueTilings(length); 109 | } 110 | 111 | int index = height * MaxN * MaxN + previous * MaxN + length; 112 | 113 | if (m_derivedTilingsCache[index] > 0) return m_derivedTilingsCache[index]; 114 | 115 | ulong result = DerivedTilings(height - 1, 1, length + 1); 116 | 117 | for (int i = 2; i <= height; i++) 118 | { 119 | for (int j = 2; j <= i; j++) 120 | { 121 | if (j == previous) continue; 122 | 123 | result += UniqueTilings(length) * DerivedTilings(height - i, j, 0); 124 | } 125 | } 126 | 127 | m_derivedTilingsCache[index] = result; 128 | 129 | return result; 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /SquaresSolver/SquareTilingHeuristic.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using SquaresSolverTypes; 5 | 6 | namespace SquaresSolver 7 | { 8 | public class SquareTilingHeuristic : SquareTilingBase 9 | { 10 | // The maximum difference between the best and the worst cost paths to keep 11 | protected int m_costMargin = 0; 12 | 13 | // The maximum deviation from the optimal square size for a given block 14 | protected int m_sizeDeviation = 0; 15 | 16 | // Should we improve the result with optimal stripes 17 | protected bool m_improve = false; 18 | 19 | protected int[] MinSquares; 20 | 21 | public SquareTilingHeuristic(bool[,] map, bool improve = false, int costMargin = 0, int sizeDeviation = 3) : 22 | base(map) 23 | { 24 | m_costMargin = costMargin; 25 | m_sizeDeviation = sizeDeviation; 26 | m_improve = improve; 27 | 28 | MinSquares = new int[M + 1]; 29 | } 30 | 31 | protected DateTime timeStarted; 32 | 33 | protected int minnewcost = 0; 34 | 35 | public override List Solve() 36 | { 37 | var solution = SolveHeuristic(); 38 | 39 | Console.WriteLine("Phase 1 (Heuristic) Complete: " + ((int)(DateTime.UtcNow - timeStarted).TotalMilliseconds).ToString() + " ms."); 40 | 41 | if (m_improve) 42 | { 43 | int subWidth = 14; 44 | int subStep = 5; 45 | 46 | SubSolveHorizontal(ref solution, 0, subStep, N, subWidth); 47 | 48 | SubSolveVertical(ref solution, 0, subStep, subWidth, M); 49 | 50 | SubSolveHorizontal(ref solution, M - subWidth, -subStep, N, subWidth); 51 | 52 | SubSolveVertical(ref solution, N - subWidth, -subStep, subWidth, M); 53 | 54 | Console.WriteLine("Phase 2 (Stripe Optimal) Complete: " + ((int)(DateTime.UtcNow - timeStarted).TotalMilliseconds).ToString() + " ms."); 55 | } 56 | 57 | return solution; 58 | } 59 | 60 | protected virtual List SolveHeuristic() 61 | { 62 | timeStarted = DateTime.UtcNow; 63 | 64 | CalculateMaxSquares(); 65 | 66 | PathStateMedium init = new PathStateMedium(); 67 | 68 | for (int i = 0; i < M; i++) 69 | { 70 | init[i] = 1; 71 | } 72 | 73 | var left = new PathStateMedium[1]; 74 | var right = new Dictionary(1 + m_costMargin * 100000); 75 | 76 | left[0] = init; 77 | 78 | int leftMinCost = 0; 79 | 80 | for (int x = 0; x < N; x++) 81 | { 82 | minnewcost = int.MaxValue; 83 | 84 | foreach(var path in left) 85 | { 86 | if (path.cost - leftMinCost > m_costMargin) continue; 87 | 88 | PathStateMedium p = new PathStateMedium(path); 89 | p.prev = path; 90 | 91 | for (int j = M - 1; j >= 0; j--) 92 | { 93 | if (p[j] <= 1) 94 | { 95 | MaxSize[j] = Math.Min(1 + MaxSize[j + 1], MaxSquare[x, j]); 96 | 97 | if (MaxSize[j] > 0) 98 | { 99 | JumpTo[j] = 0; 100 | 101 | if (JumpTo[j + 1] > 0) 102 | { 103 | MinSquares[j + 1] = MinSquares[j + 1 + JumpTo[j + 1]]; 104 | } 105 | 106 | MinSquares[j] = 1 + MinSquares[j + MaxSize[j]]; 107 | } 108 | else 109 | { 110 | p[j] = 0; 111 | JumpTo[j] = 1 + JumpTo[j + 1]; 112 | } 113 | } 114 | else 115 | { 116 | p.Dec(j); 117 | 118 | MaxSize[j] = 0; 119 | JumpTo[j] = 1 + JumpTo[j + 1]; 120 | } 121 | } 122 | 123 | Tile(x, 0, p, p.cost, right); 124 | 125 | if (right.Count > RunTimeConfiguration.HeuristicsMaxUniqueTiles) break; 126 | } 127 | 128 | left = right.Values.ToArray(); 129 | 130 | right = new Dictionary(1 + m_costMargin * 100000); 131 | 132 | leftMinCost = minnewcost; 133 | 134 | int leftMinCostIndex = 0; 135 | 136 | for (int i = 0; i < left.Length; i++) 137 | { 138 | if (left[i].cost == leftMinCost) 139 | { 140 | leftMinCostIndex = i; 141 | break; 142 | } 143 | } 144 | 145 | var temp = left[0]; 146 | left[0] = left[leftMinCostIndex]; 147 | left[leftMinCostIndex] = temp; 148 | 149 | double time = (DateTime.UtcNow - timeStarted).TotalMilliseconds; 150 | 151 | if (time > RunTimeConfiguration.HeuristicsTurnOnGreedy) m_sizeDeviation = 0; 152 | else if (time > RunTimeConfiguration.HeuristicsCostReductionGate3) m_costMargin = 0; 153 | else if (time > RunTimeConfiguration.HeuristicsCostReductionGate2) m_costMargin = 2; 154 | else if (x < 20 && time > RunTimeConfiguration.HeuristicsCostReductionGate1) m_costMargin = 3; 155 | } 156 | 157 | var solution = GetSolution(left); 158 | 159 | return solution; 160 | } 161 | 162 | private void Tile(int x, int y, PathStateMedium p, int cost, Dictionary right) 163 | { 164 | y += JumpTo[y]; 165 | 166 | if (y == M) 167 | { 168 | // store result 169 | ulong key = 0; 170 | 171 | int prevY = 0; 172 | int prevPos = p[prevY]; 173 | 174 | for (int i = 1; i < M; i++) 175 | { 176 | int currentPos = p[i]; 177 | 178 | if (currentPos == prevPos) 179 | { 180 | continue; 181 | } 182 | 183 | key += SquareTilingCombinatorics.CombinationsBefore(M - prevY, i - prevY, prevPos); 184 | 185 | prevY = i; 186 | prevPos = currentPos; 187 | } 188 | 189 | key += SquareTilingCombinatorics.CombinationsBefore(M - prevY, M - prevY, prevPos); 190 | 191 | minnewcost = Math.Min(cost, minnewcost); 192 | 193 | PathStateMedium existingPath; 194 | 195 | if (!right.TryGetValue(key, out existingPath)) 196 | { 197 | p.cost = cost; 198 | right.Add(key, new PathStateMedium(p)); 199 | } 200 | else 201 | { 202 | //collissions++; 203 | 204 | if (existingPath.cost > cost) 205 | { 206 | p.cost = cost; 207 | existingPath.Copy(p); 208 | } 209 | } 210 | 211 | return; 212 | } 213 | 214 | int blockMaxSize = MaxSize[y]; 215 | 216 | for (int i = blockMaxSize; i >= 1; i--) 217 | { 218 | if (cost + MinSquares[y + i] - minnewcost >= m_costMargin) break; 219 | 220 | for (int j = 0; j < i; j++) 221 | { 222 | p[y + j] = i; 223 | } 224 | 225 | Tile(x, y + i, p, cost + 1, right); 226 | 227 | if (minnewcost < int.MaxValue && i <= blockMaxSize - m_sizeDeviation) break; 228 | } 229 | } 230 | 231 | void SubSolveHorizontal(ref List solution, int sY, int vY, int dX, int dY) 232 | { 233 | int sX = 0; 234 | 235 | for (; sY >= 0 && sY + dY <= M; sY += vY) 236 | { 237 | if ((DateTime.UtcNow - timeStarted).TotalMilliseconds > RunTimeConfiguration.HeuristicsStopOptimizing) return; 238 | 239 | bool[,] subMap = new bool[N, dY]; 240 | 241 | for (int x = 0; x < dX; x++) 242 | { 243 | for (int y = 0; y < dY; y++) 244 | { 245 | subMap[x, y] = Map[sX + x, sY + y]; 246 | } 247 | } 248 | 249 | int originalMin = 0; 250 | 251 | var newSolution = new List(); 252 | 253 | foreach (var square in solution) 254 | { 255 | if (square.x >= sX && square.x + square.size <= sX + dX && 256 | square.y >= sY && square.y + square.size <= sY + dY) 257 | { 258 | // completely inside the sub-map - skip 259 | originalMin++; 260 | continue; 261 | } 262 | 263 | newSolution.Add(square); 264 | 265 | for (int x = Math.Max(0, square.x - sX); x < Math.Min(dX, square.x + square.size - sX); x++) 266 | { 267 | for (int y = Math.Max(0, square.y - sY); y < Math.Min(dY, square.y + square.size - sY); y++) 268 | { 269 | subMap[x, y] = false; 270 | } 271 | } 272 | } 273 | 274 | var subTiling = new SquareTilingOptimal(subMap); 275 | 276 | var subSolution = subTiling.Solve(); 277 | 278 | if (subSolution.Count >= originalMin) 279 | { 280 | continue; 281 | } 282 | 283 | for (int i = 0; i < subSolution.Count; i++) 284 | { 285 | newSolution.Add(new Square() 286 | { 287 | x = subSolution[i].x + sX, 288 | y = subSolution[i].y + sY, 289 | size = subSolution[i].size 290 | }); 291 | } 292 | 293 | solution = newSolution; 294 | } 295 | } 296 | 297 | void SubSolveVertical(ref List solution, int sX, int vX, int dX, int dY) 298 | { 299 | int sY = 0; 300 | 301 | for (; sX >= 0 && sX + dX <= N; sX += vX) 302 | { 303 | if ((DateTime.UtcNow - timeStarted).TotalMilliseconds > RunTimeConfiguration.HeuristicsStopOptimizing) return; 304 | 305 | bool[,] subMap = new bool[M, dX]; 306 | 307 | for (int x = 0; x < dX; x++) 308 | { 309 | for (int y = 0; y < dY; y++) 310 | { 311 | subMap[y, x] = Map[sX + x, sY + y]; 312 | } 313 | } 314 | 315 | int originalMin = 0; 316 | 317 | var newSolution = new List(); 318 | 319 | foreach (var square in solution) 320 | { 321 | if (square.x >= sX && square.x + square.size <= sX + dX && 322 | square.y >= sY && square.y + square.size <= sY + dY) 323 | { 324 | // completely inside the sub-map - skip 325 | originalMin++; 326 | continue; 327 | } 328 | 329 | newSolution.Add(square); 330 | 331 | for (int x = Math.Max(0, square.x - sX); x < Math.Min(dX, square.x + square.size - sX); x++) 332 | { 333 | for (int y = Math.Max(0, square.y - sY); y < Math.Min(dY, square.y + square.size - sY); y++) 334 | { 335 | subMap[y, x] = false; 336 | } 337 | } 338 | } 339 | 340 | var subTiling = new SquareTilingOptimal(subMap); 341 | 342 | var subSolution = subTiling.Solve(); 343 | 344 | if (subSolution.Count >= originalMin) 345 | { 346 | continue; 347 | } 348 | 349 | for (int i = 0; i < subSolution.Count; i++) 350 | { 351 | newSolution.Add(new Square() 352 | { 353 | x = subSolution[i].y + sX, 354 | y = subSolution[i].x + sY, 355 | size = subSolution[i].size 356 | }); 357 | } 358 | 359 | solution = newSolution; 360 | } 361 | } 362 | 363 | private List GetSolution(PathStateMedium[] left) 364 | { 365 | List solution = new List(); 366 | 367 | int bestI = 0; 368 | 369 | for (int i = 1; i < left.Length; i++) 370 | { 371 | if (left[i].cost < left[bestI].cost) 372 | { 373 | bestI = i; 374 | } 375 | } 376 | 377 | PathStateMedium trace = left[bestI]; 378 | 379 | int x = N - 1; 380 | while (x >= 0 && trace != null) 381 | { 382 | int currentnew = 0; 383 | for (int i = 0; i < M; i++) 384 | { 385 | if (trace[i] == 0) continue; 386 | 387 | if (x == 0 || trace.prev[i] <= trace[i]) 388 | { 389 | solution.Add(new Square() 390 | { 391 | x = x, 392 | y = i, 393 | size = trace[i] 394 | }); 395 | currentnew++; 396 | 397 | i += trace[i] - 1; 398 | } 399 | } 400 | 401 | x--; 402 | trace = trace.prev; 403 | } 404 | 405 | return solution; 406 | } 407 | } 408 | } 409 | -------------------------------------------------------------------------------- /SquaresSolver/SquareTilingHeuristicLarge.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using SquaresSolverTypes; 5 | 6 | namespace SquaresSolver 7 | { 8 | public class SquareTilingHeuristicLarge : SquareTilingHeuristic 9 | { 10 | public SquareTilingHeuristicLarge(bool[,] map, bool improve = false, int costMargin = 0, int sizeDeviation = 2) : 11 | base(map, improve, costMargin, sizeDeviation) 12 | { 13 | } 14 | 15 | private bool stopTiling = false; 16 | 17 | protected override List SolveHeuristic() 18 | { 19 | timeStarted = DateTime.UtcNow; 20 | 21 | CalculateMaxSquares(); 22 | 23 | PathStateLarge init = new PathStateLarge() { state = new int[M] }; 24 | 25 | for (int i = 0; i < M; i++) 26 | { 27 | init[i] = 1; 28 | } 29 | 30 | var left = new PathStateLarge[1]; 31 | var right = new Dictionary(1 + m_costMargin * 100000); 32 | 33 | left[0] = init; 34 | 35 | int leftMinCost = 0; 36 | 37 | for (int x = 0; x < N; x++) 38 | { 39 | minnewcost = int.MaxValue; 40 | 41 | stopTiling = false; 42 | 43 | foreach(var path in left) 44 | { 45 | if (path.cost - leftMinCost > m_costMargin) continue; 46 | 47 | PathStateLarge p = new PathStateLarge(path); 48 | p.prev = path; 49 | 50 | for (int j = M - 1; j >= 0; j--) 51 | { 52 | if (p[j] <= 1) 53 | { 54 | MaxSize[j] = Math.Min(1 + MaxSize[j + 1], MaxSquare[x, j]); 55 | 56 | if (MaxSize[j] > 0) 57 | { 58 | JumpTo[j] = 0; 59 | 60 | if (JumpTo[j + 1] > 0) 61 | { 62 | MinSquares[j + 1] = MinSquares[j + 1 + JumpTo[j + 1]]; 63 | } 64 | 65 | MinSquares[j] = 1 + MinSquares[j + MaxSize[j]]; 66 | } 67 | else 68 | { 69 | p[j] = 0; 70 | JumpTo[j] = 1 + JumpTo[j + 1]; 71 | } 72 | } 73 | else 74 | { 75 | p.Dec(j); 76 | 77 | MaxSize[j] = 0; 78 | JumpTo[j] = 1 + JumpTo[j + 1]; 79 | } 80 | } 81 | 82 | Tile(x, 0, p, p.cost, right); 83 | 84 | if (right.Count > RunTimeConfiguration.HeuristicsMaxUniqueTiles) break; 85 | } 86 | 87 | left = right.Values.ToArray(); 88 | 89 | right = new Dictionary(1 + m_costMargin * 100000); 90 | 91 | leftMinCost = minnewcost; 92 | 93 | int leftMinCostIndex = 0; 94 | 95 | for (int i = 0; i < left.Length; i++) 96 | { 97 | if (left[i].cost == leftMinCost) 98 | { 99 | leftMinCostIndex = i; 100 | break; 101 | } 102 | } 103 | 104 | var temp = left[0]; 105 | left[0] = left[leftMinCostIndex]; 106 | left[leftMinCostIndex] = temp; 107 | 108 | double time = (DateTime.UtcNow - timeStarted).TotalMilliseconds; 109 | 110 | if (time > RunTimeConfiguration.HeuristicsTurnOnGreedy) m_sizeDeviation = 0; 111 | else if (time > RunTimeConfiguration.HeuristicsCostReductionGate3) m_costMargin = 0; 112 | else if (time > RunTimeConfiguration.HeuristicsCostReductionGate2) m_costMargin = 2; 113 | else if (x < 20 && time > RunTimeConfiguration.HeuristicsCostReductionGate1) m_costMargin = 3; 114 | } 115 | 116 | var solution = GetSolution(left); 117 | 118 | return solution; 119 | } 120 | 121 | private void Tile(int x, int y, PathStateLarge p, int cost, Dictionary right) 122 | { 123 | y += JumpTo[y]; 124 | 125 | if (y == M) 126 | { 127 | // store result 128 | ulong key = Fnv1a64.GetHash(p.state); 129 | 130 | minnewcost = Math.Min(cost, minnewcost); 131 | 132 | PathStateLarge existingPath; 133 | 134 | if (!right.TryGetValue(key, out existingPath)) 135 | { 136 | p.cost = cost; 137 | right.Add(key, new PathStateLarge(p)); 138 | 139 | if (right.Count > RunTimeConfiguration.HeuristicsMaxUniqueTiles) 140 | { 141 | stopTiling = true; 142 | } 143 | } 144 | else 145 | { 146 | if (existingPath.cost > cost) 147 | { 148 | p.cost = cost; 149 | existingPath.Copy(p); 150 | } 151 | } 152 | 153 | return; 154 | } 155 | 156 | int blockMaxSize = MaxSize[y]; 157 | 158 | for (int i = blockMaxSize; i >= 1; i--) 159 | { 160 | if (cost + MinSquares[y + i] - minnewcost >= m_costMargin) break; 161 | 162 | for (int j = 0; j < i; j++) 163 | { 164 | p[y + j] = i; 165 | } 166 | 167 | Tile(x, y + i, p, cost + 1, right); 168 | 169 | if (stopTiling) break; 170 | 171 | if (minnewcost < int.MaxValue && i <= blockMaxSize - m_sizeDeviation) break; 172 | } 173 | } 174 | 175 | private List GetSolution(PathStateLarge[] left) 176 | { 177 | List solution = new List(); 178 | 179 | int bestI = 0; 180 | 181 | for (int i = 1; i < left.Length; i++) 182 | { 183 | if (left[i].cost < left[bestI].cost) 184 | { 185 | bestI = i; 186 | } 187 | } 188 | 189 | PathStateLarge trace = left[bestI]; 190 | 191 | int x = N - 1; 192 | while (x >= 0 && trace != null) 193 | { 194 | int currentnew = 0; 195 | for (int i = 0; i < M; i++) 196 | { 197 | if (trace[i] == 0) continue; 198 | 199 | if (x == 0 || trace.prev[i] <= trace[i]) 200 | { 201 | solution.Add(new Square() 202 | { 203 | x = x, 204 | y = i, 205 | size = trace[i] 206 | }); 207 | currentnew++; 208 | 209 | i += trace[i] - 1; 210 | } 211 | } 212 | 213 | x--; 214 | trace = trace.prev; 215 | } 216 | 217 | return solution; 218 | } 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /SquaresSolver/SquareTilingOptimal.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using SquaresSolverTypes; 5 | 6 | namespace SquaresSolver 7 | { 8 | public class SquareTilingOptimal : SquareTilingBase 9 | { 10 | public SquareTilingOptimal(bool[,] map) : 11 | base(map) 12 | { 13 | } 14 | 15 | public override List Solve() 16 | { 17 | CalculateMaxSquares(); 18 | 19 | PathStateShort init = new PathStateShort(); 20 | 21 | for (int i = 0; i < M; i++) 22 | { 23 | init[i] = 1; 24 | } 25 | 26 | var left = new List(); 27 | var right = new Dictionary(25000); 28 | 29 | left.Add(init); 30 | 31 | for (int x = 0; x < N; x++) 32 | { 33 | for(int i = 0; i < left.Count; i++) 34 | { 35 | PathStateShort p = new PathStateShort(left[i]); 36 | p.prev = left[i]; 37 | 38 | for (int j = M - 1; j >= 0; j--) 39 | { 40 | if (p[j] <= 1) 41 | { 42 | p[j] = 0; 43 | 44 | MaxSize[j] = Math.Min(1 + MaxSize[j + 1], MaxSquare[x, j]); 45 | JumpTo[j] = MaxSize[j] > 0 ? 0 : 1 + JumpTo[j + 1]; 46 | } 47 | else 48 | { 49 | p.Dec(j); 50 | 51 | MaxSize[j] = 0; 52 | JumpTo[j] = 1 + JumpTo[j + 1]; 53 | } 54 | } 55 | 56 | Tile(x, 0, p, p.cost, right); 57 | } 58 | 59 | left = right.Values.ToList(); 60 | 61 | right = new Dictionary(25000); 62 | } 63 | 64 | var solution = GetSolution(left); 65 | 66 | return solution; 67 | } 68 | 69 | private void Tile(int x, int y, PathStateShort p, int cost, Dictionary right) 70 | { 71 | y += JumpTo[y]; 72 | 73 | if (y == M) 74 | { 75 | // store result 76 | PathStateShort existingPath; 77 | 78 | if (!right.TryGetValue(p.Key, out existingPath)) 79 | { 80 | p.cost = cost; 81 | right.Add(p.Key, new PathStateShort(p)); 82 | } 83 | else 84 | { 85 | if (existingPath.cost > cost) 86 | { 87 | p.cost = cost; 88 | existingPath.Copy(p); 89 | } 90 | } 91 | 92 | return; 93 | } 94 | 95 | for (int i = MaxSize[y]; i >= 1; i--) 96 | { 97 | for (int j = 0; j < i; j++) 98 | { 99 | p[y + j] = i; 100 | } 101 | 102 | Tile(x, y + i, p, cost + 1, right); 103 | } 104 | } 105 | 106 | private List GetSolution(List left) 107 | { 108 | List solution = new List(); 109 | 110 | int bestI = 0; 111 | 112 | for (int i = 1; i < left.Count; i++) 113 | { 114 | if (left[i].cost < left[bestI].cost) 115 | { 116 | bestI = i; 117 | } 118 | } 119 | 120 | PathStateShort trace = left[bestI]; 121 | 122 | int x = N - 1; 123 | while (x >= 0 && trace != null) 124 | { 125 | int currentnew = 0; 126 | for (int i = 0; i < M; i++) 127 | { 128 | if (trace[i] == 0) continue; 129 | 130 | if (x == 0 || trace.prev[i] <= trace[i]) 131 | { 132 | solution.Add(new Square() 133 | { 134 | x = x, 135 | y = i, 136 | size = trace[i] 137 | }); 138 | currentnew++; 139 | 140 | i += trace[i] - 1; 141 | } 142 | } 143 | 144 | x--; 145 | trace = trace.prev; 146 | } 147 | 148 | return solution; 149 | } 150 | 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /SquaresSolver/SquaresSolver.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {3501B846-E1D2-4253-A786-48E324E50C27} 8 | Library 9 | Properties 10 | SquaresSolver 11 | SquaresSolver 12 | v4.6 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | AnyCPU 33 | 34 | 35 | true 36 | bin\x64\Debug\ 37 | DEBUG;TRACE 38 | full 39 | x64 40 | prompt 41 | MinimumRecommendedRules.ruleset 42 | 43 | 44 | bin\x64\Release\ 45 | 46 | 47 | true 48 | pdbonly 49 | x64 50 | prompt 51 | MinimumRecommendedRules.ruleset 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | {3c668274-b94a-487e-af47-970d3a0515e5} 79 | SquaresSolverTypes 80 | 81 | 82 | 83 | 90 | -------------------------------------------------------------------------------- /SquaresSolverTypes/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SquaresSolverTypes")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("SquaresSolverTypes")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("f996df40-88ab-4d9b-b9da-c751dcafb9c6")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /SquaresSolverTypes/Square.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | using System.Threading.Tasks; 7 | 8 | namespace SquaresSolverTypes 9 | { 10 | public struct Square 11 | { 12 | public int x; 13 | public int y; 14 | public int size; 15 | 16 | public Square(string json) 17 | { 18 | string[] parts = json.Split(','); 19 | 20 | x = 0; 21 | Int32.TryParse(parts[0], out x); 22 | 23 | y = 0; 24 | Int32.TryParse(parts[1], out y); 25 | 26 | size = 0; 27 | Int32.TryParse(parts[2], out size); 28 | } 29 | 30 | public override string ToString() 31 | { 32 | return x.ToString() + "," + y.ToString() + "," + size.ToString(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /SquaresSolverTypes/SquaresSolverTypes.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {3C668274-B94A-487E-AF47-970D3A0515E5} 8 | Library 9 | Properties 10 | SquaresSolverTypes 11 | SquaresSolverTypes 12 | v4.6 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | true 35 | bin\x64\Debug\ 36 | DEBUG;TRACE 37 | full 38 | x64 39 | prompt 40 | MinimumRecommendedRules.ruleset 41 | 42 | 43 | bin\x64\Release\ 44 | 45 | 46 | true 47 | pdbonly 48 | x64 49 | prompt 50 | MinimumRecommendedRules.ruleset 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 73 | -------------------------------------------------------------------------------- /packages/repositories.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | --------------------------------------------------------------------------------