-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay24.kt
101 lines (91 loc) · 3.32 KB
/
Day24.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package aoc2021.day24
import util.readInputLineByLine
fun part1(list: List<Instruction>): Long {
val inpCount = list.count { it.op == Operation.INP }
val min = "8".repeat(inpCount).toLong()
val max = "9".repeat(inpCount).toLong()
var largestModel: Long = 0
for (number in max downTo min) {
if (verifyModelNumber(list, number.toString())) {
largestModel = number
break
}
}
return largestModel
}
fun verifyModelNumber(instructions: List<Instruction>, input: String): Boolean {
if (input.any { it == '0' }) {
return false
}
val inputList = input.toCharArray()
val valueMap: MutableMap<Char, Int> = mutableMapOf('w' to 0, 'x' to 0, 'y' to 0, 'z' to 0)
var currentInpIndex = 0
instructions.forEach { instruction ->
val a = valueMap[instruction.first]!!
val digitOrChar = digitOrChar(instruction.second)
val b = if (digitOrChar.first != '-') valueMap[digitOrChar.first]!! else digitOrChar.second
valueMap[instruction.first] = when (instruction.op) {
Operation.INP -> inputList[currentInpIndex++].digitToInt()
Operation.ADD -> a + b
Operation.MUL -> a * b
Operation.DIV -> Math.floorDiv(a, b)
Operation.MOD -> Math.floorMod(a, b)
Operation.EQL -> if (a == b) 1 else 0
}
}
println(valueMap['z'])
return valueMap['z'] == 0
}
fun solve(input: List<String>): Pair<String, String> {
val digits = mutableMapOf<Int, Pair<Int, Int>>()
val stack = mutableListOf<Pair<Int, Int>>()
var (push, sub, dig) = Triple(false, 0, 0)
input.forEachIndexed { i, line ->
val operand = line.substringAfterLast(" ")
if (i % 18 == 4) push = operand == "1"
if (i % 18 == 5) sub = operand.toInt()
if (i % 18 == 15) {
if (push) {
stack.add(dig to operand.toInt())
} else {
val (sibling, add) = stack.removeLast()
val diff = add + sub
if (diff < 0) {
digits[sibling] = -diff + 1 to 9
digits[dig] = 1 to 9 + diff
} else {
digits[sibling] = 1 to 9 - diff
digits[dig] = 1 + diff to 9
}
}
dig++
}
}
return digits.toSortedMap().values.unzip().let { (a, b) ->
b.joinToString("") to a.joinToString("")
}
}
fun digitOrChar(input: String?): Pair<Char, Int> {
if (input == null) {
return Pair('-', 0)
}
if (input.all { char -> char.isDigit() }) {
return Pair('-', Integer.parseInt(input))
}
return Pair(input.first(), 0)
}
fun readInputToInstructions(input: String): List<Instruction> {
val instructions: MutableList<Instruction> = mutableListOf()
readInputLineByLine(input).forEach { line ->
val split = line.split(" ")
instructions.add(
if (split.size == 3)
Instruction(Operation.valueOf(split[0].uppercase()), split[1].first(), split[2])
else
Instruction(Operation.valueOf(split[0].uppercase()), split[1].first())
)
}
return instructions
}
open class Instruction(val op: Operation, val first: Char, val second: String? = null)
enum class Operation { INP, ADD, MUL, DIV, MOD, EQL }