Last active
June 4, 2021 18:39
-
-
Save sungkmi/6f5f4f9e059d7bec8ce31d9ef62aaa9c 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.day23 | |
case class CupCircle( | |
cups: Vector[Int] | |
) | |
object CupCircle: | |
def apply(cups: Vector[Int], current: Int): CupCircle = | |
val (f, e) = cups.splitAt(cups.indexOf(current) + 1) | |
CupCircle(e ++ f) | |
def parse(s: String): CupCircle = | |
val cups: Vector[Int] = s.map(_ - '0').toVector | |
CupCircle(cups.tail :+ cups.head) | |
extension (c: CupCircle) | |
def pickup: Vector[Int] = c.cups.take(3) | |
def destination: Int = | |
@annotation.tailrec | |
def loop(n: Int): Int = | |
if pickup contains n then loop(n - 1) | |
else if n < 1 then loop(c.cups.size) | |
else n | |
loop(c.cups.last - 1) | |
def move: CupCircle = | |
val (pickup, remainder) = c.cups.splitAt(3) | |
// println(s"===> $pickup / $remainder") | |
val destIndex = remainder.indexOf(c.destination) | |
if (destIndex == -1) then println(s"===> wrong dest: ${c.destination}") | |
val (front1, end1) = remainder.splitAt(destIndex + 1) | |
// println(s"===> $front1 / $end1") | |
val cups1 = front1.tail ++ pickup ++ end1 :+ front1.head | |
// println(s"===> $cups1") | |
CupCircle(cups1) | |
def solve1(s: String): String = | |
val cups1 = (1 to 100).foldLeft(CupCircle.parse(s))((cups, _) => cups.move) | |
val indexOf1 = cups1.cups.indexOf(1) | |
(cups1.cups ++ cups1.cups).drop(indexOf1 + 1).take(cups1.cups.size - 1).mkString | |
def solve2(s: String): BigInt = | |
val CupCircle(cups0) = CupCircle.parse(s) | |
val cups = CupCircle(cups0 ++ ((cups0.size + 1) to 1000000)) | |
val cups1: Vector[Int] = (1 to 10000000).foldLeft(cups)((cups, _) => cups.move).cups | |
val indexOf1 = cups1.indexOf(1) | |
val n1 = cups1((indexOf1 + 1) % 10000000) | |
val n2 = cups1((indexOf1 + 2) % 10000000) | |
BigInt(n1) * BigInt(n2) | |
@main def part1: Unit = | |
val ans = solve1(input) | |
println(ans) | |
@main def part2: Unit = | |
val ans = solve2(input) | |
println(ans) | |
lazy val input: String = """487912365""" |
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.day23 | |
import scala.collection.immutable.Queue | |
class Day23Test extends munit.FunSuite { | |
val testInput = """389125467""" | |
val cups1 = CupCircle(Vector(3,8,9,1,2,5,4,6,7), 3) | |
val cups2 = CupCircle(Vector(3,2,8,9,1,5,4,6,7), 2) | |
val cups3 = CupCircle(Vector(3,2,5,4,6,7,8,9,1), 5) | |
val cups4 = CupCircle(Vector(7,2,5,8,9,1,3,4,6), 8) | |
val cups5 = CupCircle(Vector(3,2,5,8,4,6,7,9,1), 4) | |
val cups6 = CupCircle(Vector(9,2,5,8,4,1,3,6,7), 1) | |
val cups7 = CupCircle(Vector(7,2,5,8,4,1,9,3,6), 9) | |
val cups8 = CupCircle(Vector(8,3,6,7,4,1,9,2,5), 2) | |
val cups9 = CupCircle(Vector(7,4,1,5,8,3,9,2,6), 6) | |
val cups10 = CupCircle(Vector(5,7,4,1,8,3,9,2,6), 5) | |
val cupsF = CupCircle(Vector(5,8,3,7,4,1,9,2,6), 8) | |
test("day23 parse") { | |
assertEquals(CupCircle.parse(testInput), cups1) | |
} | |
test("day23 CupCircle.pickup") { | |
assertEquals(cups1.pickup, Vector(8,9,1)) | |
assertEquals(cups2.pickup, Vector(8,9,1)) | |
assertEquals(cups3.pickup, Vector(4,6,7)) | |
assertEquals(cups4.pickup, Vector(9,1,3)) | |
assertEquals(cups5.pickup, Vector(6,7,9)) | |
assertEquals(cups6.pickup, Vector(3,6,7)) | |
assertEquals(cups7.pickup, Vector(3,6,7)) | |
assertEquals(cups8.pickup, Vector(5,8,3)) | |
assertEquals(cups9.pickup, Vector(7,4,1)) | |
assertEquals(cups10.pickup, Vector(7,4,1)) | |
} | |
test("day23 CupCircle.destination") { | |
assertEquals(cups1.destination, 2) | |
assertEquals(cups2.destination, 7) | |
assertEquals(cups3.destination, 3) | |
assertEquals(cups4.destination, 7) | |
assertEquals(cups5.destination, 3) | |
assertEquals(cups6.destination, 9) | |
assertEquals(cups7.destination, 8) | |
assertEquals(cups8.destination, 1) | |
assertEquals(cups9.destination, 5) | |
assertEquals(cups10.destination, 3) | |
} | |
//test("day23 CupCircle.move") { | |
// assertEquals(cups2.move, cups3) | |
//} | |
test("day23 CupCircle.move") { | |
assertEquals(cups1.move, cups2) | |
assertEquals(cups2.move, cups3) | |
assertEquals(cups3.move, cups4) | |
assertEquals(cups4.move, cups5) | |
assertEquals(cups5.move, cups6) | |
assertEquals(cups6.move, cups7) | |
assertEquals(cups7.move, cups8) | |
assertEquals(cups8.move, cups9) | |
assertEquals(cups9.move, cups10) | |
assertEquals(cups10.move, cupsF) | |
} | |
test("day23 solve1") { | |
assertEquals(solve1(testInput), "67384529") | |
} | |
//test("day23 solve2") { | |
// assertEquals(solve2("389125467"), BigInt("149245887792")) | |
//} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment