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(" \n addChar: '${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
+ }
0 commit comments