aboutsummaryrefslogtreecommitdiff
path: root/aoc2017-gleam/src/aoc_2017/day_11.gleam
blob: 7d3df0b618fd7a278f27db55a0f664339cbd8fe3 (plain)
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)
    }
  }
}