Skip to content

Instantly share code, notes, and snippets.

@akkartik
Last active December 14, 2019 23:02
Show Gist options
  • Save akkartik/94b8ab6526b312c836c3d6d281f23504 to your computer and use it in GitHub Desktop.
Save akkartik/94b8ab6526b312c836c3d6d281f23504 to your computer and use it in GitHub Desktop.
Advent 2019, day 3, problem 1
(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)
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))
@akkartik
Copy link
Author

akkartik commented Dec 14, 2019

To run, download the input set into 3.in, and then:

$ python 3-1.py < 3.in
$ arc.sh 3-1.arc < 3.in  # https://github.com/arclanguage/anarki

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment