Skip to content

Instantly share code, notes, and snippets.

@sungkmi
Created May 14, 2021 13:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sungkmi/6eeeb7406efd3032b7635a6079484e41 to your computer and use it in GitHub Desktop.
Save sungkmi/6eeeb7406efd3032b7635a6079484e41 to your computer and use it in GitHub Desktop.
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:
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