Skip to content

Commit 83fc14d

Browse files
committed
reorg day 9 in prep for part 2
1 parent 3fb86b4 commit 83fc14d

File tree

3 files changed

+88
-82
lines changed

3 files changed

+88
-82
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package org.codefork.aoc2018
2+
3+
import scala.annotation.tailrec
4+
import scala.io.Source
5+
6+
object Day9 {
7+
8+
case class Game(numPlayers: Int, lastMarblePoints: Int) {
9+
10+
def findHighestScore: Int = calculateFinalScores().values.max
11+
12+
// player is 0-indexed instead of 1-indexed as in example
13+
@tailrec
14+
final def calculateFinalScores(player: Int = 0,
15+
circle: Vector[Int] = Vector(0),
16+
indexOfCurrentMarble: Int = 0,
17+
marbleCounter: Int = 0,
18+
scores: Map[Int, Int] = Map.empty,
19+
lastScore: Int = -1): Map[Int, Int] = {
20+
if (marbleCounter == lastMarblePoints) {
21+
scores
22+
} else {
23+
24+
val nextPlayer = (player + 1) % numPlayers
25+
26+
val toPlace = marbleCounter + 1
27+
28+
if (toPlace % 23 == 0) {
29+
val indexToRemove = {
30+
val minus7 = indexOfCurrentMarble - 7
31+
if (minus7 < 0) minus7 + circle.size else minus7
32+
}
33+
34+
val score = toPlace + circle(indexToRemove)
35+
36+
val newScores = scores + (player -> (scores.getOrElse(player, 0) + score))
37+
38+
val newCircle = circle.patch(indexToRemove, List.empty, 1)
39+
40+
println("player " + player + " scored " + score + " with marble " + toPlace)
41+
println("index at -7 = " + indexToRemove + ", marble = " + circle(indexToRemove) + " newCurrent=" + newCircle(indexToRemove))
42+
43+
//println(player, newCircle)
44+
45+
// "The marble located immediately clockwise of the marble
46+
// that was removed becomes the new current marble."
47+
calculateFinalScores(nextPlayer,
48+
newCircle,
49+
indexToRemove,
50+
marbleCounter + 1,
51+
newScores,
52+
score)
53+
} else {
54+
55+
// this inserts at start of list instead of at end, so it looks diff from example
56+
// on website, but it's effectively the same thing
57+
val indexToInsert =
58+
if (circle.size == 1) 1
59+
else (indexOfCurrentMarble + 2) % circle.size
60+
61+
val newCircle = circle.patch(indexToInsert, Seq(toPlace), 0)
62+
63+
//println(player, newCircle)
64+
65+
calculateFinalScores(nextPlayer,
66+
newCircle,
67+
indexToInsert,
68+
marbleCounter + 1,
69+
scores)
70+
}
71+
}
72+
}
73+
}
74+
75+
//val getTestData = "9 players; last marble is worth 32 points"
76+
//val getTestData = "10 players; last marble is worth 1618 points"
77+
//val getTestData = "13 players; last marble is worth 7999 points"
78+
79+
val getInputData = {
80+
val url = getClass.getResource("/day9/input.txt")
81+
Source.fromURL(url).mkString.stripLineEnd
82+
}
83+
84+
}
Lines changed: 2 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,12 @@
11
package org.codefork.aoc2018
22

3-
import scala.annotation.tailrec
4-
import scala.io.Source
5-
63
object Day9Part1 extends Part {
74

8-
case class Game(numPlayers: Int, lastMarblePoints: Int) {
9-
10-
def findHighestScore: Int = calculateFinalScores().values.max
11-
12-
// player is 0-indexed instead of 1-indexed as in example
13-
@tailrec
14-
final def calculateFinalScores(player: Int = 0,
15-
circle: Vector[Int] = Vector(0),
16-
indexOfCurrentMarble: Int = 0,
17-
marbleCounter: Int = 0,
18-
scores: Map[Int, Int] = Map.empty,
19-
lastScore: Int = -1): Map[Int, Int] = {
20-
if (marbleCounter == lastMarblePoints) {
21-
scores
22-
} else {
23-
24-
val nextPlayer = (player + 1) % numPlayers
25-
26-
val toPlace = marbleCounter + 1
27-
28-
if (toPlace % 23 == 0) {
29-
val indexToRemove = {
30-
val minus7 = indexOfCurrentMarble - 7
31-
if (minus7 < 0) minus7 + circle.size else minus7
32-
}
33-
34-
val score = toPlace + circle(indexToRemove)
35-
36-
val newScores = scores + (player -> (scores.getOrElse(player, 0) + score))
37-
38-
val newCircle = circle.patch(indexToRemove, List.empty, 1)
39-
40-
//println(player + " scored " + score)
41-
//println("marble at -7 was " + circle(indexToRemove))
42-
43-
//println(player, newCircle)
44-
45-
// "The marble located immediately clockwise of the marble
46-
// that was removed becomes the new current marble."
47-
calculateFinalScores(nextPlayer,
48-
newCircle,
49-
indexToRemove,
50-
marbleCounter + 1,
51-
newScores,
52-
score)
53-
} else {
54-
55-
// this inserts at start of list instead of at end, so it looks diff from example
56-
// on website, but it's effectively the same thing
57-
val indexToInsert =
58-
if (circle.size == 1) 1
59-
else (indexOfCurrentMarble + 2) % circle.size
60-
61-
val newCircle = circle.patch(indexToInsert, Seq(toPlace), 0)
62-
63-
//println(player, newCircle)
64-
65-
calculateFinalScores(nextPlayer,
66-
newCircle,
67-
indexToInsert,
68-
marbleCounter + 1,
69-
scores)
70-
}
71-
}
72-
}
73-
}
74-
75-
//val getTestData = "9 players; last marble is worth 32 points"
76-
//val getTestData = "10 players; last marble is worth 1618 points"
77-
//val getTestData = "13 players; last marble is worth 7999 points"
78-
79-
val getInputData = {
80-
val url = getClass.getResource("/day9/input.txt")
81-
Source.fromURL(url).mkString.stripLineEnd
82-
}
83-
845
override def answer: String = {
856
//val input = getTestData
86-
val input = getInputData
7+
val input = Day9.getInputData
878
val matches = raw"\d+".r.findAllMatchIn(input).toList.map(_.toString.toInt)
88-
Game(matches(0), matches(1)).findHighestScore.toString
9+
Day9.Game(matches(0), matches(1)).findHighestScore.toString
8910
}
9011

9112
}

src/main/scala/org/codefork/aoc2018/Main.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ object Main {
1818
Day7Part1,
1919
Day7Part2,
2020
Day8Part1,
21-
Day8Part2
21+
Day8Part2,
22+
Day9Part1
2223
)
2324

2425
def main(args: Array[String]) = {

0 commit comments

Comments
 (0)