advent of code 2025 in gleam!
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

day 6

+306 -7
+10 -3
src/advent_2025.gleam
··· 1 1 import day1 2 2 import day2 3 - import gleam/io 3 + import day3 4 + import day4 5 + import day5 6 + import day6 4 7 5 8 pub fn main() { 6 - day1.day1main() 7 - day2.day2main() 9 + // day1.day1main() 10 + // day2.day2main() 11 + // day3.day3main() 12 + // day4.day4main() 13 + // day5.day5main() 14 + day6.day6main() 8 15 }
+43
src/day3.gleam
··· 1 + import gleam/int 2 + import gleam/io 3 + import gleam/list 4 + import gleam/regexp 5 + import gleam/result 6 + import gleam/string 7 + import herbie as h 8 + import simplifile 9 + 10 + pub fn day3main() { 11 + let assert Ok(file) = simplifile.read("./data/day3test") 12 + let batteries = 13 + file 14 + |> string.trim 15 + |> string.split("\n") 16 + |> list.map(fn(x) { 17 + string.to_graphemes(x) 18 + |> list.map(h.quickint) 19 + }) 20 + 21 + part1(batteries) 22 + |> echo 23 + } 24 + 25 + fn part1(input: List(List(Int))) -> Int { 26 + list.fold(input, 0, fn(acc, x) { 27 + let first_digit = 28 + x 29 + |> list.reverse 30 + |> list.drop(1) 31 + |> list.reverse 32 + |> list.max(int.compare) 33 + |> result.unwrap(69) 34 + 35 + let second_digit = 36 + x 37 + |> list.drop_while(fn(y) { y <= first_digit - 1 }) 38 + |> list.drop(1) 39 + |> list.max(int.compare) 40 + |> result.unwrap(69) 41 + acc + { first_digit * 10 } + second_digit 42 + }) 43 + }
+68
src/day4.gleam
··· 1 + import gleam/dict.{type Dict} 2 + import gleam/int 3 + import gleam/io 4 + import gleam/list 5 + import gleam/regexp 6 + import gleam/result 7 + import gleam/string 8 + import herbie as h 9 + import simplifile 10 + 11 + pub fn day4main() { 12 + let assert Ok(file) = simplifile.read("./data/day4") 13 + let grid = 14 + file 15 + |> string.trim 16 + |> string.split("\n") 17 + |> list.map(string.to_graphemes) 18 + |> h.grid_to_coords() 19 + 20 + part1(grid) 21 + inner(#(grid, 0)) 22 + outer(#(grid, 0)) 23 + |> echo 24 + } 25 + 26 + fn outer(grid: #(dict.Dict(#(Int, Int), String), Int)) { 27 + let old = grid 28 + let new = inner(grid) 29 + 30 + case new.1 == old.1 { 31 + True -> grid 32 + False -> outer(new) 33 + } 34 + } 35 + 36 + fn inner( 37 + input: #(dict.Dict(#(Int, Int), String), Int), 38 + ) -> #(dict.Dict(#(Int, Int), String), Int) { 39 + let #(grid, acc) = input 40 + 41 + dict.fold(grid, #(dict.new(), acc), fn(acc, k, v) { 42 + let newgrid = acc.0 43 + let replacements = acc.1 44 + case v { 45 + "@" -> { 46 + let count = 47 + h.neighbors_9_flat_vals(k, grid) 48 + |> list.count(fn(x) { x == "@" }) 49 + case count < 5 { 50 + True -> #(dict.insert(newgrid, k, "X"), replacements + 1) 51 + False -> #(dict.insert(newgrid, k, v), replacements) 52 + } 53 + } 54 + _ -> #(dict.insert(newgrid, k, v), replacements) 55 + } 56 + }) 57 + } 58 + 59 + fn part1(grid: dict.Dict(#(Int, Int), String)) -> Int { 60 + dict.filter(grid, fn(k, v) { 61 + let count = 62 + h.neighbors_9_flat_vals(k, grid) 63 + |> list.count(fn(x) { x == "@" }) 64 + count < 5 && v == "@" 65 + }) 66 + |> dict.values 67 + |> list.length 68 + }
+72
src/day5.gleam
··· 1 + import gleam/int 2 + import gleam/list 3 + import gleam/string 4 + import herbie as h 5 + import simplifile 6 + 7 + pub fn day5main() { 8 + let #(ranges, values) = inputs() 9 + 10 + part1(ranges, values) 11 + |> echo 12 + 13 + part2(ranges) 14 + |> echo 15 + } 16 + 17 + fn part2(ranges: List(#(Int, Int))) -> Int { 18 + ranges 19 + |> sort_ranges() 20 + |> merge_ranges([]) 21 + |> list.fold(0, fn(acc, x: #(Int, Int)) { x.1 - x.0 + 1 + acc }) 22 + } 23 + 24 + fn merge_ranges( 25 + ranges: List(#(Int, Int)), 26 + acc: List(#(Int, Int)), 27 + ) -> List(#(Int, Int)) { 28 + case ranges, acc { 29 + [new, ..rest], [] -> merge_ranges(rest, [new]) 30 + [new, ..rest], [last, ..acc] if last.0 <= new.0 && last.1 >= new.1 -> 31 + merge_ranges(rest, [last, ..acc]) 32 + [new, ..rest], [last, ..acc] if last.1 < new.0 -> 33 + merge_ranges(rest, [new, last, ..acc]) 34 + [new, ..rest], [last, ..acc] if last.0 <= new.0 && last.1 <= new.1 -> 35 + merge_ranges(rest, [#(last.0, new.1), ..acc]) 36 + [], _ -> acc 37 + [_, ..], [_, ..] -> panic as "aw beans" 38 + } 39 + } 40 + 41 + fn sort_ranges(ranges: List(#(Int, Int))) { 42 + ranges 43 + |> list.sort(fn(a, b) { int.compare(a.0, b.0) }) 44 + } 45 + 46 + fn part1(ranges: List(#(Int, Int)), values: List(Int)) -> Int { 47 + list.count(values, fn(value) { part1check(value, ranges) }) 48 + } 49 + 50 + fn part1check(value: Int, ranges: List(#(Int, Int))) -> Bool { 51 + list.any(ranges, fn(range) { value >= range.0 && value <= range.1 }) 52 + } 53 + 54 + fn inputs() -> #(List(#(Int, Int)), List(Int)) { 55 + let assert Ok(file) = simplifile.read("./data/day5") 56 + let assert [ranges, values] = 57 + file 58 + |> string.trim 59 + |> string.split("\n\n") 60 + let ranges = 61 + ranges 62 + |> string.split("\n") 63 + |> list.map(fn(x) { 64 + let assert [first, last] = string.split(x, "-") |> list.map(h.quickint) 65 + #(first, last) 66 + }) 67 + let values = 68 + values 69 + |> string.split("\n") 70 + |> list.map(h.quickint) 71 + #(ranges, values) 72 + }
+109
src/day6.gleam
··· 1 + import gleam/int 2 + import gleam/list 3 + import gleam/string 4 + import herbie as h 5 + import simplifile 6 + 7 + pub type Column { 8 + Column(sign: Sign, digits: List(Int)) 9 + } 10 + 11 + pub type Sign { 12 + Plus 13 + Multiply 14 + } 15 + 16 + pub fn day6main() { 17 + let part1 = 18 + pt1_inputs() 19 + |> add_column 20 + |> echo 21 + 22 + let part2 = 23 + pt2_inputs() 24 + |> add_column 25 + |> echo 26 + } 27 + 28 + fn pt1_inputs() -> List(Column) { 29 + let assert Ok(file) = simplifile.read("./data/day6test") 30 + file 31 + |> string.trim 32 + |> string.split("\n") 33 + |> list.map(fn(line) { 34 + string.split(line, " ") |> list.filter(fn(char) { char != "" }) 35 + }) 36 + |> list.transpose() 37 + |> list.map(build_columns) 38 + } 39 + 40 + fn build_columns(input: List(String)) -> Column { 41 + let assert [sign, ..digits] = 42 + input 43 + |> list.reverse 44 + 45 + let sign = symbol_type(sign) 46 + 47 + let digits = 48 + digits 49 + |> list.map(h.quickint) 50 + Column(sign:, digits:) 51 + } 52 + 53 + fn symbol_type(sign: String) -> Sign { 54 + case sign { 55 + "+" -> Plus 56 + _ -> Multiply 57 + } 58 + } 59 + 60 + fn add_column(maths: List(Column)) -> Int { 61 + list.fold(maths, 0, column_fold) 62 + } 63 + 64 + fn column_fold(acc: Int, input: Column) -> Int { 65 + let #(operand, accumulator) = case input.sign { 66 + Plus -> #(int.add, 0) 67 + Multiply -> #(int.multiply, 1) 68 + } 69 + list.fold(input.digits, accumulator, operand) + acc 70 + } 71 + 72 + fn pt2_inputs() -> List(Column) { 73 + let assert Ok(file) = simplifile.read("./data/day6test") 74 + let assert [raw_symbols, ..digits] = 75 + file 76 + |> string.trim 77 + |> string.split("\n") 78 + |> list.map(string.to_graphemes) 79 + |> list.reverse 80 + 81 + let symbols = 82 + raw_symbols 83 + |> list.filter(fn(char) { char != " " }) 84 + 85 + let column_count = list.length(symbols) 86 + let chunksize = list.length(h.quickfirst(digits)) / column_count 87 + 88 + digits 89 + |> group_by_sign 90 + |> list.sized_chunk(into: chunksize) 91 + |> list.map2(symbols, fn(digits, sign) { 92 + let sign = symbol_type(sign) 93 + Column(sign:, digits:) 94 + }) 95 + } 96 + 97 + fn group_by_sign(digits: List(List(String))) -> List(Int) { 98 + digits 99 + |> list.transpose 100 + |> list.map(fn(line) { 101 + list.reverse(line) 102 + |> list.filter(fn(char) { char != " " }) 103 + }) 104 + |> list.filter(fn(x) { x != [] }) 105 + |> list.map(fn(num) { 106 + string.concat(num) 107 + |> h.quickint 108 + }) 109 + }
+4 -4
src/herbie.gleam
··· 61 61 } 62 62 63 63 pub fn neighbors_9_flat_vals( 64 - coordgrid: dict.Dict(Coord, a), 65 64 start: Coord, 66 - ) -> List(List(a)) { 65 + coordgrid: dict.Dict(Coord, a), 66 + ) -> List(a) { 67 67 list.flat_map([-1, 0, 1], fn(x) { 68 - list.map([-1, 0, 1], fn(y) { 68 + list.flat_map([-1, 0, 1], fn(y) { 69 69 case dict.get(coordgrid, #(start.0 + x, start.1 + y)) { 70 70 Ok(val) -> [val] 71 71 _ -> [] ··· 75 75 } 76 76 77 77 pub fn neighbors_9_grid( 78 - coordgrid: dict.Dict(Coord, a), 79 78 start: Coord, 79 + coordgrid: dict.Dict(Coord, a), 80 80 ) -> dict.Dict(#(Int, Int), a) { 81 81 list.flat_map([-1, 0, 1], fn(x) { 82 82 list.flat_map([-1, 0, 1], fn(y) {