Initial commit
This commit is contained in:
commit
f242d2b0df
420 changed files with 62521 additions and 0 deletions
133
2020/day23/day23.c
Normal file
133
2020/day23/day23.c
Normal file
|
@ -0,0 +1,133 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define TEST_INPUT 389125467UL
|
||||
#define TEST_RESULT_10 92658374UL
|
||||
#define TEST_RESULT_100 67384529UL
|
||||
#define TEST_RESULT_PART2 149245887792UL
|
||||
#define INPUT 198753462UL
|
||||
|
||||
void print_cups(unsigned long cups[static 1], unsigned long start) {
|
||||
printf("(%lu) ", start);
|
||||
unsigned long c = cups[start];
|
||||
while (c != start) {
|
||||
printf("%lu ", c);
|
||||
if (c == 0) {
|
||||
printf("\nreached zero, abort!\n");
|
||||
return;
|
||||
}
|
||||
c = cups[c];
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
unsigned long move(size_t size, unsigned long cups[size], unsigned long current) {
|
||||
/* print_cups(cups, current); */
|
||||
/* printf("current: %lu\n", current); */
|
||||
|
||||
unsigned long picked_up[3] = {0};
|
||||
unsigned long c = current;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
picked_up[i] = cups[c];
|
||||
c = cups[c];
|
||||
}
|
||||
/* printf("pick up: %lu, %lu, %lu\n", picked_up[0], picked_up[1],
|
||||
* picked_up[2]); */
|
||||
|
||||
unsigned long dest = current - 1;
|
||||
while ((dest == 0) || (dest == picked_up[0]) || (dest == picked_up[1]) ||
|
||||
(dest == picked_up[2])) {
|
||||
dest = (size + dest - 1) % size;
|
||||
}
|
||||
/* printf("destination: %lu\n", dest); */
|
||||
|
||||
cups[current] = cups[picked_up[2]];
|
||||
cups[picked_up[2]] = cups[dest];
|
||||
cups[dest] = picked_up[0];
|
||||
|
||||
return cups[current];
|
||||
}
|
||||
|
||||
unsigned long *play(size_t size, unsigned long cups[size], unsigned long start,
|
||||
unsigned long steps) {
|
||||
unsigned long current = start;
|
||||
for (size_t i = 0; i < steps; ++i) {
|
||||
/* printf("-- move %zu --\n", i+1); */
|
||||
current = move(size, cups, current);
|
||||
}
|
||||
|
||||
return cups;
|
||||
}
|
||||
|
||||
unsigned long *init_cups(unsigned long n, size_t size) {
|
||||
unsigned long *cups = calloc(size, sizeof(unsigned long));
|
||||
unsigned long start = n / 100000000;
|
||||
|
||||
unsigned long q = n;
|
||||
unsigned long r = start;
|
||||
while (q != 0) {
|
||||
cups[q % 10] = r;
|
||||
r = q % 10;
|
||||
q = q / 10;
|
||||
}
|
||||
|
||||
if (size > 10) {
|
||||
cups[n % 10] = 10;
|
||||
for (size_t i = 10; i < size - 1; ++i) {
|
||||
cups[i] = i + 1;
|
||||
}
|
||||
cups[size - 1] = start;
|
||||
}
|
||||
|
||||
return cups;
|
||||
}
|
||||
|
||||
unsigned long run_part(int part, unsigned long n, unsigned long steps) {
|
||||
size_t size = 0;
|
||||
if (part == 1) {
|
||||
size = 10;
|
||||
} else if (part == 2) {
|
||||
size = 1000001;
|
||||
}
|
||||
unsigned long *cups = init_cups(n, size);
|
||||
unsigned long start = n / 100000000;
|
||||
play(size, cups, start, steps);
|
||||
|
||||
unsigned long res = 0;
|
||||
if (part == 1) {
|
||||
unsigned long c = cups[1];
|
||||
while (c != 1) {
|
||||
res = 10 * res + c;
|
||||
c = cups[c];
|
||||
}
|
||||
} else if (part == 2) {
|
||||
res = cups[1] * cups[cups[1]];
|
||||
}
|
||||
|
||||
free(cups);
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
unsigned long res = 0;
|
||||
|
||||
res = run_part(1, TEST_INPUT, 10);
|
||||
if (res != TEST_RESULT_10) {
|
||||
printf("Test 1: %lu (expected = %lu)\n", res, TEST_RESULT_10);
|
||||
}
|
||||
res = run_part(1, TEST_INPUT, 100);
|
||||
if (res != TEST_RESULT_100) {
|
||||
printf("Test 2: %lu (expected = %lu)\n", res, TEST_RESULT_100);
|
||||
}
|
||||
|
||||
printf("%lu\n", run_part(1, INPUT, 100));
|
||||
|
||||
res = run_part(2, TEST_INPUT, 10000000);
|
||||
if (res != TEST_RESULT_PART2) {
|
||||
printf("Test 3: %lu (expected = %lu)\n", res, TEST_RESULT_PART2);
|
||||
}
|
||||
|
||||
printf("%lu\n", run_part(2, INPUT, 10000000));
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
71
2020/day23/day23.rkt
Normal file
71
2020/day23/day23.rkt
Normal file
|
@ -0,0 +1,71 @@
|
|||
#lang racket
|
||||
|
||||
(module+ test
|
||||
(require rackunit))
|
||||
|
||||
(define (labelling->cups num)
|
||||
(define cups (make-vector 10 0))
|
||||
(define start (quotient num 100000000))
|
||||
(let loop ([prev start]
|
||||
[n num])
|
||||
(define-values (q r) (quotient/remainder n 10))
|
||||
(vector-set! cups r prev)
|
||||
(if (= q 0)
|
||||
(values cups start)
|
||||
(loop r q))))
|
||||
|
||||
(define (cups->labelling cups)
|
||||
(let loop ([idx (vector-ref cups 1)]
|
||||
[num 0])
|
||||
(if (= 1 idx)
|
||||
num
|
||||
(loop (vector-ref cups idx) (+ (* 10 num) idx)))))
|
||||
|
||||
(define (move! cups current)
|
||||
(define picked-up (let loop ([idxs (list (vector-ref cups current))]
|
||||
[i 0])
|
||||
(if (>= i 2)
|
||||
idxs
|
||||
(loop (cons (vector-ref cups (car idxs)) idxs) (add1 i)))))
|
||||
(define destination (let loop ([d (sub1 current)])
|
||||
(if (or (= 0 d) (member d picked-up))
|
||||
(loop (modulo (sub1 d) (vector-length cups)))
|
||||
d)))
|
||||
(vector-set! cups current (vector-ref cups (car picked-up)))
|
||||
(vector-set! cups (car picked-up) (vector-ref cups destination))
|
||||
(vector-set! cups destination (last picked-up))
|
||||
(vector-ref cups current))
|
||||
|
||||
(define (play! cups start steps)
|
||||
(for/fold ([current start])
|
||||
([i (in-range steps)])
|
||||
(move! cups current)))
|
||||
|
||||
(define (part1 input steps)
|
||||
(define-values (cups start) (labelling->cups input))
|
||||
(play! cups start steps)
|
||||
(cups->labelling cups))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part1 389125467 10) 92658374)
|
||||
(check-equal? (part1 389125467 100) 67384529))
|
||||
|
||||
(module+ main
|
||||
(displayln (part1 198753462 100)))
|
||||
|
||||
(define (part2 input)
|
||||
(define-values (base-cups start) (labelling->cups input))
|
||||
(define cups (make-vector 1000001 0))
|
||||
(vector-copy! cups 0 base-cups)
|
||||
(vector-set! cups (remainder input 10) 10)
|
||||
(for ([i (in-range 10 1000000)])
|
||||
(vector-set! cups i (add1 i)))
|
||||
(vector-set! cups 1000000 start)
|
||||
(play! cups start 10000000)
|
||||
(* (vector-ref cups 1) (vector-ref cups (vector-ref cups 1))))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part2 389125467) 149245887792))
|
||||
|
||||
(module+ main
|
||||
(displayln (part2 198753462)))
|
Loading…
Add table
Add a link
Reference in a new issue