sol.scm (2086B) [raw]
1 #!/usr/local/bin/chicken-csi -ss 2 ;; the day, the functional programming, died! 3 ;; - Don McLean 4 ;; 5 ;; Parsing this one is gonna be hard without set! 6 (import srfi-69 ; hash tables 7 (chicken io) 8 (chicken sort) 9 (chicken irregex) 10 (chicken string)) 11 12 ; globals 13 (define cwd "") 14 15 (define sizes (make-hash-table)) 16 17 ; my first macro! :) 18 (define-syntax setnret! 19 (syntax-rules () 20 ((_ x y) 21 (begin (set! x y) x)))) 22 23 (define (filter pred lst) 24 (if (null? lst) 25 '() 26 (if (pred (car lst)) 27 (cons (car lst) (filter pred (cdr lst))) 28 (filter pred (cdr lst))))) 29 30 (define (parent dir) 31 (irregex-replace "[^/]*/$" dir "")) 32 33 (define (cd! dir) 34 (cond ((equal? dir "..") 35 (setnret! cwd (parent cwd))) 36 ((equal? dir "/") 37 (setnret! cwd "/")) 38 (else (setnret! cwd (string-append cwd dir "/"))))) 39 40 (define (add-size! n) 41 (define (add-size-dir! dir) 42 (let ((newsize (+ n (hash-table-ref/default sizes dir 0)))) 43 (hash-table-set! sizes dir newsize))) 44 ; TODO: would be more efficient to do this after all lines processed 45 (let loop ((dir cwd)) 46 (if (not (equal? dir "")) 47 (begin (add-size-dir! dir) 48 (loop (parent dir)))))) 49 50 (define (parse line) 51 (let ((parts (string-split line))) 52 (cond ((equal? (car parts) "$") 53 (cond ((equal? (cadr parts) "ls") 54 'no-op) 55 ((equal? (cadr parts) "cd") 56 (cd! (caddr parts))) 57 (else (error "Bad cmd " (cadr parts))))) 58 ((equal? (car parts) "dir") 59 'no-op) 60 (else (add-size! (string->number (car parts))))))) 61 62 (define (big-enough? n) 63 (>= n (- 30000000 64 (- 70000000 (hash-table-ref sizes "/"))))) 65 66 (define (main args) 67 (let ((lines (read-lines))) 68 (for-each parse lines) 69 ; (hash-table-for-each sizes (lambda (x n) (print x n))) 70 (print (apply + (filter (lambda (x) (<= x 100000)) (hash-table-values sizes)))) 71 (print (car (sort (filter big-enough? (hash-table-values sizes)) 72 <)))))