this repo has no description
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}