diff options
Diffstat (limited to '15')
| -rw-r--r-- | 15/2.rkt | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/15/2.rkt b/15/2.rkt new file mode 100644 index 0000000..1825a65 --- /dev/null +++ b/15/2.rkt @@ -0,0 +1,76 @@ +#lang racket + +(define line + (call-with-input-file "input" + (λ (fp) (read-line fp)))) + +(define strs (string-split line ",")) + +(define (parse-len str) + (define str-len (string-length str)) + (define last-char (string-ref str (- str-len 1))) + (if (char=? #\- last-char) + (list (substring str 0 (- str-len 1)) #\-) + (let () + (define tp (string-split str "=")) + (list (car tp) #\= (string->number (cadr tp)))))) + +(define (calc-hash str) + (define len (string-length str)) + (let loop ((i 0) (cur 0)) + (if (< i len) + (let () + (define c (string-ref str i)) + (define ascii (char->integer c)) + (loop (+ i 1) (modulo (* 17 (+ cur ascii)) 256))) + cur))) + +(define (remove-len lst lable) + (let loop ((cur lst) (ret '())) + (if (null? cur) + (reverse ret) + (if (equal? (caar cur) lable) + (loop (cdr cur) ret) + (loop (cdr cur) (cons (car cur) ret)))))) + +(define (insert-len lst lable value) + (let loop ((cur lst) (ret '()) (inserted #f)) + (if (null? cur) + (if inserted + (reverse ret) + (reverse (cons (cons lable value) ret))) + (if (equal? (caar cur) lable) + (loop (cdr cur) (cons (cons lable value) ret) #t) + (loop (cdr cur) (cons (car cur) ret) inserted))))) + +(define boxes (make-vector 256 '())) + +(define lens (map parse-len strs)) + +(define (process-len len box) + (if (char=? #\- (cadr len)) + (remove-len box (car len)) + (insert-len box (car len) (caddr len)))) + +;; do lens installation +(let loop ((cur lens)) + (if (null? cur) + (void) + (let () + (define lable (caar cur)) + (define hash-num (calc-hash lable)) + (vector-set! boxes hash-num (process-len (car cur) (vector-ref boxes hash-num))) + (loop (cdr cur))))) + +;; calculate focusing power +(let loop ((i 1) (ret 0)) + (if (> i 256) + ret + (let () + (define box (vector-ref boxes (- i 1))) + (define sum + (let loop ((j 1) (cur box) (s 0)) + (if (null? cur) + s + (loop (+ j 1) (cdr cur) (+ s (* i j (cdar cur))))))) + (loop (+ i 1) (+ ret sum))))) |
