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
|
import gleam/int
import gleam/list
import gleam/string
pub type Direction {
North
Northeast
Northwest
South
Southeast
Southwest
}
type HexPosition {
HexPosition(x: Int, y: Int, z: Int)
}
const start = HexPosition(0, 0, 0)
fn to_direction(str: String) -> Direction {
case str {
"n" -> North
"ne" -> Northeast
"nw" -> Northwest
"s" -> South
"se" -> Southeast
"sw" -> Southwest
_ -> panic as "unrecognized direction"
}
}
fn distance(hp1: HexPosition, hp2: HexPosition) -> Int {
{
int.absolute_value(hp1.x - hp2.x)
+ int.absolute_value(hp1.y - hp2.y)
+ int.absolute_value(hp1.z - hp2.z)
}
/ 2
}
fn move(p, direction) -> HexPosition {
case direction {
North -> HexPosition(..p, y: p.y + 1, z: p.z - 1)
South -> HexPosition(..p, y: p.y - 1, z: p.z + 1)
Northeast -> HexPosition(..p, x: p.x + 1, z: p.z - 1)
Southwest -> HexPosition(..p, x: p.x - 1, z: p.z + 1)
Southeast -> HexPosition(..p, x: p.x + 1, y: p.y - 1)
Northwest -> HexPosition(..p, x: p.x - 1, y: p.y + 1)
}
}
pub fn parse(input: String) -> List(Direction) {
input
|> string.split(",")
|> list.map(to_direction)
}
pub fn pt_1(input: List(Direction)) {
do_walk(input, start, 0).0
}
pub fn pt_2(input: List(Direction)) {
do_walk(input, start, 0).1
}
fn do_walk(steps, position, max) {
case steps {
[] -> #(distance(position, HexPosition(0, 0, 0)), max)
[next, ..rest] -> {
let new_position = move(position, next)
let new_max = int.max(max, distance(new_position, start))
do_walk(rest, new_position, new_max)
}
}
}
|