Created
December 18, 2017 02:28
-
-
Save Stefan-Wagner/d3050dadc31a5344b841a762e1db88b2 to your computer and use it in GitHub Desktop.
advent of code, day 15, part b
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
// 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