Advent of Code 2023 day 3
12/03/2024, 5:00 AMNeil Banman
12/03/2024, 5:12 AMbj0
12/03/2024, 5:17 AMMarcin Wisniowski
12/03/2024, 5:18 AMMarcin Wisniowski
12/03/2024, 5:18 AMMarcin Wisniowski
12/03/2024, 5:19 AMstring.something(regex)
or regex.something(string)
.Michael de Kaste
12/03/2024, 5:24 AMJakub Gwóźdź
12/03/2024, 5:32 AMPaul Woitaschek
12/03/2024, 5:35 AMRonny Bräunlich
12/03/2024, 5:36 AMdo()
and then remove everything after don't()
so that I can use the regex again. But it only works if you put everything in one line 😅
fun part1(input: List<String>): Int {
val regEx = """mul\((\d{1,3}),(\d{1,3})\)""".toRegex()
return input.flatMap { line ->
regEx.findAll(line).map {
val (first, second) = it.destructured
first.toInt() * second.toInt()
}
}.sum()
}
fun part2(input: List<String>): Int {
val regEx = """mul\((\d{1,3}),(\d{1,3})\)""".toRegex()
return input.flatMap { line ->
line.split("do()")
}.map { line ->
if(line.contains("don't()")) {
val firstDont = line.indexOf("don't()")
line.take(firstDont)
} else {
line
}
}.flatMap { line ->
regEx.findAll(line).map {
val (first, second) = it.destructured
first.toInt() * second.toInt()
}
}.sum()
}
Ozioma Ogbe
12/03/2024, 5:43 AMMichael de Kaste
12/03/2024, 5:46 AM"""string"""
might suit you better, especially when writing regexesJonathan Kolberg
12/03/2024, 5:48 AMNeil Banman
12/03/2024, 5:48 AMy9san9
12/03/2024, 5:52 AMtheapache64
12/03/2024, 5:52 AMfor
loop guy…
private val regEx = "(mul\\((\\d+),(\\d+)\\)|don't\\(\\)|do\\(\\))".toRegex()
private fun part1(): Int {
var mulSum = 0
for (mul in regEx.findAll(input)) {
val (key, x, y) = mul.destructured
if (key.contains("mul")) {
mulSum += (x.toInt() * y.toInt())
}
}
return mulSum
}
private fun part2(): Int {
var mulSum = 0
var isEnabled = true
for (mul in regEx.findAll(input)) {
val (key, x, y) = mul.destructured
when {
key == "don't()" -> {
isEnabled = false
}
key == "do()" -> {
isEnabled = true
}
key.contains("mul") && isEnabled -> {
mulSum += (x.toInt() * y.toInt())
}
}
}
return mulSum
}
Neil Banman
12/03/2024, 5:55 AMbj0
12/03/2024, 6:19 AMfold
and tailrec
, fold was fastest but i was surprised how much slower tailrec wasbj0
12/03/2024, 6:21 AMMichael de Kaste
12/03/2024, 6:37 AMbj0
12/03/2024, 6:52 AMbj0
12/03/2024, 6:53 AMbj0
12/03/2024, 6:53 AM.drop
on sequence would have been fastLidonis Calhau
12/03/2024, 6:55 AMEndre Deak
12/03/2024, 6:57 AM// String.longs is a helper
fun main() {
solve("Mull It Over") {
val input = text
val regex = Regex("""(mul\(\d+,\d+\))|(do\(\))|(don't\(\))""")
fun String.calc() = this.longs().zipWithNext().first().let { (a, b) -> a * b }
part1(161289189) {
regex.findAll(input)
.mapNotNull { g -> g.value.takeIf { it.contains("mul") } }
.sumOf(String::calc)
}
part2(83595109) {
regex
.findAll(input)
.map { it.value }
.fold(0L to true) { acc, next ->
when (next) {
"don't()" -> acc.first to false
"do()" -> acc.first to true
else ->
(if (acc.second) {
next.longs().zipWithNext().first().let { (a, b) -> a * b }
} else
acc.first) to acc.second
}
}
.first
}
}
}
PoisonedYouth
12/03/2024, 7:04 AMplastiv
12/03/2024, 7:18 AMfun part1(input: List<String>): Int {
val regex = """mul\((?<first>\d+),(?<second>\d+)\)""".toRegex()
return input.sumOf { str ->
regex.findAll(str).sumOf { result ->
val first = result.groups["first"]!!.value.toInt()
val second = result.groups["second"]!!.value.toInt()
first * second
}
}
}
Jakub Gwóźdź
12/03/2024, 7:40 AMJakub Gwóźdź
12/03/2024, 7:44 AM"""...."""
as a nice way to avoid necessity of backslash escaping.
val regex2 = Regex("""(mul\((\d{1,3}),(\d{1,3})\))|(do\(\))|(don't\(\))""") // look, ma! no more \\
Neil Banman
12/03/2024, 7:52 AMMichael de Kaste
12/03/2024, 7:53 AMphldavies
12/03/2024, 7:54 AMJaap Beetstra
12/03/2024, 7:57 AMfun part1(input: String): Int = Regex("""mul\((\d{1,3}),(\d{1,3})\)""").findAll(input).map { it.destructured }
.sumOf { (a, b) -> a.toInt() * b.toInt() }
fun part2(input: String): Int = input.split("do()").map { it.substringBefore("don't()") }.sumOf { part1(it) }
Kai Yuan
12/03/2024, 8:29 AMDan Fingal-Surma
12/03/2024, 8:50 AMDan Fingal-Surma
12/03/2024, 8:59 AMKarloti
12/03/2024, 10:40 AMAnirudh
12/03/2024, 11:27 AMmul(8,1)don't()mul(5,3)
mul(3,2)do()mul(10,1)
is the answer 8 + 6 + 10 or 8 + 10 ?
Answer: the answer is 8 + 10 since the instructions say "enables/disables future mul
instructions" not just "for the rest of the line"Anirudh
12/03/2024, 11:34 AMKarloti
12/03/2024, 11:42 AMvadzim
12/03/2024, 11:46 AMAnirudh
12/03/2024, 11:50 AMd+
instead of d{1,3}
also get the right answerMarcin Wisniowski
12/03/2024, 11:59 AMMarcin Wisniowski
12/03/2024, 12:01 PMAnirudh
12/03/2024, 12:02 PMX
and Y
are each 1-3 digit numbers" instead of just "where X and Y are numbers" - odd that it mentions the length so specifically but doesn't use itMarcin Wisniowski
12/03/2024, 12:04 PMint
(or equivalent), not a long
or BigInteger
.Marcin Wisniowski
12/03/2024, 12:04 PMMarcin Wisniowski
12/03/2024, 12:04 PMKarloti
12/03/2024, 12:05 PMAnirudh
12/03/2024, 12:05 PMMarcin Wisniowski
12/03/2024, 12:05 PMAnirudh
12/03/2024, 12:06 PMKarloti
12/03/2024, 12:07 PMMarcin Wisniowski
12/03/2024, 12:08 PMKarloti
12/03/2024, 12:09 PMJakub Gwóźdź
12/03/2024, 12:18 PMphldavies
12/03/2024, 12:21 PMMichael de Kaste
12/03/2024, 12:22 PMJaap Beetstra
12/03/2024, 12:38 PMsplit
/ substringBefore
; it was more natural for me. But very nice solution with the double regex.Karloti
12/03/2024, 12:48 PMKarloti
12/03/2024, 1:09 PMkqr
12/03/2024, 1:34 PMphldavies
12/03/2024, 1:38 PMKarloti
12/03/2024, 2:05 PMKarloti
12/03/2024, 2:25 PMephemient
12/03/2024, 2:47 PMephemient
12/03/2024, 2:49 PMephemient
12/03/2024, 4:20 PMIt should be noted that today’s input file is spread over multiple lines that must be concatenated.they don't need to be concatenated if you don't split them in the first place blob think smart (you will need
.toRegex(RegexOption.DOT_MATCHES_ALL)
if you want .
to include \n
, or replace it with something else that does, if you want to use that part of the solution)todd.ginsberg
12/03/2024, 4:22 PMephemient
12/03/2024, 4:23 PMString
as input, and most of them do .linesSequence()
or similar immediately, but in some prior years I did the line splitting outside the solutionbj0
12/03/2024, 5:02 PMfindAll
on the raw input line, no splits, joins, or multiline options and it workedephemient
12/03/2024, 5:03 PM.*?
which would be a problemNeil Banman
12/03/2024, 6:03 PMoverride fun part2(): Long =
Regex("""(?s)don't\(\).*?(?:do\(\)|$)|mul\((\d+),(\d+)\)""")
.findAll(input)
.sumOf { mr -> (mr.groupValues[1].toLongOrNull() ?: 0L) * (mr.groupValues[2].toLongOrNull() ?: 0L) }
bj0
12/03/2024, 7:28 PMdo()
enabled block, which mine doesn'tbj0
12/03/2024, 7:29 PM"...(do\(\)|$)|mul..."
Dan Fingal-Surma
12/03/2024, 8:53 PMcesards
12/04/2024, 4:22 AMprivate fun part02(lines: List<String>) {
val donts = Regex("don't\\(\\)(.*?)do\\(\\)")
val regex = Regex("mul\\(\\d{1,3},\\d{1,3}\\)")
// We need to put lines together if we want to make this work.
val word = StringBuilder()
lines.forEach { line -> word.append(line) }
val pattern = Pattern.compile(donts.pattern)
val processedLine = pattern.matcher(word.toString()).replaceAll("")
var sum = 0L
regex.findAll(processedLine).forEach {
val aha = it.value.substringBefore(",").substringAfter("(").toInt() *
it.value.substringAfter(",").substringBefore(")").toInt()
sum += aha
}
println(sum)
}
I'm sure it can be improved since this is my first iteration.
The tricky with this exercise was definitely considering thes lines as a whole 😬cesards
12/04/2024, 4:24 AMdo()
enabled block, which mine doesn't
‼️
you are right @bj0Neil Banman
12/04/2024, 9:06 AM(?s)don't\(\)(?:[^d]++|d(?!o\(\)))*+(?:do\(\)|${'$'})|mul\((\d+),(\d+)\)
The problem with the old way is that the "don't-swallower" code is lazy and slow. The .*?
makes it constantly backtrack to make sure that it lets do() match with the remaining part of the pattern. There's no unique characters to exclude, so it's tough to do anything about it. But we can exclude every character except 'd,' and only then do a negative lookahead to exclude any do()s.ephemient
12/04/2024, 10:08 AMval regex = """
don't\(\)
(?: [^d]++ | d (?! o\(\) ) )*+
(?: do\(\) | $ ) |
mul\(
(\d+) , (\d+)
\)
""".toRegex(setOf(RegexOption.COMMENTS, RegexOption.DOT_MATCHES_ALL))
Michael de Kaste
12/04/2024, 10:30 AMsealed interface Instruction {
data object DO : Instruction
data object DONT : Instruction
data class MUL(val value: Int) : Instruction
companion object {
fun of(matchResult: MatchResult): Instruction {
val (inst, a, b) = matchResult.destructured
return when(inst){
"do()" -> DO
"don't()" -> DONT
else -> MUL(a.toInt() * b.toInt())
}
}
}
}
and I remember from Shivers intcode from some years ago, you had to iteratively add more and more instructionsNeil Banman
12/04/2024, 5:40 PMSafi K
12/07/2024, 2:09 PMSafi K
12/07/2024, 2:10 PMfun filterEnabledMultiplications(input: String): String {
val pattern = Regex("""don't\(\).+do\(\)""")
return input.replace(pattern, "")
}
Safi K
12/07/2024, 2:11 PMephemient
12/07/2024, 4:17 PMdon't()do()mul(1,1)do()
Neil Banman
12/07/2024, 5:56 PMephemient
12/07/2024, 11:20 PMNeil Banman
12/08/2024, 1:15 AMAdrian
12/11/2024, 7:15 AMimport java.io.File
fun main() {
val filename = "src/data.txt"
val testInput = "xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))"
val testInput2 = "xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))"
val regex = Regex("mul\\(\\d{1,3},\\d{1,3}\\)")
val controlRegex = Regex("do\\(\\)|don't\\(\\)")
val mulAndInstructionsRegex = Regex("mul\\(\\d{1,3},\\d{1,3}\\)|do\\(\\)|don't\\(\\)")
val fileLines: List<String> = File(filename).readLines()
val matchesFromFile: List<Int> = fileLines.flatMap { line -> extractMulAndDoMultiplication(line, regex) }
val matchesFromTestInput: List<Int> = extractMulAndDoMultiplication(testInput, regex)
println(matchesFromTestInput.sum())
println("Answer part 1: ${matchesFromFile.sum()}")
var r = controll(testInput2, mulAndInstructionsRegex, controlRegex)
val mathcesWithControl: List<Int> = fileLines.flatMap { line -> controll(line, mulAndInstructionsRegex, controlRegex) }
println(r.sum())
println("Answer part 2: ${mathcesWithControl.sum()}")
}
fun extractMulAndDoMultiplication(input: String, regex: Regex): List<Int> {
return regex.findAll(input).toList().map { it.value }.map { match -> doMul(match) }
}
fun doMul(input: String): Int {
val regex = Regex("\\d+")
val integersAsList = regex.findAll(input).toList().map { it.value.toInt() }
return integersAsList[0] * integersAsList[1]
}
fun controll(input: String, regex: Regex, controlRegex: Regex): List<Int> {
val result: MutableList<Int> = mutableListOf<Int>()
var canProcess: Boolean = true
val mulAndInstructions: List<MatchResult> = regex.findAll(input).toList()
for (matchResult in mulAndInstructions) {
val value = matchResult.value
println("Processing instruction: $value, canProcess: $canProcess")
if (controlRegex.matches(value)) {
canProcess = value == "do()"
println("Control instruction: $value, updated canProcess to: $canProcess")
}else if(canProcess ) {
result.add(doMul(value))
println("Performed multiplication for: $value")
}
}
return result
}
Adrian
12/11/2024, 1:07 PMManel Martos
12/21/2024, 12:39 PM