- import scala.collection.mutable.{Map => MMap}
- import scala.collection.mutable.{Set => MSet}
- object Wrapper {
- // 0 1 2 3 4 5 6 7
- // 0 1 2 3 4 5 6 7
- // 0 1 2 3 4 5 6 7
- // 0 1 2 3 4 5 6 7
- val dy = Array( 0, 0, -1, -1, 1, 1)
- val dx = Array( 1, -1, 1, 0, 1, 0)
- // Took ages to realize that dx depends on the Y
- val dxx = Array( 1, -1, 0, -1, 0, -1)
- val mv = Array( "e", "w","ne","nw","se","sw")
- val lines = scala.io.Source.fromFile("input").getLines.toArray
- def part1(lines: Array[String]) = {
- val tiles = MMap[(Int, Int), Int]()
- lines.foreach { line =>
- var moves = line
- var x = 0
- var y = 0
- while(!moves.isEmpty){
- for(m <- 0 until 6){
- if(moves.startsWith(mv(m))){
- if(y%2 == 0)
- x += dx(m)
- else
- x += dxx(m)
- y += dy(m)
- moves = moves.substring(mv(m).length)
- }
- }
- }
- if(tiles.contains(x->y)){
- tiles(x->y) = 1 - tiles(x->y)
- } else {
- tiles(x->y) = 1
- }
- }
- println(tiles.values.sum)
- tiles
- }
- def neighbours(x: Int, y:Int) = {
- (0 until 6) map { m =>
- val xx = x + (if(y%2 == 0) dx(m) else dxx(m))
- val yy = y + dy(m)
- (xx, yy)
- }
- }
- def part2(tiles: MSet[(Int, Int)]){
- var cur = tiles.clone
- var next = MSet[(Int, Int)]()
- for(turn <- 1 to 100){
- val whites = MSet[(Int, Int)]()
- next = MSet[(Int, Int)]()
- cur.foreach { case (x, y) =>
- val nb = neighbours(x,y).toSet
- val blacks = nb.filter(cur)
- if(!(blacks.size == 0 || blacks.size > 2))
- next += x -> y
- whites ++= nb
- }
- whites --= cur
- whites.foreach { case (x, y) =>
- val nb = neighbours(x,y)
- val blacks = nb.filter(cur)
- if( blacks.size == 2)
- next += x -> y
- }
- cur = next.clone
- }
- println(cur.size)
- }
- def solve() = {
- val tiles = part1(lines).filter(_._2 == 1)
- val blacks = MSet[(Int, Int)]()
- blacks ++= tiles.keySet
- part2(blacks)
- }
- }
- Wrapper.solve()