aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J <thechairman@thechairman.info>2024-06-17 16:18:04 -0400
committerH.J <thechairman@thechairman.info>2024-06-17 16:18:04 -0400
commit49b9c2eab0285356f42391c0b313d06688aba13f (patch)
treed914fd38bfc5905d9af818d1423a2f7e9d2b2c57
parent32bc75cae2a0fceafea5c48c550888bc1d7c6016 (diff)
downloadgleam_aoc-49b9c2eab0285356f42391c0b313d06688aba13f.tar.gz
gleam_aoc-49b9c2eab0285356f42391c0b313d06688aba13f.zip
gleam 2017 day 15 complete
-rw-r--r--aoc2017-gleam/src/aoc_2017/day_15.gleam95
1 files changed, 91 insertions, 4 deletions
diff --git a/aoc2017-gleam/src/aoc_2017/day_15.gleam b/aoc2017-gleam/src/aoc_2017/day_15.gleam
index a0a1145..e0557f5 100644
--- a/aoc2017-gleam/src/aoc_2017/day_15.gleam
+++ b/aoc2017-gleam/src/aoc_2017/day_15.gleam
@@ -1,7 +1,94 @@
-pub fn pt_1(input: String) {
- todo as "part 1 not implemented"
+import gleam/int
+import gleam/io
+import gleam/string
+
+const sixteen_bits = 0xFFFF
+
+const generator_a = 16_807
+
+const generator_b = 48_271
+
+const divisor = 2_147_483_647
+
+const max_reps_pt1 = 40_000_000
+
+const max_reps_pt2 = 5_000_000
+
+pub fn parse(input: String) {
+ let assert Ok(#(a_str, b_str)) = string.split_once(input, ",")
+ let assert Ok(a) = int.parse(a_str)
+ let assert Ok(b) = int.parse(b_str)
+
+ #(a, b)
+}
+
+pub fn pt_1(input: #(Int, Int)) {
+ let #(a, b) = input
+
+ next_comparison(
+ a: a,
+ b: b,
+ selecting_a_using: next_value,
+ selecting_b_using: next_value,
+ initial_matches: 0,
+ initial_cycle: 0,
+ up_to: max_reps_pt1,
+ )
+}
+
+pub fn pt_2(input: #(Int, Int)) {
+ let #(a, b) = input
+
+ next_comparison(
+ a: a,
+ b: b,
+ selecting_a_using: next_but_divisible_by(4),
+ selecting_b_using: next_but_divisible_by(8),
+ initial_matches: 0,
+ initial_cycle: 0,
+ up_to: max_reps_pt2,
+ )
+}
+
+fn next_value(current, generator) {
+ { current * generator } % divisor
+}
+
+fn picky_generator(current, generator, divisible_by) {
+ let trial = next_value(current, generator)
+ case trial % divisible_by {
+ 0 -> trial
+ _ -> picky_generator(trial, generator, divisible_by)
+ }
+}
+
+fn next_but_divisible_by(divisible_by) {
+ fn(c, g) { picky_generator(c, g, divisible_by) }
+}
+
+fn last_16_bits(n: Int) {
+ int.bitwise_and(n, sixteen_bits)
}
-pub fn pt_2(input: String) {
- todo as "part 2 not implemented"
+fn next_comparison(
+ a a: Int,
+ b b: Int,
+ selecting_a_using for_a: fn(Int, Int) -> Int,
+ selecting_b_using for_b: fn(Int, Int) -> Int,
+ initial_matches same: Int,
+ initial_cycle count: Int,
+ up_to max: Int,
+) {
+ case count == max {
+ True -> same
+ False -> {
+ let next_a = for_a(a, generator_a)
+ let next_b = for_b(b, generator_b)
+ let maybe_same = case last_16_bits(next_a) == last_16_bits(next_b) {
+ True -> same + 1
+ False -> same
+ }
+ next_comparison(next_a, next_b, for_a, for_b, maybe_same, count + 1, max)
+ }
+ }
}