-
Notifications
You must be signed in to change notification settings - Fork 2
/
Day05.kt
59 lines (48 loc) · 1.86 KB
/
Day05.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
/*
* Copyright (c) 2022 by Todd Ginsberg
*/
/**
* Advent of Code 2022, Day 5 - Supply Stacks
* Problem Description: http://adventofcode.com/2022/day/5
* Blog Post/Commentary: https://todd.ginsberg.com/post/advent-of-code/2022/day5/
*/
package com.ginsberg.advent2022
class Day05(input: List<String>) {
private val stacks: List<MutableList<Char>> = createStacks(input)
private val instructions: List<Instruction> = parseInstructions(input)
fun solvePart1(): String {
performInstructions(true)
return stacks.tops()
}
fun solvePart2(): String {
performInstructions(false)
return stacks.tops()
}
private fun performInstructions(reverse: Boolean) {
instructions.forEach { (amount, source, destination) ->
val toBeMoved = stacks[source].take(amount)
repeat(amount) { stacks[source].removeFirst() }
stacks[destination].addAll(0, if (reverse) toBeMoved.reversed() else toBeMoved)
}
}
private fun Iterable<Iterable<Char>>.tops(): String =
map { it.first() }.joinToString("")
private fun createStacks(input: List<String>): List<MutableList<Char>> {
val stackRows = input.takeWhile { it.contains('[') }
return (1..stackRows.last().length step 4).map { index ->
stackRows
.mapNotNull { it.getOrNull(index) }
.filter { it.isUpperCase() }
.toMutableList()
}
}
private fun parseInstructions(input: List<String>): List<Instruction> =
input
.dropWhile { !it.startsWith("move") }
.map { row ->
row.split(" ").let { parts ->
Instruction(parts[1].toInt(), parts[3].toInt() - 1, parts[5].toInt() - 1)
}
}
private data class Instruction(val amount: Int, val source: Int, val target: Int)
}