Added overdue helper functions splitInts() and splitLongs()

This commit is contained in:
Chris Hodges 2023-12-09 09:20:30 +01:00
parent 837e5827f4
commit fb3a5ce5d2
6 changed files with 27 additions and 20 deletions

View File

@ -15,6 +15,9 @@ fun Iterable<Long>.lcm(): Long = reduce(Long::lcm)
fun readInput(name: String) = File("src", "$name.txt") fun readInput(name: String) = File("src", "$name.txt")
.readLines() .readLines()
fun String.splitInts(): List<Int> = split(" ").filter(String::isNotBlank).map(String::toInt)
fun String.splitLongs(): List<Long> = split(" ").filter(String::isNotBlank).map(String::toLong)
fun listOfIntegerLists(input: List<String>): ArrayList<List<Int>> { fun listOfIntegerLists(input: List<String>): ArrayList<List<Int>> {
val output = ArrayList<List<Int>>() val output = ArrayList<List<Int>>()
var currList = ArrayList<Int>() var currList = ArrayList<Int>()

View File

@ -2,6 +2,7 @@ package aoc2022
import println import println
import readInput import readInput
import splitInts
/* /*
--- Day 5: Supply Stacks --- --- Day 5: Supply Stacks ---
@ -106,7 +107,7 @@ move 1 from 1 to 2
data class StackOp(val num: Int, val src: Int, val dest: Int) data class StackOp(val num: Int, val src: Int, val dest: Int)
fun part1(input: List<String>): String { fun part1(input: List<String>): String {
val numItems = input.first { it.startsWith(" 1") }.split(" ").filter { it.isNotBlank() }.map { it.toInt() }.max() val numItems = input.first { it.startsWith(" 1") }.splitInts().max()
val stackOps = input.filter { it.startsWith("move") }.map { val stackOps = input.filter { it.startsWith("move") }.map {
val line = it.split(" ") val line = it.split(" ")
StackOp(line[1].toInt(), line[3].toInt() - 1, line[5].toInt() - 1) StackOp(line[1].toInt(), line[3].toInt() - 1, line[5].toInt() - 1)
@ -131,7 +132,7 @@ move 1 from 1 to 2
} }
fun part2(input: List<String>): String { fun part2(input: List<String>): String {
val numItems = input.first { it.startsWith(" 1") }.split(" ").filter { it.isNotBlank() }.map { it.toInt() }.max() val numItems = input.first { it.startsWith(" 1") }.splitInts().max()
val stackOps = input.filter { it.startsWith("move") }.map { val stackOps = input.filter { it.startsWith("move") }.map {
val line = it.split(" ") val line = it.split(" ")
StackOp(line[1].toInt(), line[3].toInt() - 1, line[5].toInt() - 1) StackOp(line[1].toInt(), line[3].toInt() - 1, line[5].toInt() - 1)

View File

@ -2,6 +2,7 @@ package aoc2023
import println import println
import readInput import readInput
import splitInts
/* /*
--- Day 4: Scratchcards --- --- Day 4: Scratchcards ---
@ -48,8 +49,8 @@ Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11
"Card +(\\d+): (.*)".toRegex().matchEntire(it)?.destructured "Card +(\\d+): (.*)".toRegex().matchEntire(it)?.destructured
?.let { (id, game) -> ?.let { (id, game) ->
val (wins, numbers) = game.split(" | ") val (wins, numbers) = game.split(" | ")
val winSet = wins.split(" ").filter { it.isNotEmpty() }.map { it.toInt() }.toSet() val winSet = wins.splitInts().toSet()
val numberSet = numbers.trim().split(" ").filter { it.isNotEmpty() }.map { it.toInt() }.toSet() val numberSet = numbers.splitInts().toSet()
val matches = winSet.intersect(numberSet) val matches = winSet.intersect(numberSet)
1 shl (matches.size - 1) 1 shl (matches.size - 1)
} }
@ -61,8 +62,8 @@ Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11
"Card +(\\d+): (.*)".toRegex().matchEntire(it)?.destructured "Card +(\\d+): (.*)".toRegex().matchEntire(it)?.destructured
?.let { (id, game) -> ?.let { (id, game) ->
val (wins, numbers) = game.split(" | ") val (wins, numbers) = game.split(" | ")
val winSet = wins.split(" ").filter { it.isNotEmpty() }.map { it.toInt() }.toSet() val winSet = wins.splitInts().toSet()
val numberSet = numbers.trim().split(" ").filter { it.isNotEmpty() }.map { it.toInt() }.toSet() val numberSet = numbers.splitInts().toSet()
val matches = winSet.intersect(numberSet) val matches = winSet.intersect(numberSet)
matches.size matches.size
}!! }!!

View File

@ -2,6 +2,7 @@ package aoc2023
import println import println
import readInput import readInput
import splitLongs
/* /*
--- Day 5: If You Give A Seed A Fertilizer --- --- Day 5: If You Give A Seed A Fertilizer ---
@ -147,14 +148,14 @@ humidity-to-location map:
if (i.contains(":")) { if (i.contains(":")) {
val (type, data) = i.split(":") val (type, data) = i.split(":")
when (type) { when (type) {
"seeds" -> seeds = data.trim().split(" ").map { it.toLong() }.toLongArray() "seeds" -> seeds = data.splitLongs().toLongArray()
else -> { else -> {
val from = type.split("-")[0] val from = type.split("-")[0]
fromId = typeMap[from]!! fromId = typeMap[from]!!
} }
} }
} else if (i.isNotBlank()) { } else if (i.isNotBlank()) {
val (destRangeStart, sourceRangeStart, length) = i.split(" ").map { it.toLong() } val (destRangeStart, sourceRangeStart, length) = i.splitLongs()
val rangeLists = mapOfMaps.getOrPut(fromId) { ArrayList() } val rangeLists = mapOfMaps.getOrPut(fromId) { ArrayList() }
rangeLists.add(LongRange(sourceRangeStart, sourceRangeStart + length - 1) to destRangeStart) rangeLists.add(LongRange(sourceRangeStart, sourceRangeStart + length - 1) to destRangeStart)
} }
@ -192,8 +193,9 @@ humidity-to-location map:
if (i.contains(":")) { if (i.contains(":")) {
val (type, data) = i.split(":") val (type, data) = i.split(":")
when (type) { when (type) {
"seeds" -> seeds = ArrayDeque(data.trim().split(" ").map { it.toLong() }.chunked(2) "seeds" -> seeds = ArrayDeque(
.map { LongRange(it[0], it[0] + it[1] - 1) }) data.splitLongs().chunked(2)
.map { LongRange(it[0], it[0] + it[1] - 1) })
else -> { else -> {
val from = type.split("-")[0] val from = type.split("-")[0]
@ -201,7 +203,7 @@ humidity-to-location map:
} }
} }
} else if (i.isNotBlank()) { } else if (i.isNotBlank()) {
val (destRangeStart, sourceRangeStart, length) = i.split(" ").map { it.toLong() } val (destRangeStart, sourceRangeStart, length) = i.splitLongs()
val rangeLists = mapOfMaps.getOrPut(fromId) { ArrayList() } val rangeLists = mapOfMaps.getOrPut(fromId) { ArrayList() }
rangeLists.add(LongRange(sourceRangeStart, sourceRangeStart + length - 1) to destRangeStart) rangeLists.add(LongRange(sourceRangeStart, sourceRangeStart + length - 1) to destRangeStart)
} }
@ -241,7 +243,7 @@ humidity-to-location map:
sourceRanges.addFirst(LongRange(newSource, newSource + newSourceLength - 1)) sourceRanges.addFirst(LongRange(newSource, newSource + newSourceLength - 1))
found = true found = true
break break
// funnily, this is unused, but it should also be a possibility // funnily, this is unused, but it should also be a possibility
// } else if (sourceRange.first < mapRange.first && sourceRange.last > mapRange.last) { // } else if (sourceRange.first < mapRange.first && sourceRange.last > mapRange.last) {
// val destLength = mapRange.last + 1 - mapRange.first // val destLength = mapRange.last + 1 - mapRange.first
// val dest = destPos + mapRange.first - sourceRange.first // val dest = destPos + mapRange.first - sourceRange.first

View File

@ -2,6 +2,7 @@ package aoc2023
import println import println
import readInput import readInput
import splitInts
/* /*
--- Day 6: Wait For It --- --- Day 6: Wait For It ---
@ -50,8 +51,8 @@ Distance: 9 40 200
// distance = (bt * (bt+1))/2 + bt * (tt - 2 * bt) // distance = (bt * (bt+1))/2 + bt * (tt - 2 * bt)
// Spend 30 minutes figuring out why I don't win any race when the boat is actually accelerating! // Spend 30 minutes figuring out why I don't win any race when the boat is actually accelerating!
fun part1(input: List<String>): Int { fun part1(input: List<String>): Int {
val times = input[0].split(":")[1].split(" ").filter { it.isNotBlank() }.map { it.toInt() } val times = input[0].split(":")[1].splitInts()
val distances = input[1].split(":")[1].split(" ").filter { it.isNotBlank() }.map { it.toInt() } val distances = input[1].split(":")[1].splitInts()
val result = times.withIndex().map { (i, tt) -> val result = times.withIndex().map { (i, tt) ->
IntRange(1, tt - 1).count { IntRange(1, tt - 1).count {
it * (tt - it) > distances[i] it * (tt - it) > distances[i]

View File

@ -2,6 +2,7 @@ package aoc2023
import println import println
import readInput import readInput
import splitInts
/* /*
--- Day 9: Mirage Maintenance --- --- Day 9: Mirage Maintenance ---
@ -72,23 +73,21 @@ fun main() {
fun delta(i: List<Int>): Int { fun delta(i: List<Int>): Int {
if (i.all { it == 0 }) return 0 if (i.all { it == 0 }) return 0
val d = i.zipWithNext { a, b -> b - a } val d = i.zipWithNext { a, b -> b - a }
val p = delta(d) return d.last() + delta(d)
return d.last() + p
} }
fun delta2(i: List<Int>): Int { fun delta2(i: List<Int>): Int {
if (i.all { it == 0 }) return 0 if (i.all { it == 0 }) return 0
val d = i.zipWithNext { a, b -> b - a } val d = i.zipWithNext { a, b -> b - a }
val p = delta2(d) return d.first() - delta2(d)
return d.first() - p
} }
fun part1(input: List<String>): Int { fun part1(input: List<String>): Int {
return input.map { it.split(" ").map { it.toInt() } }.sumOf { delta(it) + it.last() } return input.map { it.splitInts() }.sumOf { delta(it) + it.last() }
} }
fun part2(input: List<String>): Int { fun part2(input: List<String>): Int {
return input.map { it.split(" ").map { it.toInt() } }.sumOf { it.first() - delta2(it) } return input.map { it.splitInts() }.sumOf { it.first() - delta2(it) }
} }
// test if implementation meets criteria from the description, like: // test if implementation meets criteria from the description, like: