$ cat 13a.rkt
#lang racket
(provide
example-input
fold-on-constant-x
fold-on-constant-y
read-input
)
(define (aoc-13a input)
(let-values (((points folds) (read-input input)))
(if (null? folds)
0
(let ((fold (car folds)))
(set-count
((if (string=? (car fold) "x")
fold-on-constant-x
fold-on-constant-y) points (cdr fold)))))))
(define (fold-on-constant-x points v)
(list->set
(set-map
points
(lambda (p)
(let ((x (car p)))
(if (> x v)
(cons (- (* v 2) x) (cdr p))
p))))))
(define (fold-on-constant-y points v)
(list->set
(set-map
points
(lambda (p)
(let ((y (cdr p)))
(if (> y v)
(cons (car p) (- (* v 2) y))
p))))))
(define (read-folds input)
(define (read-fold line)
(let ((fold (string-split (caddr (string-split line " ")) "=")))
(cons (car fold) (string->number (cadr fold)))))
(let loop ((input (string-split input "\n")) (folds '()))
(if (null? input)
(reverse folds)
(loop (cdr input) (cons (read-fold (car input)) folds)))))
(define (read-points input)
(define (read-point line)
(let ((coords (map string->number (string-split line ","))))
(cons (car coords) (cadr coords))))
(list->set
(let loop ((input (string-split input "\n")) (points '()))
(if (null? input)
points
(let ((line (car input)))
(if (non-empty-string? line)
(loop (cdr input) (cons (read-point line) points))
points))))))
(define (split-input input)
(let ((split (string-split input "\n\n")))
(if (not (= (length split) 2))
(error 'split-input
"expecting two pieces of split input, got ~s" (length split))
(values (car split) (cadr split)))))
(define (read-input input)
(let-values (((points folds) (split-input input)))
(values (read-points points) (read-folds folds))))
(define example-input
(string-join '(
"6,10"
"0,14"
"9,10"
"0,3"
"10,4"
"4,11"
"6,0"
"6,12"
"4,1"
"0,13"
"10,12"
"3,4"
"3,0"
"8,4"
"1,10"
"2,14"
"8,10"
"9,0"
""
"fold along y=7"
"fold along x=5"
)
"\n"))
(module+ main
(require "aoc.rkt")
(aoc-solve-problem 13 (lambda (x) x) (list aoc-13a)))
(module+ test
(require rackunit)
(check-eq? (aoc-13a "0,0\n0,4\n\nfold along y=2") 1)
(check-eq? (aoc-13a "0,0\n0,3\n\nfold along y=2") 2)
(check-eq? (aoc-13a "0,0\n4,0\n\nfold along x=2") 1)
(check-eq? (aoc-13a "0,0\n3,0\n\nfold along x=2") 2)
(check-eq? (aoc-13a example-input) 17)
)
$ raco test 13a.rkt
raco test: (submod "13a.rkt" test)
5 tests passed
$