Created
May 14, 2021 13:32
-
-
Save sungkmi/6eeeb7406efd3032b7635a6079484e41 to your computer and use it in GitHub Desktop.
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 sungkmi.aoc2020.day20 | |
import scala.collection.BitSet | |
type Tile = IndexedSeq[BitSet] | |
extension (t: Tile) | |
def edges: IndexedSeq[BitSet] = | |
def regulateEdge(edge: BitSet): BitSet = | |
def toBigInt(bitset: BitSet): BigInt = | |
bitset.foldLeft(BigInt(0))(_ `setBit` _) | |
val reversed = edge.map(9 - _) | |
if toBigInt(edge) < toBigInt(reversed) then edge else reversed | |
val rightEdge = BitSet((for { | |
(bitset, index) <- t.zipWithIndex if bitset.contains(0) | |
} yield index):_*) | |
val leftEdge = BitSet((for { | |
(bitset, index) <- t.zipWithIndex if bitset.contains(9) | |
} yield index):_*) | |
IndexedSeq(t.head, rightEdge, t.last, leftEdge).map(regulateEdge) | |
def parseTile(s: String): Tile = s.split("\n").toIndexedSeq.map: | |
line => | |
BitSet((for { | |
(ch, i) <- line.reverse.zipWithIndex if ch == '#' | |
} yield i):_*) | |
def parse(s: String): Map[Int, Tile] = s.split("\n\n").map: | |
lines => | |
val Array(head, tails) = lines.split(":\n") | |
head.drop(5).trim.toInt -> parseTile(tails) | |
.toMap | |
def groupTiles(tiles: Map[Int, Tile]): Map[BitSet, Set[Int]] = | |
tiles.foldLeft(Map.empty[BitSet, Set[Int]].withDefaultValue(Set.empty)): | |
case (group, (index, tile)) => tile.edges.foldLeft(group): | |
(group, edge) => | |
group + (edge -> (group(edge) + index)) | |
def neighborMap(tileGroup: Map[BitSet, Set[Int]]): Map[Int, Set[Int]] = | |
tileGroup.values.filter(_.size > 1) | |
.foldLeft(Map.empty[Int, Set[Int]].withDefaultValue(Set.empty)): | |
(map, tiles) => | |
tiles.foldLeft(map): | |
(map, tile) => | |
map + (tile -> (map(tile) ++ tiles.filter(_ != tile))) | |
def solve1(input: String): BigInt = | |
neighborMap(groupTiles(parse(input))) | |
.filter(_._2.size == 2).keySet.map(BigInt(_)) | |
.product | |
def solve2(input: String): Int = ??? | |
@main def part1: Unit = | |
val ans = solve1(input) | |
println(ans) | |
@main def part2: Unit = | |
val ans = solve2(input) | |
println(ans) | |
//lazy val input: String = """Tile 1249: |
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 sungkmi.aoc2020.day20 | |
import scala.collection.BitSet | |
class Day20Test extends munit.FunSuite { | |
val tileString1 = """..##.#..#. | |
##..#..... | |
#...##..#. | |
####.#...# | |
##.##.###. | |
##...#.### | |
.#.#.#..## | |
..#....#.. | |
###...#.#. | |
..###..###""" | |
val tile1 = IndexedSeq( | |
BitSet(1,4,6,7), | |
BitSet(5,8,9), | |
BitSet(1,4,5,9), | |
BitSet(0,4,6,7,8,9), | |
BitSet(1,2,3,5,6,8,9), | |
BitSet(0,1,2,4,8,9), | |
BitSet(0,1,4,6,8), | |
BitSet(2,7), | |
BitSet(1,3,7,8,9), | |
BitSet(0,1,2,5,6,7), | |
) | |
val edges1 = IndexedSeq( | |
BitSet(1,4,6,7), | |
BitSet(0,3,4,6), | |
BitSet(0,1,2,5,6,7), | |
BitSet(1,2,3,4,5,8), | |
) | |
val testInput = """Tile 2311: | |
..##.#..#. | |
##..#..... | |
#...##..#. | |
####.#...# | |
##.##.###. | |
##...#.### | |
.#.#.#..## | |
..#....#.. | |
###...#.#. | |
..###..### | |
Tile 1951: | |
#.##...##. | |
#.####...# | |
.....#..## | |
#...###### | |
.##.#....# | |
.###.##### | |
###.##.##. | |
.###....#. | |
..#.#..#.# | |
#...##.#.. | |
Tile 1171: | |
####...##. | |
#..##.#..# | |
##.#..#.#. | |
.###.####. | |
..###.#### | |
.##....##. | |
.#...####. | |
#.##.####. | |
####..#... | |
.....##... | |
Tile 1427: | |
###.##.#.. | |
.#..#.##.. | |
.#.##.#..# | |
#.#.#.##.# | |
....#...## | |
...##..##. | |
...#.##### | |
.#.####.#. | |
..#..###.# | |
..##.#..#. | |
Tile 1489: | |
##.#.#.... | |
..##...#.. | |
.##..##... | |
..#...#... | |
#####...#. | |
#..#.#.#.# | |
...#.#.#.. | |
##.#...##. | |
..##.##.## | |
###.##.#.. | |
Tile 2473: | |
#....####. | |
#..#.##... | |
#.##..#... | |
######.#.# | |
.#...#.#.# | |
.######### | |
.###.#..#. | |
########.# | |
##...##.#. | |
..###.#.#. | |
Tile 2971: | |
..#.#....# | |
#...###... | |
#.#.###... | |
##.##..#.. | |
.#####..## | |
.#..####.# | |
#..#.#..#. | |
..####.### | |
..#.#.###. | |
...#.#.#.# | |
Tile 2729: | |
...#.#.#.# | |
####.#.... | |
..#.#..... | |
....#..#.# | |
.##..##.#. | |
.#.####... | |
####.#.#.. | |
##.####... | |
##..#.##.. | |
#.##...##. | |
Tile 3079: | |
#.#.#####. | |
.#..###### | |
..#....... | |
######.... | |
####.#..#. | |
.#...#.##. | |
#.#####.## | |
..#.###... | |
..#....... | |
..#.###...""" | |
test("day20 parseTile") { | |
assertEquals(parseTile(tileString1), tile1) | |
} | |
test("day20 edges") { | |
assertEquals(tile1.edges, edges1) | |
} | |
test("day20 neighborMap") { | |
assertEquals( | |
neighborMap(groupTiles(parse(input))).filter(_._2.size == 2).size, | |
4 | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment