this repo has no description
at main 87 lines 2.0 kB view raw
1import gleam/int 2import gleam/io 3import gleam/list 4import gleam/result 5import gleam/string 6import simplifile 7 8pub fn start() -> Nil { 9 let assert Ok(content) = simplifile.read("inputs/day5.txt") 10 let data = parse(content) 11 12 let _ = io.debug(part1(data)) 13 let _ = io.debug(part2(data)) 14 15 Nil 16} 17 18type Range { 19 Range(start: Int, end: Int) 20} 21 22type Input { 23 Input(fresh: List(Range), ids: List(Int)) 24} 25 26fn parse(data: String) -> Input { 27 let assert [ranges, identifiers] = string.split(data, "\n\n") 28 29 let fresh = 30 string.split(ranges, "\n") 31 |> list.map(fn(range) { 32 let assert [start, end] = 33 string.split(range, "-") 34 |> list.map(int.parse) 35 |> list.map(result.unwrap(_, 0)) 36 37 Range(start, end) 38 }) 39 40 let ids = 41 string.split(identifiers, "\n") 42 |> list.map(int.parse) 43 |> list.map(result.unwrap(_, 0)) 44 45 Input(fresh, ids) 46} 47 48fn part1(data: Input) { 49 list.count(data.ids, fn(x) { 50 list.any(data.fresh, fn(y) { y.start <= x && x <= y.end }) 51 }) 52} 53 54fn find_to_merge(lst: List(Range), range: Range) { 55 list.filter(lst, fn(x) { 56 { x.start <= range.start && x.end >= range.start } 57 || { x.start <= range.end && x.end >= range.end } 58 || { x.start <= range.start && x.end >= range.end } 59 || { range.start <= x.start && range.end >= x.end } 60 }) 61} 62 63fn part2(data: Input) { 64 list.fold(data.fresh, list.new(), fn(acc, range) { 65 let to_merge = [range, ..find_to_merge(acc, range)] 66 let min = 67 list.fold(to_merge, 9_223_372_036_854_775_807, fn(min, r) { 68 case r.start < min { 69 True -> r.start 70 False -> min 71 } 72 }) 73 74 let max = 75 list.fold(to_merge, 0, fn(max, r) { 76 case r.end > max { 77 True -> r.end 78 False -> max 79 } 80 }) 81 82 list.filter(acc, fn(x) { !list.contains(to_merge, x) }) 83 |> list.prepend(Range(min, max)) 84 }) 85 |> io.debug 86 |> list.fold(0, fn(acc, r) { acc + r.end - r.start + 1 }) 87}