Browse Source

Initial commit up to day 8

master
mid-kid 5 years ago
commit
ccc86bac5e
  1. 13
      Makefile
  2. 105
      d01.c
  3. 12
      d01.lua
  4. 1000000
      d01_bigboyinput.txt
  5. 100
      d01_input.txt
  6. 68
      d02.lua
  7. 1
      d02_input.txt
  8. 119
      d03.lua
  9. 2
      d03_bigboyinput.txt
  10. 2
      d03_input.txt
  11. 87
      d04.lua
  12. 1
      d04_bigboyinput.txt
  13. 1
      d04_input.txt
  14. 95
      d05.lua
  15. 48
      d06.lua
  16. 999999
      d06_bigboyinput.txt
  17. 1438
      d06_input.txt
  18. 68
      d08.lua
  19. 1
      d08_bigboyinput_46x36.txt
  20. 1
      d08_input_25x6.txt

13
Makefile

@ -0,0 +1,13 @@
OPT := -O3 -fgraphite-identity -floop-nest-optimize -fdevirtualize-at-ltrans -fipa-pta -fno-semantic-interposition -flto -fuse-linker-plugin
CFLAGS := $(OPT) -Wall -Wextra -std=c17
LDFLAGS := $(OPT)
d01: CFLAGS += $(shell pkg-config --cflags openssl) -pthread
d01: LDLIBS += $(shell pkg-config --libs openssl)
programs := $(patsubst %.c, %, $(wildcard *.c))
.PHONY: all
all: $(programs)
.PHONY: clean
clean:
rm -f $(programs)

105
d01.c

@ -0,0 +1,105 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <err.h>
#include <openssl/bn.h>
struct thread_params {
char *begin;
char *end;
BIGNUM *results[2];
};
void *thread(void *arg)
{
struct thread_params *params = arg;
char *line = params->begin;
BIGNUM *cur = NULL;
while (line && line < params->end && *line) {
BN_dec2bn(&cur, line);
BN_div_word(cur, 3);
BN_sub_word(cur, 2);
BN_add(params->results[0], params->results[0], cur);
while (!BN_is_negative(cur) && !BN_is_zero(cur)) {
BN_add(params->results[1], params->results[1], cur);
BN_div_word(cur, 3);
BN_sub_word(cur, 2);
}
line = strchr(line, '\n');
if (line) line++;
}
BN_free(cur);
return NULL;
}
int main(int argc, char *argv[])
{
long jobs = 8;
if (argc <= 1) return EXIT_FAILURE;
if (argc > 2) jobs = strtol(argv[2], NULL, 0);
FILE *f = fopen(argv[1], "r");
if (!f) err(EXIT_FAILURE, "fopen");
fseek(f, 0, SEEK_END);
long f_len = ftell(f);
fseek(f, 0, SEEK_SET);
char *file = malloc(f_len + 1);
if (!file) err(EXIT_FAILURE, "malloc");
if (fread(file, f_len, 1, f) != 1) err(EXIT_FAILURE, "fread");
file[f_len] = '\0';
fclose(f);
unsigned lines = 0;
for (char *c = file; *c; c++) if (*c == '\n') lines++;
if (file[f_len - 1] != '\n') lines++;
unsigned lines_per_job = lines / jobs;
struct thread_params params[jobs];
pthread_t threads[jobs];
char *begin = file;
char *end = begin;
for (unsigned i = 0; i < jobs; i++) {
params[i].results[0] = BN_new();
params[i].results[1] = BN_new();
if (i == jobs - 1) {
end = file + strlen(file);
} else {
for (unsigned i = 0; i < lines_per_job; i++) {
end = strchr(end, '\n');
if (!end) {
end = file + strlen(file);
break;
}
end++;
}
}
params[i].begin = begin;
params[i].end = end;
begin = end;
pthread_create(&threads[i], NULL, thread, &params[i]);
}
BIGNUM *result_p1 = BN_new();
BIGNUM *result_p2 = BN_new();
for (unsigned i = 0; i < jobs; i++) {
pthread_join(threads[i], NULL);
BN_add(result_p1, result_p1, params[i].results[0]);
BN_add(result_p2, result_p2, params[i].results[1]);
BN_free(params[i].results[0]);
BN_free(params[i].results[1]);
}
char *result_p1_str = BN_bn2dec(result_p1);
char *result_p2_str = BN_bn2dec(result_p2);
BN_free(result_p1);
BN_free(result_p2);
printf("Part 1: %s\n", result_p1_str);
printf("Part 2: %s\n", result_p2_str);
OPENSSL_free(result_p1_str);
OPENSSL_free(result_p2_str);
free(file);
}

12
d01.lua

@ -0,0 +1,12 @@
result_p1 = 0
result_p2 = 0
for mass in io.lines(arg[1], "n") do
fuel = mass // 3 - 2
result_p1 = result_p1 + fuel
while fuel > 0 do
result_p2 = result_p2 + fuel
fuel = fuel // 3 - 2
end
end
print("Part 1:", result_p1)
print("Part 2:", result_p2)

1000000
d01_bigboyinput.txt

File diff suppressed because it is too large

100
d01_input.txt

@ -0,0 +1,100 @@
141923
145715
63157
142712
147191
96667
117032
98123
135120
90609
132022
61962
110315
78993
130183
102188
128800
140640
144402
133746
66157
136169
88585
82083
78884
66913
142607
62297
116267
92283
108383
142698
53334
139604
144184
89522
142032
68327
111034
58033
72836
90483
111008
91385
115528
66856
76318
63000
61721
86102
89367
91018
126390
135550
106711
118434
117698
108304
98998
82998
147998
83344
149309
53964
111042
112244
114337
134419
76114
147869
107076
78626
66552
133785
112234
52693
73606
116199
72505
137500
64873
147893
56938
87481
146006
82226
133657
84149
123742
137593
55372
64696
54386
83466
135058
133268
84234
119067
143566
134224

68
d02.lua

