Last active
December 14, 2019 23:02
-
-
Save akkartik/94b8ab6526b312c836c3d6d281f23504 to your computer and use it in GitHub Desktop.
Advent 2019, day 3, problem 1
This file contains hidden or 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
(def parse (inst) | |
(with (dir inst.0 | |
mag (int (cut inst 1))) | |
(case dir | |
#\U (list 0 (* -1 mag)) | |
#\D (list 0 mag) | |
#\L (list (* -1 mag) 0) | |
#\R (list mag 0)))) | |
(def add (a b) | |
(map + a b)) | |
(def sign (x) | |
(if (is x 0) 0 | |
(> x 0) 1 | |
(< x 0) -1)) | |
(def dir (a) | |
(map sign a)) | |
(def mag (a) | |
(abs:a (if (is a.0 0) 1 | |
(is a.1 0) 0 | |
err "non-manhattan line"))) | |
(def draw-all-hash (init vectors) | |
(ret h (table) | |
(let curr copy.init | |
(each vector vectors | |
(with (n (mag vector) | |
increment (dir vector)) | |
(for i 1 (<= i n) ++.i | |
(= curr (add curr increment)) | |
(set h.curr))))))) | |
(def intersect (h1 h2) ; -> list | |
(accum acc | |
(each (k v) h1 | |
(if h2.k | |
(acc k))))) | |
(def manhattan-distance (x) | |
(+ (abs x.0) (abs x.1))) | |
(prn "reading") | |
(= line1* (map parse (tokens (readline) #\,))) | |
(= line2* (map parse (tokens (readline) #\,))) | |
(prn "drawing line 1") | |
(= h1 (draw-all-hash '(0 0) line1*)) | |
(prn "drawing line 2") | |
(= h2 (draw-all-hash '(0 0) line2*)) | |
(prn "intersecting") | |
(= cands (intersect h1 h2)) | |
(prn:best (compare < manhattan-distance) cands) |
This file contains hidden or 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
import sys | |
def parse(inst): | |
dir = inst[0] | |
mag = int(inst[1:]) | |
if dir == 'U': return (0, -mag) | |
if dir == 'D': return (0, mag) | |
if dir == 'L': return (-mag, 0) | |
if dir == 'R': return (mag, 0) | |
raise 'bad inst {}'.format(inst) | |
def add(a, b): | |
return (a[0]+b[0], a[1]+b[1]) | |
def sign(x): | |
if x == 0: return 0 | |
if x > 0: return 1 | |
return -1 | |
def dir(x, y): | |
return (sign(x), sign(y)) | |
def mag(x, y): | |
if x == 0: return abs(y) | |
if y == 0: return abs(x) | |
raise "non-manhattan line" | |
# little non-idiomatic: excludes 'init', but not final point | |
def draw(init, vector): | |
n = mag(*vector) | |
inc = dir(*vector) | |
curr = init | |
for _ in range(1, n+1): # 1's for documentation | |
curr = add(curr, inc) | |
yield curr | |
def draw_all(init, vectors): | |
curr = init | |
for vector in vectors: | |
for v in draw(curr, vector): | |
yield v | |
curr = add(curr, vector) | |
def manhattan_distance(x): | |
return abs(x[0]) + abs(x[1]) | |
line1 = map(parse, sys.stdin.readline().split(',')) | |
line2 = map(parse, sys.stdin.readline().split(',')) | |
line1_points = set(draw_all([0, 0], line1)) | |
line2_points = set(draw_all([0, 0], line2)) | |
print(min(line1_points.intersection(line2_points), key=manhattan_distance)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To run, download the input set into 3.in, and then: