Skip to content

Commit 90817b8

Browse files
committed
Use the MutableRingList in KnotHash
1 parent 6b127a2 commit 90817b8

File tree

3 files changed

+45
-18
lines changed

3 files changed

+45
-18
lines changed

src/main/kotlin/de/ronny_h/aoc/extensions/collections/MutableRingList.kt

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
package de.ronny_h.aoc.extensions.collections
22

3-
class MutableRingList<T>(initialList: List<T>) {
4-
private val list: MutableList<T> = initialList.toMutableList()
3+
class MutableRingList<T>(initialCapacity: Int) {
4+
private val list: MutableList<T> = ArrayList<T>(initialCapacity)
55
private var offset = 0
66

7+
constructor(initialList: List<T>) : this(initialList.size) {
8+
list.addAll(initialList)
9+
}
10+
11+
constructor(size: Int, init: (index: Int) -> T) : this(size) {
12+
repeat(size) { index -> list.add(init(index)) }
13+
}
14+
715
companion object {
816
fun <T> mutableRingListOf(vararg elements: T): MutableRingList<T> = MutableRingList(elements.toList())
917
fun mutableRingListOf(elements: String): MutableRingList<Char> = MutableRingList(elements.toList())
@@ -48,6 +56,20 @@ class MutableRingList<T>(initialList: List<T>) {
4856
return this
4957
}
5058

59+
fun reverseSubList(s: Int, length: Int): MutableRingList<T> {
60+
val start = (offset + s) % list.size
61+
if (start + length < list.size) {
62+
list.subList(start, start + length).toList()
63+
} else {
64+
list.subList(start, list.size) + list.subList(0, length - list.size + start)
65+
}
66+
.reversed()
67+
.forEachIndexed { i, item ->
68+
list[(start + i) % list.size] = item
69+
}
70+
return this
71+
}
72+
5173
/**
5274
* @return A snapshot of the current state of this [MutableRingList]
5375
*/

src/main/kotlin/de/ronny_h/aoc/year2017/day10/KnotHash.kt

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package de.ronny_h.aoc.year2017.day10
22

33
import de.ronny_h.aoc.AdventOfCode
4+
import de.ronny_h.aoc.extensions.collections.MutableRingList
45

56
fun main() = KnotHash().run("3770", "a9d0e68649d0174c8756a59ba21d4dc6")
67

@@ -31,30 +32,18 @@ private fun sparseHash(
3132
lengths: List<Int>,
3233
rounds: Int = 1,
3334
): List<Int> {
34-
val circularList = MutableList(size) { it }
35+
val circularList = MutableRingList(size) { it }
3536
var position = 0
3637
var skipSize = 0
3738

38-
fun reverseSubList(start: Int, length: Int) {
39-
if (start + length < size) {
40-
circularList.subList(start, start + length).toList()
41-
} else {
42-
circularList.subList(start, size) + circularList.subList(0, length - size + start)
43-
}
44-
.reversed()
45-
.forEachIndexed { i, item ->
46-
circularList[(start + i) % size] = item
47-
}
48-
}
49-
5039
repeat(rounds) {
5140
lengths.forEach { length ->
52-
reverseSubList(position, length)
41+
circularList.reverseSubList(position, length)
5342
position = (position + length + skipSize) % size
5443
skipSize++
5544
}
5645
}
57-
return circularList
46+
return circularList.toList()
5847
}
5948

6049
fun List<Int>.reduceToDenseHash() = chunked(16) {

src/test/kotlin/de/ronny_h/aoc/extensions/collections/MutableRingListTest.kt

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,18 @@ import io.kotest.matchers.shouldBe
66

77
class MutableRingListTest : StringSpec({
88

9-
"a MutableRingList<Char> can be created from a variable amounts of Chars and toString() generates a nice representation" {
9+
"a MutableRingList<Char> can be created from a variable amount of Chars and toString() generates a nice representation" {
1010
mutableRingListOf('a', 'b', 'c', 'd', 'e').toString() shouldBe "[a, b, c, d, e]"
1111
}
1212

1313
"a MutableRingList<Char> can be created from a String and toJoinedString() recreates that String" {
1414
mutableRingListOf("abcde").toJoinedString() shouldBe "abcde"
1515
}
1616

17+
"a MutableRingList can be created with an initializer function" {
18+
MutableRingList(6) { it }.toJoinedString() shouldBe "012345"
19+
}
20+
1721
"get(index) returns the element at index" {
1822
mutableRingListOf("abcde").get(2) shouldBe 'c'
1923
mutableRingListOf("abcde")[2] shouldBe 'c'
@@ -72,4 +76,16 @@ class MutableRingListTest : StringSpec({
7276
mutableRingListOf("abcde").swap('a', 'e').toJoinedString() shouldBe "ebcda"
7377
mutableRingListOf("abcde").swap('c', 'c').toJoinedString() shouldBe "abcde"
7478
}
79+
80+
"reversSubList on an unmodified ringList" {
81+
mutableRingListOf(1, 2, 3, 4, 5, 6).reverseSubList(1, 4).toList() shouldBe listOf(1, 5, 4, 3, 2, 6)
82+
mutableRingListOf(1, 2, 3, 4, 5, 6).reverseSubList(4, 4).toList() shouldBe listOf(6, 5, 3, 4, 2, 1)
83+
}
84+
85+
"reversSubList on a shifted ringList" {
86+
mutableRingListOf(1, 2, 3, 4, 5, 6).shiftRight(2)
87+
.reverseSubList(1, 4).toList() shouldBe listOf(5, 3, 2, 1, 6, 4)
88+
mutableRingListOf(1, 2, 3, 4, 5, 6).shiftRight(2)
89+
.reverseSubList(4, 4).toList() shouldBe listOf(4, 3, 1, 2, 6, 5)
90+
}
7591
})

0 commit comments

Comments
 (0)