diff --git a/input/day14 b/input/day14 new file mode 100644 index 0000000..16af315 --- /dev/null +++ b/input/day14 @@ -0,0 +1,500 @@ +p=8,15 v=12,-27 +p=58,24 v=91,-30 +p=63,33 v=-60,-5 +p=41,53 v=42,79 +p=84,100 v=-15,7 +p=19,45 v=-17,-25 +p=49,46 v=14,57 +p=46,5 v=-73,-32 +p=66,41 v=18,56 +p=83,61 v=18,-63 +p=53,26 v=-14,37 +p=40,73 v=51,2 +p=0,70 v=81,-16 +p=93,9 v=44,91 +p=48,18 v=-94,61 +p=70,96 v=-65,-15 +p=22,16 v=23,-41 +p=92,18 v=55,96 +p=72,95 v=91,92 +p=31,47 v=5,-47 +p=74,39 v=-88,57 +p=30,99 v=28,-36 +p=18,23 v=61,-73 +p=58,40 v=-60,-65 +p=66,3 v=18,13 +p=89,52 v=-59,-39 +p=73,99 v=32,66 +p=50,48 v=37,37 +p=90,74 v=95,-40 +p=28,68 v=38,-64 +p=91,19 v=-84,91 +p=26,6 v=-35,-38 +p=71,22 v=-6,-90 +p=2,2 v=66,-35 +p=86,15 v=-66,-52 +p=48,19 v=-68,91 +p=78,47 v=-73,-51 +p=23,88 v=-13,-18 +p=94,77 v=-11,-38 +p=35,23 v=-96,30 +p=0,85 v=67,-98 +p=89,95 v=-31,-70 +p=67,43 v=-97,36 +p=95,36 v=4,65 +p=11,70 v=-57,-99 +p=4,40 v=9,-67 +p=66,95 v=-51,-55 +p=25,47 v=11,-27 +p=98,26 v=-29,-66 +p=14,49 v=-56,-8 +p=97,52 v=-99,60 +p=100,57 v=76,60 +p=64,6 v=-5,-52 +p=43,12 v=-46,-34 +p=8,66 v=37,-22 +p=2,47 v=76,-3 +p=83,22 v=-56,53 +p=57,98 v=-10,-20 +p=84,59 v=-19,-81 +p=55,58 v=-78,-44 +p=32,45 v=56,39 +p=33,95 v=93,47 +p=21,39 v=-49,-67 +p=71,82 v=73,-96 +p=46,23 v=51,-80 +p=73,93 v=91,46 +p=90,40 v=-80,35 +p=22,62 v=35,-90 +p=28,36 v=98,9 +p=95,3 v=12,70 +p=75,0 v=68,-56 +p=1,96 v=68,-18 +p=64,62 v=-14,-21 +p=2,14 v=12,16 +p=11,51 v=-11,-71 +p=4,33 v=-91,64 +p=1,77 v=-34,2 +p=72,70 v=-51,63 +p=75,10 v=-48,-18 +p=67,98 v=-65,-13 +p=57,14 v=78,12 +p=51,47 v=23,-85 +p=97,78 v=-92,-51 +p=85,65 v=-43,-63 +p=30,30 v=29,-24 +p=30,22 v=93,32 +p=6,78 v=-62,-16 +p=26,91 v=47,46 +p=16,15 v=29,-10 +p=64,40 v=62,-74 +p=55,74 v=42,-36 +p=95,6 v=12,90 +p=8,25 v=-39,-28 +p=54,72 v=78,-18 +p=22,63 v=95,1 +p=26,54 v=43,38 +p=41,62 v=-20,83 +p=98,56 v=21,-86 +p=82,94 v=31,88 +p=97,102 v=-15,-16 +p=15,76 v=53,1 +p=88,88 v=7,-54 +p=66,3 v=-42,-73 +p=77,83 v=-98,-34 +p=69,74 v=-74,-80 +p=50,66 v=-87,43 +p=24,68 v=-58,20 +p=29,26 v=6,-90 +p=36,62 v=-25,-78 +p=96,94 v=40,-73 +p=25,16 v=75,-83 +p=55,50 v=59,40 +p=8,62 v=83,-82 +p=89,30 v=-74,86 +p=49,67 v=-80,-82 +p=63,71 v=-41,41 +p=67,27 v=-42,99 +p=77,99 v=77,70 +p=59,89 v=69,66 +p=0,21 v=21,93 +p=13,54 v=20,59 +p=88,24 v=-43,32 +p=54,2 v=78,8 +p=32,28 v=24,-45 +p=87,42 v=-84,38 +p=94,28 v=-22,-38 +p=20,7 v=-71,81 +p=92,78 v=-29,-79 +p=36,41 v=-59,57 +p=75,97 v=3,-56 +p=76,102 v=-30,84 +p=6,92 v=-26,49 +p=75,0 v=-95,7 +p=9,94 v=94,-95 +p=45,45 v=8,46 +p=32,6 v=66,-92 +p=38,86 v=-82,-99 +p=31,36 v=-12,33 +p=6,15 v=4,81 +p=11,58 v=39,81 +p=41,81 v=-13,85 +p=3,20 v=-15,3 +p=20,66 v=-7,-85 +p=29,87 v=-51,-72 +p=83,65 v=-4,-33 +p=0,79 v=39,85 +p=4,94 v=7,-98 +p=88,97 v=-66,89 +p=92,61 v=58,80 +p=63,65 v=32,40 +p=16,82 v=-53,-20 +p=57,57 v=55,-63 +p=13,0 v=-30,24 +p=55,23 v=46,-48 +p=11,69 v=57,-41 +p=17,26 v=34,-8 +p=10,58 v=-21,-61 +p=30,45 v=15,38 +p=36,5 v=74,-56 +p=45,37 v=83,14 +p=14,65 v=64,90 +p=40,99 v=74,-50 +p=46,46 v=-69,-89 +p=39,89 v=97,-17 +p=27,92 v=24,85 +p=16,21 v=-71,92 +p=77,102 v=-47,-53 +p=60,84 v=87,32 +p=98,49 v=97,-70 +p=58,65 v=18,-17 +p=69,86 v=18,-79 +p=67,64 v=-65,-3 +p=34,102 v=-91,-16 +p=100,81 v=35,23 +p=55,11 v=-42,11 +p=34,82 v=-68,25 +p=42,49 v=-46,37 +p=68,101 v=-60,89 +p=57,25 v=64,-70 +p=36,28 v=97,-28 +p=83,5 v=41,51 +p=22,4 v=73,61 +p=45,69 v=-53,-73 +p=32,58 v=-13,64 +p=87,94 v=-61,90 +p=46,76 v=97,-3 +p=1,89 v=7,-97 +p=42,6 v=-99,-17 +p=23,99 v=-81,-34 +p=15,33 v=19,-27 +p=86,33 v=93,-56 +p=77,31 v=-44,-83 +p=91,5 v=95,9 +p=0,1 v=11,52 +p=70,5 v=-84,-53 +p=43,91 v=32,-57 +p=48,47 v=-72,24 +p=37,26 v=47,-50 +p=64,81 v=-47,23 +p=21,82 v=33,1 +p=94,71 v=-30,43 +p=74,85 v=-24,-57 +p=78,93 v=-84,-16 +p=27,82 v=-17,-36 +p=22,78 v=-49,41 +p=5,89 v=42,-13 +p=54,41 v=-46,15 +p=92,13 v=-16,-48 +p=35,97 v=-77,-93 +p=100,42 v=-11,77 +p=86,96 v=56,37 +p=11,48 v=70,-49 +p=71,78 v=35,68 +p=15,53 v=53,-16 +p=29,99 v=93,-77 +p=66,0 v=-19,69 +p=46,77 v=91,-23 +p=5,37 v=7,17 +p=63,50 v=87,-44 +p=87,24 v=-71,-11 +p=86,93 v=53,90 +p=74,99 v=68,-12 +p=3,85 v=-58,-78 +p=72,25 v=84,75 +p=90,44 v=90,-45 +p=61,46 v=73,-5 +p=83,10 v=-67,-21 +p=63,53 v=-14,-67 +p=86,37 v=-84,79 +p=98,68 v=90,2 +p=60,55 v=45,-81 +p=68,99 v=82,26 +p=82,82 v=-15,-63 +p=59,30 v=65,18 +p=39,44 v=-64,70 +p=27,102 v=37,-27 +p=79,37 v=4,74 +p=97,76 v=-46,-52 +p=33,87 v=-65,87 +p=61,8 v=-57,-24 +p=36,67 v=-82,-42 +p=79,8 v=45,8 +p=89,82 v=-52,65 +p=47,20 v=-11,-79 +p=75,31 v=12,64 +p=41,5 v=19,-53 +p=26,31 v=-82,38 +p=23,72 v=-3,43 +p=12,42 v=-31,6 +p=63,21 v=-52,-58 +p=78,42 v=22,-28 +p=91,26 v=-20,94 +p=45,36 v=-19,-59 +p=35,24 v=33,13 +p=97,18 v=90,-10 +p=36,25 v=13,-34 +p=51,101 v=60,8 +p=91,30 v=-72,27 +p=11,44 v=-57,-68 +p=42,11 v=24,66 +p=47,101 v=-32,-95 +p=55,18 v=-69,-71 +p=55,76 v=46,43 +p=86,1 v=53,27 +p=11,52 v=-66,-5 +p=94,78 v=-43,-17 +p=49,24 v=79,-9 +p=97,0 v=12,48 +p=62,72 v=89,8 +p=30,41 v=84,-67 +p=97,40 v=2,-23 +p=59,7 v=91,-48 +p=54,56 v=-64,60 +p=41,61 v=-18,-2 +p=27,40 v=-21,17 +p=14,97 v=76,-11 +p=12,48 v=-99,98 +p=24,67 v=66,-41 +p=84,63 v=-52,62 +p=37,3 v=28,8 +p=18,11 v=-44,7 +p=100,49 v=-39,-64 +p=6,36 v=56,-73 +p=30,91 v=-50,12 +p=47,60 v=-75,-32 +p=68,38 v=-5,-87 +p=3,75 v=-93,-49 +p=68,53 v=42,37 +p=68,2 v=50,10 +p=7,7 v=52,31 +p=70,71 v=-30,-52 +p=50,77 v=-19,-14 +p=34,38 v=20,-69 +p=5,89 v=71,1 +p=18,77 v=18,78 +p=26,30 v=56,-70 +p=91,99 v=-62,-94 +p=32,15 v=83,-10 +p=78,71 v=-47,19 +p=23,98 v=-17,70 +p=87,52 v=-8,-92 +p=77,74 v=-88,26 +p=84,3 v=-20,-21 +p=72,25 v=-56,-89 +p=63,25 v=60,33 +p=19,69 v=75,63 +p=91,10 v=63,48 +p=9,54 v=-25,-97 +p=12,79 v=89,-39 +p=30,57 v=-77,-43 +p=60,12 v=-73,-72 +p=79,7 v=-77,42 +p=41,82 v=41,56 +p=91,76 v=-66,66 +p=37,80 v=60,-14 +p=60,16 v=-23,10 +p=33,69 v=97,25 +p=52,75 v=-15,48 +p=93,94 v=-21,-85 +p=77,88 v=-29,-33 +p=32,6 v=-94,-59 +p=51,30 v=-78,-90 +p=66,100 v=-74,-34 +p=2,12 v=-52,-11 +p=9,11 v=90,94 +p=83,13 v=-61,-10 +p=16,80 v=98,-38 +p=72,13 v=-24,10 +p=40,67 v=-19,-25 +p=33,4 v=-1,-26 +p=44,87 v=-53,65 +p=85,98 v=35,-31 +p=31,45 v=1,-65 +p=28,17 v=56,63 +p=78,9 v=-93,-82 +p=6,37 v=-57,-93 +p=93,53 v=-34,75 +p=100,1 v=7,9 +p=55,32 v=69,96 +p=13,74 v=-44,25 +p=80,65 v=30,-29 +p=40,37 v=51,97 +p=21,53 v=36,-8 +p=52,97 v=-41,-93 +p=15,98 v=-44,-15 +p=37,95 v=10,-97 +p=95,23 v=-29,-71 +p=33,97 v=20,10 +p=46,15 v=-96,92 +p=14,70 v=89,-20 +p=74,82 v=-12,48 +p=7,65 v=20,-8 +p=84,13 v=-48,74 +p=68,51 v=-5,38 +p=36,67 v=47,-62 +p=11,95 v=57,-14 +p=47,28 v=-59,-91 +p=38,53 v=-4,63 +p=61,96 v=85,3 +p=68,58 v=73,-21 +p=75,64 v=87,83 +p=63,83 v=82,-78 +p=58,78 v=64,-38 +p=38,7 v=-27,-95 +p=24,68 v=66,-21 +p=61,72 v=32,-81 +p=20,33 v=11,-89 +p=86,53 v=-69,98 +p=13,9 v=-74,-84 +p=80,46 v=-52,-46 +p=30,26 v=1,-49 +p=38,56 v=19,62 +p=80,71 v=-66,19 +p=65,65 v=64,-1 +p=38,36 v=-77,-5 +p=80,46 v=-68,-32 +p=35,31 v=-82,13 +p=45,27 v=70,-6 +p=4,86 v=-39,45 +p=64,50 v=73,79 +p=71,61 v=13,22 +p=77,59 v=81,23 +p=10,29 v=25,54 +p=100,42 v=10,56 +p=74,99 v=91,49 +p=84,6 v=99,94 +p=72,99 v=43,8 +p=4,29 v=76,33 +p=93,97 v=99,-49 +p=25,82 v=-59,65 +p=38,29 v=74,95 +p=45,83 v=74,-80 +p=71,76 v=82,23 +p=83,30 v=86,-24 +p=32,80 v=-77,25 +p=48,50 v=55,-47 +p=95,7 v=21,-73 +p=61,97 v=-6,44 +p=9,16 v=-11,-50 +p=90,97 v=-79,86 +p=58,31 v=-69,35 +p=38,49 v=-72,18 +p=91,5 v=99,85 +p=29,62 v=-31,43 +p=45,66 v=33,-42 +p=67,83 v=73,-57 +p=23,3 v=6,7 +p=57,32 v=-60,-89 +p=83,54 v=-33,-24 +p=28,4 v=57,49 +p=100,97 v=-62,-77 +p=89,71 v=-21,-25 +p=94,39 v=-6,-27 +p=71,41 v=-1,-90 +p=87,39 v=-98,-68 +p=72,43 v=54,98 +p=78,91 v=-22,-83 +p=29,58 v=-64,-26 +p=21,2 v=-3,71 +p=38,6 v=2,-40 +p=75,62 v=96,99 +p=4,22 v=39,53 +p=63,73 v=-60,23 +p=26,38 v=2,-94 +p=94,16 v=-65,-30 +p=11,101 v=89,89 +p=48,38 v=-91,29 +p=64,15 v=-47,-95 +p=79,78 v=91,23 +p=92,72 v=58,-58 +p=2,76 v=99,24 +p=89,6 v=31,33 +p=98,79 v=90,4 +p=78,30 v=-83,-66 +p=77,44 v=27,77 +p=99,0 v=44,73 +p=33,72 v=93,22 +p=9,97 v=-92,-96 +p=84,13 v=35,-87 +p=68,97 v=-19,-95 +p=68,61 v=-72,-30 +p=26,13 v=65,-66 +p=85,94 v=-25,74 +p=42,20 v=74,-8 +p=63,58 v=-10,93 +p=6,83 v=-62,-97 +p=42,54 v=90,-97 +p=10,78 v=-32,-99 +p=43,16 v=-26,6 +p=40,68 v=-36,62 +p=32,42 v=-26,27 +p=69,69 v=73,85 +p=78,78 v=-42,68 +p=51,34 v=-95,57 +p=88,41 v=-75,-44 +p=80,86 v=-65,22 +p=33,95 v=-22,-54 +p=86,56 v=-89,18 +p=93,0 v=90,-55 +p=22,89 v=48,29 +p=6,39 v=-43,-44 +p=70,19 v=51,97 +p=67,31 v=82,14 +p=8,80 v=-30,66 +p=65,7 v=-5,52 +p=17,62 v=7,-84 +p=93,96 v=-25,6 +p=86,3 v=-44,-29 +p=73,18 v=32,33 +p=41,62 v=4,-5 +p=88,72 v=-45,23 +p=79,86 v=77,87 +p=43,95 v=-55,65 +p=61,72 v=22,3 +p=32,74 v=67,27 +p=9,59 v=-11,-63 +p=31,86 v=24,85 +p=34,26 v=-45,80 +p=56,78 v=-55,-70 +p=73,91 v=-47,-77 +p=5,98 v=81,48 +p=63,77 v=13,22 +p=2,70 v=-39,-95 +p=90,46 v=95,14 +p=1,32 v=72,16 +p=1,102 v=-16,71 +p=44,5 v=-96,-75 +p=7,9 v=35,49 +p=23,92 v=84,-94 +p=68,2 v=-52,33 +p=99,85 v=90,-98 +p=30,80 v=-31,67 +p=44,19 v=10,-71 +p=70,80 v=-42,5 +p=82,22 v=48,9 +p=60,9 v=-60,89 +p=4,80 v=94,45 +p=19,66 v=-3,-84 +p=71,23 v=59,33 +p=41,42 v=92,-47 diff --git a/src/day14.scala b/src/day14.scala new file mode 100644 index 0000000..a462a2c --- /dev/null +++ b/src/day14.scala @@ -0,0 +1,72 @@ +package aoc +package day14 + +val dayNumber = "14" + +@main def part1: Unit = + println(part1(loadInput(dayNumber))) + +@main def part2: Unit = + println(part2(loadInput(dayNumber))) + +def part1(input: String): String = + val robots = parseInput(input) + Room(robots, width = 101, height = 103).atTime(100).safetyFactor.toString + +def part2(input: String): String = + val robots = parseInput(input) + val initialRoom = Room(robots, width = 101, height = 103) + for (seconds, room) <- initialRoom.atLikelyEasterEgg do + println(room.show) + println(seconds) + "" + +case class Room(robots: List[Robot], width: Int, height: Int): + def atTime(s: Int): Room = + this.copy(robots.map(_.atTime(s, width, height))) + + def safetyFactor: Long = + robots + .filterNot(r => r.x == width / 2 || r.y == height / 2) + .groupBy(r => (r.x < width / 2, r.y < height / 2)) + .values + .map(_.size.toLong) + .product + + def atLikelyEasterEgg: Iterator[(Int, Room)] = + Iterator + .from(1) + .map(t => t -> atTime(t)) + .filter(_._2.robots.groupBy(r => (r.x, r.y)).values.forall(_.length <= 1)) + + def show: String = + ( + for x <- (0 until width) + yield ( + for y <- (0 until height) + yield robots.count(r => r.x == x && r.y == y) match + case 0 => ' ' + case _ => '#' + ).mkString + ).mkString("\n") + +case class Robot(x: Int, y: Int, vx: Int, vy: Int): + def atTime(s: Int, width: Int, height: Int): Robot = + val nx = (x + vx * s) % width + val ny = (y + vy * s) % height + Robot( + x = if nx < 0 then width + nx else nx, + y = if ny < 0 then height + ny else ny, + vx = vx, + vy = vy + ) + +def parseInput(input: String): List[Robot] = + object i: + def unapply(s: String): Option[Int] = s.toIntOption + input + .split("\n") + .map { case s"p=${i(x)},${i(y)} v=${i(vx)},${i(vy)}" => + Robot(x, y, vx, vy) + } + .toList