Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (defpackage :aoc-10
- (:use :cl))
- (in-package :aoc-10)
- (defun asteroids ()
- (with-open-file (in #P"input10")
- (loop for y from 0 while (listen in)
- nconc (loop for x from 0
- for char = (read-char in nil 'eof)
- until (or (eq char #\newline)
- (eq char 'eof))
- when (eq char #\#)
- collect (cons x y)))))
- (defun circular (lst)
- (setf (cdr (last lst)) lst)
- lst)
- (defun angle-between (a b)
- (let ((fpi (coerce pi 'single-float)))
- (mod (+ (/ fpi 2) (atan (- (cdr b) (cdr a))
- (- (car b) (car a))))
- (* fpi 2))))
- (defun distance-between (a b)
- (+ (abs (- (car a)
- (car b)))
- (abs (- (cdr a)
- (cdr b)))))
- (defun best-asteroid (asteroids)
- (loop for asteroid in asteroids
- with best-asteroid = nil
- for detected = (length
- (remove-duplicates
- (loop for other in asteroids
- unless (equal asteroid other)
- collect (angle-between asteroid other))))
- maximizing detected into most-detected
- do (when (= detected most-detected)
- (setq best-asteroid asteroid))
- finally (return (values best-asteroid
- most-detected))))
- (defun solve-challenge ()
- (nth-value 1 (best-asteroid (asteroids))))
- (defun group-consecutive (lst &optional (eq-test #'eq))
- (nreverse (reduce (lambda (acc cur)
- (if (funcall eq-test cur (caar acc))
- (cons (cons cur (car acc)) (rest acc))
- (progn (setf (car acc) (nreverse (car acc)))
- (cons (list cur) acc))))
- (rest lst)
- :initial-value (list (list (car lst))))))
- (defun solve-challenge-2 ()
- (destructuring-bind (x . y)
- (loop
- with asteroids = (asteroids)
- with station = (best-asteroid asteroids)
- with grouped = (group-consecutive
- (sort asteroids
- (lambda (a b)
- (let ((angle-a (angle-between station a))
- (angle-b (angle-between station b)))
- (if (= angle-a angle-b)
- (< (distance-between station a)
- (distance-between station b))
- (< angle-a angle-b)))))
- (lambda (a b)
- (= (angle-between station a)
- (angle-between station b))))
- repeat 200 for group in (circular grouped)
- for head = (pop group)
- finally (return head))
- (+ (* x 100) y)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement