this repo has no description

Day 8

+131
+2
src/aoc.gleam
··· 7 7 import days/day5 8 8 import days/day6 9 9 import days/day7 10 + import days/day8 10 11 import gleam/erlang 11 12 import gleam/int 12 13 import gleam/io ··· 33 34 5 -> day5.start() 34 35 6 -> day6.start() 35 36 7 -> day7.start() 37 + 8 -> day8.start() 36 38 _ -> io.println("Tried to run day " <> int.to_string(day)) 37 39 } 38 40 birl.now()
+129
src/days/day8.gleam
··· 1 + import gleam/float 2 + import gleam/int 3 + import gleam/io 4 + import gleam/list 5 + import gleam/order 6 + import gleam/result 7 + import gleam/set 8 + import gleam/string 9 + import gleam_community/maths 10 + import simplifile 11 + 12 + pub fn start() -> Nil { 13 + let assert Ok(content) = simplifile.read("inputs/day8.txt") 14 + let data = parse(content) 15 + 16 + let _ = io.debug(part1(data)) 17 + let _ = io.debug(part2(data)) 18 + 19 + Nil 20 + } 21 + 22 + type Coord { 23 + Coord(x: Float, y: Float, z: Float) 24 + } 25 + 26 + fn parse(data: String) { 27 + string.split(data, "\n") 28 + |> list.map(fn(x) { 29 + let assert [x, y, z] = 30 + string.split(x, ",") 31 + |> list.map(fn(x) { int.parse(x) |> result.unwrap(0) |> int.to_float }) 32 + Coord(x, y, z) 33 + }) 34 + } 35 + 36 + fn distance(c1: Coord, c2: Coord) -> Float { 37 + let to_root = 38 + { 39 + float.power(c1.x -. c2.x, 2.0) 40 + |> result.unwrap(0.0) 41 + } 42 + +. { 43 + float.power(c1.y -. c2.y, 2.0) 44 + |> result.unwrap(0.0) 45 + } 46 + +. { 47 + float.power(c1.z -. c2.z, 2.0) 48 + |> result.unwrap(0.0) 49 + } 50 + 51 + float.square_root(to_root) |> result.unwrap(9_999_999_999_999_999_999.0) 52 + } 53 + 54 + fn part1(data: List(Coord)) { 55 + let circuits = list.map(data, fn(x) { set.from_list([x]) }) 56 + list.index_map(data, fn(first, idx) { 57 + list.drop(data, idx + 1) 58 + |> list.map(fn(second) { 59 + let d = distance(first, second) 60 + #(first, second, d) 61 + }) 62 + }) 63 + |> list.flatten 64 + |> list.sort(fn(c1, c2) { 65 + case c1.2 <. c2.2 { 66 + True -> order.Lt 67 + _ -> 68 + case c1.2 == c2.2 { 69 + True -> order.Eq 70 + _ -> order.Gt 71 + } 72 + } 73 + }) 74 + |> list.take(1000) 75 + |> list.fold(circuits, fn(acc, coords) { 76 + let #(c1, c2, _) = coords 77 + let assert Ok(s1) = list.find(acc, set.contains(_, c1)) 78 + let assert Ok(s2) = list.find(acc, set.contains(_, c2)) 79 + let acc = 80 + list.filter(acc, fn(x) { !{ set.contains(x, c1) || set.contains(x, c2) } }) 81 + 82 + [set.union(s1, s2), ..acc] 83 + }) 84 + |> list.map(set.size) 85 + |> list.sort(int.compare) 86 + |> list.reverse 87 + |> list.take(3) 88 + |> list.fold(1, int.multiply) 89 + } 90 + 91 + fn part2(data) { 92 + let circuits = list.map(data, fn(x) { set.from_list([x]) }) 93 + list.index_map(data, fn(first, idx) { 94 + list.drop(data, idx + 1) 95 + |> list.map(fn(second) { 96 + let d = distance(first, second) 97 + #(first, second, d) 98 + }) 99 + }) 100 + |> list.flatten 101 + |> list.sort(fn(c1, c2) { 102 + case c1.2 <. c2.2 { 103 + True -> order.Lt 104 + _ -> 105 + case c1.2 == c2.2 { 106 + True -> order.Eq 107 + _ -> order.Gt 108 + } 109 + } 110 + }) 111 + |> list.fold_until(circuits, fn(acc, coords) { 112 + let #(c1, c2, _) = coords 113 + let assert Ok(s1) = list.find(acc, set.contains(_, c1)) 114 + let assert Ok(s2) = list.find(acc, set.contains(_, c2)) 115 + let acc = 116 + list.filter(acc, fn(x) { !{ set.contains(x, c1) || set.contains(x, c2) } }) 117 + 118 + let new = [set.union(s1, s2), ..acc] 119 + case list.length(new) { 120 + 1 -> list.Stop([set.new() |> set.insert(c1) |> set.insert(c2)]) 121 + _ -> list.Continue(new) 122 + } 123 + }) 124 + |> list.first 125 + |> result.unwrap(set.new()) 126 + |> set.to_list() 127 + |> list.fold(1.0, fn(acc, x) { acc *. x.x }) 128 + |> float.round 129 + }