-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay20.kt
68 lines (54 loc) · 1.92 KB
/
Day20.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
/*
* Copyright (c) 2017 by Todd Ginsberg
*/
package com.ginsberg.advent2017
import kotlin.math.absoluteValue
/**
* AoC 2017, Day 20
*
* Problem Description: http://adventofcode.com/2017/day/20
* Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2017/day20/
*/
class Day20(input: List<String>) {
private val particles: List<Particle> = input.mapIndexed { idx, s -> parseParticle(idx, s) }
fun solvePart1(): Int =
(1..1000).fold(particles) { acc, _ ->
acc.map { it.move() }
}.minBy { it.position.distance }?.id ?: throw IllegalArgumentException("Wat")
fun solvePart2(): Int =
(1..1000).fold(particles) { acc, _ ->
acc.map { it.move() }
.groupBy { it.position }
.filterValues { it.size == 1 }
.flatMap { it.value }
}.size
private fun parseParticle(id: Int, input: String): Particle =
input.split("<", ">").let {
Particle(
id = id,
position = parseVec(it[1]),
velocity = parseVec(it[3]),
acceleration = parseVec(it[5])
)
}
private fun parseVec(input: String): Vec3D =
input.split(",").map { it.trim().toLong() }.let {
Vec3D(it[0], it[1], it[2])
}
data class Vec3D(val x: Long, val y: Long, val z: Long) {
val distance: Long =
x.absoluteValue + y.absoluteValue + z.absoluteValue
operator fun plus(that: Vec3D): Vec3D =
Vec3D(x = x + that.x, y = y + that.y, z = z + that.z)
}
data class Particle(val id: Int,
val position: Vec3D,
val velocity: Vec3D,
var acceleration: Vec3D) {
fun move() =
this.copy(
velocity = velocity + acceleration,
position = position + velocity + acceleration
)
}
}