Skip to content

Instantly share code, notes, and snippets.

@Stefan-Wagner
Created December 18, 2017 02:28
Show Gist options
  • Save Stefan-Wagner/d3050dadc31a5344b841a762e1db88b2 to your computer and use it in GitHub Desktop.
Save Stefan-Wagner/d3050dadc31a5344b841a762e1db88b2 to your computer and use it in GitHub Desktop.
advent of code, day 15, part b
// See problem on Advent of Code
// http://adventofcode.com/2017/day/15
import annotation.tailrec
object adventOfCode15 {
// generic testmethod
def test [I, O] (indata: I, outdata: O, f: (I => O)) : Boolean = {
val res = f(indata)
if (res == outdata) {
println ("Success: " + indata.toString ().take (200) + "\t" + res)
true
}
else {
println ("--Fail: f(" + indata.toString ().take (200) + ")\t= " + res + "\texpected: " + outdata)
false
}
}
case class Tor15b (startvalA: Long, startvalB: Long) {
val m = Int.MaxValue
val m5 = 5*1000*1000
def lowbits (i: Long) : Long = ((i << 48) >> 48)
// count downwards from 5M steps, stop at 0
@tailrec
final def addMatches (steps: Int, sum: Int, a: Long, b: Long) : Int = steps match {
case 0 => sum
case _ => {
val aval : Long = a * 16807 % m
val bval : Long = b * 48271 % m
// if (aval == 1023762912L) println (s"---> aVal found! step: ${1+m5-steps} a: $aval b: $bval")
if ((aval & 3L) == 0L && (bval & 7L) == 0L) {
val hit = if (lowbits(a)==lowbits(b)) 1 else 0
if (hit == 1) println (s"hit: step ${1+m5-steps} a: $aval b: $bval")
addMatches (steps - 1, sum + hit, aval, bval)
}
// proceede with previous values (a or b) for the one, who found divisibility:
else if ((aval & 3) == 0) addMatches (steps, sum, a, bval)
else if ((bval & 7) == 0) addMatches (steps, sum, aval, b)
else addMatches (steps, sum, aval, bval)
}
}
// ein off-by-one-Error?
def findMatches (anz: Int) = addMatches (anz+1, 0, startvalA, startvalB)
}
// fill program with test- and serious values
def tor15btest () : Boolean = {
val m5 = 1000*1000*5
// testdata:
val tor15bt = Tor15b (65L, 8921L)
test (1055, 0, tor15bt.findMatches)
println ("---------------------")
test (1056, 1, tor15bt.findMatches)
println ("---------------------")
test (1057, 1, tor15bt.findMatches)
println ("---------------------")
test (m5, 309, tor15bt.findMatches) // fail 69 => echo $(((5*67+4*(67-1)+1)/2)) = 309 => 67 statt 69: => 300
// serious data:
//Generator A starts with 618, B starts with 814
val tor15bp = Tor15b (618L, 814L)
// 999 is just a dummy value, to satisfy the test syntax
test (m5, 999, tor15bp.findMatches) // findet 67 => 300 too low, 302 too low
}
def main (s: Array[String]) : Unit = tor15btest
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment