manzyuk / genius-star

The Genius Star puzzle solver

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

genius-star: The Genius Star puzzle solver

A simple solver for The Genius Star puzzle from happypuzzle.co.uk implemented in Haskell.

The solver tries to fill the grid by placing each of the eleven shapes in order (starting from the larger and more irregular ones) in all possible ways and backtracking when it is not possible to place the next shape.

The interesting part was choosing a representation of the grid and a way to navigate around it. I've settled on the following idea. There are three directions on the grid, which I arbitrarily called X, Y, Z, and each triangular cell has sides parallel to these directions. Each cell has up to three neighbour cells obtained by reflecting it with respect to its sides. The neighbours are described by the function

neighbour :: Direction -> Int -> Maybe Int

where neighbour d n = Just m if by reflecting the triangle containing the number n with respect to its side parallel to the direction d we obtain a triangle containing the number m; and neighbour d n = Nothing if the side parallel to the direction d lies on the border of the grid.

A shape is a set of triangular cells. We describe each shape by choosing a reference cell within it and defining all other cells in terms of sequences of reflections connecting each cell to the reference cell. For example, the shape

  ____
 /\* /\
/__\/__\
\  /\  /
 \/  \/

(with the reference cell marked with *) is described by the following sequences of reflections:

[[], [X], [Y], [X, Z], [Y, Z]]

Each reflection is identified by the direction with respect to which it is made. To try to place such a shape on a grid, we choose an empty cell as a reference cell and from it walk the reflection paths to find the numbers of the triangles covered by the shape. Of course, we can place a shape in different ways, rotating and flipping it. To accommodate for this, we compute for each shape the set of its possible orientations by applying all possible symmetries of the grid (rotations and reflections) to the sequences describing the elements of the shape.

With these choices, the rest of the implementation becomes an exercise in list comprehensions. The function tryPlaceShape checks if a particular orientation of a shape (a particular collection of reflection paths describing the elements of the shape with respect to a reference cell) can be placed on a given grid (represented as a set of numbers in the empty cells) using a given number as a reference cell. The function placeShape returns the set of all possible placements of a given shape on a given grid, using all possible orientations and all possible reference cells. The function placeShapes returns the list of all possible placements of a given list of shapes together with the set of cells that are not yet covered. To solve a particular puzzle, we apply this function to the grid obtained from the full grid by removing seven cells occupied by the "blocker" pieces, whose positions are determined by rolling the provided dice, and to the list of the eleven shapes.

About

The Genius Star puzzle solver

License:BSD 3-Clause "New" or "Revised" License


Languages

Language:Haskell 100.0%