summary refs log blame commit diff stats
path: root/day3.scm
blob: 21fadf020400491ba586f82ad9d3b07cdcceed43 (plain) (tree)






















































                                                                                                                         
#!/usr/bin/env gosh
(use file.util)
(use util.match)
(use scheme.set)
(use gauche.sequence)

(define (read-input filename)
  (let ((parse-entry 
          (lambda (x)
            (cons (string-ref x 0) 
                  (string->number (substring x 1 (string-length x)))))))
  (map (lambda (x) (map parse-entry x))
    (map (lambda (x) (string-split x ",")) 
         (file->string-list filename)))))

(define (get-path steps x y acc)
  (if (equal? '() steps) 
    acc
    (match (car steps)
      [`(#\U . ,distance) 
        (get-path (cdr steps) (+ x distance) y (append acc (map (lambda (dx) (cons (+ x dx) y) ) (iota distance 1))))]
      [`(#\D . ,distance)
        (get-path (cdr steps) (- x distance) y (append acc (map (lambda (dx) (cons (- x dx) y) ) (iota distance 1))))]
      [`(#\L . ,distance)
        (get-path (cdr steps) x (- y distance) (append acc (map (lambda (dy) (cons x (- y dy)) ) (iota distance 1))))]
      [`(#\R . ,distance)
        (get-path (cdr steps) x (+ y distance) (append acc (map (lambda (dy) (cons x (+ y dy)) ) (iota distance 1))))])))

(define (intersections steps)
  (set->list (apply set-intersection
                (map (lambda (list) (list->set equal-comparator (get-path list 0 0 '())))
                  steps))))

(define (part1 input)
  (letrec ((manhattan-distance
            (lambda (x)
              (+ (abs (car x)) (abs (cdr x))))))
    (car (sort (map manhattan-distance (intersections input))))))

(define (part2 input)
  (letrec ((first-wire 
            (get-path (car input) 0 0 '()))
           (second-wire 
            (get-path (cadr input) 0 0 '()))
           (linear-distance
            (lambda (x)
              (+ (find-index (lambda (y) (equal? x y)) first-wire)
                 (find-index (lambda (y) (equal? x y)) second-wire)
                 2))))
    (car (sort (map linear-distance (intersections input))))))

(define (main args)
  (let ((input (read-input "inputs/day3.txt")))
    (print (part1 input))
    (print (part2 input))))