#lang racket (require "../lib.rkt") (define input (problem-input 10)) (define width (string-length (car input))) (define height (length input)) (define (out-of-range? x y) (or (< x 0) (< y 0) (>= x width) (>= y height))) (define (coprime? i j) (= 1 (gcd i j))) (define (offsets x y) (let ([is (range (negate x) (- width x))] [js (range (negate y) (- height y))]) (filter (uncurry coprime?) (cartesian-product is js)))) (define (asteroid? x y) (define row (list-ref input y)) (eq? #\# (string-ref row x))) (define (asteroid-offset x y i j) (let loop ([m 1]) (let ([x* (+ x (* i m))] [y* (+ y (* j m))]) (cond [(out-of-range? x* y*) #f] [(asteroid? x* y*) (list x* y*)] [else (loop (add1 m))])))) (define (asteroids x y) (filter-map (uncurry (curry asteroid-offset x y)) (offsets x y))) (define-values (part1 location in-view) (let* ([cols (range width)] [rows (range height)] [locations (filter (uncurry asteroid?) (cartesian-product cols rows))] [in-views (map (uncurry asteroids) locations)] [counts (map length in-views)] [maximum (apply max counts)] [index (index-of counts maximum)]) (values maximum (list-ref locations index) (list-ref in-views index)))) (define (offset