Skip to content

Instantly share code, notes, and snippets.

@saidaspen
Created August 25, 2020 00:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save saidaspen/378b3bb8aff01f382c99cd8435b1b5ab to your computer and use it in GitHub Desktop.
Save saidaspen/378b3bb8aff01f382c99cd8435b1b5ab to your computer and use it in GitHub Desktop.
Advent of Code 2017 Day21 - Does not work
package aoc207
import java.io.File
fun main() {
val input = File(ClassLoader.getSystemResource("201721").file).readText()
println("Part 1: " + Day21(input).part1(5))
}
class Day21(input: String) {
private val start = ".#./..#/###"
private val rules: Map<String, String>
init {
rules = input.lines()
.map { it.split("=>") }
.filter { it.size == 2 } // We don't need that empty last line
.map { Pair(it[0].trim(), it[1].trim()) }
.flatMap { variants(it.first).map { v -> Pair(v, it.second) } }
.map { it.first.replace("/", "") to it.second.replace("/", "") }
.toMap()
}
/* We should be able to handle each part independently.
* A 2x2 turns into a 3x3, a 3x3 turns into four 2x2 */
fun part1(iterations: Int): Int {
var sections = listOf(start.replace("/", ""))
for (i in 0 until iterations) sections = sections.flatMap { map(it) }
return sections.joinToString("").toCharArray().filter { it == '#' }.count()
}
/* A 2x2 turns into a 3x3 (still section), a 3x3 turns into a 4x4, which is split into four sections of 2x2 */
private fun map(s: String): List<String> {
val mapped = rules[s] ?: error("unable to find $s in rules")
return if (s.length == 4) listOf(mapped) else split(mapped)
}
fun split(s: String): List<String> {
// Known size to be 9 (4x4)
return listOf("${s[0]}${s[1]}${s[4]}${s[5]}",
"${s[2]}${s[3]}${s[6]}${s[7]}",
"${s[8]}${s[9]}${s[12]}${s[13]}",
"${s[10]}${s[11]}${s[14]}${s[15]}")
}
/* Do we need to both rotate and flip? Or only rotate or flip? */
fun variants(rule: String): List<String> {
return listOf(rule, flipHorizontal(rule), flipVertical(rule),
rotateCw(rule, 1), rotateCw(rule, 2), rotateCw(rule, 3),
rotateCw(flipHorizontal(rule), 1), rotateCw(flipHorizontal(rule), 2), rotateCw(flipHorizontal(rule), 3),
rotateCw(flipVertical(rule), 1), rotateCw(flipVertical(rule), 2), rotateCw(flipVertical(rule), 3)
)
}
/** Rotate clockwise
* Original 1 turn 2 turns 3 turns
* abc -> gda -> ihg -> cfi
* def heb fed beh
* ghi ifc cba adg
*
* And for 2x2
* ab -> ca -> dc -> bd
* cd -> db ba ac
*/
private fun rotateCw(r: String, i: Int): String {
val rotated = if (r.length == 5) {
"${r[3]}${r[0]}/${r[4]}${r[1]}"
} else {
"${r[8]}${r[4]}${r[0]}/${r[9]}${r[5]}${r[1]}/${r[10]}${r[6]}${r[2]}"
}
return if (i == 1) rotated else rotateCw(rotated, i - 1)
}
private fun flipVertical(rule: String): String {
val split = rule.split("/").toMutableList()
if (split.size == 2) split[0] = split[1].also { split[1] = split[0] }
else split[0] = split[2].also { split[2] = split[0] }
return split.joinToString("/")
}
private fun flipHorizontal(rule: String): String {
return rule.split("/").joinToString("/") { it.reversed() }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment