this repo has no description
at main 153 lines 3.4 kB view raw
1import gleam/float 2import gleam/int 3import gleam/io 4import gleam/list 5import gleam/result 6import gleam/string 7import gleam_community/maths 8import simplifile 9import utils/utils 10 11type Range = 12 #(Int, Int) 13 14pub fn start() -> Nil { 15 let assert Ok(content) = simplifile.read("inputs/day2.txt") 16 let data = parse(content) 17 18 let _ = io.debug(part1(data)) 19 let _ = io.debug(part2(data)) 20 21 Nil 22} 23 24fn parse(data: String) -> List(Range) { 25 data 26 |> string.split(",") 27 |> list.map(fn(x) { 28 let lst = 29 x 30 |> string.split("-") 31 |> list.map(int.parse) 32 |> list.map(result.unwrap(_, 0)) 33 34 #( 35 list.first(lst) |> result.unwrap(0), 36 list.drop(lst, 1) |> list.first |> result.unwrap(0), 37 ) 38 }) 39} 40 41fn is_made_of_part(x: Int) -> Bool { 42 let length = 43 maths.logarithm_10(int.to_float(x)) 44 |> result.unwrap(0.0) 45 |> float.floor 46 |> float.add(1.0) 47 |> float.round 48 49 utils.create_int_range(2, length + 1) 50 |> list.filter(fn(y) { 51 int.to_float(length) /. int.to_float(y) 52 == float.floor(int.to_float(length) /. int.to_float(y)) 53 }) 54 |> list.map(fn(l) { 55 let half_power = 56 { int.to_float(length) /. int.to_float(l) } 57 |> float.floor 58 |> float.power(10.0, _) 59 |> result.unwrap(0.0) 60 |> float.round() 61 62 #(utils.create_int_range(0, l), half_power) 63 }) 64 |> list.map(fn(index) { 65 let #(idx, half_power) = index 66 list.map(idx, fn(y) { 67 { 68 int.to_float(x) 69 /. { 70 int.power(half_power, int.to_float(y)) 71 |> result.unwrap(1.0) 72 } 73 |> float.modulo(int.to_float(half_power)) 74 |> result.unwrap(0.0) 75 |> float.floor 76 |> float.round 77 } 78 }) 79 }) 80 |> list.any(fn(x) { 81 list.all(x, fn(y) { y == { list.first(x) |> result.unwrap(0) } }) 82 }) 83} 84 85fn is_symetric(x: Int) -> Bool { 86 let length = 87 maths.logarithm_10(int.to_float(x)) 88 |> result.unwrap(0.0) 89 |> float.floor 90 |> float.add(1.0) 91 92 let half_power = 93 float.divide(length, 2.0) 94 |> result.unwrap(0.0) 95 |> float.floor 96 |> float.power(10.0, _) 97 |> result.unwrap(0.0) 98 |> float.round() 99 100 x / half_power == x % half_power 101} 102 103fn part1(data: List(Range)) { 104 data 105 |> list.map(fn(range: Range) { 106 let #(start, end) = range 107 utils.loop( 108 case is_symetric(start) { 109 True -> #(start, start) 110 False -> #(start, 0) 111 }, 112 fn(x: #(Int, Int)) { 113 let #(start, _) = x 114 start <= end 115 }, 116 fn(x: #(Int, Int)) { 117 let #(start, count) = x 118 case is_symetric(start + 1) { 119 True -> #(start + 1, count + start + 1) 120 False -> #(start + 1, count) 121 } 122 }, 123 fn(x: #(Int, Int)) { x }, 124 ) 125 }) 126 |> list.fold(0, fn(acc, v: #(Int, Int)) { acc + v.1 }) 127} 128 129fn part2(data) { 130 data 131 |> list.map(fn(range: Range) { 132 let #(start, end) = range 133 utils.loop( 134 case is_made_of_part(start) { 135 True -> #(start, start) 136 False -> #(start, 0) 137 }, 138 fn(x: #(Int, Int)) { 139 let #(start, _) = x 140 start <= end 141 }, 142 fn(x: #(Int, Int)) { 143 let #(start, count) = x 144 case is_made_of_part(start + 1) { 145 True -> #(start + 1, count + start + 1) 146 False -> #(start + 1, count) 147 } 148 }, 149 fn(x: #(Int, Int)) { x }, 150 ) 151 }) 152 |> list.fold(0, fn(acc, v: #(Int, Int)) { acc + v.1 }) 153}