aboutsummaryrefslogtreecommitdiff
path: root/aoc2017-gleam
diff options
context:
space:
mode:
Diffstat (limited to 'aoc2017-gleam')
-rw-r--r--aoc2017-gleam/src/aoc_2017/day_10.gleam78
1 files changed, 78 insertions, 0 deletions
diff --git a/aoc2017-gleam/src/aoc_2017/day_10.gleam b/aoc2017-gleam/src/aoc_2017/day_10.gleam
new file mode 100644
index 0000000..dc17615
--- /dev/null
+++ b/aoc2017-gleam/src/aoc_2017/day_10.gleam
@@ -0,0 +1,78 @@
+import gleam/int
+import gleam/io
+import gleam/list
+import gleam/result
+import gleam/string
+
+const size = 256
+
+const suffix = [17, 31, 73, 47, 23]
+
+fn parse_as_numbers(input: String) {
+ input
+ |> string.split(",")
+ |> list.map(int.parse)
+ |> result.values()
+}
+
+fn parse_as_bytes(input: String) {
+ input
+ |> string.to_utf_codepoints
+ |> list.map(string.utf_codepoint_to_int)
+ |> list.append(suffix)
+}
+
+pub fn pt_1(input: String) {
+ let twisted = twist(list.range(0, size - 1), parse_as_numbers(input), 0, 0)
+
+ let assert #([first, second, ..], _, _) = twisted
+ first * second
+}
+
+pub fn pt_2(input: String) {
+ megatwist(list.range(0, size - 1), parse_as_bytes(input), 0, 0, 64)
+ |> list.sized_chunk(16)
+ |> list.map(fold_xor)
+ |> string.concat()
+}
+
+fn twist(loop: List(Int), lengths: List(Int), skip: Int, index: Int) {
+ case lengths {
+ [] -> #(loop, skip, index)
+ [l, ..ls] ->
+ loop
+ |> roll(index)
+ |> flip(l)
+ |> roll({ size - index } % size)
+ |> twist(ls, skip + 1, { index + l + skip } % size)
+ }
+}
+
+fn megatwist(loop, lengths, skip, index, iterations) {
+ case iterations {
+ 0 -> loop
+ n -> {
+ let #(next_loop, next_skip, next_index) =
+ twist(loop, lengths, skip, index)
+ megatwist(next_loop, lengths, next_skip, next_index, n - 1)
+ }
+ }
+}
+
+fn roll(list: List(a), by: Int) {
+ let #(left, right) = list.split(list, by % size)
+ list.append(right, left)
+}
+
+fn flip(list: List(a), length: Int) {
+ let #(left, right) = list.split(list, length)
+ list.append(list.reverse(left), right)
+}
+
+fn fold_xor(xs: List(Int)) {
+ let assert Ok(n) = list.reduce(xs, int.bitwise_exclusive_or)
+ n
+ |> int.to_base16()
+ |> string.pad_left(to: 2, with: "0")
+ |> string.lowercase()
+}