aoc2020/23.rkt

71 lines
2.3 KiB
Racket
Raw Normal View History

#lang curly-fn racket
(require "scripts/aoc.rkt")
;; solution for day 23
(define (move-opt* input times)
(define items-map (for/vector ([i (in-range 0 (add1 (vector-length input)))])
(if (zero? i) #f (mcons i #f))))
(define fst (vector-ref items-map (vector-ref input 0)))
(define lst (vector-ref items-map (vector-ref input (sub1 (vector-length input)))))
(set-mcdr! lst fst)
(for ([i (in-range 1 (vector-length input))])
(define item (vector-ref items-map (vector-ref input i)))
(define prev (vector-ref items-map (vector-ref input (sub1 i))))
(set-mcdr! prev item))
(define total (vector-length input))
(define (do-round item-ref)
(define current (mcar item-ref))
(define top (mcdr item-ref))
(define bottom (mcdr (mcdr top)))
(define cset
(let loop ([d top] [cards (set)])
(if (eq? d bottom)
(set-add cards (mcar d))
(loop (mcdr d) (set-add cards (mcar d))))))
(set-mcdr! item-ref (mcdr bottom))
(set-mcdr! bottom #f)
(define wanted-value (let loop ([wanted (sub1 current)])
(cond [(zero? wanted) (loop total)]
[(set-member? cset wanted) (loop (sub1 wanted))]
[else wanted])))
(define wanted-ref (vector-ref items-map wanted-value))
(set-mcdr! bottom (mcdr wanted-ref))
(set-mcdr! wanted-ref top)
(mcdr item-ref))
(for/fold ([v fst]) ([i (in-range times)])
(do-round v))
(vector-ref items-map 1))
(define (part1 input)
;; TODO: What are the labels on the cups after cup 1?
;; unimplemented lol
(define res (move-opt* input 100))
(let loop ([x (mcdr res)])
(if (eq? x res)
""
(string-append (number->string (mcar x)) (loop (mcdr x))))))
(define (part2 input)
(define rst (for/vector ([x (in-range (add1 (vector-length input)) 1000001)]) x))
(define all (vector-append input rst))
(define res (move-opt* all 10000000))
(* (mcar (mcdr (mcdr res))) (mcar (mcdr res))))
;; parse input file
(define (parse fname)
(define input (file->string fname))
(list->vector (filter identity (map string->number (string-split input "")))))
(module+ main
(define input (parse "inputs/23"))
(answer 23 1 (time (part1 input)))
(answer 23 2 (time (part2 input)))
(displayln "meow"))