#!/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))))