Skip to content

Commit 76828d2

Browse files
committed
Add day 8 part 1
1 parent b986879 commit 76828d2

File tree

5 files changed

+493
-0
lines changed

5 files changed

+493
-0
lines changed

2015/src/main/kotlin/day08/Day08.kt

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package day08
2+
3+
import shared.DebugLogger
4+
5+
class Day08 {
6+
companion object {
7+
8+
val log = DebugLogger(false)
9+
10+
fun part1(input: ByteArray): Day08Result {
11+
12+
val stateMachine = StateMachine()
13+
14+
input.forEach(stateMachine::addChar)
15+
16+
stateMachine.newLine() // Add last result to the results
17+
return Day08Result(stateMachine.lineResults)
18+
}
19+
20+
fun part2(input: List<String>): Int {
21+
TODO("IMPLEMENT")
22+
}
23+
24+
class Day08Result(val lineResults: List<LineResult>) {
25+
fun countTotal() = lineResults.sumOf {
26+
it.codeCount - it.memoryCount
27+
}
28+
}
29+
30+
31+
enum class CharBytes(private val char: Char) {
32+
NEW_LINE('\n'),
33+
ZERO('0'),
34+
NINE('9'),
35+
SLASH('\\'),
36+
QUOTE('"'),
37+
X('x');
38+
39+
val code: Int
40+
get() = char.code
41+
42+
val byte: Byte
43+
get() = code.toByte()
44+
}
45+
46+
data class LineResult(var codeCount: Int = 0, var memoryCount: Int = 0) {
47+
fun clear() {
48+
codeCount = 0
49+
memoryCount = 0
50+
}
51+
}
52+
53+
interface CharState {
54+
fun addChar(stateMachine: StateMachine, charByte: Byte)
55+
}
56+
57+
class StateMachine {
58+
private var currentState: CharState = NormalState()
59+
60+
val lineResults = mutableListOf<LineResult>()
61+
var currentLineResult = LineResult(0, 0)
62+
63+
fun addChar(charByte: Byte) {
64+
currentLineResult.codeCount++ // Always increase code count
65+
log.debugln("\naddChar: '${charByte.toInt().toChar()}' codeCount: ${currentLineResult.codeCount}")
66+
currentState.addChar(this, charByte)
67+
}
68+
69+
fun addMemoryCount() {
70+
currentLineResult.memoryCount++
71+
log.debugln("addMemoryCount: ${currentLineResult.memoryCount}")
72+
}
73+
74+
fun newLine() {
75+
currentLineResult.memoryCount -= 2 // Remove start and end quotes
76+
log.debugln("newLine code '${currentLineResult.codeCount}' memory '${currentLineResult.memoryCount}'")
77+
log.debugln("=".repeat(20))
78+
lineResults.add(currentLineResult)
79+
80+
// Reset line and state
81+
currentLineResult = LineResult(0, 0)
82+
setNewState(NormalState())
83+
}
84+
85+
fun setNewState(newState: CharState) {
86+
log.debugln("setNewState: $currentState > $newState")
87+
currentState = newState
88+
}
89+
}
90+
91+
// "" = 2 code, 0 memory
92+
// "abc" = 5 code, 3 memory
93+
// "aaa\"aaa" = 10 code, 7 memory
94+
// "\x27" = 6 code, 1 memory
95+
class NormalState() : CharState {
96+
override fun addChar(stateMachine: StateMachine, charByte: Byte) {
97+
log.debugln("--- NormalState")
98+
99+
when(charByte) {
100+
CharBytes.SLASH.byte -> stateMachine.setNewState(SlashState())
101+
CharBytes.NEW_LINE.byte -> {
102+
stateMachine.currentLineResult.codeCount -= 1 // Remove new line
103+
stateMachine.newLine()
104+
}
105+
else -> stateMachine.addMemoryCount()
106+
}
107+
}
108+
}
109+
110+
class SlashState() : CharState {
111+
override fun addChar(stateMachine: StateMachine, charByte: Byte) {
112+
log.debugln("--- SlashState")
113+
when(charByte) {
114+
CharBytes.X.byte -> stateMachine.setNewState(HexState())
115+
else -> { // Like '\\' or '\"'
116+
stateMachine.addMemoryCount()
117+
stateMachine.setNewState(NormalState())
118+
}
119+
}
120+
}
121+
}
122+
123+
class HexState() : CharState {
124+
var hexadecimalCount = 0;
125+
126+
override fun addChar(stateMachine: StateMachine, charByte: Byte) {
127+
log.debugln("--- HexState")
128+
129+
hexadecimalCount++
130+
131+
// Like '\x27' or '\x3d'
132+
if (hexadecimalCount == 2) {
133+
stateMachine.addMemoryCount()
134+
stateMachine.setNewState(NormalState())
135+
}
136+
}
137+
}
138+
139+
}
140+
}

2015/src/test/kotlin/Day08Test.kt

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import day08.Day08
2+
import day08.Day08.Companion.LineResult
3+
import org.junit.jupiter.api.Test
4+
5+
import org.junit.jupiter.api.Assertions.*
6+
import org.junit.jupiter.params.ParameterizedTest
7+
import org.junit.jupiter.params.provider.CsvSource
8+
9+
internal class Day08Test {
10+
11+
@Test
12+
fun `part1 examples`() {
13+
val input = Resource.readFileAsBytes("day08_test")
14+
val result = Day08.part1(input)
15+
assertLineResult(result.lineResults[0], 2, 0) // "" = 2 code, 0 memory
16+
assertLineResult(result.lineResults[1], 5, 3) // "abc" = 5 code, 3 memory
17+
assertLineResult(result.lineResults[2], 10, 7) // "aaa\"aaa" = 10 code, 7 memory
18+
assertLineResult(result.lineResults[3], 6, 1) // "\x27" = 6 code, 1 memory
19+
}
20+
21+
private fun assertLineResult(lineResult: LineResult, codeCount: Int, memoryCount: Int) {
22+
assertEquals(codeCount, lineResult.codeCount)
23+
assertEquals(memoryCount, lineResult.memoryCount)
24+
}
25+
26+
@Test
27+
fun `part1 puzzel input`() {
28+
val input = Resource.readFileAsBytes("day08")
29+
assertEquals(1333, Day08.part1(input).countTotal())
30+
}
31+
32+
@ParameterizedTest
33+
@CsvSource(
34+
"input, 0",
35+
)
36+
fun `part2 examples`(input: String, expectedResult: Int) {
37+
assertEquals(expectedResult, Day08.part2(listOf(input)))
38+
}
39+
40+
@Test
41+
fun `part2 puzzel input`() {
42+
val input = Resource.readFileLines("day08")
43+
assertEquals(0, Day08.part2(input))
44+
}
45+
}

2015/src/test/kotlin/FileUtils.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ class Resource {
1515
fun readFileLines(fileName: String): List<String> {
1616
return Resource::class.java.getResource("$fileName.txt").readText(Charsets.UTF_8).split("\n")
1717
}
18+
19+
fun readFileAsBytes(fileName: String): ByteArray {
20+
return Resource::class.java.getResource("$fileName.txt").readBytes()
21+
}
1822
}
1923
}
2024

0 commit comments

Comments
 (0)