@ -0,0 +1,68 @@
function check_mem(max, offs)
if max < offs then
print(string.format("Error: Memory offset out of bounds: %d", offs))
os.exit(false)
end
end
function interpret(mem)
pos = 1
while true do
if #mem < pos then
print(string.format("Instruction pointer ran off of memory"))
os.exit(false)
end
if mem[pos] == 1 or mem[pos] == 2 then
if #mem < pos + 3 then
print(string.format("Error: Opcode too short at end of memory: %d", pos))
os.exit(false)
end
arg1 = mem[pos + 1] + 1
arg2 = mem[pos + 2] + 1
res = mem[pos + 3] + 1
check_mem(#mem, arg1)
check_mem(#mem, arg2)
check_mem(#mem, res)
if mem[pos] == 1 then
mem[res] = mem[arg1] + mem[arg2]
else
mem[res] = mem[arg1] * mem[arg2]
end
pos = pos + 4
elseif mem[pos] == 99 then
return
else
print(string.format("Error: Invalid opcode %d at %d", mem[pos], pos - 1))
os.exit(false)
end
end
end
file = io.open(arg[1])
memory = {}
for num in string.gmatch(file:read(), "(%d+),") do
table.insert(memory, tonumber(num))
end
file:close()
memory_p1 = {table.unpack(memory)}
memory_p1[2] = 12
memory_p1[3] = 2
interpret(memory_p1)
print("Part 1:", memory_p1[1])
-- Brute force
for noun = 0, 99 do
for verb = 0, 99 do
memory_p2 = {table.unpack(memory)}
memory_p2[2] = noun
memory_p2[3] = verb
interpret(memory_p2)
if memory_p2[1] == 19690720 then
print("Part 2:", 100 * noun + verb)
os.exit(true)
end
end
end

1
d02_input.txt

@ -0,0 +1 @@
1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,10,1,19,1,19,5,23,1,23,9,27,2,27,6,31,1,31,6,35,2,35,9,39,1,6,39,43,2,10,43,47,1,47,9,51,1,51,6,55,1,55,6,59,2,59,10,63,1,6,63,67,2,6,67,71,1,71,5,75,2,13,75,79,1,10,79,83,1,5,83,87,2,87,10,91,1,5,91,95,2,95,6,99,1,99,6,103,2,103,6,107,2,107,9,111,1,111,5,115,1,115,6,119,2,6,119,123,1,5,123,127,1,127,13,131,1,2,131,135,1,135,10,0,99,2,14,0,0

119
d03.lua

@ -0,0 +1,119 @@
lines = {}
for text in io.lines(arg[1]) do
line = {}
for dir, dist in string.gmatch(text, "(%a)(%d+),") do
table.insert(line, {dir=dir, dist=tonumber(dist)})
end
table.insert(lines, line)
end
function manhattan(x, y)
return math.abs(x) + math.abs(y)
end
function sum(table)
out = 0
for _, x in ipairs(table) do
out = out + x
end
return out
end
board = {}
intersect_p1 = nil
intersect_p2 = nil
function add_trace(x, y, index, steps)
if not board[y] then
board[y] = {}
end
if not board[y][x] then
board[y][x] = {}
end
if not board[y][x][index] or steps < board[y][x][index] then
board[y][x][index] = steps
end
if #board[y][x] > 1 then
if not intersect_p1 or manhattan(x, y) < intersect_p1 then
intersect_p1 = manhattan(x, y)
end
if not intersect_p2 or sum(board[y][x]) < intersect_p2 then
intersect_p2 = sum(board[y][x])
end
end
end
min_x = 0
max_x = 0
min_y = 0
max_y = 0
for line_index, line in ipairs(lines) do
pos_x = 0
pos_y = 0
steps = 0
for trace_index, trace in ipairs(line) do
if trace.dir == "U" then
for y = pos_y + 1, pos_y + trace.dist do
steps = steps + 1
add_trace(pos_x, y, line_index, steps)
end
pos_y = pos_y + trace.dist
elseif trace.dir == "D" then
for y = pos_y - 1, pos_y - trace.dist, -1 do
steps = steps + 1
add_trace(pos_x, y, line_index, steps)
end
pos_y = pos_y - trace.dist
elseif trace.dir == "L" then
for x = pos_x - 1, pos_x - trace.dist, -1 do
steps = steps + 1
add_trace(x, pos_y, line_index, steps)
end
pos_x = pos_x - trace.dist
elseif trace.dir == "R" then
for x = pos_x + 1, pos_x + trace.dist do
steps = steps + 1
add_trace(x, pos_y, line_index, steps)
end
pos_x = pos_x + trace.dist
end
if pos_x > max_x then
max_x = pos_x
end
if pos_x < min_x then
min_x = pos_x
end
if pos_y > max_y then
max_y = pos_y
end
if pos_x < min_y then
min_y = pos_y
end
end
end
print("Part 1:", intersect_p1)
print("Part 2:", intersect_p2)
if arg[2] then
out = io.open(arg[2], "w")
out:write(string.format("P3\n%d %d\n255\n", max_x - min_x + 1, max_y - min_y + 1))
for y = min_y, max_y do
for x = min_x, max_x do
if not board[y] then
out:write("255 255 255 ")
elseif not board[y][x] then
out:write("255 255 255 ")
else
for i = 1, 3 do
if board[y][x][i] then
out:write("255 ")
else
out:write("0 ")
end
end
end
end
out:write("\n")
end
out:close()
end

2
d03_bigboyinput.txt

File diff suppressed because one or more lines are too long

2
d03_input.txt

@ -0,0 +1,2 @@
R998,U502,R895,D288,R416,U107,R492,U303,R719,D601,R783,D154,L236,U913,R833,D329,R28,D759,L270,D549,L245,U653,L851,U676,L211,D949,R980,U314,L897,U764,R149,D214,L195,D907,R534,D446,R362,D6,L246,D851,L25,U925,L334,U673,L998,U581,R783,U912,R53,D694,L441,U411,L908,D756,R946,D522,L77,U468,R816,D555,L194,D707,R97,D622,R99,D265,L590,U573,R132,D183,L969,D207,L90,D331,R88,D606,L315,U343,R546,U460,L826,D427,L232,U117,R125,U309,R433,D53,R148,U116,L437,U339,L288,D879,L52,D630,R201,D517,L341,U178,R94,U636,L759,D598,L278,U332,R192,U463,L325,U850,L200,U810,L686,U249,L226,D297,R915,D117,R56,D59,R760,U445,R184,U918,R173,D903,R212,D868,L88,D798,L829,U835,L563,U19,R480,D989,R529,D834,R515,U964,L876,D294,R778,D551,L457,D458,R150,D698,R956,D781,L310,D948,R50,U56,R98,U348,L254,U614,L654,D359,R632,D994,L701,D615,R64,D507,R668,D583,L687,D902,L564,D214,R930,D331,L212,U943,R559,U886,R590,D805,R426,U669,L141,D233,L573,D682,L931,U267,R117,D900,L944,U667,L838,D374,L406,U856,R987,D870,R716,D593,R596,D654,R653,U120,L666,U145,R490,D629,R172,D881,L808,D324,R956,D532,L475,U165,L503,U361,R208,U323,R568,D876,R663,D11,L839,D67,R499,U75,L643,U954,R94,D418,R761,D842,L213,D616,L785,D42,R707,D343,L513,D480,L531,D890,L899,D2,L30,D188,R32,U588,R480,U33,R849,U443,L666,U117,L13,D974,L453,U93,R960,D369,R332,D61,L17,U557,R818,D744,L124,U916,L454,D572,R451,D29,R711,D134,R481,U366,L327,U132,L819,U839,R485,U941,R224,U531,R688,U561,R958,D899,L315,U824,L408,D941,R517,D163,L878,U28,R767,D798,R227
L1009,U399,R373,U980,L48,U638,R725,U775,R714,D530,L887,D576,L682,D940,L371,D621,L342,D482,R676,D445,R752,U119,L361,D444,L769,D854,L874,U259,R332,U218,R866,U28,L342,D233,L958,U649,R998,U262,L8,D863,L283,D449,L73,D438,L516,D54,R964,D981,R338,U332,L761,U704,L705,D468,L115,U834,R367,D156,R480,U27,R846,U73,R846,D720,R811,D466,L407,U928,R816,U50,R90,D893,L930,D833,L159,D972,L823,U868,R689,D558,L777,D13,R844,D8,L168,U956,L111,D462,L667,U559,L839,U503,R906,D838,R83,D323,L782,U588,R599,D233,L700,U679,L51,U779,L110,D260,L201,U992,L43,D557,L628,D875,L201,U535,L246,D976,L546,D22,R600,D301,L542,D41,R532,U316,L765,D310,L666,D369,R853,U684,L457,U816,L667,U758,R798,U959,R893,D185,L842,U168,R68,D348,R394,D296,R966,D511,L319,U717,L57,U129,R843,U439,L744,D870,L162,D991,R77,D565,R494,U601,L851,U748,L96,U124,L379,D446,L882,U371,R133,U820,L935,D704,L670,D911,L182,U138,R844,U926,L552,D716,L849,U624,R723,U117,R252,D737,L216,U796,R156,U322,R812,D390,L50,D493,L665,U314,L584,U798,L11,U524,R171,U837,R981,U32,L277,U650,L865,U28,R399,U908,R652,D543,L779,D406,L839,D198,L190,D319,L776,U752,R383,D884,R385,D682,R729,D163,R252,U533,L690,D767,R533,D147,R366,U716,R548,U171,R932,U720,L9,D39,R895,U850,L276,D988,L528,U551,L262,D480,L275,D567,R70,D599,L814,U876,R120,U93,L565,U795,L278,D41,R695,D693,R208,U272,L923,U498,R238,U268,L244,U278,R965,U395,R990,U329,L478,D245,R980,D473,L702,U396,R358,U636,R400,D919,R240,U780,L251,D633,L55,D723,L529,U319,L299,D89,L251,D557,L705,D705,L391,D58,R241

87
d04.lua

@ -0,0 +1,87 @@
n_begin, n_end = string.match(arg[1], "(%d+)-(%d+)")
--[[
t_begin = {}
t_end = {}
for c in n_begin:gmatch(".") do
table.insert(t_begin, tonumber(c))
end
for c in n_end:gmatch(".") do
table.insert(t_end, tonumber(c))
end
-- Minimum possible value
highest = 0
for i, x in ipairs(t_begin) do
if x < highest then
t_begin[i] = highest
elseif x > highest then
highest = x
end
end
function compare(tbl1, tbl2)
for i, x in ipairs(tbl1) do
local v = x - tbl2[i]
if v ~= 0 then
return v
end
end
end
num = {table.unpack(t_begin)}
part1 = 0
while compare(num, t_end) < 0 do
for i = 1, #num do
if num[i] < t_end[i] then
if num[i] < num[i + 1] then
num[i] = num[i] + 1
part1 = part1 + 1
end
else
end
end
end
print(part1)
for _, x in ipairs(num) do
io.stdout:write(x)
end
io.stdout:write("\n")
]]--
function is_valid(num)
local str = tostring(num)
local lastchar = nil
local inarow = 0
local gotmatch = false
for char = 1, #str do
if lastchar and str:byte(char) < lastchar then
return false
end
if str:byte(char) == lastchar then
inarow = inarow + 1
--gotmatch = true
else
if inarow == 1 then
gotmatch = true
end
inarow = 0
end
lastchar = str:byte(char)
end
if inarow == 1 then
gotmatch = true
end
return gotmatch
end
possibilities = 0
for i = tonumber(n_begin), tonumber(n_end) do
if is_valid(i) then
possibilities = possibilities + 1
end
end
print(possibilities)

1
d04_bigboyinput.txt

@ -0,0 +1 @@
100000000-1000000000

1
d04_input.txt

@ -0,0 +1 @@
273025-767253

95
d05.lua

@ -0,0 +1,95 @@
function get_arg(mem, pos, arg)
local param_mode = mem[pos] // (10 ** (arg + 1)) % 10
if #mem < pos + arg then
print(string.format("Error: Opcode too short at end of memory: %d", pos))
os.exit(false)
end
local arg = mem[pos + arg]
if param_mode == 0 then
arg = arg + 1
if #mem < arg then
print(string.format("Error: Memory offset out of bounds: %d", arg))
os.exit(false)
end
end
return arg
end
function get_param(mem, pos, arg)
local param_mode = mem[pos] // (10 ** (arg + 1)) % 10
local arg = get_arg(mem, pos, arg)
if param_mode == 0 then
return mem[arg]
end
return arg
end
function interpret(mem)
local pos = 1
while true do
if #mem < pos then
print(string.format("Instruction pointer ran off of memory"))
os.exit(false)
end
local opcode = mem[pos] % 100
if opcode == 1 or opcode == 2 then
local arg1 = get_param(mem, pos, 1)
local arg2 = get_param(mem, pos, 2)
local res = get_arg(mem, pos, 3)
if opcode == 1 then
mem[res] = arg1 + arg2
else
mem[res] = arg1 * arg2
end
pos = pos + 4
elseif opcode == 3 then
local arg = get_arg(mem, pos, 1)
io.stdout:write("> ")
local val = io.stdin:read("n")
io.stdout:write(val)
io.stdout:write("\n")
mem[arg] = val
pos = pos + 2
elseif opcode == 4 then
io.stdout:write(get_param(mem, pos, 1))
pos = pos + 2
elseif opcode == 99 then
return
else
print(string.format("Error: Invalid opcode %d at %d", opcode, pos - 1))
os.exit(false)
end
end
end
file = io.open(arg[1])
memory = {}
for num in string.gmatch(file:read(), "(%d+),") do
table.insert(memory, tonumber(num))
end
file:close()
memory_p1 = {table.unpack(memory)}
memory_p1[2] = 12
memory_p1[3] = 2
interpret(memory_p1)
print("Part 1:", memory_p1[1])
-- Brute force
for noun = 0, 99 do
for verb = 0, 99 do
memory_p2 = {table.unpack(memory)}
memory_p2[2] = noun
memory_p2[3] = verb
interpret(memory_p2)
if memory_p2[1] == 19690720 then
print("Part 2:", 100 * noun + verb)
os.exit(true)
end
end
end

48
d06.lua

@ -0,0 +1,48 @@
orbits = {}
for line in io.lines(arg[1]) do
a, b = line:match("(%w+)%)(%w+)")
if not orbits[a] then
orbits[a] = {}
end
table.insert(orbits[a], b)
end
print("Parsed...")
pos_you = nil
pos_san = nil
function getorbits(a, branches, depth)
local value = depth
if not orbits[a] then
return value
end
local b = branches
if #orbits[a] > 1 then
b = {table.unpack(branches)}
table.insert(b, {depth=depth, name=a})
end
for _, orbit in ipairs(orbits[a]) do
if orbit == "YOU" then
pos_you = {branches=branches, depth=depth}
end
if orbit == "SAN" then
pos_san = {branches=branches, depth=depth}
end
value = value + getorbits(orbit, b, depth + 1)
end
return value
end
print("Part 1:", getorbits("COM", {}, 0))
commbranch = 1
while true do
if pos_you.branches[commbranch] ~= pos_san.branches[commbranch] then
break
end
commbranch = commbranch + 1
end
branch = pos_you.branches[commbranch - 1]
distance = pos_you.depth + pos_san.depth - branch.depth * 2
print("Part 2:", distance)

999999
d06_bigboyinput.txt

File diff suppressed because it is too large

1438
d06_input.txt

File diff suppressed because it is too large

68
d08.lua

@ -0,0 +1,68 @@
width = tonumber(arg[2])
height = tonumber(arg[3])
layers = {}
layer = {}
row = {}
for x in io.open(arg[1]):read("a"):gmatch("%d") do
table.insert(row, tonumber(x))
if #row >= width then
table.insert(layer, row)
row = {}
if #layer >= height then
table.insert(layers, layer)
layer = {}
end
end
end
layer = nil
row = nil
fewest = nil
for layer_index, layer in ipairs(layers) do
count = 0
for _, row in ipairs(layer) do
for _, pixel in ipairs(row) do
if pixel == 0 then
count = count + 1
end
end
end
if not fewest or count < fewest[1] then
fewest = {count, layer_index}
end
end
result_p1 = {0, 0}
for _, row in ipairs(layers[fewest[2]]) do
for _, pixel in ipairs(row) do
if not result_p1[pixel] then
result_p1[pixel] = 0
end
result_p1[pixel] = result_p1[pixel] + 1
end
end
print("Part 1:", result_p1[1] * result_p1[2])
if not arg[4] then
os.exit(true)
end
output = io.open(arg[4], "w")
output:write(string.format("P1\n%d %d\n", #layers[1][1], #layers[1]))
for row_index, row in ipairs(layers[1]) do
for pixel_index, pixel in ipairs(row) do
if pixel == 2 then
for x = 2, #layers do
pixel = layers[x][row_index][pixel_index]
if pixel ~= 2 then
break
end
end
end
output:write(pixel)
output:write(" ")
end
end

1
d08_bigboyinput_46x36.txt

File diff suppressed because one or more lines are too long

1
d08_input_25x6.txt

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save