Advent of Code 2025 solutions in Gleam

Day 2 / part 2

Changed files
+53 -26
src
test
+51 -24
src/days/day02.gleam
··· 7 7 Range(start: String, end: String) 8 8 } 9 9 10 + pub fn solve(input: String) -> Nil { 11 + io.println("Day 2:") 12 + io.println("Part 1: " <> part1(input)) 13 + io.println("Part 2: " <> part2(input)) 14 + } 15 + 16 + pub fn part1(input: String) -> String { 17 + parse_input(input) 18 + |> list.flat_map(fn(range) { 19 + find_invalid_ids_in_range(range, is_id_invalid_exactly_twice) 20 + }) 21 + |> int.sum 22 + |> int.to_string 23 + } 24 + 25 + pub fn part2(input: String) -> String { 26 + parse_input(input) 27 + |> list.flat_map(fn(range) { 28 + find_invalid_ids_in_range(range, is_id_invalid_at_least_twice) 29 + }) 30 + |> int.sum 31 + |> int.to_string 32 + } 33 + 10 34 pub fn parse_input(input: String) -> List(Range) { 11 35 input 12 36 |> string.trim ··· 20 44 }) 21 45 } 22 46 23 - fn is_id_invalid(id: String) -> Bool { 47 + fn find_invalid_ids_in_range( 48 + range: Range, 49 + validator: fn(String) -> Bool, 50 + ) -> List(Int) { 51 + let assert Ok(start) = int.parse(range.start) 52 + let assert Ok(end) = int.parse(range.end) 53 + list.range(start, end) 54 + |> list.filter(fn(id) { validator(int.to_string(id)) }) 55 + } 56 + 57 + fn is_id_invalid_exactly_twice(id: String) -> Bool { 24 58 let len = string.length(id) 25 59 case len % 2 == 0 { 26 60 False -> False ··· 33 67 } 34 68 } 35 69 36 - fn find_invalid_ids_in_range(range: Range) -> List(Int) { 37 - let assert Ok(start) = int.parse(range.start) 38 - let assert Ok(end) = int.parse(range.end) 39 - list.range(start, end) 40 - |> list.filter(fn(id) { is_id_invalid(int.to_string(id)) }) 41 - } 42 - 43 - pub fn part1(input: String) -> String { 44 - parse_input(input) 45 - |> list.flat_map(find_invalid_ids_in_range) 46 - |> int.sum 47 - |> int.to_string 48 - } 49 - 50 - pub fn part2(_input: String) -> String { 51 - // TODO: Implement part 2 52 - "Not implemented" 53 - } 54 - 55 - pub fn solve(input: String) -> Nil { 56 - io.println("Day 2:") 57 - io.println("Part 1: " <> part1(input)) 58 - io.println("Part 2: " <> part2(input)) 70 + fn is_id_invalid_at_least_twice(id: String) -> Bool { 71 + let len = string.length(id) 72 + list.range(2, len) 73 + |> list.any(fn(divisor) { 74 + case len % divisor == 0 { 75 + False -> False 76 + True -> { 77 + let part_len = len / divisor 78 + let first_part = string.slice(id, 0, part_len) 79 + list.range(1, divisor - 1) 80 + |> list.all(fn(i) { 81 + string.slice(id, i * part_len, part_len) == first_part 82 + }) 83 + } 84 + } 85 + }) 59 86 }
+2 -2
test/days/day02_test.gleam
··· 4 4 5 5 pub fn part1_test() { 6 6 let assert Ok(input) = simplifile.read("inputs/day2.txt") 7 - day02.part1(input) |> should.equal("TODO") 7 + day02.part1(input) |> should.equal("54234399924") 8 8 } 9 9 10 10 pub fn part2_test() { 11 11 let assert Ok(input) = simplifile.read("inputs/day2.txt") 12 - day02.part2(input) |> should.equal("TODO") 12 + day02.part2(input) |> should.equal("70187097315") 13 13 }