Update
This commit is contained in:
parent
b45596b6a8
commit
c31d6e53c2
14 changed files with 1022 additions and 0 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -9,3 +9,4 @@
|
||||||
*.prof
|
*.prof
|
||||||
|
|
||||||
__pycache__
|
__pycache__
|
||||||
|
target/
|
||||||
|
|
52
Day01/Day1A.s
Normal file
52
Day01/Day1A.s
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
extern printf
|
||||||
|
extern scanf
|
||||||
|
|
||||||
|
;;;;;;;;;;;;
|
||||||
|
;;; TEXT ;;;
|
||||||
|
;;;;;;;;;;;;
|
||||||
|
section .text
|
||||||
|
global main
|
||||||
|
main:
|
||||||
|
sub rsp, 8
|
||||||
|
|
||||||
|
xor rcx, rcx
|
||||||
|
|
||||||
|
.loop:
|
||||||
|
lea rdi, [rel format]
|
||||||
|
lea rsi, [rel operation]
|
||||||
|
lea rdx, [rel count]
|
||||||
|
xor ax, ax
|
||||||
|
call scanf
|
||||||
|
|
||||||
|
xor rax, rax
|
||||||
|
mov eax, [rel count]
|
||||||
|
cmp byte [rel operation], '+'
|
||||||
|
je .add
|
||||||
|
neg rax
|
||||||
|
.add:
|
||||||
|
add rcx, rax
|
||||||
|
|
||||||
|
push rcx
|
||||||
|
lea rdi, [rel message]
|
||||||
|
mov rsi, rcx
|
||||||
|
xor ax, ax
|
||||||
|
call printf
|
||||||
|
pop rcx
|
||||||
|
|
||||||
|
jmp .loop
|
||||||
|
|
||||||
|
|
||||||
|
add rsp, 8
|
||||||
|
ret
|
||||||
|
|
||||||
|
;;;;;;;;;;;;
|
||||||
|
;;; DATA ;;;
|
||||||
|
;;;;;;;;;;;;
|
||||||
|
section .data
|
||||||
|
format: db "%c%d",0
|
||||||
|
message: db "%d",10,0
|
||||||
|
|
||||||
|
section .bss
|
||||||
|
buffer: resb 64
|
||||||
|
operation: resb 1
|
||||||
|
count: resb 4
|
128
Day19/Day19A.c
Normal file
128
Day19/Day19A.c
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t opcode;
|
||||||
|
uint32_t a, b, c;
|
||||||
|
} Instruction;
|
||||||
|
|
||||||
|
Instruction instructions[1024];
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ADDR, ADDI, MULR, MULI, BANR, BANI, BORR, BORI,
|
||||||
|
SETR, SETI, GTIR, GTRI, GTRR, EQIR, EQRI, EQRR,
|
||||||
|
IP,
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *names[] = {
|
||||||
|
"addr", "addi", "mulr", "muli", "banr", "bani", "borr", "bori",
|
||||||
|
"setr", "seti", "gtir", "gtri", "gtrr", "eqir", "eqri", "eqrr",
|
||||||
|
"#ip",
|
||||||
|
};
|
||||||
|
|
||||||
|
int instruction_read(Instruction *i, FILE *file) {
|
||||||
|
char mnemonic[64] = {0};
|
||||||
|
size_t count = fscanf(file, "%s %u %u %u", mnemonic, &i->a, &i->b, &i->c);
|
||||||
|
if (count != 4 && count != 2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (int opcode = 0; opcode <= IP; opcode++) {
|
||||||
|
if (strcmp(names[opcode], mnemonic) == 0) {
|
||||||
|
i->opcode = opcode;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("Unknown mnemonic '%s'\n", mnemonic);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void instruction_execute(const Instruction *i, uint32_t *r, uint32_t *ip, uint32_t *ip_r) {
|
||||||
|
if (*ip_r != -1)
|
||||||
|
r[*ip_r] = *ip;
|
||||||
|
|
||||||
|
switch (i->opcode) {
|
||||||
|
// Addition
|
||||||
|
case ADDR: r[i->c] = r[i->a] + r[i->b]; break;
|
||||||
|
case ADDI: r[i->c] = r[i->a] + i->b; break;
|
||||||
|
|
||||||
|
// Multiplication
|
||||||
|
case MULR: r[i->c] = r[i->a] * r[i->b]; break;
|
||||||
|
case MULI: r[i->c] = r[i->a] * i->b; break;
|
||||||
|
|
||||||
|
// Bitwise AND
|
||||||
|
case BANR: r[i->c] = (r[i->a] & r[i->b]); break;
|
||||||
|
case BANI: r[i->c] = (r[i->a] & i->b); break;
|
||||||
|
|
||||||
|
// Bitwise OR
|
||||||
|
case BORR: r[i->c] = (r[i->a] | r[i->b]); break;
|
||||||
|
case BORI: r[i->c] = (r[i->a] | i->b); break;
|
||||||
|
|
||||||
|
// Assignment
|
||||||
|
case SETR: r[i->c] = r[i->a]; break;
|
||||||
|
case SETI: r[i->c] = i->a; break;
|
||||||
|
|
||||||
|
// Greater-than testing
|
||||||
|
case GTIR: r[i->c] = (i->a > r[i->b]); break;
|
||||||
|
case GTRI: r[i->c] = (r[i->a] > i->b); break;
|
||||||
|
case GTRR: r[i->c] = (r[i->a] > r[i->b]); break;
|
||||||
|
|
||||||
|
// Equality testing
|
||||||
|
case EQIR: r[i->c] = (i->a == r[i->b]); break;
|
||||||
|
case EQRI: r[i->c] = (r[i->a] == i->b); break;
|
||||||
|
case EQRR: r[i->c] = (r[i->a] == r[i->b]); break;
|
||||||
|
|
||||||
|
case IP: *ip_r = i->a; *ip -= 1; break;
|
||||||
|
|
||||||
|
default: assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*ip_r != -1)
|
||||||
|
*ip = r[*ip_r];
|
||||||
|
|
||||||
|
*ip += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
if (argc != 2) {
|
||||||
|
printf("Usage: %s [input]\n", argv[0]);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *file = fopen(argv[1], "r");
|
||||||
|
|
||||||
|
uint32_t registers[6] = {0};
|
||||||
|
uint32_t ip_reg = -1;
|
||||||
|
size_t instr_count = 0;
|
||||||
|
for (instr_count = 0; instr_count < 1024 && instruction_read(&instructions[instr_count], file); instr_count++) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("opcode: %2d (%s), a: %d, b: %d, c: %d\n", instructions[instr_count].opcode,
|
||||||
|
names[instructions[instr_count].opcode], instructions[instr_count].a, instructions[instr_count].b,
|
||||||
|
instructions[instr_count].c);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < instr_count;) {
|
||||||
|
Instruction instruction = instructions[i];
|
||||||
|
#ifdef DEBUG
|
||||||
|
const char *name = names[instruction.opcode];
|
||||||
|
printf("opcode: %2d (%s), a: %d, b: %d, c: %d\n", instruction.opcode,
|
||||||
|
name, instruction.a, instruction.b, instruction.c);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
instruction_execute(&instruction, registers, &i, &ip_reg);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("registers: %d %d %d %d %d %d\n", registers[0], registers[1],
|
||||||
|
registers[2], registers[3], registers[4], registers[5]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
printf("%d\n", registers[0]);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
130
Day20/Day20.py
Normal file
130
Day20/Day20.py
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
from collections import deque
|
||||||
|
from pprint import pprint
|
||||||
|
|
||||||
|
NORTH = 1
|
||||||
|
EAST = 2
|
||||||
|
SOUTH = 4
|
||||||
|
WEST = 8
|
||||||
|
|
||||||
|
ROOT = 0
|
||||||
|
IN_PARENS = 1
|
||||||
|
SKIPPING = 2
|
||||||
|
|
||||||
|
start_pos = 200, 200
|
||||||
|
grid = [[0] * start_pos[0] * 2 for _ in range(start_pos[1] * 2)]
|
||||||
|
|
||||||
|
min_x, max_x = start_pos
|
||||||
|
min_y, max_y = start_pos
|
||||||
|
|
||||||
|
|
||||||
|
def print_grid(x_=None, y_=None):
|
||||||
|
for y in range(min_y, max_y + 1):
|
||||||
|
for x in range(min_x, max_x + 1):
|
||||||
|
print(end="@")
|
||||||
|
print(end="-" if grid[y][x] & NORTH else "@")
|
||||||
|
print("#")
|
||||||
|
|
||||||
|
for x in range(min_x, max_x + 1):
|
||||||
|
print(end="|" if grid[y][x] & WEST else "@")
|
||||||
|
if (x, y) == start_pos:
|
||||||
|
print(end="X")
|
||||||
|
elif x == x_ and y == y_:
|
||||||
|
print(end=".")
|
||||||
|
else:
|
||||||
|
print(end=" ")
|
||||||
|
print("@")
|
||||||
|
print("@" * ((max_x - min_x) * 2 + 3))
|
||||||
|
|
||||||
|
|
||||||
|
def parse_input(inp):
|
||||||
|
global min_x, max_x, min_y, max_y
|
||||||
|
|
||||||
|
# print(inp, end="\n\n")
|
||||||
|
# print("\033[2J\033[;H")
|
||||||
|
stack = [(0, start_pos[0], start_pos[1])]
|
||||||
|
while stack:
|
||||||
|
# print("===================================")
|
||||||
|
# print(stack, end=" -> ")
|
||||||
|
start, x, y = stack.pop()
|
||||||
|
# print(start)
|
||||||
|
|
||||||
|
depth = 0
|
||||||
|
skip_to_end = False
|
||||||
|
for i in range(start, len(inp)):
|
||||||
|
c = inp[i]
|
||||||
|
|
||||||
|
if depth == 0 and not skip_to_end:
|
||||||
|
# print(f"{depth} {inp[:i]}\033[4;3{depth+1}m{inp[i]}\033[0m{inp[i+1:]} ({x:>2},{y:>2}) -> ", end="")
|
||||||
|
|
||||||
|
if c == "N": grid[y][x] |= NORTH; y -= 1; grid[y][x] |= SOUTH
|
||||||
|
elif c == "E": grid[y][x] |= EAST; x += 1; grid[y][x] |= WEST
|
||||||
|
elif c == "S": grid[y][x] |= SOUTH; y += 1; grid[y][x] |= NORTH
|
||||||
|
elif c == "W": grid[y][x] |= WEST; x -= 1; grid[y][x] |= EAST
|
||||||
|
|
||||||
|
if x < min_x: min_x = x
|
||||||
|
if x > max_x: max_x = x
|
||||||
|
if y < min_y: min_y = y
|
||||||
|
if y > max_y: max_y = y
|
||||||
|
|
||||||
|
# print(f"({x:>2},{y:>2})")
|
||||||
|
# print_grid(x, y)
|
||||||
|
# print()
|
||||||
|
|
||||||
|
|
||||||
|
if c == "(" and not skip_to_end:
|
||||||
|
if depth == 0:
|
||||||
|
stack.append((i + 1, x, y))
|
||||||
|
depth += 1
|
||||||
|
elif c == "|" and not skip_to_end:
|
||||||
|
if depth == 1:
|
||||||
|
stack.append((i + 1, x, y))
|
||||||
|
elif depth == 0:
|
||||||
|
skip_to_end = True
|
||||||
|
elif c == ")":
|
||||||
|
depth -= 1
|
||||||
|
if depth == -1:
|
||||||
|
skip_to_end = False
|
||||||
|
break
|
||||||
|
|
||||||
|
# print()
|
||||||
|
# print("\033[0;0H", end="")
|
||||||
|
# print_grid()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def bfs():
|
||||||
|
pos = start_pos
|
||||||
|
|
||||||
|
queue = deque([(pos, 0)])
|
||||||
|
seen = set()
|
||||||
|
lengths = []
|
||||||
|
max_len = 0
|
||||||
|
long_paths = 0
|
||||||
|
|
||||||
|
while queue:
|
||||||
|
(x, y), depth = queue.popleft()
|
||||||
|
if (x, y) in seen:
|
||||||
|
continue
|
||||||
|
seen.add((x, y))
|
||||||
|
|
||||||
|
if depth > max_len:
|
||||||
|
max_len = depth
|
||||||
|
if depth >= 1000:
|
||||||
|
long_paths += 1
|
||||||
|
|
||||||
|
if grid[y][x] & WEST: queue.append(((x - 1, y), depth + 1))
|
||||||
|
if grid[y][x] & EAST: queue.append(((x + 1, y), depth + 1))
|
||||||
|
if grid[y][x] & NORTH: queue.append(((x, y - 1), depth + 1))
|
||||||
|
if grid[y][x] & SOUTH: queue.append(((x, y + 1), depth + 1))
|
||||||
|
|
||||||
|
print("part 1:", max_len)
|
||||||
|
print("part 2:", long_paths)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
inp = input()
|
||||||
|
parse_input(inp[1:-1])
|
||||||
|
bfs()
|
||||||
|
|
||||||
|
|
||||||
|
main()
|
184
Day21/Day21A.cpp
Normal file
184
Day21/Day21A.cpp
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <climits>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t opcode;
|
||||||
|
int32_t a, b, c;
|
||||||
|
} Instruction;
|
||||||
|
|
||||||
|
Instruction instructions[1024];
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ADDR, ADDI, MULR, MULI, BANR, BANI, BORR, BORI,
|
||||||
|
SETR, SETI, GTIR, GTRI, GTRR, EQIR, EQRI, EQRR,
|
||||||
|
IP,
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *names[] = {
|
||||||
|
"addr", "addi", "mulr", "muli", "banr", "bani", "borr", "bori",
|
||||||
|
"setr", "seti", "gtir", "gtri", "gtrr", "eqir", "eqri", "eqrr",
|
||||||
|
"#ip",
|
||||||
|
};
|
||||||
|
|
||||||
|
int instruction_read(Instruction *i, FILE *file) {
|
||||||
|
char mnemonic[64] = {0};
|
||||||
|
size_t count = fscanf(file, "%s %u %u %u", mnemonic, &i->a, &i->b, &i->c);
|
||||||
|
if (count != 4 && count != 2)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (int opcode = 0; opcode <= IP; opcode++) {
|
||||||
|
if (strcmp(names[opcode], mnemonic) == 0) {
|
||||||
|
i->opcode = opcode;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("Unknown mnemonic '%s'\n", mnemonic);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void instruction_execute(const Instruction *i, int32_t *r, int32_t *ip, int32_t *ip_r) {
|
||||||
|
if (*ip_r != -1)
|
||||||
|
r[*ip_r] = *ip;
|
||||||
|
|
||||||
|
switch (i->opcode) {
|
||||||
|
// Addition
|
||||||
|
case ADDR: r[i->c] = r[i->a] + r[i->b]; break;
|
||||||
|
case ADDI: r[i->c] = r[i->a] + i->b; break;
|
||||||
|
|
||||||
|
// Multiplication
|
||||||
|
case MULR: r[i->c] = r[i->a] * r[i->b]; break;
|
||||||
|
case MULI: r[i->c] = r[i->a] * i->b; break;
|
||||||
|
|
||||||
|
// Bitwise AND
|
||||||
|
case BANR: r[i->c] = (r[i->a] & r[i->b]); break;
|
||||||
|
case BANI: r[i->c] = (r[i->a] & i->b); break;
|
||||||
|
|
||||||
|
// Bitwise OR
|
||||||
|
case BORR: r[i->c] = (r[i->a] | r[i->b]); break;
|
||||||
|
case BORI: r[i->c] = (r[i->a] | i->b); break;
|
||||||
|
|
||||||
|
// Assignment
|
||||||
|
case SETR: r[i->c] = r[i->a]; break;
|
||||||
|
case SETI: r[i->c] = i->a; break;
|
||||||
|
|
||||||
|
// Greater-than testing
|
||||||
|
case GTIR: r[i->c] = (i->a > r[i->b]); break;
|
||||||
|
case GTRI: r[i->c] = (r[i->a] > i->b); break;
|
||||||
|
case GTRR: r[i->c] = (r[i->a] > r[i->b]); break;
|
||||||
|
|
||||||
|
// Equality testing
|
||||||
|
case EQIR: r[i->c] = (i->a == r[i->b]); break;
|
||||||
|
case EQRI: r[i->c] = (r[i->a] == i->b); break;
|
||||||
|
case EQRR: r[i->c] = (r[i->a] == r[i->b]); break;
|
||||||
|
|
||||||
|
case IP: *ip_r = i->a; *ip -= 1; break;
|
||||||
|
|
||||||
|
default: assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*ip_r != -1)
|
||||||
|
*ip = r[*ip_r];
|
||||||
|
|
||||||
|
*ip += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
setlocale(LC_NUMERIC, "");
|
||||||
|
if (argc != 2) {
|
||||||
|
printf("Usage: %s [input]\n", argv[0]);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *file = fopen(argv[1], "r");
|
||||||
|
|
||||||
|
int32_t jump_regs[6] = {-1};
|
||||||
|
int32_t registers[6] = {INT_MAX, 0};
|
||||||
|
int32_t ip_reg = -1;
|
||||||
|
size_t instr_count = 0;
|
||||||
|
for (instr_count = 0; instr_count < 1024 && instruction_read(&instructions[instr_count], file); instr_count++) {
|
||||||
|
if (instructions[instr_count].opcode == IP) {
|
||||||
|
ip_reg = instructions[instr_count].a;
|
||||||
|
instr_count -= 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("[%2zu] %s %d %d %d\n", instr_count, names[instructions[instr_count].opcode],
|
||||||
|
instructions[instr_count].a, instructions[instr_count].b,
|
||||||
|
instructions[instr_count].c);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
std::unordered_set<size_t> breakpoints;
|
||||||
|
bool stepping = true;
|
||||||
|
|
||||||
|
uint64_t instructions_executed = 0;
|
||||||
|
for (int32_t i = 0; i < instr_count;) {
|
||||||
|
Instruction instruction = instructions[i];
|
||||||
|
|
||||||
|
if (breakpoints.find(i) != breakpoints.end())
|
||||||
|
stepping = true;
|
||||||
|
|
||||||
|
if (stepping) {
|
||||||
|
const char *name = names[instruction.opcode];
|
||||||
|
printf("[%2d] \033[33m%s %d %d %d\033[0m\r", i,
|
||||||
|
name, instruction.a, instruction.b, instruction.c);
|
||||||
|
}
|
||||||
|
instruction_execute(&instruction, registers, &i, &ip_reg);
|
||||||
|
if (stepping) {
|
||||||
|
printf("\033[30C[%d, %d, %d, %d, %d, %d]\n", registers[0], registers[1],
|
||||||
|
registers[2], registers[3], registers[4], registers[5]);
|
||||||
|
|
||||||
|
read:
|
||||||
|
printf("> ");
|
||||||
|
char c;
|
||||||
|
scanf(" %c", &c);
|
||||||
|
switch (c) {
|
||||||
|
case 0:
|
||||||
|
printf("q\n");
|
||||||
|
[[fallthrough]];
|
||||||
|
|
||||||
|
case 'q':
|
||||||
|
i = instr_count;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'c':
|
||||||
|
stepping = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'b':
|
||||||
|
breakpoints.insert(i);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\n':
|
||||||
|
goto read;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("Unknown command '%c'\n", c);
|
||||||
|
goto read;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
instructions_executed += 1;
|
||||||
|
if (!stepping && instructions_executed % (1 << 20) == 0) {
|
||||||
|
printf("%'lu %d ", instructions_executed, i);
|
||||||
|
printf("[%'d, %'d, %'d, %'d, %'d, %'d]\033[K\r", registers[0], registers[1],
|
||||||
|
registers[2], registers[3], registers[4], registers[5]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("instructions: %lu\n", instructions_executed);
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
printf("%d\n", registers[0]);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
4
Day22/day22/Cargo.lock
generated
Normal file
4
Day22/day22/Cargo.lock
generated
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[[package]]
|
||||||
|
name = "Day22"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
7
Day22/day22/Cargo.toml
Normal file
7
Day22/day22/Cargo.toml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
[package]
|
||||||
|
name = "Day22"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Sijmen Schoon <me@sijmenschoon.nl>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
123
Day22/day22/src/grid.rs
Normal file
123
Day22/day22/src/grid.rs
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
use super::{Point, State, Tool};
|
||||||
|
use std::collections::{BinaryHeap, HashMap};
|
||||||
|
|
||||||
|
const ROCKY: u16 = 0;
|
||||||
|
const WET: u16 = 1;
|
||||||
|
const NARROW: u16 = 2;
|
||||||
|
|
||||||
|
fn neighbors((x, y): Point) -> Vec<Point> {
|
||||||
|
vec![(x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn distance((ax, ay): Point, (bx, by): Point) -> usize {
|
||||||
|
((ax - bx).abs() + (ay - by).abs()) as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
fn valid_items(region: u16) -> Vec<Tool> {
|
||||||
|
match region {
|
||||||
|
ROCKY => vec![Tool::Torch, Tool::Climbing],
|
||||||
|
WET => vec![Tool::None, Tool::Climbing],
|
||||||
|
NARROW => vec![Tool::None, Tool::Torch],
|
||||||
|
_ => panic!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Grid {
|
||||||
|
pub grid: Vec<Vec<Option<u16>>>,
|
||||||
|
pub depth: usize,
|
||||||
|
pub target: Point,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Grid {
|
||||||
|
pub fn new(depth: usize, target: Point) -> Self {
|
||||||
|
Self {
|
||||||
|
grid: vec![vec![None; depth]; depth],
|
||||||
|
depth,
|
||||||
|
target,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn erosion(&mut self, pos: Point) -> u16 {
|
||||||
|
let m = 20183;
|
||||||
|
let value = match pos {
|
||||||
|
(0, 0) => self.depth,
|
||||||
|
_ if pos == self.target => self.depth,
|
||||||
|
(x, 0) => (x as usize * 16807 + self.depth) % m,
|
||||||
|
(0, y) => (y as usize * 48271 + self.depth) % m,
|
||||||
|
(x, y) => {
|
||||||
|
if let Some(value) = self.grid[y as usize][x as usize] {
|
||||||
|
value as usize
|
||||||
|
} else {
|
||||||
|
let value = usize::from(self.erosion((x - 1, y)))
|
||||||
|
* usize::from(self.erosion((x, y - 1)));
|
||||||
|
let value_ = (value + self.depth) % m;
|
||||||
|
self.grid[y as usize][x as usize] = Some(value_ as u16);
|
||||||
|
value_
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} as u16;
|
||||||
|
|
||||||
|
value
|
||||||
|
}
|
||||||
|
|
||||||
|
fn valid(&self, (x, y): Point) -> bool {
|
||||||
|
x >= 0 && y >= 0 && x < self.depth as isize && y < self.depth as isize
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn path_find(&mut self) -> usize {
|
||||||
|
let start = (0, 0);
|
||||||
|
let first = State::new(0, start, distance(start, self.target), Tool::Torch);
|
||||||
|
|
||||||
|
let mut queue = BinaryHeap::new();
|
||||||
|
queue.push(first);
|
||||||
|
|
||||||
|
let mut visited = HashMap::new();
|
||||||
|
while !queue.is_empty() {
|
||||||
|
let current = queue.pop().unwrap();
|
||||||
|
if visited.contains_key(¤t.key()) && current.depth >= visited[¤t.key()] {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
visited.insert(current.key(), current.depth);
|
||||||
|
|
||||||
|
if current.position == self.target && current.tool == Tool::Torch {
|
||||||
|
return current.depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
let tools = valid_items(self.erosion(current.position) % 3);
|
||||||
|
for tool in tools {
|
||||||
|
if tool != current.tool {
|
||||||
|
queue.push(State::new(
|
||||||
|
current.depth + 7,
|
||||||
|
current.position,
|
||||||
|
current.distance,
|
||||||
|
tool,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for new_pos in neighbors(current.position) {
|
||||||
|
if !self.valid(new_pos) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let region = self.erosion(new_pos) % 3;
|
||||||
|
if valid_items(region).contains(¤t.tool) {
|
||||||
|
let dist = distance(new_pos, self.target);
|
||||||
|
queue.push(State::new(current.depth + 1, new_pos, dist, current.tool));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!("did not find path")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn risk(&mut self) -> u16 {
|
||||||
|
let mut risk = 0;
|
||||||
|
for y in 0..=self.target.1 {
|
||||||
|
for x in 0..=self.target.0 {
|
||||||
|
risk += self.erosion((x, y)) % 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
risk
|
||||||
|
}
|
||||||
|
}
|
31
Day22/day22/src/main.rs
Normal file
31
Day22/day22/src/main.rs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
mod grid;
|
||||||
|
mod state;
|
||||||
|
use self::grid::Grid;
|
||||||
|
use self::state::State;
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
pub type Point = (isize, isize);
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
|
||||||
|
pub enum Tool {
|
||||||
|
None,
|
||||||
|
Torch,
|
||||||
|
Climbing,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let args: Vec<_> = env::args().collect();
|
||||||
|
if args.len() != 4 {
|
||||||
|
println!("Usage: {} [depth] [target_x] [target_y]", args[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let depth = args[1].parse().unwrap();
|
||||||
|
let target: Point = (args[2].parse().unwrap(), args[3].parse().unwrap());
|
||||||
|
|
||||||
|
let mut grid = Grid::new(depth, target);
|
||||||
|
|
||||||
|
println!("part 1: {}", grid.risk());
|
||||||
|
println!("part 2: {}", grid.path_find());
|
||||||
|
}
|
41
Day22/day22/src/state.rs
Normal file
41
Day22/day22/src/state.rs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
use super::{Point, Tool};
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||||
|
pub struct State {
|
||||||
|
pub depth: usize,
|
||||||
|
pub position: Point,
|
||||||
|
pub distance: usize,
|
||||||
|
pub tool: Tool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl State {
|
||||||
|
pub fn new(depth: usize, position: Point, distance: usize, tool: Tool) -> Self {
|
||||||
|
Self {
|
||||||
|
depth,
|
||||||
|
position,
|
||||||
|
distance,
|
||||||
|
tool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn priority(&self) -> usize {
|
||||||
|
self.depth + self.distance
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn key(&self) -> (Point, Tool) {
|
||||||
|
(self.position, self.tool)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for State {
|
||||||
|
fn cmp(&self, other: &State) -> Ordering {
|
||||||
|
other.priority().cmp(&self.priority())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for State {
|
||||||
|
fn partial_cmp(&self, other: &State) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
95
Day23/day23/Cargo.lock
generated
Normal file
95
Day23/day23/Cargo.lock
generated
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "0.6.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day23"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.45"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thread_local"
|
||||||
|
version = "0.3.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ucd-util"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8-ranges"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
"checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e"
|
||||||
|
"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
|
||||||
|
"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
|
||||||
|
"checksum libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)" = "2d2857ec59fadc0773853c664d2d18e7198e83883e7060b63c924cb077bd5c74"
|
||||||
|
"checksum memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "db4c41318937f6e76648f42826b1d9ade5c09cafb5aef7e351240a70f39206e9"
|
||||||
|
"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f"
|
||||||
|
"checksum regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4e47a2ed29da7a9e1960e1639e7a982e6edc6d49be308a3b02daf511504a16d1"
|
||||||
|
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
||||||
|
"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
|
||||||
|
"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737"
|
||||||
|
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
|
8
Day23/day23/Cargo.toml
Normal file
8
Day23/day23/Cargo.toml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[package]
|
||||||
|
name = "day23"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Sijmen Schoon <me@sijmenschoon.nl>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
regex = "^1.1.0"
|
1
Day23/day23/src/attempts.txt
Normal file
1
Day23/day23/src/attempts.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
102330992 -> too low
|
217
Day23/day23/src/main.rs
Normal file
217
Day23/day23/src/main.rs
Normal file
|
@ -0,0 +1,217 @@
|
||||||
|
use regex::Regex;
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
use std::collections::BinaryHeap;
|
||||||
|
use std::io;
|
||||||
|
use std::io::prelude::*;
|
||||||
|
|
||||||
|
type Point = (i64, i64, i64);
|
||||||
|
|
||||||
|
fn distance((ax, ay, az): Point, (bx, by, bz): Point) -> i64 {
|
||||||
|
(bx - ax).abs() + (by - ay).abs() + (bz - az).abs()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
|
struct Bot {
|
||||||
|
position: Point,
|
||||||
|
radius: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Bot {
|
||||||
|
fn in_range(&self, other: &Self) -> bool {
|
||||||
|
distance(self.position, other.position) <= self.radius
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for Bot {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
self.radius.cmp(&other.radius)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for Bot {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
|
struct Node {
|
||||||
|
min: Point,
|
||||||
|
max: Point,
|
||||||
|
count: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Node {
|
||||||
|
fn new(min: Point, max: Point, count: i64) -> Self {
|
||||||
|
Self { min, max, count }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn score(&self) -> (i64, i128, i64) {
|
||||||
|
let area = (self.max.0 - self.min.0) as i128
|
||||||
|
* (self.max.1 - self.min.1) as i128
|
||||||
|
* (self.max.2 - self.min.2) as i128;
|
||||||
|
let dist = distance((0, 0, 0), self.min);
|
||||||
|
|
||||||
|
(self.count, -area, -dist)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for Node {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
self.score().cmp(&other.score())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for Node {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sq_dist(p: &Point, min: &Point, max: &Point) -> i64 {
|
||||||
|
let mut dist = 0;
|
||||||
|
if p.0 < min.0 {
|
||||||
|
dist += (min.0 - p.0) * (min.0 - p.0);
|
||||||
|
} else if p.0 > max.0 {
|
||||||
|
dist += (p.0 - max.0) * (p.0 - max.0);
|
||||||
|
}
|
||||||
|
if p.1 < min.1 {
|
||||||
|
dist += (min.1 - p.1) * (min.1 - p.1);
|
||||||
|
} else if p.1 > max.1 {
|
||||||
|
dist += (p.1 - max.1) * (p.1 - max.1);
|
||||||
|
}
|
||||||
|
if p.2 < min.2 {
|
||||||
|
dist += (min.2 - p.2) * (min.2 - p.2);
|
||||||
|
} else if p.2 > max.2 {
|
||||||
|
dist += (p.2 - max.2) * (p.2 - max.2);
|
||||||
|
}
|
||||||
|
dist
|
||||||
|
}
|
||||||
|
|
||||||
|
fn intersect(b: &Bot, min: &Point, max: &Point) -> bool {
|
||||||
|
let dist = sq_dist(&b.position, min, max);
|
||||||
|
dist <= b.radius * b.radius
|
||||||
|
}
|
||||||
|
|
||||||
|
fn idk(bots: &Vec<Bot>, min: &Point, max: &Point) -> i64 {
|
||||||
|
let mut count = 0;
|
||||||
|
let mut min_dist = std::i64::MAX;
|
||||||
|
for bot in bots {
|
||||||
|
if intersect(bot, min, max) {
|
||||||
|
count += 1;
|
||||||
|
|
||||||
|
let dist = distance((0, 0, 0), bot.position);
|
||||||
|
if dist < min_dist {
|
||||||
|
min_dist = dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
count
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let re = Regex::new(r"^pos=<([-\d]+),([-\d]+),([-\d]+)>, r=(\d+)$").unwrap();
|
||||||
|
let mut bots = Vec::new();
|
||||||
|
|
||||||
|
let mut min = (std::i64::MAX, std::i64::MAX, std::i64::MAX);
|
||||||
|
let mut max = (std::i64::MIN, std::i64::MIN, std::i64::MIN);
|
||||||
|
for line in io::stdin().lock().lines() {
|
||||||
|
let line = line.unwrap();
|
||||||
|
if let Some(input) = re.captures(&line) {
|
||||||
|
let bot = Bot {
|
||||||
|
position: (
|
||||||
|
input[1].parse().unwrap(),
|
||||||
|
input[2].parse().unwrap(),
|
||||||
|
input[3].parse().unwrap(),
|
||||||
|
),
|
||||||
|
radius: input[4].parse().unwrap(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if bot.position.0 < min.0 {
|
||||||
|
min.0 = bot.position.0;
|
||||||
|
}
|
||||||
|
if bot.position.1 < min.1 {
|
||||||
|
min.1 = bot.position.1;
|
||||||
|
}
|
||||||
|
if bot.position.2 < min.2 {
|
||||||
|
min.2 = bot.position.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if bot.position.0 > max.0 {
|
||||||
|
max.0 = bot.position.0;
|
||||||
|
}
|
||||||
|
if bot.position.1 > max.1 {
|
||||||
|
max.1 = bot.position.1;
|
||||||
|
}
|
||||||
|
if bot.position.2 > max.2 {
|
||||||
|
max.2 = bot.position.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
bots.push(bot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let max_bot = bots.iter().max().unwrap();
|
||||||
|
let count = bots.iter().filter(|&bot| max_bot.in_range(bot)).count();
|
||||||
|
println!("part 1: {}", count);
|
||||||
|
|
||||||
|
let mut queue = BinaryHeap::new();
|
||||||
|
queue.push(Node::new(min, max, bots.len() as i64));
|
||||||
|
|
||||||
|
while !queue.is_empty() {
|
||||||
|
let node = queue.pop().unwrap();
|
||||||
|
println!("{:?}", node);
|
||||||
|
if node.max.0 - node.min.0 == 1
|
||||||
|
&& node.max.1 - node.min.1 == 1
|
||||||
|
&& node.max.2 - node.min.2 == 1
|
||||||
|
{
|
||||||
|
min = node.min;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let half = (
|
||||||
|
((node.max.0 + node.min.0) as f64 / 2.0).ceil() as i64,
|
||||||
|
((node.max.1 + node.min.1) as f64 / 2.0).ceil() as i64,
|
||||||
|
((node.max.2 + node.min.2) as f64 / 2.0).ceil() as i64,
|
||||||
|
);
|
||||||
|
|
||||||
|
for (min, max) in vec![
|
||||||
|
(
|
||||||
|
(node.min.0, node.min.1, node.min.2),
|
||||||
|
(half.0, half.1, half.2),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
(node.min.0, node.min.1, half.2),
|
||||||
|
(half.0, half.1, node.max.2),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
(node.min.0, half.1, node.min.2),
|
||||||
|
(half.0, node.max.1, half.2),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
(node.min.0, half.1, half.2),
|
||||||
|
(half.0, node.max.1, node.max.2),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
(half.0, node.min.1, node.min.2),
|
||||||
|
(node.max.0, half.1, half.2),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
(half.0, node.min.1, half.2),
|
||||||
|
(node.max.0, half.1, node.max.2),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
(half.0, half.1, node.min.2),
|
||||||
|
(node.max.0, node.max.1, half.2),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
(half.0, half.1, half.2),
|
||||||
|
(node.max.0, node.max.1, node.max.2),
|
||||||
|
),
|
||||||
|
] {
|
||||||
|
queue.push(Node::new(min, max, idk(&bots, &min, &max)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!("part 2: {}", distance((0, 0, 0), min));
|
||||||
|
}
|
Loading…
Reference in a new issue