this repo has no description

Day 7

+166
+2
src/aoc.gleam
··· 6 6 import days/day4 7 7 import days/day5 8 8 import days/day6 9 + import days/day7 9 10 import gleam/erlang 10 11 import gleam/int 11 12 import gleam/io ··· 31 32 4 -> day4.start() 32 33 5 -> day5.start() 33 34 6 -> day6.start() 35 + 7 -> day7.start() 34 36 _ -> io.println("Tried to run day " <> int.to_string(day)) 35 37 } 36 38 birl.now()
+164
src/days/day7.gleam
··· 1 + import gleam/dict 2 + import gleam/float 3 + import gleam/function 4 + import gleam/int 5 + import gleam/io 6 + import gleam/list 7 + import gleam/otp/task 8 + import gleam/result 9 + import gleam/set 10 + import gleam/string 11 + import simplifile 12 + import utils/utils 13 + 14 + type Type { 15 + Tachion 16 + Splitter 17 + } 18 + 19 + type Position { 20 + Position(x: Int) 21 + } 22 + 23 + type Cell { 24 + Cell(pos: Position, typ: Type) 25 + } 26 + 27 + pub fn start() -> Nil { 28 + let assert Ok(content) = simplifile.read("inputs/day7.txt") 29 + let data = parse(content) 30 + 31 + let _ = io.debug(part1(data)) 32 + let _ = io.debug(part2(data)) 33 + 34 + Nil 35 + } 36 + 37 + fn parse(data: String) { 38 + string.split(data, "\n") 39 + |> list.index_map(fn(l, y) { 40 + list.index_map(string.to_graphemes(l), fn(c, x) { 41 + case c { 42 + "S" -> Ok(Cell(Position(x), Tachion)) 43 + "^" -> Ok(Cell(Position(x), Splitter)) 44 + 45 + // Should never happen 46 + _ -> Error(Nil) 47 + } 48 + }) 49 + |> list.filter_map(function.identity) 50 + }) 51 + |> list.filter(fn(x) { !list.is_empty(x) }) 52 + } 53 + 54 + type Res { 55 + Res(splits: Int, tachions: List(Cell)) 56 + } 57 + 58 + fn part1(data: List(List(Cell))) { 59 + let res = 60 + list.fold(data, Res(0, []), fn(acc, cells_on_line) { 61 + let new_tachions = 62 + list.map(cells_on_line, fn(c) { 63 + case c.typ { 64 + Tachion -> #([c], 0, []) 65 + Splitter -> { 66 + let Position(cx) = c.pos 67 + case list.find(acc.tachions, fn(x) { x.pos.x == cx }) { 68 + Ok(c) -> #( 69 + [ 70 + Cell(Position(cx - 1), Tachion), 71 + Cell(Position(cx + 1), Tachion), 72 + ], 73 + 1, 74 + [c], 75 + ) 76 + Error(_) -> #([], 0, []) 77 + } 78 + } 79 + } 80 + }) 81 + 82 + let used_tachions = 83 + list.fold(new_tachions, [], fn(acc, x) { [x.2, ..acc] }) 84 + |> list.flatten 85 + |> list.fold(set.new(), set.insert) 86 + |> set.to_list 87 + 88 + let new_splits = 89 + acc.splits + list.fold(new_tachions, 0, fn(acc, t) { acc + t.1 }) 90 + 91 + let new_tachions = 92 + list.map(new_tachions, fn(x) { x.0 }) 93 + |> list.filter(fn(x) { !list.is_empty(x) }) 94 + |> list.flatten 95 + 96 + let tachions = 97 + list.filter(acc.tachions, fn(x) { !list.contains(used_tachions, x) }) 98 + |> list.append(new_tachions) 99 + |> list.fold(set.new(), set.insert) 100 + |> set.to_list 101 + 102 + Res(new_splits, tachions) 103 + }) 104 + 105 + res.splits 106 + } 107 + 108 + type Cache = 109 + dict.Dict(#(Int, Int), Int) 110 + 111 + fn rec( 112 + line: Int, 113 + next: List(List(Cell)), 114 + depth: Int, 115 + cache: Cache, 116 + ) -> #(Int, Cache) { 117 + let next_splitter = 118 + utils.list_find_indexes(next, fn(x) { 119 + result.is_ok(list.find(x, fn(y) { y.pos.x == line && y.typ == Splitter })) 120 + }) 121 + |> list.filter(fn(x) { x > depth }) 122 + |> list.first() 123 + 124 + case next_splitter { 125 + Ok(lidx) -> { 126 + let assert Ok(l) = list.drop(next, lidx) |> list.first 127 + let assert Ok(splitter) = 128 + list.find(l, fn(y) { y.pos.x == line && y.typ == Splitter }) 129 + 130 + // Check left Side 131 + let #(left, cache) = case 132 + dict.has_key(cache, #(splitter.pos.x - 1, lidx)) 133 + { 134 + True -> { 135 + let assert Ok(v) = dict.get(cache, #(splitter.pos.x - 1, lidx)) 136 + #(v, cache) 137 + } 138 + False -> rec(splitter.pos.x - 1, next, lidx, cache) 139 + } 140 + let cache = dict.insert(cache, #(splitter.pos.x - 1, lidx), left) 141 + 142 + // Check right Side 143 + let #(right, cache) = case 144 + dict.has_key(cache, #(splitter.pos.x + 1, lidx)) 145 + { 146 + True -> { 147 + let assert Ok(v) = dict.get(cache, #(splitter.pos.x + 1, lidx)) 148 + #(v, cache) 149 + } 150 + False -> rec(splitter.pos.x + 1, next, lidx, cache) 151 + } 152 + let cache = dict.insert(cache, #(splitter.pos.x + 1, lidx), right) 153 + 154 + #(left + right, cache) 155 + } 156 + Error(_) -> #(1, cache) 157 + } 158 + } 159 + 160 + fn part2(data: List(List(Cell))) { 161 + let assert Ok(fl) = list.first(data) 162 + let assert Ok(t) = list.first(fl) 163 + rec(t.pos.x, data, 0, dict.new()).0 164 + }