Created
August 25, 2020 00:33
-
-
Save saidaspen/378b3bb8aff01f382c99cd8435b1b5ab to your computer and use it in GitHub Desktop.
Advent of Code 2017 Day21 - Does not work
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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