10000 Scala: simplify tiles code · bereal/AdventOfCode2020@c41a2bc · GitHub
[go: up one dir, main page]

Skip to content

Commit

Permalink
Scala: simplify tiles code
Browse files Browse the repository at this point in the history
  • Loading branch information
bereal committed Dec 23, 2020
1 parent 1dd33b7 commit c41a2bc
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 32 deletions.
51 changes: 21 additions & 30 deletions 20_scala/solve.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,40 +9,31 @@ object Types {
object D4 extends Enumeration {
import Types._

val R0, R1, R2, R3, SH, SV, D1, D2 = Value

def apply(op: Value, square: Matrix[Char]): Matrix[Char] = {
op match {
case R0 => square
case SH => square.reverse
case SV => square.map(_.reverse)
case D1 => square.transpose
case D2 => square.reverse.map(_.reverse).transpose
case R1 => square.transpose.reverse
case R2 => square.reverse.map(_.reverse)
case R3 => square.reverse.transpose
}
}

def allConfigs(square: Matrix[Char]): Seq[Matrix[Char]] =
values.toSeq.map(apply(_, square));
def apply(m: Matrix[Char]): Seq[Matrix[Char]] = List(
m, // R0
m.reverse, // SH
m.map(_.reverse), // SV
m.transpose, // D1
m.reverse.map(_.reverse).transpose, // D2
m.transpose.reverse, // R1
m.reverse.map(_.reverse), // R2
m.reverse.transpose // R3
)
}

class TileConfig(val id: Int, val body: Types.Matrix[Char]) {
val top = body.head.mkString
val left = body.map(_.head).mkString
val right = body.map(_.last).mkString
val bottom = body.last.mkString
}
class Tile(val id: Int, val body: Types.Matrix[Char]) {
lazy val top = body.head.mkString
lazy val left = body.map(_.head).mkString
lazy val right = body.map(_.last).mkString
lazy val bottom = body.last.mkString

class Tile(val id: Int, val init: Types.Matrix[Char]) {
val allConfigs = D4.allConfigs(init).map(new TileConfig(id, _))
lazy val configs = D4(body).map(new Tile(id, _))
}

class Area(val tiles: Seq[Tile]) {
import Types._

val tileConfigs = tiles.flatMap(_.allConfigs)
val tileConfigs = tiles.flatMap(_.configs)
val tileConfigsById = tileConfigs.groupBy(_.id)
val mapSize = Math.sqrt(tiles.length).toInt
val tileSize = tileConfigs.head.body.length
Expand All @@ -55,15 +46,15 @@ class Area(val tiles: Seq[Tile]) {
def findCorners() = tileConfigs.filter(t => isUnique(t.top) && isUnique(t.left)).map(_.id).toSet

def fillMap(): Matrix[Char] = {
val map: MMap[(Int, Int), TileConfig] = MMap()
val map: MMap[(Int, Int), Tile] = MMap()
val pendingSet = MSet.from(tileConfigsById.keys)
val update = (i: Int, j: Int, t: TileConfig) => {
val update = (i: Int, j: Int, t: Tile) => {
pendingSet.remove(t.id)
map.update((i, j), t)
}

// find a tile matching the criterias
val find: (TileConfig => Boolean) => TileConfig = (f) =>
val find: (Tile => Boolean) => Tile = (f) =>
pendingSet.flatMap(tileConfigsById).filter(f).head

for (i <- 1 to mapSize; j <- 1 to mapSize) {
Expand Down Expand Up @@ -134,6 +125,6 @@ object Main {
val area = new Area(readInput())
println(area.findCorners().map(_.toLong).reduce(_ * _))
val sea = area.fillMap()
println(D4.allConfigs(sea).map(area.findMonsters).flatten.head)
println(D4(sea).map(area.findMonsters).flatten.head)
}
}
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -453,14 +453,15 @@ _Knowledge_: 1

_Site_: https://www.scala-lang.org/

_Puzzle_: [Jurassic Jigsaw](https://adventofcode.com/2020/day/20)
_Puzzle_: [Jurassic Jigsaw](https://adventofcode.com/2020/day/20). A jigsaw puzzle and pattern matching.

Oh. My. God. It's less than 150 lines, but I'm exhausted. I ended up solving the second part in imperative style,
and not ashamed. I guess, now I can see how it can be done functionally, but definitely, not today.
I wish I could blame Scala, but it (and IntelliJ Idea) was quite helpful with all the type hints.
I wish I could blame Scala, but it (and the IDE) was quite helpful with all the autocompletions and type hints.
Still, I'm not sure about Scala, I mean, too much stuff happen implicitly, and all the type annotations
are sometimes more cryptic than in C++. And forget about using it without an IDE (I tried Metals for VS Code,
but at some point autocompletion refused to work, so I resorted to installing good old IntelliJ Idea).

The good news is that I revisited [symmetry groups](https://en.wikipedia.org/wiki/Symmetry_group), and
that was fun.

Expand Down

0 comments on commit c41a2bc

Please sign in to comment.
0