#!/usr/local/bin/chicken-csi -ss (import (chicken string) (chicken io)) (define (parse-line l) (let ((parts (string-split l))) (cond ((equal? (car parts) "noop") (list (string->symbol (car parts)))) ((equal? (car parts) "addx") (list (string->symbol (car parts)) (string->number (cadr parts)))) (else "Error: bad line" l)))) (define (simul cmds) (let loop ((cmds cmds) (x 1)) (if (null? cmds) '() (let ((cmd (car cmds))) (cond ((eq? (car cmd) 'noop) (cons x (loop (cdr cmds) x))) ((eq? (car cmd) 'addx) ; takes 2 counts, so append x THEN append x + val (let ((x2 (+ (cadr cmd) x))) (cons x (cons x2 (loop (cdr cmds) x2))))) (else "Bad cmd " cmd)))))) ; x is 3-wide, covers (x - 1, x, x + 1), (x + 39 , x + 40, x + 41), ... (define (overlaps? x c) ; NOTE: need to add 1 to X since cycle is 1 indexed (>= 1 (abs (- (add1 x) (modulo c 40))))) (define (part-1 sim) (let loop ((i 1) (sim sim) (count 0)) ; (print (list i (car sim) count)) (if (null? sim) count (if (= 0 (modulo (+ i 20) 40)) (loop (add1 i) (cdr sim) (+ count (* i (car sim)))) (loop (add1 i) (cdr sim) count))))) (define (part-2 sim) (let loop ((i 0) (sim sim)) (if (null? sim) 'done (begin (and (= 0 (modulo i 40)) (newline)) (if (overlaps? (car sim) (add1 i)) (display "#") (display " ")) (loop (add1 i) (cdr sim)))))) (define (main args) (let* ((lines (read-lines)) (cmds (map parse-line lines)) (x-vals (cons 1 (simul cmds)))) ; NOTE: need first val (print (part-1 x-vals)) (part-2 x-vals)))