Commit 15c85b83 by Alexander Gehrke

### [day9] solution

parent 42e78d51
 package aoc2020 import lib.RingBuffer def day9(input: List[Long]): String = ( for { invalid <- findInvalidInInput(input, 25) range <- findSumRange(input, invalid) } yield (invalid, range) ).fold("No invalid number"){ case (invalid, (min, max)) => s"first invalid: \$invalid\nMin/max of sum range: \$min / \$max\nWeakness (min + max): \${min + max}" } def findInvalidInInput(input: List[Long], preambleSize: Int) = val (preamble, message) = input.splitAt(preambleSize) findInvalid(RingBuffer(preamble.toVector, preambleSize), message) def findInvalid(preamble: RingBuffer[Long], message: List[Long]): Option[Long] = message match { case h :: t => if (preamble.combinations(2).exists(_.sum == h)) findInvalid(preamble :+ h, t) else Some(h) case Nil => None } def findSumRange(input: List[Long], invalid: Long) = import math.{min, max} @annotation.tailrec def checkHead(remaining: List[Long], sum: Long, minS: Long, maxS: Long): Option[(Long, Long)] = remaining match { case Nil => None case h :: t => val nsum = sum + h if (nsum > invalid) None else if (nsum == invalid) Some((min(minS, h), max(maxS, h))) else checkHead(t, nsum, min(minS, h), max(maxS, h)) } input.tails.collectFirst((checkHead(_, 0L, Long.MaxValue, Long.MinValue)).unlift)
 ... ... @@ -10,5 +10,7 @@ package aoc2020 case 6 => input()(day6) case 7 => input()(day7) case 8 => input()(day8) case 9 => input(_.toLong)(day9) case _ => "No such day implemented" } println(out)
 package aoc2020.lib import scala.collection.immutable._ import scala.annotation.alpha /* Wrap a vector to create a limited size ring buffer */ case class RingBuffer[A](underlying: Vector[A], maxSize: Int) { /* pass through any methods to the underlying vector, except appending and * prepending single elements */ export underlying.{ :+ => _, appended => _, +: => _, prepended => _, _ } inline def full: Boolean = underlying.size == maxSize //TODO alpha is renamed to targetName in M2 or M3 @alpha("appended") def :+[B >: A](b: B): RingBuffer[B] = val appendedVec = (if full then underlying.tail else underlying) :+ b new RingBuffer(appendedVec, maxSize) @alpha("prepended") def +:[B >: A](b: B): RingBuffer[B] = val prependedVec = b +: (if full then underlying.init else underlying) new RingBuffer(prependedVec, maxSize) } object RingBuffer { def apply[A](underlying: Vector[A], maxSize: Int): RingBuffer[A] = new RingBuffer( if underlying.size > maxSize then underlying.view.slice(0, maxSize).toVector else underlying, maxSize ) }
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!