For fun, made a streams-only version for day 3

This commit is contained in:
2019-12-04 01:25:55 +01:00
parent 5beaeab6ab
commit cbe279c02d
4 changed files with 105 additions and 2 deletions

View File

@@ -15,6 +15,7 @@
<kotlin.version>1.3.61</kotlin.version> <kotlin.version>1.3.61</kotlin.version>
<kotlin.code.style>official</kotlin.code.style> <kotlin.code.style>official</kotlin.code.style>
<junit.version>4.12</junit.version> <junit.version>4.12</junit.version>
<kotlin.compiler.jvmTarget>1.8</kotlin.compiler.jvmTarget>
</properties> </properties>
<dependencies> <dependencies>
@@ -46,6 +47,9 @@
<groupId>org.jetbrains.kotlin</groupId> <groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId> <artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version> <version>${kotlin.version}</version>
<configuration>
<jvmTarget>${kotlin.compiler.jvmTarget}</jvmTarget>
</configuration>
<executions> <executions>
<execution> <execution>
<id>compile</id> <id>compile</id>

View File

@@ -13,7 +13,7 @@ fun main() {
object Day2 { object Day2 {
val opcodes = mapOf( private val opcodes = mapOf(
Pair(1, ::add), Pair(1, ::add),
Pair(2, ::multiply) Pair(2, ::multiply)
) )

View File

@@ -4,7 +4,7 @@ import com.basdado.adventofcode.lines
import java.lang.StringBuilder import java.lang.StringBuilder
import kotlin.math.abs import kotlin.math.abs
const val DAY3_PATH = "/day/3/ex1.txt" const val DAY3_PATH = "/day/3/input.txt"
fun main() { fun main() {
Day3.puzzle1() Day3.puzzle1()

View File

@@ -0,0 +1,99 @@
package com.basdado.adventofcode.day3
import com.basdado.adventofcode.lines
import java.util.Comparator.comparing
import kotlin.math.abs
import kotlin.time.ExperimentalTime
import kotlin.time.measureTimedValue
@ExperimentalTime
fun main() {
StreamyDay3.puzzle1()
println(measureTimedValue { StreamyDay3.puzzle2() })
}
object StreamyDay3 {
fun puzzle1() {
println(lines(DAY3_PATH)
.map { it.split(",") }
.peek { println(it) }
.map { ops ->
ops.stream()
.map { op ->
// Calculate what the operation does to the previous position
(1..op.substring(1).toInt()).map {n ->
when (op[0]) {
'L' -> LEFT * n
'R' -> RIGHT * n
'U' -> UP * n
'D' -> DOWN * n
else -> throw IllegalArgumentException()
}
}
}
.reduce(listOf(Point(0,0))) { res, new -> res + (new.map { res.last() + it }) }
}
.map { it.toSet() }
// Find coordinates that exists on both wires
.peek { println(it) }
.reduce{ a, b -> a.filter { b.contains(it) }.toSet() }
.get().stream()
.filter { it != Point(0, 0) }
.min(comparing<Point, Int>(::manhattan))
.get()
.let(::manhattan)
)
}
fun puzzle2() {
println(lines(DAY3_PATH)
.map { it.split(",") }
.peek { println(it) }
.map { ops ->
ops.stream()
.map { op ->
// Calculate what the operation does to the previous position
(1..op.substring(1).toInt()).map {n ->
when (op[0]) {
'L' -> LEFT * n
'R' -> RIGHT * n
'U' -> UP * n
'D' -> DOWN * n
else -> throw IllegalArgumentException()
}
}
}
// Using the operations, build a list of the coordinates this wire touches (in order)
.reduce(listOf(Point(0,0))) { res, new -> res + (new.map { res.last() + it }) }
}
// Find coordinates that exists on both wires
// .peek { println(it) }
.map { w -> w.mapIndexed { i, p -> Pair(p, i) }.filter { it.first != ORIGIN }.groupingBy { it.first }
.reduce { key, accumulator, element -> if (accumulator.second < element.second) accumulator else element }
.map { Pair(it.key, it.value.second) }
.toMap()
}
.reduce{ a, b -> a.filter { b.containsKey(it.key) }.map { Pair(it.key, it.value + b[it.key]!! ) }.toMap() }
.get()
.minBy { it.value }
)
}
fun manhattan(p: Point) = abs(p.x) + abs(p.y)
data class Point(val x: Int, val y: Int) {
operator fun times(n: Int) = Point(x * n, y * n)
operator fun plus(p: Point) = Point(x + p.x, y + p.y)
}
val LEFT = Point(-1, 0)
val RIGHT = Point(1, 0)
val UP = Point(0, 1)
val DOWN = Point(0, -1)
val ORIGIN = Point(0, 0)
}