Skip to content

Commit 06a1836

Browse files
committed
Solution 2015-12 (JSAbacusFramework.io)
1 parent 5e61e26 commit 06a1836

File tree

2 files changed

+138
-0
lines changed

2 files changed

+138
-0
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package de.ronny_h.aoc.year2015.day12
2+
3+
import de.ronny_h.aoc.AdventOfCode
4+
5+
fun main() = JSAbacusFramework().run(111754, 65402)
6+
7+
class JSAbacusFramework : AdventOfCode<Int>(2015, 12) {
8+
9+
private val numberRegex = "[-]{0,1}[0-9]+".toRegex()
10+
11+
override fun part1(input: List<String>) = input.first().sumAllNumbers()
12+
13+
override fun part2(input: List<String>) = input.first().filterOutRedObjects().first.sumAllNumbers()
14+
15+
private fun String.sumAllNumbers(): Int = numberRegex.findAll(this).sumOf { match -> match.value.toInt() }
16+
}
17+
18+
private const val redValue = ":\"red\""
19+
20+
/**
21+
* From a JSON String, filters out sub-objects that have a value equal to "red".
22+
*
23+
* @return A pair of the filtered JSON String and the length of the JSON object that was processed.
24+
*/
25+
fun String.filterOutRedObjects(): Pair<String, Int> {
26+
var isRed = false
27+
var inRedValue = 0
28+
var prefix = ""
29+
var i = 0
30+
var lastSubObjectAt = 0
31+
while (i < length) {
32+
when (this[i]) {
33+
'{' -> {
34+
val (infix, len) = substring(i + 1).filterOutRedObjects()
35+
prefix = prefix + substring(lastSubObjectAt..i) + infix
36+
i += len
37+
lastSubObjectAt = i
38+
}
39+
40+
'}' -> if (isRed) {
41+
return "" to i + 1
42+
} else {
43+
return prefix + substring(lastSubObjectAt, i) to i + 1
44+
}
45+
46+
redValue[inRedValue] -> inRedValue++
47+
48+
else -> inRedValue = 0
49+
}
50+
if (inRedValue == redValue.length) {
51+
isRed = true
52+
inRedValue = 0
53+
}
54+
i++
55+
}
56+
return prefix + this.substring(lastSubObjectAt) to length
57+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package de.ronny_h.aoc.year2015.day12
2+
3+
import io.kotest.core.spec.style.StringSpec
4+
import io.kotest.matchers.shouldBe
5+
6+
class JSAbacusFrameworkTest : StringSpec({
7+
8+
val day12 = JSAbacusFramework()
9+
10+
"part 1: a sum of 6" {
11+
day12.part1(listOf("[1,2,3]")) shouldBe 6
12+
day12.part1(listOf("{\"a\":2,\"b\":4}")) shouldBe 6
13+
}
14+
15+
"part 1: a sum of 3" {
16+
day12.part1(listOf("[[[3]]]")) shouldBe 3
17+
day12.part1(listOf("{\"a\":{\"b\":4},\"c\":-1}")) shouldBe 3
18+
}
19+
20+
"part 1: a sum of 0" {
21+
day12.part1(listOf("{\"a\":[-1,1]}")) shouldBe 0
22+
day12.part1(listOf("[-1,{\"a\":1}]")) shouldBe 0
23+
day12.part1(listOf("[]")) shouldBe 0
24+
day12.part1(listOf("{}")) shouldBe 0
25+
}
26+
27+
"readNonRedObject of simple array" {
28+
"[1,2,3]".filterOutRedObjects() shouldBe Pair("[1,2,3]", 7)
29+
}
30+
31+
"readNonRedObject of simple object" {
32+
"""{"a":1}""".filterOutRedObjects() shouldBe Pair("""{"a":1}""", 7)
33+
}
34+
35+
"readNonRedObject of simple object containing value red" {
36+
"""{"a":"red"}""".filterOutRedObjects() shouldBe Pair("{}", 11)
37+
}
38+
39+
"readNonRedObject of nested object" {
40+
"""{"a":{"b":"c"}}""".filterOutRedObjects() shouldBe Pair("""{"a":{"b":"c"}}""", 15)
41+
}
42+
43+
"readNonRedObject of nested object containing value red" {
44+
"""{"a":{"b":"red"}}""".filterOutRedObjects() shouldBe Pair("""{"a":{}}""", 17)
45+
}
46+
47+
"readNonRedObject with two red objects on nested level" {
48+
"""{"a":{"b":"red"},"c":{"d":"red"}}""".filterOutRedObjects() shouldBe Pair("""{"a":{},"c":{}}""", 33)
49+
}
50+
51+
"readNonRedObject of double-nested object" {
52+
"""{"a":{"b":{"c":"d"}},"e":1}""".filterOutRedObjects() shouldBe Pair(
53+
"""{"a":{"b":{"c":"d"}},"e":1}""",
54+
27
55+
)
56+
}
57+
58+
"readNonRedObject of double-nested object containing red" {
59+
"""{"a":{"b":{"c":"red"},"d":1}}""".filterOutRedObjects() shouldBe Pair("""{"a":{"b":{},"d":1}}""", 29)
60+
}
61+
62+
"readNonRedObject of double-nested object containing red on mid-level" {
63+
"""{"a":{"b":"red","c":{"d":0},"d":1}}""".filterOutRedObjects() shouldBe Pair("""{"a":{}}""", 35)
64+
}
65+
66+
"part 2: a sum of 6" {
67+
day12.part2(listOf("[1,2,3]")) shouldBe 6
68+
}
69+
70+
"part 2: a sum of 4 when ignoring object with a value of red" {
71+
day12.part2(listOf("""[1,{"c":"red","b":2},3]""")) shouldBe 4
72+
}
73+
74+
"part 2: a sum of 0 when ignoring object with a value of red" {
75+
day12.part2(listOf("""{"d":"red","e":[1,2,3,4],"f":5}""")) shouldBe 0
76+
}
77+
78+
"part 2: a sum of 6 with red in an array" {
79+
day12.part2(listOf("""[1,"red",5]""")) shouldBe 6
80+
}
81+
})

0 commit comments

Comments
 (0)