-
Notifications
You must be signed in to change notification settings - Fork 0
/
day09.dwl
91 lines (85 loc) · 2.65 KB
/
day09.dwl
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
%dw 2.0
output application/json
import lines, words from dw::core::Strings
import drop from dw::core::Arrays
var parsed = lines(payload) map (words($) then [$[0], $[1]])
type Position = {| x: Number, y: Number|}
type State = {| head: Position, tails: Array<Position>, visited: Array<Position> |}
@TailRec()
fun moveTail(state: State, track: Number, x: Number, this: Position | Null, other: Position): State = do {
var newThis = (this match {
case is Position -> {
x: if ($.x == other.x) $.x else if ($.x < other.x) $.x + 1 else $.x - 1,
y: if ($.y == other.y) $.y else if ($.y < other.y) $.y + 1 else $.y - 1
}
case is Null -> { //Should never be used but is needed for the type checker
x: other.x,
y: other.y
}
})
var diffX = other.x - (this.x default 0)
var diffY = other.y - (this.y default 0)
---
if(
this == null or
((diffX == 0 or diffX == -1 or diffX == 1) and
(diffY == 0 or diffY == -1 or diffY == 1))
)
state
else
moveTail(
if(x == track)
state update {
case .tails -> $ map if($$ == x) newThis else $
case .visited -> newThis >> $
}
else
state update {
case .tails -> $ map if($$ == x) newThis else $
},
track,
x + 1,
state.tails[x + 1],
newThis
)
}
fun updateState(direction: String, amount: Number, track: Number, state: State): State =
(0 to amount - 1) reduce (item: Number, acc: State=state) -> do{
var newState = if (direction == "R") acc update {
case .head.x -> $ + 1
} else if(direction == "L") acc update {
case .head.x -> $ - 1
} else if(direction == "U") acc update {
case .head.y -> $ - 1
} else acc update {
case .head.y -> $ + 1
}
---
moveTail(
newState,
track,
0,
newState.tails[0],
newState.head
)
}
fun simulate(commands: Array<Array<String>>, track: Number, state: State): State = commands reduce (item: Array<String>, acc: State = state) -> updateState(item[0], item[1] as Number, track, acc)
---
{
part1: simulate(
parsed,
0,
{
head:{x:0, y:0},
tails:[{x:0, y:0}],
visited:[{x:0, y:0}]
}).visited distinctBy ($) then sizeOf($),
part2: simulate(
parsed,
8,
{
head:{x:0, y:0},
tails: 1 to 9 map {x:0, y:0},
visited:[{x:0, y:0}]
}).visited distinctBy ($) then sizeOf($)
}