-
Notifications
You must be signed in to change notification settings - Fork 0
/
tiles.hs
76 lines (58 loc) · 2.39 KB
/
tiles.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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
import Data.List
size = SIZE
states = [0.. STATES-1]
baseMatrices =
#ifdef brick
allBrickMatrices
#else
allMatrices
#endif
allCombinations :: [[a]] -> [[a]]
allCombinations [] = [[]]
allCombinations (x:rest) = (:) <$> x <*> allCombinations rest
allColumns :: [[Int]]
allColumns = allCombinations $ take size $ repeat states
allMatrices :: [[[Int]]]
allMatrices = allCombinations $ take size $ repeat allColumns
-- This only makes sense when size is even
allBrickMatrices :: [[[Int]]]
allBrickMatrices = map makeBrick $ allCombinations $ take (size `quot` 2) $ repeat allColumns where
makeBrick halfMatrix = halfMatrix ++ map (rotateList $ size `quot` 2) halfMatrix
rotateList :: Int -> [a] -> [a]
rotateList n list = drop n list ++ take n list
rotateRows :: [[a]] -> [[a]]
rotateRows = map rotateRow where
rotateRow (first:rest) = rest ++ [first]
rotateRow [] = []
rotateColumns :: [[a]] -> [[a]]
rotateColumns = transpose . rotateRows . transpose
reflect :: [[a]] -> [[a]]
reflect = map reverse
rotate :: [[a]] -> [[a]]
rotate = reflect . transpose
permuteStates :: [[Int]] -> [[[Int]]]
permuteStates matrix = map (permuteStatesInMatrix matrix) (permutations states)
permuteStatesInMatrix :: [[Int]] -> [Int] -> [[Int]]
permuteStatesInMatrix matrix permutation = map (map (permutation !!)) matrix
allVariations :: [[Int]] -> [[[Int]]]
allVariations matrix = do
rotations <- take 4 $ iterate rotate matrix
-- The other transformations end up producing all variations of the patterns, so we don't need transpositions
-- transpositions <- [rotations, transpose rotations]
-- reflections <- [transpositions, reflect transpositions]
reflections <- [rotations, reflect rotations]
rowRotations <- take size $ iterate rotateRows reflections
columnRotations <- take size $ iterate rotateColumns rowRotations
statePermutations <- permuteStates columnRotations
return statePermutations
filteredMatrices :: [[[Int]]]
filteredMatrices = nub $ map (maximum . allVariations) baseMatrices
result :: [(Int, [[Int]])]
result = map matrixResult filteredMatrices where
matrixResult matrix = (length $ nub $ allVariations matrix, matrix)
-- Assumes 1 digit integers
matrixToString :: [[Int]] -> String
matrixToString = concatMap $ concatMap show
resultToString :: (Int, [[Int]]) -> String
resultToString (variations, matrix) = show variations ++ " " ++ matrixToString matrix
main = mapM (putStrLn . resultToString) result