diff options
Diffstat (limited to 'aoc2017-gleam/src/aoc_2017')
-rw-r--r-- | aoc2017-gleam/src/aoc_2017/day_10.gleam | 78 |
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() +} |