From 3684b721d55cdf9e5b572f4c176981107577cb31 Mon Sep 17 00:00:00 2001 From: dave Date: Mon, 10 Dec 2018 22:42:57 -0800 Subject: [PATCH] day 11 --- 11/a.py | 46 +++++++++++++++++++++++++++++ 11/b.py | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) create mode 100755 11/a.py create mode 100755 11/b.py diff --git a/11/a.py b/11/a.py new file mode 100755 index 0000000..0c3c1b8 --- /dev/null +++ b/11/a.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 + + +SERIAL = 6878 + + +def getcelvalue(x, y): + """ + Find the fuel cell's rack ID, which is its X coordinate plus 10. + Begin with a power level of the rack ID times the Y coordinate. + Increase the power level by the value of the grid serial number (your puzzle input). + Set the power level to itself multiplied by the rack ID. + Keep only the hundreds digit of the power level (so 12345 becomes 3; numbers with no hundreds digit become 0). + Subtract 5 from the power level. + """ + rackid = x + 10 + pwr = rackid * y + pwr += SERIAL + pwr *= rackid + pwr = int(pwr / 100) % 10 + return pwr - 5 + + +def getregionvalue(x, y, size): + total = 0 + for xi in range(x, x + size): + for yi in range(y, y + size): + total += getcelvalue(xi, yi) + return total + + +def main(): + bestcoords = None + bestvalue = 0 + for x in range(1, 299): + for y in range(1, 299): + value = getregionvalue(x, y) + if value > bestvalue: + bestcoords = (x, y, ) + bestvalue = value + + print(bestcoords, bestvalue) + + +if __name__ == '__main__': + main() diff --git a/11/b.py b/11/b.py new file mode 100755 index 0000000..23f98cd --- /dev/null +++ b/11/b.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python3 + + +SERIAL = 6878 + + +def getcelvalue(x, y): + """ + Find the fuel cell's rack ID, which is its X coordinate plus 10. + Begin with a power level of the rack ID times the Y coordinate. + Increase the power level by the value of the grid serial number (your puzzle input). + Set the power level to itself multiplied by the rack ID. + Keep only the hundreds digit of the power level (so 12345 becomes 3; numbers with no hundreds digit become 0). + Subtract 5 from the power level. + """ + rackid = x + 10 + pwr = rackid * y + pwr += SERIAL + pwr *= rackid + pwr = int(pwr / 100) % 10 + return pwr - 5 + + +def getregionbestsizevalue(x, y, sizemax): + """ + Calculate each square size in passes as illustrated below + 1 2 3 4 + 2 2 3 4 + 3 3 3 4 + 4 4 4 4 + """ + # size with the highest total + bestsize = None + # score of the best size + bestsizevalue = -999999 + # maximum square we can fit + size = min(sizemax + 1 - x, sizemax + 1 - y) + # running total for this coordinate + total = 0 + for sz in range(0, size): + # the column/row we're currently iterating + xcol = x + sz + yrow = y + sz + # iteration counters + yit = yrow - 1 + xit = xcol + while yit >= y: + total += getcelvalue(xcol, yit) + yit -= 1 + while xit >= x: + total += getcelvalue(xit, yrow) + xit -= 1 + + if total > bestsizevalue: + bestsizevalue = total + bestsize = sz + + return (x, y, bestsize + 1, bestsizevalue) + + +from concurrent.futures import ProcessPoolExecutor, as_completed +from multiprocessing import cpu_count + + +def main(): + bestcoords = None + bestvalue = 0 + compl = 0 + todo = 300 * 300 + + with ProcessPoolExecutor(max_workers=cpu_count()) as pool: + futures = [] + for x in range(1, 300): + for y in range(1, 300): + futures.append(pool.submit(getregionbestsizevalue, x, y, 300, )) + + for f in as_completed(futures): + rx, ry, size, value = f.result() + if value > bestvalue: + bestvalue = value + bestcoords = (rx, ry, size) + print("new best:", bestcoords, "@", bestvalue) + compl += 1 + if compl % 100 == 0: + print(compl, "({}%)".format(int(compl / todo * 100))) + + print("Value:", bestvalue) + print("Solution:", ",".join([str(i) for i in bestcoords])) + + +if __name__ == '__main__': + main()