bjonnh
12/10/2020, 3:54 AMadamratzman
12/10/2020, 5:47 AMandyb
12/10/2020, 6:14 AMfun main() {
val input = resourceFile("day10/Adapters.txt").readLines()
.map(String::toInt).sorted()
val adapters = listOf(0) + input + listOf(input.maxOrNull()!!+3)
val differences = adapters.zipWithNext().map{it.second - it.first}.groupBy { it }
println("Part 1 : " + differences[1]!!.size*differences[3]!!.size)
println("Part 2 : " + findRoutes(adapters).last())
}
fun findRoutes(adapters:List<Int>) : List<Long> {
return (1..adapters.last()).asSequence().accumulate(listOf(1L)){
acc, i -> acc + (i-3..i-1).filter { it in adapters }.sumOf { acc[it] }
}.last()
}
/**
* Accumulate Function
*
* Basically a Combination of Fold and Map which uses the result of previous element to act as the entry into the next.
*/
fun <T, R> Sequence<T>.accumulate(initial: R, operation: (acc: R, T) -> R): Sequence<R> = sequence {
yield(initial)
var accumulator = initial
forEach {
accumulator = operation(accumulator, it)
yield(accumulator)
}
}
Marcin Wisniowski
12/10/2020, 6:27 AMephemient
12/10/2020, 8:10 AMfold
. using primitive arrays for speed.Michael de Kaste
12/10/2020, 9:23 AMobject Day10 : AdventOfCode() {
private val parsed = input.lines().map(String::toInt).toCollection(TreeSet())
override fun part1() = parsed.fold(IntArray(3){0} to 0){ (array, prev), cur ->
array[cur - prev - 1]++
array to cur
}.let { (array, _) -> array[0] * (array[2] + 1)}
override fun part2() : Any? {
val memory = mutableMapOf(parsed.last() to BigInteger.ONE)
parsed.descendingIterator().forEach { curIndex ->
val curValue = memory.getValue(curIndex)
parsed.subSet(curIndex - 3, true, curIndex, false).forEach {
memory.merge(it, curValue, BigInteger::add)
}
}
return parsed.subSet(0, false, 3, true).sumOf(memory::getValue)
}
}
reverse iteration with TreeSet to build up a possibilities list all the way up to the first few members. Technically O(n log n) due to using a treeset, but they are easy to use in this instance so I didn't mind.Joris PZ
12/10/2020, 9:44 AM| Platform | Average (µs) |
| -----------------| --------------|
| GraalVM | 2483 ± 5719 |
| Node JS | 6837 ± 8230 |
| Native | 2432 ± 669 |
Joris PZ
12/10/2020, 9:47 AMandyb
12/10/2020, 10:46 AMfun findRoutes2(adapters:List<Int>) : Long {
return (1..adapters.last()).fold(listOf(1L)){
acc, i -> acc + (i-3..i-1).filter { it in adapters }.sumOf { acc[it] }
}.last()
}
ephemient
12/10/2020, 12:45 PMandyb
12/10/2020, 1:19 PMfun findRoutes(adapters:List<Int>) : Long {
fun <E> MutableList<E>.setInPlace(i: Int, value:E):MutableList<E>{
this[i] = value
return this
}
val accumulator: MutableList<Long> = (0..adapters.last()).map { if (it == 0) 1L else 0L }.toMutableList()
return (1..adapters.last()).fold(accumulator){
acc, i -> acc.setInPlace(i, (i-3..i-1).filter { it in adapters }.sumOf { acc[it] })
}.last()
}
ephemient
12/10/2020, 1:20 PMandyb
12/10/2020, 1:21 PMephemient
12/10/2020, 1:21 PMtodd.ginsberg
12/10/2020, 2:48 PMclass Day10(input: List<Int>) {
private val adapters: List<Int> = input.plus(0).plus(input.maxOrNull()!! + 3).sorted()
fun solvePart1(): Int =
adapters
.asSequence()
.zipWithNext()
.map { it.second - it.first }
.groupingBy { it }
.eachCount()
.run {
this.getOrDefault(1, 1) * this.getOrDefault(3, 1)
}
fun solvePart2(): Long {
val pathCounts = LongArray(adapters.size) { if (it == 0) 1L else 0L }
pathCounts.indices.forEach { pathIndex ->
pathIndex.trailingRange(3).forEach { candidate ->
if (adapters[candidate] + 3 >= adapters[pathIndex]) {
pathCounts[pathIndex] = pathCounts[pathIndex] + pathCounts[candidate]
}
}
}
return pathCounts.last()
}
private fun Int.trailingRange(n: Int): IntRange =
(this - n).coerceAtLeast(0) until this
}
Part 2 just figures out how many candidates there are to get us to any given adapter and adds the number of ways to get to that to our candidate. We only have to look back at most three places. I'll probably refactor p2 to not be as clunky, but it works quickly and I can explain it. 🙂Edgars
12/10/2020, 3:02 PMtodd.ginsberg
12/10/2020, 3:29 PMWietlol
12/10/2020, 3:49 PMNir
12/10/2020, 4:01 PMNir
12/10/2020, 4:01 PMfun getData() = (aocDataDir / "day10.txt").readLines().map { it.toLong() }
fun part1() = (sequenceOf(0L) + getData().sorted().asSequence())
.zipWithNext { a, b -> b - a}
.groupingBy { it }.eachCount()
.run {
getValue(1) * (getValue(3) + 1)
}
fun part2(): Long {
val data = getData().sorted()
val result = mutableMapOf(0L to 1L)
for (e in data) {
result[e] = (1..3).map { result.getOrDefault(e-it, 0) }.sum()
}
return result.getValue(data.last())
}
Nir
12/10/2020, 4:03 PMtodd.ginsberg
12/10/2020, 4:15 PMNir
12/10/2020, 4:19 PMtodd.ginsberg
12/10/2020, 4:26 PMkrotki
12/10/2020, 4:36 PMbjonnh
12/10/2020, 4:42 PMfun main() {
val lines = linesFile("data/2020/10_input.txt").map { it.toLong() }.sorted()
val jolts = lines + listOf(lines.last() + 3L)
var bottom = 0L
val chain = listOf(0L) + jolts.mapNotNull {
if (it > bottom && it - bottom <= 3) { it.let { bottom = it } } else null
}
val counts = chain.windowed(2).map { it[1] - it[0] }
println(counts.count { it == 1L } * counts.count { it == 3L })
val result = mutableMapOf(0L to 1L)
println(jolts.map { e -> (1..3).map { result[e - it] ?: 0 }.sum().also { result[e] = it } }.last())
}
Nir
12/10/2020, 4:53 PMNir
12/10/2020, 4:53 PMNir
12/10/2020, 4:54 PMNir
12/10/2020, 4:54 PMNir
12/10/2020, 4:55 PMNir
12/10/2020, 4:57 PMNir
12/10/2020, 4:58 PMkrotki
12/10/2020, 5:02 PMNir
12/10/2020, 5:07 PMNir
12/10/2020, 5:07 PMbjonnh
12/10/2020, 5:11 PMbjonnh
12/10/2020, 5:12 PMephemient
12/10/2020, 6:13 PMNir
12/10/2020, 6:14 PMNir
12/10/2020, 6:15 PMNir
12/10/2020, 11:57 PMephemient
12/11/2020, 12:33 AMbjonnh
12/11/2020, 12:35 AMbjonnh
12/11/2020, 12:36 AMNir
12/11/2020, 12:36 AMNir
12/11/2020, 12:36 AMephemient
12/11/2020, 12:37 AMNir
12/11/2020, 12:37 AMNir
12/11/2020, 12:37 AMNir
12/11/2020, 12:38 AMNir
12/11/2020, 12:38 AMephemient
12/11/2020, 12:38 AMNir
12/11/2020, 12:38 AMNir
12/11/2020, 12:38 AMephemient
12/11/2020, 12:41 AMNir
12/11/2020, 12:41 AMfun MutableMap<Long, Long?>.part2Helper(key: Long): Long {
get(key)?.let { return it }
if (key !in this) {
return 0L
}
return (1..3).map { part2Helper(key - it) }.sum().also { set(key, it) }
}
fun part2Fast(): Long {
val cache = mutableMapOf<Long, Long?>().apply {
getData().associateTo(this) { it to null }
}
cache[0L] = 1L
return cache.part2Helper(cache.keys.maxOrNull()!!)
}
ephemient
12/11/2020, 12:42 AMephemient
12/11/2020, 12:44 AMephemient
12/11/2020, 12:45 AMNir
12/11/2020, 12:46 AMNir
12/11/2020, 12:46 AMNir
12/11/2020, 12:47 AMephemient
12/11/2020, 1:17 AM