@@ -42,43 +42,33 @@ def part2(input: String): BigInt =
4242
4343def countWinning (card : String ): Int =
4444 val numbers = card
45- .substring(card.indexOf(" :" ) + 1 ) // discard "Card X:"
45+ .substring(card.indexOf(" :" ) + 1 )
4646 .split(" " )
4747 .filterNot(_.isEmpty())
4848 val (winningNumberStrs, givenNumberStrs) = numbers.span(_ != " |" )
4949 val winningNumbers = winningNumberStrs.map(_.toInt).toSet
50- // drop the initial "|"
5150 val givenNumbers = givenNumberStrs.drop(1 ).map(_.toInt).toSet
5251 winningNumbers.intersect(givenNumbers).size
53- end countWinning
5452
5553def winningCounts (input : String ): Iterator [Int ] =
5654 input.linesIterator.map(countWinning)
57- end winningCounts
5855
5956def part1_ (input : String ): String =
6057 winningCounts(input)
6158 .map(winning => if winning > 0 then Math .pow(2 , winning - 1 ).toInt else 0 )
6259 .sum
6360 .toString()
64- end part1_
6561
6662def part2_ (input : String ): String =
6763 winningCounts(input)
68- // we only track the multiplicities of the next few cards as needed, not all of them;
69- // and the first element always exists, and corresponds to the current card;
70- // and the elements are always positive (because there is at least 1 original copy of each card)
7164 .foldLeft((0 , Vector (1 ))) { case ((numCards, multiplicities), winning) =>
7265 val thisMult = multiplicities(0 )
7366 val restMult = multiplicities
7467 .drop(1 )
75- // these are the original copies of the next few cards
7668 .padTo(Math .max(1 , winning), 1 )
7769 .zipWithIndex
78- // these are the extra copies we just won
7970 .map((mult, idx) => if idx < winning then mult + thisMult else mult)
8071 (numCards + thisMult, restMult)
8172 }
8273 ._1
8374 .toString()
84- end part2_
0 commit comments