/
Adjacency.elm
105 lines (86 loc) · 3.36 KB
/
Adjacency.elm
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
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
module Adjacency exposing (DraftRules, Rule, Rules, combineRules, finalize, fromIds)
{-| The draft/final rules distinction is no longer necessary and should really
be cleaned up.
-}
import Array
import Dict exposing (Dict)
import Direction exposing (Direction)
import Grid exposing (Grid)
import Set exposing (Set)
type alias Rule comparable =
{ direction : Direction
, to : Set comparable
}
type alias Rules comparable =
Dict ( comparable, Direction ) (Set comparable)
finalize : DraftRules comparable -> Rules comparable
finalize (DraftRules draft) =
draft
combineRules : List (Rule comparable) -> List (Rule comparable)
combineRules original =
original
|> List.foldl
(\rule ->
Dict.update rule.direction
(\maybeRule ->
case maybeRule of
Just existing ->
Just { existing | to = Set.union existing.to rule.to }
Nothing ->
Just rule
)
)
Dict.empty
|> Dict.values
-- Draft Rules (they should be combinable, eventually!)
type DraftRules comparable
= DraftRules (Dict ( comparable, Direction ) (Set comparable))
fromIds : Grid comparable -> DraftRules comparable
fromIds grid =
let
rows =
Grid.toArrays grid
in
rows
|> Array.indexedMap
(\rowNum row ->
Array.indexedMap
(\colNum id ->
List.filterMap identity
[ Grid.getWrapping { row = rowNum, column = colNum - 1 } grid
|> Maybe.map (\dest -> ( id, Direction.left, dest ))
, Grid.getWrapping { row = rowNum, column = colNum + 1 } grid
|> Maybe.map (\dest -> ( id, Direction.right, dest ))
, Grid.getWrapping { row = rowNum - 1, column = colNum } grid
|> Maybe.map (\dest -> ( id, Direction.up, dest ))
, Grid.getWrapping { row = rowNum + 1, column = colNum } grid
|> Maybe.map (\dest -> ( id, Direction.down, dest ))
]
)
row
)
|> Array.foldl
(\row dictFromRow ->
Array.foldl
(\rules dictFromRules ->
List.foldl
(\( from, direction, to ) dict ->
Dict.update ( from, direction )
(\currentValue ->
Just <|
case currentValue of
Just set ->
Set.insert to set
Nothing ->
Set.singleton to
)
dict
)
dictFromRules
rules
)
dictFromRow
row
)
Dict.empty
|> DraftRules