You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
aoc-racket/typed/day01.rkt

78 lines
2.3 KiB
Racket

#lang typed/racket
(require typed/rackunit)
(provide (all-defined-out))
(define up-char #\()
(define down-char #\))
(: make-matcher (-> Char (-> String Natural)))
(define (make-matcher c)
(λ((str : String)) (length (regexp-match* (regexp (format "\\~a" c)) str))))
(define get-ups (make-matcher up-char))
(define get-downs (make-matcher down-char))
(: get-destination (-> String Integer))
(define (get-destination str) (- (get-ups str) (get-downs str)))
(: q1 (-> String Integer))
(define (q1 str)
(get-destination str))
(: elevator-string->ints (-> String (Listof Integer)))
(define (elevator-string->ints str)
(for/list : (Listof Integer)
([c (in-string str)])
(if (equal? c up-char)
1
-1)))
(: q1-alt (-> String Integer))
(define (q1-alt str)
(apply + (elevator-string->ints str)))
(: in-basement? (-> (Listof Integer) Boolean))
(define (in-basement? movements)
(negative? (apply + movements)))
(: q2 (-> String Integer))
(define (q2 str)
(define relative-movements
(for/fold : (Listof Integer)
([movements-so-far : (Listof Integer) empty])
([c (in-string str)]
;#:break (in-basement? movements-so-far)
)
(if (in-basement? movements-so-far)
movements-so-far
(cons (get-destination (~a c)) movements-so-far))))
(length relative-movements))
(: q2-for/first (-> String (U #f Integer)))
(define (q2-for/first str)
(define basement-position
(let ([ints (elevator-string->ints str)])
(for/or : (U #f Integer) ;;bg first=>or
([idx (in-range (length ints))]
#:when (negative? (apply + (take ints idx))))
idx)))
basement-position)
(: q2-for/or (-> String (U #f Integer)))
(define (q2-for/or str)
(define basement-position
(let ([ints (elevator-string->ints str)])
(for/or : (U #f Integer)
([idx (in-range (length ints))])
(and (negative? (apply + (take ints idx))) idx))))
basement-position)
(module+ test
(define input-str (file->string "../day01-input.txt"))
(check-equal? (q1 input-str) 74)
(check-equal? (q1-alt input-str) 74)
(check-equal? (q2 input-str) 1795)
(check-equal? (q2-for/first input-str) 1795)
(check-equal? (q2-for/or input-str) 1795))