Compare commits
3 commits
6acee8422d
...
b45596b6a8
Author | SHA1 | Date | |
---|---|---|---|
b45596b6a8 | |||
007234f7b2 | |||
1c227f6906 |
3 changed files with 251 additions and 49 deletions
|
@ -14,7 +14,7 @@ class Elf:
|
||||||
self.targeted = False
|
self.targeted = False
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "E"
|
return "\033[32mE\033[0m"
|
||||||
|
|
||||||
|
|
||||||
class Goblin:
|
class Goblin:
|
||||||
|
@ -28,7 +28,7 @@ class Goblin:
|
||||||
self.targeted = False
|
self.targeted = False
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "G"
|
return "\033[31mG\033[0m"
|
||||||
|
|
||||||
|
|
||||||
Elf.enemy = Goblin
|
Elf.enemy = Goblin
|
||||||
|
@ -41,7 +41,7 @@ class Wall:
|
||||||
self.targeted = False
|
self.targeted = False
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "#"
|
return "\u2588"
|
||||||
|
|
||||||
|
|
||||||
class Empty:
|
class Empty:
|
||||||
|
@ -51,7 +51,7 @@ class Empty:
|
||||||
self.targeted = False
|
self.targeted = False
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "." if not self.targeted else "\033[33m?\033[0m"
|
return " " if not self.targeted else "\033[33m?\033[0m"
|
||||||
|
|
||||||
|
|
||||||
NEIGHBORS = [(0, -1), (-1, 0), (1, 0), (0, 1)]
|
NEIGHBORS = [(0, -1), (-1, 0), (1, 0), (0, 1)]
|
||||||
|
@ -121,10 +121,6 @@ def find_closest(field, pos, targets):
|
||||||
|
|
||||||
|
|
||||||
def move(field, x, y, value):
|
def move(field, x, y, value):
|
||||||
for row in field:
|
|
||||||
for col in row:
|
|
||||||
col.targeted = False
|
|
||||||
|
|
||||||
targets = []
|
targets = []
|
||||||
for tx, ty in value.enemy.locations:
|
for tx, ty in value.enemy.locations:
|
||||||
targets.extend([(tx + dx, ty + dy) for dx, dy in NEIGHBORS])
|
targets.extend([(tx + dx, ty + dy) for dx, dy in NEIGHBORS])
|
||||||
|
@ -132,9 +128,6 @@ def move(field, x, y, value):
|
||||||
if not targets:
|
if not targets:
|
||||||
raise StopIteration
|
raise StopIteration
|
||||||
|
|
||||||
for tx, ty in targets:
|
|
||||||
field[ty][tx].targeted = True
|
|
||||||
|
|
||||||
closest = find_closest(field, (x, y), targets)
|
closest = find_closest(field, (x, y), targets)
|
||||||
# print_field(field, highlight=(x, y), path=closest)
|
# print_field(field, highlight=(x, y), path=closest)
|
||||||
# time.sleep(0.3)
|
# time.sleep(0.3)
|
||||||
|
@ -176,8 +169,9 @@ def attack(field, x, y, value):
|
||||||
|
|
||||||
|
|
||||||
def print_field(field, steps=None, highlight=None, path=None):
|
def print_field(field, steps=None, highlight=None, path=None):
|
||||||
if steps is not None:
|
print("\033[2J\033[;HElf attack power:", Elf.power)
|
||||||
print(f"round={steps}")
|
# if steps is not None:
|
||||||
|
# print(f"round={steps}")
|
||||||
for y, row in enumerate(field):
|
for y, row in enumerate(field):
|
||||||
units = []
|
units = []
|
||||||
for x, value in enumerate(row):
|
for x, value in enumerate(row):
|
||||||
|
@ -194,10 +188,11 @@ def print_field(field, steps=None, highlight=None, path=None):
|
||||||
etc = sorted(units, key=lambda unit: (str(unit), unit.health))
|
etc = sorted(units, key=lambda unit: (str(unit), unit.health))
|
||||||
print(" ", ", ".join(f"{x}({x.health})" for x in etc))
|
print(" ", ", ".join(f"{x}({x.health})" for x in etc))
|
||||||
print()
|
print()
|
||||||
|
time.sleep(0.05)
|
||||||
|
|
||||||
|
|
||||||
def step(field, steps):
|
def step(field, steps):
|
||||||
# print_field(field, steps)
|
print_field(field, steps)
|
||||||
seen_units = set()
|
seen_units = set()
|
||||||
for y, row in enumerate(field):
|
for y, row in enumerate(field):
|
||||||
for x, value in enumerate(row):
|
for x, value in enumerate(row):
|
||||||
|
@ -235,8 +230,9 @@ def main():
|
||||||
while True:
|
while True:
|
||||||
main()
|
main()
|
||||||
if Elf.deaths == 0:
|
if Elf.deaths == 0:
|
||||||
print("yay")
|
print("No elves died! :D")
|
||||||
break
|
break
|
||||||
|
|
||||||
Elf.power += 1
|
Elf.power += 1
|
||||||
print("oh no :(, trying", Elf.power)
|
print(f"{Elf.deaths} elves died, trying power={Elf.power}")
|
||||||
|
time.sleep(4)
|
||||||
|
|
|
@ -16,43 +16,31 @@ typedef struct {
|
||||||
} Sample;
|
} Sample;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ADDR, ADDI, MULR, MULI,
|
ADDR, ADDI, MULR, MULI, BANR, BANI, BORR, BORI,
|
||||||
BANR, BANI, BORR, BORI,
|
SETR, SETI, GTIR, GTRI, GTRR, EQIR, EQRI, EQRR,
|
||||||
SETR, SETI, GTIR, GTRI,
|
|
||||||
GTRR, EQIR, EQRI, EQRR,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
const char *names[] = {
|
const char *names[] = {
|
||||||
"addr", "addi", "mulr", "muli",
|
"addr", "addi", "mulr", "muli", "banr", "bani", "borr", "bori",
|
||||||
"banr", "bani", "borr", "bori",
|
"setr", "seti", "gtir", "gtri", "gtrr", "eqir", "eqri", "eqrr",
|
||||||
"setr", "seti", "gtir", "gtri",
|
|
||||||
"gtrr", "eqir", "eqri", "eqrr",
|
|
||||||
};
|
|
||||||
|
|
||||||
uint16_t table[16] = {
|
|
||||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
|
||||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
|
||||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
|
||||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
int opcodes[16];
|
int opcodes[16];
|
||||||
|
|
||||||
int sample_read(Sample *s, FILE *file) {
|
int sample_read(Sample *s, FILE *file) {
|
||||||
int read = 0;
|
int read = 0;
|
||||||
|
|
||||||
read =
|
read = fscanf(file, "Before: [%u, %u, %u, %u]\n",
|
||||||
fscanf(file, "Before: [%u, %u, %u, %u]\n",
|
|
||||||
&s->before[0], &s->before[1], &s->before[2], &s->before[3]);
|
&s->before[0], &s->before[1], &s->before[2], &s->before[3]);
|
||||||
if (read != 4) return 0;
|
if (read != 4) return 0;
|
||||||
|
|
||||||
Instruction *i = &s->instruction;
|
Instruction *i = &s->instruction;
|
||||||
read = fscanf(file, "%" SCNu8 " %u %u %u\n",
|
read = fscanf(file, "%" SCNu8 " %u %u %u\n", &i->opcode, &i->a, &i->b, &i->c);
|
||||||
&i->opcode, &i->a, &i->b, &i->c);
|
|
||||||
if (read != 4) return 0;
|
if (read != 4) return 0;
|
||||||
|
|
||||||
read =
|
read = fscanf(file, "After: [%u, %u, %u, %u]\n\n",
|
||||||
fscanf(file, "After: [%u, %u, %u, %u]\n\n",
|
|
||||||
&s->after[0], &s->after[1], &s->after[2], &s->after[3]);
|
&s->after[0], &s->after[1], &s->after[2], &s->after[3]);
|
||||||
if (read != 4) return 0;
|
if (read != 4) return 0;
|
||||||
|
|
||||||
|
@ -63,25 +51,32 @@ uint16_t sample_possible_opcodes(const Sample s) {
|
||||||
uint16_t possible_opcodes = 0;
|
uint16_t possible_opcodes = 0;
|
||||||
|
|
||||||
Instruction i = s.instruction;
|
Instruction i = s.instruction;
|
||||||
|
|
||||||
// Addition
|
// Addition
|
||||||
if (s.after[i.c] == s.before[i.a] + s.before[i.b]) possible_opcodes |= 1 << ADDR;
|
if (s.after[i.c] == s.before[i.a] + s.before[i.b]) possible_opcodes |= 1 << ADDR;
|
||||||
if (s.after[i.c] == s.before[i.a] + i.b) possible_opcodes |= 1 << ADDI;
|
if (s.after[i.c] == s.before[i.a] + i.b) possible_opcodes |= 1 << ADDI;
|
||||||
|
|
||||||
// Multiplication
|
// Multiplication
|
||||||
if (s.after[i.c] == s.before[i.a] * s.before[i.b]) possible_opcodes |= 1 << MULR;
|
if (s.after[i.c] == s.before[i.a] * s.before[i.b]) possible_opcodes |= 1 << MULR;
|
||||||
if (s.after[i.c] == s.before[i.a] * i.b) possible_opcodes |= 1 << MULI;
|
if (s.after[i.c] == s.before[i.a] * i.b) possible_opcodes |= 1 << MULI;
|
||||||
|
|
||||||
// Bitwise AND
|
// Bitwise AND
|
||||||
if (s.after[i.c] == (s.before[i.a] & s.before[i.b])) possible_opcodes |= 1 << BANR;
|
if (s.after[i.c] == (s.before[i.a] & s.before[i.b])) possible_opcodes |= 1 << BANR;
|
||||||
if (s.after[i.c] == (s.before[i.a] & i.b)) possible_opcodes |= 1 << BANI;
|
if (s.after[i.c] == (s.before[i.a] & i.b)) possible_opcodes |= 1 << BANI;
|
||||||
|
|
||||||
// Bitwise OR
|
// Bitwise OR
|
||||||
if (s.after[i.c] == (s.before[i.a] | s.before[i.b])) possible_opcodes |= 1 << BORR;
|
if (s.after[i.c] == (s.before[i.a] | s.before[i.b])) possible_opcodes |= 1 << BORR;
|
||||||
if (s.after[i.c] == (s.before[i.a] | i.b)) possible_opcodes |= 1 << BORI;
|
if (s.after[i.c] == (s.before[i.a] | i.b)) possible_opcodes |= 1 << BORI;
|
||||||
|
|
||||||
// Assignment
|
// Assignment
|
||||||
if (s.after[i.c] == s.before[i.a]) possible_opcodes |= 1 << SETR;
|
if (s.after[i.c] == s.before[i.a]) possible_opcodes |= 1 << SETR;
|
||||||
if (s.after[i.c] == i.a) possible_opcodes |= 1 << SETI;
|
if (s.after[i.c] == i.a) possible_opcodes |= 1 << SETI;
|
||||||
|
|
||||||
// Greater-than testing
|
// Greater-than testing
|
||||||
if (s.after[i.c] == (i.a > s.before[i.b])) possible_opcodes |= 1 << GTIR;
|
if (s.after[i.c] == (i.a > s.before[i.b])) possible_opcodes |= 1 << GTIR;
|
||||||
if (s.after[i.c] == (s.before[i.a] > i.b)) possible_opcodes |= 1 << GTRI;
|
if (s.after[i.c] == (s.before[i.a] > i.b)) possible_opcodes |= 1 << GTRI;
|
||||||
if (s.after[i.c] == (s.before[i.a] > s.before[i.b])) possible_opcodes |= 1 << GTRR;
|
if (s.after[i.c] == (s.before[i.a] > s.before[i.b])) possible_opcodes |= 1 << GTRR;
|
||||||
|
|
||||||
// Equality testing
|
// Equality testing
|
||||||
if (s.after[i.c] == (i.a == s.before[i.b])) possible_opcodes |= 1 << EQIR;
|
if (s.after[i.c] == (i.a == s.before[i.b])) possible_opcodes |= 1 << EQIR;
|
||||||
if (s.after[i.c] == (s.before[i.a] == i.b)) possible_opcodes |= 1 << EQRI;
|
if (s.after[i.c] == (s.before[i.a] == i.b)) possible_opcodes |= 1 << EQRI;
|
||||||
|
@ -101,8 +96,19 @@ int bits_set(uint16_t n) {
|
||||||
return bit;
|
return bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void find_opcodes() {
|
void find_opcodes(FILE *file) {
|
||||||
int unknown = 16;
|
int unknown = 16;
|
||||||
|
uint16_t table[16] = {
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||||
|
};
|
||||||
|
|
||||||
|
Sample sample;
|
||||||
|
while (sample_read(&sample, file)) {
|
||||||
|
uint16_t possible_opcodes = sample_possible_opcodes(sample);
|
||||||
|
table[sample.instruction.opcode] &= possible_opcodes;
|
||||||
|
}
|
||||||
|
|
||||||
while (unknown > 0) {
|
while (unknown > 0) {
|
||||||
for (int opcode = 0; opcode < 16; opcode++) {
|
for (int opcode = 0; opcode < 16; opcode++) {
|
||||||
int bit = bits_set(table[opcode]);
|
int bit = bits_set(table[opcode]);
|
||||||
|
@ -117,9 +123,10 @@ void find_opcodes() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 16; i++) {
|
#ifdef DEBUG
|
||||||
|
for (int i = 0; i < 16; i++)
|
||||||
printf("%d: %s\n", i, names[opcodes[i]]);
|
printf("%d: %s\n", i, names[opcodes[i]]);
|
||||||
}
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int instruction_read(Instruction *i, FILE *file) {
|
int instruction_read(Instruction *i, FILE *file) {
|
||||||
|
@ -170,25 +177,27 @@ int main(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *file = fopen(argv[1], "r");
|
FILE *file = fopen(argv[1], "r");
|
||||||
Sample sample = {0};
|
find_opcodes(file);
|
||||||
|
|
||||||
while (sample_read(&sample, file)) {
|
|
||||||
uint16_t possible_opcodes = sample_possible_opcodes(sample);
|
|
||||||
table[sample.instruction.opcode] &= possible_opcodes;
|
|
||||||
}
|
|
||||||
find_opcodes();
|
|
||||||
|
|
||||||
uint32_t registers[4] = {0};
|
uint32_t registers[4] = {0};
|
||||||
Instruction instruction = {0};
|
Instruction instruction = {0};
|
||||||
while (instruction_read(&instruction, file)) {
|
while (instruction_read(&instruction, file)) {
|
||||||
|
#ifdef DEBUG
|
||||||
const char *name = names[opcodes[instruction.opcode]];
|
const char *name = names[opcodes[instruction.opcode]];
|
||||||
printf("opcode: %2d (%s), a: %d, b: %d, c: %d\n", instruction.opcode,
|
printf("opcode: %2d (%s), a: %d, b: %d, c: %d\n", instruction.opcode,
|
||||||
name, instruction.a, instruction.b, instruction.c);
|
name, instruction.a, instruction.b, instruction.c);
|
||||||
|
#endif
|
||||||
|
|
||||||
instruction_execute(&instruction, registers);
|
instruction_execute(&instruction, registers);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
printf("registers: %d %d %d %d\n", registers[0], registers[1],
|
printf("registers: %d %d %d %d\n", registers[0], registers[1],
|
||||||
registers[2], registers[3]);
|
registers[2], registers[3]);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
|
printf("%d\n", registers[0]);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
197
Day17/Day17A.c
Normal file
197
Day17/Day17A.c
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define AT(x, y) grid[(y) * x_max + (x)]
|
||||||
|
|
||||||
|
void get_limits(FILE *file, int *x_min, int *x_max, int *y_min, int *y_max) {
|
||||||
|
char *line = NULL;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
*x_min = INT_MAX;
|
||||||
|
*x_max = INT_MAX;
|
||||||
|
*x_max = 0;
|
||||||
|
*y_max = 0;
|
||||||
|
|
||||||
|
while (getline(&line, &len, file) != -1) {
|
||||||
|
int xa, xb, ya, yb;
|
||||||
|
if (sscanf(line, "x=%d, y=%d..%d", &xa, &ya, &yb) == 3) {
|
||||||
|
if (xa < *x_min) *x_min = xa;
|
||||||
|
if (xa + 1 > *x_max) *x_max = xa + 1;
|
||||||
|
if (ya < *y_min) *y_min = ya;
|
||||||
|
if (yb + 1 > *y_max) *y_max = yb + 1;
|
||||||
|
} else if (sscanf(line, "y=%d, x=%d..%d", &ya, &xa, &xb) == 3) {
|
||||||
|
if (xa < *x_min) *x_min = xa;
|
||||||
|
if (xb + 1 > *x_max) *x_max = xa + 1;
|
||||||
|
if (ya < *y_min) *y_min = ya;
|
||||||
|
if (ya + 1 > *y_max) *y_max = yb + 1;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*x_max += 10;
|
||||||
|
*x_min -= 10;
|
||||||
|
printf("grid: x=%d..%d y=%d..%d\n", *x_min, *x_max, *y_min, *y_max);
|
||||||
|
|
||||||
|
rewind(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
void build_grid(FILE *file, char *grid, int x_max) {
|
||||||
|
char *line = NULL;
|
||||||
|
size_t len;
|
||||||
|
while (getline(&line, &len, file) != -1) {
|
||||||
|
int xa, xb, ya, yb;
|
||||||
|
if (sscanf(line, "x=%d, y=%d..%d", &xa, &ya, &yb) == 3) {
|
||||||
|
printf("x=%d, y=%d..%d\n", xa, ya, yb);
|
||||||
|
for (int y = ya; y <= yb; y++)
|
||||||
|
AT(xa, y) = '#';
|
||||||
|
} else if (sscanf(line, "y=%d, x=%d..%d", &ya, &xa, &xb) == 3) {
|
||||||
|
printf("x=%d..%d, y=%d\n", xa, xb, ya);
|
||||||
|
for (int x = xa; x <= xb; x++)
|
||||||
|
AT(x, ya) = '#';
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
grid[500] = '+';
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_grid(char *grid, int x_min, int x_max, int y_min, int y_max) {
|
||||||
|
printf("\n");
|
||||||
|
printf(" "); for (int x = x_min; x < x_max; x++) printf("%d", x / 100 % 10); printf("\n");
|
||||||
|
printf(" "); for (int x = x_min; x < x_max; x++) printf("%d", x / 10 % 10); printf("\n");
|
||||||
|
printf(" "); for (int x = x_min; x < x_max; x++) printf("%d", x % 10); printf("\n");
|
||||||
|
|
||||||
|
for (int y = 0; y < y_max + 3; y++) {
|
||||||
|
if (y < y_min || y >= y_max)
|
||||||
|
printf("\033[41m");
|
||||||
|
printf("%4d \033[0m", y);
|
||||||
|
for (int x = x_min; x < x_max; x++) {
|
||||||
|
switch (grid[y * x_max + x]) {
|
||||||
|
case '.':
|
||||||
|
putchar(' ');
|
||||||
|
putchar(' ');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '|':
|
||||||
|
printf("\033[44m\u2551\u2551\033[0m");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '~':
|
||||||
|
printf("\033[44m\u2248\u2248\033[0m");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '#':
|
||||||
|
printf("\033[33m\u2588\u2588\033[0m");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '+':
|
||||||
|
printf("\033[41m\u256C\u256C\033[0m");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *read_grid(FILE *file, int *x_min, int *x_max, int *y_min, int *y_max) {
|
||||||
|
get_limits(file, x_min, x_max, y_min, y_max);
|
||||||
|
|
||||||
|
size_t size = (*y_max + 50) * *x_max;
|
||||||
|
char *grid = malloc(size);
|
||||||
|
memset(grid, '.', size);
|
||||||
|
|
||||||
|
build_grid(file, grid, *x_max);
|
||||||
|
return grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void step(char *grid, int x_min, int x_max, int y_min, int y_max) {
|
||||||
|
for (int y = 0; y < y_max + 50; y++) {
|
||||||
|
for (int x = x_min; x < x_max; x++) {
|
||||||
|
if (AT(x, y) == '+' || AT(x, y) == '|') {
|
||||||
|
if (AT(x, y + 1) == '.') {
|
||||||
|
AT(x, y + 1) = '|';
|
||||||
|
} else if (AT(x, y + 1) == '#' || AT(x, y + 1) == '~') {
|
||||||
|
int is_still = 1;
|
||||||
|
int left_wall = -1, right_wall = -1;
|
||||||
|
|
||||||
|
for (int x_ = x; x_ >= x_min - 1; x_--) {
|
||||||
|
if (AT(x_, y) == '#') {
|
||||||
|
left_wall = x_ + 1;
|
||||||
|
break;
|
||||||
|
} else if (AT(x_, y + 1) == '.' || AT(x_, y + 1) == '|') {
|
||||||
|
is_still = 0;
|
||||||
|
left_wall = x_;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int x_ = x; x_ <= x_max; x_++) {
|
||||||
|
if (AT(x_, y) == '#') {
|
||||||
|
right_wall = x_ - 1;
|
||||||
|
break;
|
||||||
|
} else if (AT(x_, y + 1) == '.' || AT(x_, y + 1) == '|') {
|
||||||
|
is_still = 0;
|
||||||
|
right_wall = x_;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (left_wall != -1 && right_wall != -1) {
|
||||||
|
for (int x_ = left_wall; x_ <= right_wall; x_++) {
|
||||||
|
assert(AT(x_, y) != '#');
|
||||||
|
AT(x_, y) = is_still ? '~' : '|';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int count_water(char *grid, int x_min, int x_max, int y_min, int y_max) {
|
||||||
|
int water = 0;
|
||||||
|
for (int y = y_min; y < y_max; y++) {
|
||||||
|
for (int x = x_min; x < x_max; x++) {
|
||||||
|
water += (AT(x, y) == '~') ? 1 : 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return water;
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
|
||||||
|
int x_min, x_max, y_min, y_max;
|
||||||
|
char *grid = read_grid(file, &x_min, &x_max, &y_min, &y_max);
|
||||||
|
|
||||||
|
print_grid(grid, x_min, x_max, y_min, y_max);
|
||||||
|
int last_water = -1, water = -1;
|
||||||
|
int extra_steps = 0;
|
||||||
|
do {
|
||||||
|
step(grid, x_min, x_max, y_min, y_max);
|
||||||
|
|
||||||
|
last_water = water;
|
||||||
|
water = count_water(grid, x_min, x_max, y_min, y_max);
|
||||||
|
printf("Water: %d\r", water);
|
||||||
|
|
||||||
|
if (last_water == water)
|
||||||
|
extra_steps += 1;
|
||||||
|
else
|
||||||
|
extra_steps = 0;
|
||||||
|
} while (extra_steps < 200);
|
||||||
|
|
||||||
|
print_grid(grid, x_min, x_max, y_min, y_max);
|
||||||
|
printf("Water: %d\n", water);
|
||||||
|
}
|
Loading…
Reference in a new issue