|
| 1 | +package de.ronny_h.aoc.year2017.day10 |
| 2 | + |
| 3 | +import de.ronny_h.aoc.AdventOfCode |
| 4 | + |
| 5 | +fun main() = KnotHash().run("3770", "a9d0e68649d0174c8756a59ba21d4dc6") |
| 6 | + |
| 7 | +class KnotHash : AdventOfCode<String>(2017, 10) { |
| 8 | + override fun part1(input: List<String>): String { |
| 9 | + val lengths = input.single().split(",").map(String::toInt) |
| 10 | + val size = if (lengths.size < 5) 5 else 256 // just for testing |
| 11 | + return knotHash(size, lengths).toString() |
| 12 | + } |
| 13 | + |
| 14 | + override fun part2(input: List<String>): String { |
| 15 | + val lengths = input.single().toASCII() + listOf(17, 31, 73, 47, 23) |
| 16 | + val denseHash = sparseHash(256, lengths, 64).reduceToDenseHash() |
| 17 | + check(denseHash.size == 16) |
| 18 | + return denseHash.joinToString("") { it.toString(16).padStart(2, '0') } |
| 19 | + } |
| 20 | +} |
| 21 | + |
| 22 | +fun knotHash(size: Int, lengths: List<Int>): Int { |
| 23 | + val circularList = sparseHash(size, lengths) |
| 24 | + return circularList[0] * circularList[1] |
| 25 | +} |
| 26 | + |
| 27 | +private fun sparseHash( |
| 28 | + size: Int, |
| 29 | + lengths: List<Int>, |
| 30 | + rounds: Int = 1, |
| 31 | +): List<Int> { |
| 32 | + val circularList = MutableList(size) { it } |
| 33 | + var position = 0 |
| 34 | + var skipSize = 0 |
| 35 | + |
| 36 | + fun reverseSubList(start: Int, length: Int) { |
| 37 | + if (start + length < size) { |
| 38 | + circularList.subList(start, start + length).toList() |
| 39 | + } else { |
| 40 | + circularList.subList(start, size) + circularList.subList(0, length - size + start) |
| 41 | + } |
| 42 | + .reversed() |
| 43 | + .forEachIndexed { i, item -> |
| 44 | + circularList[(start + i) % size] = item |
| 45 | + } |
| 46 | + } |
| 47 | + |
| 48 | + repeat(rounds) { |
| 49 | + lengths.forEach { length -> |
| 50 | + reverseSubList(position, length) |
| 51 | + position = (position + length + skipSize) % size |
| 52 | + skipSize++ |
| 53 | + } |
| 54 | + } |
| 55 | + return circularList |
| 56 | +} |
| 57 | + |
| 58 | +fun List<Int>.reduceToDenseHash() = chunked(16) { |
| 59 | + it.reduce { a, b -> a xor b } |
| 60 | +} |
| 61 | + |
| 62 | +fun String.toASCII() = map(Char::code) |
0 commit comments