59 lines
1.6 KiB
Scheme
59 lines
1.6 KiB
Scheme
(import (chicken io)
|
|
(chicken format)
|
|
srfi-1
|
|
srfi-42
|
|
srfi-152
|
|
matchable)
|
|
|
|
(define (read-input #!optional (port (current-input-port)))
|
|
(map (lambda (s) (map string->number (string-split (string-drop s 2) "..")))
|
|
(string-split (string-drop (read-line port) 13) ", ")))
|
|
|
|
(define-record state
|
|
x y vx vy)
|
|
|
|
(set! (record-printer state)
|
|
(lambda (st out)
|
|
(fprintf out "#,(state ~S ~S ~S ~S)" (state-x st) (state-y st) (state-vx st) (state-vy st))))
|
|
|
|
(define (too-far? target-area st)
|
|
(match-let ((((x1 x2) (y1 y2)) target-area)
|
|
(($ state x y vx vy) st))
|
|
(< y (min y1 y2))))
|
|
|
|
(define (in-target? target-area st)
|
|
(match-let ((((x1 x2) (y1 y2)) target-area)
|
|
(($ state x y vx vy) st))
|
|
(and (<= x1 x x2) (<= y1 y y2))))
|
|
|
|
(define (sign x)
|
|
(cond
|
|
((zero? x) 0)
|
|
((> x 0) 1)
|
|
((< x 0) -1)))
|
|
|
|
(define (step st)
|
|
(match-let ((($ state x y vx vy) st))
|
|
(make-state (+ x vx) (+ y vy)
|
|
(- vx (sign vx)) (- vy 1))))
|
|
|
|
(define (simulate target-area vx vy)
|
|
(let lp ((st (make-state 0 0 vx vy))
|
|
(prev-st (make-state 0 0 vx vy))
|
|
(max-height 0))
|
|
(cond
|
|
((in-target? target-area st) (list st (max max-height (state-y st))))
|
|
((too-far? target-area st) (list prev-st max-height))
|
|
(else (lp (step st) st (max max-height (state-y st)))))))
|
|
|
|
(define (find-max-height target-area)
|
|
(list-ec (: vx 0 500)
|
|
(: vy -100 1000)
|
|
(:let st (simulate target-area vx vy))
|
|
(if (in-target? target-area (car st)))
|
|
(cadr st)))
|
|
|
|
(let* ((target-area (read-input))
|
|
(max-heights (find-max-height target-area)))
|
|
(print (apply max max-heights))
|
|
(print (length max-heights)))
|