Make Day 7 faster
This commit is contained in:
@@ -8,33 +8,47 @@ object Day07 extends Solver(7):
|
|||||||
while m * 10 <= b do m *= 10
|
while m * 10 <= b do m *= 10
|
||||||
a * (m * 10) + b
|
a * (m * 10) + b
|
||||||
|
|
||||||
|
def deconcat(a: Long, b: Long): Option[Long] =
|
||||||
|
val b_len = Math.log10(b).floor.toLong + 1
|
||||||
|
if (a % Math.pow(10, b_len).toLong == b)
|
||||||
|
then Some(a / Math.pow(10, b_len).toLong)
|
||||||
|
else None
|
||||||
|
|
||||||
class Searcher(target: Long, nums: Vector[Long], elephants: Boolean):
|
class Searcher(target: Long, nums: Vector[Long], elephants: Boolean):
|
||||||
def search(acc: Long = nums(0), pos: Int = 1): Boolean =
|
def search(acc: Long = nums(0), pos: Int = 1): Boolean =
|
||||||
if (pos >= nums.length) return acc == target
|
if (pos >= nums.length) return acc == target
|
||||||
if (acc > target) return false
|
|
||||||
search(acc + nums(pos), pos + 1)
|
search(acc + nums(pos), pos + 1)
|
||||||
|| search(acc * nums(pos), pos + 1)
|
|| search(acc * nums(pos), pos + 1)
|
||||||
|| (elephants && search(concat(acc, nums(pos)), pos + 1))
|
|| (elephants && search(concat(acc, nums(pos)), pos + 1))
|
||||||
|
|
||||||
|
class Tester(nums: Vector[Long], elephants: Boolean):
|
||||||
|
def test(target: Long, pos: Int = nums.length - 1): Boolean =
|
||||||
|
if pos == 0 then return target == nums(0)
|
||||||
|
if target <= 0 then return false
|
||||||
|
test(target - nums(pos), pos - 1)
|
||||||
|
|| (target % nums(pos) == 0 && test(target / nums(pos), pos - 1))
|
||||||
|
|| (elephants && deconcat(target, nums(pos)).exists(test(_, pos - 1)))
|
||||||
|
|
||||||
|
def check(target: Long, nums: Vector[Long], thirdElephant: Boolean): Boolean =
|
||||||
|
if nums.contains(0)
|
||||||
|
then Searcher(target, nums, thirdElephant).search()
|
||||||
|
else Tester(nums, thirdElephant).test(target)
|
||||||
|
|
||||||
def run(input: os.ReadablePath): (Timings, Solution) =
|
def run(input: os.ReadablePath): (Timings, Solution) =
|
||||||
val REGEX = """(\d+): (.*)""".r
|
val REGEX = """(\d+): (.*)""".r
|
||||||
val (pre_time, in) = timed {
|
val (pre_time, in) = timed {
|
||||||
os.read.lines(input).map {
|
os.read
|
||||||
case REGEX(value, rest) => (value.toLong, longs(rest))
|
.lines(input)
|
||||||
}.toVector
|
.map { case REGEX(value, rest) => (value.toLong, longs(rest)) }
|
||||||
|
.toVector
|
||||||
}
|
}
|
||||||
|
|
||||||
val (p1_time, p1_solution) = timed {
|
val (p1_time, p1_solution) = timed {
|
||||||
in
|
in.filter(p => check(p._1, p._2, false)).map(_.head).sum
|
||||||
.filter((target, nums) => Searcher(target, nums, false).search())
|
|
||||||
.map(_.head)
|
|
||||||
.sum
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val (p2_time, p2_solution) = timed {
|
val (p2_time, p2_solution) = timed {
|
||||||
in
|
in.filter(p => check(p._1, p._2, true)).map(_.head).sum
|
||||||
.filter((target, nums) => Searcher(target, nums, true).search())
|
|
||||||
.map(_.head)
|
|
||||||
.sum
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(
|
(
|
||||||
|
|||||||
Reference in New Issue
Block a user