He is a barbarian, and thinks the customs of his tribe and island are the laws of nature.
Previous: Day 10 | Next: Day 12###AUTO-ACQUIRED DATA FOLLOWS…
archivist/day11.lisparchivist/day11.lisp
(asdf:load-system :split-sequence) (asdf:load-system :iterate) (asdf:load-system :alexandria) (defpackage \#:aoc-11 (:use \#:cl \#:split-sequence \#:iterate \#:alexandria)) (in-package \#:aoc-11) (defun getinput () (let ((in (uiop:read-file-lines "input"))) (make-array (list (length in) (length (car in))) :initial-contents in))) (defun cval (c) (cond ((eq c \#\\#) 1) ((eq c \#\L) 0) ((eq c \#\.) 0))) (defun getval (x y arr dims) (if (or (> x (1- (car dims))) (< x 0) (> y (1- (cadr dims))) (< y 0) ) 0 (cval (aref arr x y)))) (defun next (x y arr dims) (let ((sum (+ (getval (1+ x) y arr dims) (getval (1+ x) (1+ y) arr dims) (getval x (1+ y) arr dims) (getval (1- x) (1+ y) arr dims) (getval (1- x) y arr dims) (getval (1- x) (1- y) arr dims) (getval x (1- y) arr dims) (getval (1+ x) (1- y) arr dims) )) (state (aref arr x y))) (cond ((and (eq state \#\L) (eq sum 0)) \#\\#) ((and (eq state \#\\#) (>= sum 4)) \#\L) (t state)))) (defun part1 () (let\* ((grid (getinput)) (grid-2 (copy-array grid)) (dims (array-dimensions grid))) (do ((stable nil) (filled 0 )) ((eq stable t) filled) (setf stable t) (setf filled 0) (do ((i 0 (1+ i))) ((> i (1- (car dims)))) (do ((j 0 (1+ j))) ((> j (1- (cadr dims)))) (let ((new (next i j grid dims))) (if (not (eq new (aref grid i j))) (setf stable nil)) (setf (aref grid-2 i j) new) (if (equal \#\\# new) (incf filled))))) (setf grid (copy-array grid-2))))) (defun look (x y dirx diry arr dims) (if (or (> x (1- (car dims))) (< x 0) (> y (1- (cadr dims))) (< y 0)) 0 (if (or (eq (aref arr x y) \#\\#) (eq (aref arr x y) \#\L)) (cval (aref arr x y)) (look (+ x dirx) (+ y diry) dirx diry arr dims)))) (defun next-2 (x y arr dims) (let ((sum (+ (look (1+ x) y 1 0 arr dims) (look (1+ x) (1+ y) 1 1 arr dims) (look x (1+ y) 0 1 arr dims) (look (1- x) (1+ y) -1 1 arr dims) (look (1- x) y -1 0 arr dims) (look (1- x) (1- y) -1 -1 arr dims) (look x (1- y) 0 -1 arr dims) (look (1+ x) (1- y) 1 -1 arr dims))) (state (aref arr x y))) ;(format t "~a,~a: ~a~%" x y sum) (cond ((and (eq state \#\L) (eq sum 0)) \#\\#) ((and (eq state \#\\#) (>= sum 5)) \#\L) (t state)))) (defun part2 () (let\* ((grid (getinput)) (grid-2 (copy-array grid)) (dims (array-dimensions grid))) (do ((stable nil) (filled 0 )) ((eq stable t) filled) (setf stable t) (setf filled 0) (do ((i 0 (1+ i))) ((> i (1- (car dims)))) (do ((j 0 (1+ j))) ((> j (1- (cadr dims)))) (let ((new (next-2 i j grid dims))) (if (not (eq new (aref grid i j))) (setf stable nil)) (setf (aref grid-2 i j) new) (if (equal \#\\# new) (incf filled))))) (setf grid (copy-array grid-2)) )))
unknown-cnile/ucnile-day11.cunknown-cnile/ucnile-day11.c
\#include <stdlib.h> \#include <stdio.h> \#include <string.h> \#include <sys/types.h> \#include <sys/stat.h> \#include <fcntl.h> \#include <sys/mman.h> \#include <unistd.h> \#include <stdint.h> \#include <limits.h> void die(char \*str) { fprintf(stderr, "[ERROR] %s\n", str); exit(-1); } FILE \*map\_file(const char \*filename) { int fd; if ((fd = open(filename, O\_RDONLY)) == -1) die("failed to open file"); struct stat fd\_stat; if (fstat(fd, &fd\_stat) == -1) die("failed to stat file"); void \*data; // never unmapped, probably fine if ((data = mmap(NULL, fd\_stat.st\_size, PROT\_READ, MAP\_PRIVATE, fd, 0)) == MAP\_FAILED) die("failed to map file"); close(fd); return fmemopen(data, fd\_stat.st\_size, "r"); } \#define MAX\_X 128 \#define MAX\_Y 4096 uint8\_t data\_orig[MAX\_X\*MAX\_Y]; uint8\_t data\_1[MAX\_X\*MAX\_Y]; uint8\_t data\_2[MAX\_X\*MAX\_Y]; uint8\_t \*data\_cur = data\_orig; uint8\_t \*data\_nxt = data\_1; int row\_cnt = 0; \#define MAX\_LINE 512 \#define FLOOR 0 \#define EMPTY 1 \#define FULL 2 void restore() { data\_cur = data\_orig; data\_nxt = data\_1; } void swap() { data\_cur = (data\_cur == data\_1) ? data\_2 : data\_1; data\_nxt = (data\_nxt == data\_1) ? data\_2 : data\_1; } uint8\_t \*next\_seat(int x, int y, int dx, int dy, int is\_p1) { while (1) { x += dx; y += dy; if ((x < 0) || (x >= MAX\_X) || (y < 0) || (y >= row\_cnt)) return NULL; uint8\_t \*r = data\_cur + (y\*MAX\_X+x); if (\*r != FLOOR) return r; if (is\_p1) return NULL; } } int find\_adj(int is\_p1, int x, int y) { int acc = 0; for (int dx = -1; dx < 2; dx++) { for (int dy = -1; dy < 2; dy++) { if (dx | dy) { uint8\_t \*ptr = next\_seat(x, y, dx, dy, is\_p1); if (ptr && (\*ptr == FULL)) acc++; } } } return acc; } int tick(int is\_p1) { for (int y = 0; y < row\_cnt; y++) { for (int x = 0; x < MAX\_X; x++) { switch (data\_cur[y\*MAX\_X+x]) { case FLOOR: data\_nxt[y\*MAX\_X+x] = FLOOR; break; case EMPTY: data\_nxt[y\*MAX\_X+x] = find\_adj(is\_p1, x, y) ? EMPTY : FULL; break; case FULL: data\_nxt[y\*MAX\_X+x] = ((find\_adj(is\_p1, x, y) + is\_p1) >= 5) ? EMPTY : FULL; break; default: \_\_builtin\_trap(); } } } uint8\_t \*old\_nxt = data\_nxt; int r = !!memcmp(data\_cur, data\_nxt, row\_cnt\*MAX\_X); swap(); return r; } void prt() { for (int y = 0; y < row\_cnt; y++) { for (int x = 0; x < MAX\_X; x++) switch (data\_cur[y\*MAX\_X+x]) { case FLOOR: putchar(&\#39;.&\#39;); break; case EMPTY: putchar(&\#39;L&\#39;); break; case FULL: putchar(&\#39;@&\#39;); break; } putchar(&\#39;\n&\#39;); } } int cnt\_occ() { int acc = 0; for (int i = 0; i < MAX\_X\*row\_cnt; i++) { acc += data\_cur[i] == FULL; } return acc; } int main(int argc, char \*\*argv) { // read input FILE \*fd = map\_file("test.txt"); char line[MAX\_LINE]; while (fgets(line, MAX\_LINE, fd) != NULL) { for (int i = 0; line[i] > &\#39;\n&\#39;; i++) { if (i == MAX\_X) die("overflow"); uint8\_t v; switch (line[i]) { case &\#39;L&\#39;: v = EMPTY; break; case &\#39;\#&\#39;: v = FULL; break; default: v = FLOOR; break; } data\_orig[MAX\_X\*row\_cnt+i] = v; } row\_cnt++; } // part one while (tick(1)) {} printf("P1: %d\n", cnt\_occ()); restore(); // part two while (tick(0)) {} printf("P2: %d\n", cnt\_occ()); return 0; }