[–]▶ No.1001333>>1012044 [Watch Thread][Show All Posts]
https://adventofcode.com/
It's near to that time of year again, people, and the reddit competition will soon start up again. Are you going to let those twitter trannies win? Or are you going to prove your compsci degree was worth something?
(protip: it wasn't, watch as some jap codes the whole thing in assembly naked atop mt. Fuji)
What is it?
Advent of code's a programming advent calendar. 2 problems a day for every day of advent, you paste the output data into a text box. You need to register via one of a few 3rd-party websites, because there's a leaderboard: first person to complete a day's challenges get 100 points to his total, second 99, so on. If I remember correctly, someone from 4chan came first last year, but don't quote me on that.
The site's a bit cancerous, especially the sign-up thing, but it's still pretty fun. Try out a new language, or have some fun getting back to basics with one you already know.
I'll be doing it in C, with a little helper library for quickly reading files. How about you, anon?
▶ No.1009067>>1009069
yep, today's easy. with a logic table it's obvious that opcodes can be assigned deterministically. since there's no control flow instructions, there are no shenanigans with the code once you run it.
▶ No.1009069>>1009071
>>1009067
Is there supposed to be two opcodes that do the same thing?
▶ No.1009070
Ada. the Time_Machine and Aoc_Input code is just drudgery, a whole bunch of
procedure Borr (A, B : in Int; C : in Register) is
begin
Registers (C) := Registers (A) or Registers (B);
end Borr;
procedure Bori (A, B : in Int; C : in Register) is
begin
Registers (C) := Registers (A) or B;
end Bori;
▶ No.1009071>>1009072
>>1009069
nope. What I did in >>1009055 was backwards.
I figured it out in this manner:
1. get a list of all possible op(##, Instr) combinations
2. notice that one ## only has a single possible Instr
3. assign the singleton ## to its instruction, then remove that instruction from the rest of the list.
4. goto 2
▶ No.1009072
>>1009071
with the list from #1 I noticed
A. Eqir only appeared once in the list -- it can only possibly be that opcode
B. opcode 10 only appears once in the list -- it can only be this one instruction
that, before removing anything. Once you remove all occurrences of the two instructions you find in this manner, there are now more singletons that can only be one thing, repeat.
▶ No.1009088>>1009125 >>1009128
When did the puzzles stop being fun?
▶ No.1009092
>>1009015
now that's a spicy puzzle
▶ No.1009100
Day16 was a really nice puzzle. Started on it late, but it was fun.
▶ No.1009125
>>1009088
Still fun for me, Hitler. Or maybe that's just because Day 15 was such a shitshow that anything is more fun. Did today with a wall register lambdas and a dictionary that translates opcodes into those registers.
#!/usr/bin/python
import re
sample_data = re.compile('\[(\d)+, (\d)+, (\d)+, (\d)+\]')
def main():
# Dictionary of lambda functions
registers = {}
registers['addr'] = lambda inp, cmd: inp[cmd[1]] + inp[cmd[2]]
registers['addi'] = lambda inp, cmd: inp[cmd[1]] + cmd[2]
registers['mulr'] = lambda inp, cmd: inp[cmd[1]] * inp[cmd[2]]
registers['muli'] = lambda inp, cmd: inp[cmd[1]] * cmd[2]
registers['banr'] = lambda inp, cmd: inp[cmd[1]] & inp[cmd[2]]
registers['bani'] = lambda inp, cmd: inp[cmd[1]] & cmd[2]
registers['borr'] = lambda inp, cmd: inp[cmd[1]] | inp[cmd[2]]
registers['bori'] = lambda inp, cmd: inp[cmd[1]] | cmd[2]
registers['setr'] = lambda inp, cmd: inp[cmd[1]]
registers['seti'] = lambda inp, cmd: cmd[1]
registers['gtir'] = lambda inp, cmd: 1 if cmd[1] > inp[cmd[2]] else 0
registers['gtri'] = lambda inp, cmd: 1 if inp[cmd[1]] > cmd[2] else 0
registers['gtrr'] = lambda inp, cmd: 1 if inp[cmd[1]] > inp[cmd[2]] else 0
registers['eqir'] = lambda inp, cmd: 1 if cmd[1] == inp[cmd[2]] else 0
registers['eqri'] = lambda inp, cmd: 1 if inp[cmd[1]] == cmd[2] else 0
registers['eqrr'] = lambda inp, cmd: 1 if inp[cmd[1]] == inp[cmd[2]] else 0
part_one, part_two = read_file("input")
opcodes = match_opcodes(part_one, registers) # Part 1 & Part 2 prep
run_program(part_two, opcodes, registers) # Part 2
def run_program(instructions, opcodes, registers):
state = [0, 0, 0, 0]
for cmd in instructions:
code = opcodes[cmd[0]] # Match opcode with register
result = registers[code](state, cmd)
state[ cmd[3] ] = result # Last index of cmd contains write register
print('Part 2: {0}'.format(state[0]))
def match_opcodes(samples, registers):
# 0 is the input, 1 is the command, 2 is the result
count = 0 # Part 1 variable
cmd_dict = {}
for sample in samples:
values = set()
# If command matches, add to set
for k, v in registers.items():
result = v(sample[0], sample[1])
if result == sample[2][ sample[1][3] ]:
values.add(k)
num_values = len(values)
if num_values >= 3: # Add to Part 1 count if gt 3
count += 1
# Find the least ambiguous instruction set for each opcode
if not sample[1][0] in cmd_dict:
cmd_dict[ sample[1][0] ] = values
elif num_values < len(cmd_dict[ sample[1][0] ]):
cmd_dict[ sample[1][0] ] = values
print('Part 1: {0}'.format(count))
results = {}
# Remove registers that match only one opcode until nothing remains
while len(cmd_dict) > 0:
next_opcode = min(cmd_dict.values(), key=lambda x: len(x))
cmd_keys = list(cmd_dict.keys())
for k in cmd_keys:
if cmd_dict[k] == next_opcode: # Add key to results
results[k] = list(cmd_dict[k])[0]
cmd_dict.pop(k, None)
else: # Subtract it from every other set
cmd_dict[k] -= next_opcode
return results
def read_file(filename):
f = open(filename, 'r')
samples = [] # Part 1 dataset (array of 2D arrays)
instructions = [] # Part 2 dataset (2D array)
# Variables for Part 1
cmd = False
after = False
sample = []
for line in f:
# Part 1 reading
tokens = line.split(':')
if len(tokens) > 1:
if after:
after = False
sample.append([int(x) for x in sample_data.findall(line)[0]])
samples.append(sample)
sample = []
elif tokens[0] == "Before":
cmd = True
sample.append([int(x) for x in sample_data.findall(line)[0]])
elif cmd:
after = True
cmd = False
sample.append([int(x) for x in line.split(' ')])
else: # Part 2 reading
tokens = line.split(' ')
if len(tokens) > 1:
instructions.append([int(x) for x in tokens])
return samples, instructions
main()
▶ No.1009126>>1009127 >>1009128 >>1009195 >>1009228 >>1009288
>people still dump their code that no one reads
Why?
▶ No.1009127
▶ No.1009130
>program works at first try
▶ No.1009166
>>1009164
Nice. I did the code matching manually in a texteditor. You're clearly less lazy.
#!/usr/bin/env ruby
ops = {11 => :addr, 5 => :addi, 1 => :mulr, 8=> :muli, 4 => :banr, 12 => :bani, 13 => :borr, 9 => :bori, 10 => :setr, 6 => :seti, 7 => :gtir, 2 => :gtri, 3 => :gtrr, 14 => :eqir, 0 => :eqri, 15 => :eqrr}
funcs = {
:addr => ->(a,b,c) {$reg[c]=$reg[a]+$reg[b]}, # (add register) stores into register C the result of adding register A and register B.
:addi => ->(a,b,c) {$reg[c]=$reg[a]+b}, # (add immediate) stores into register C the result of adding register A and value B.
:mulr => ->(a,b,c) {$reg[c]=$reg[a]*$reg[b]}, # (multiply register) stores into register C the result of multiplying register A and register B.
:muli => ->(a,b,c) {$reg[c]=$reg[a]*b}, # (multiply immediate) stores into register C the result of multiplying register A and value B.
:banr => ->(a,b,c) {$reg[c]=$reg[a]&$reg[b]}, # (bitwise AND register) stores into register C the result of the bitwise AND of register A and register B.
:bani => ->(a,b,c) {$reg[c]=$reg[a]&b}, # (bitwise AND immediate) stores into register C the result of the bitwise AND of register A and value B.
:borr => ->(a,b,c) {$reg[c]=$reg[a]|$reg[b]}, # (bitwise OR register) stores into register C the result of the bitwise OR of register A and register B.
:bori => ->(a,b,c) {$reg[c]=$reg[a]|b}, # (bitwise OR immediate) stores into register C the result of the bitwise OR of register A and value B.
:setr => ->(a,b,c) {$reg[c]=$reg[a]}, # (set register) copies the contents of register A into register C. (Input B is ignored.)
:seti => ->(a,b,c) {$reg[c]=a}, # (set immediate) stores value A into register C. (Input B is ignored.)
:gtir => ->(a,b,c) {$reg[c]=(a>$reg[b])?1:0}, # (greater-than immediate/register) sets register C to 1 if value A is greater than register B. Otherwise, register C is set to 0.
:gtri => ->(a,b,c) {$reg[c]=($reg[a]>b)?1:0}, # (greater-than register/immediate) sets register C to 1 if register A is greater than value B. Otherwise, register C is set to 0.
:gtrr => ->(a,b,c) {$reg[c]=($reg[a]>$reg[b])?1:0}, # (greater-than register/register) sets register C to 1 if register A is greater than register B. Otherwise, register C is set to 0.
:eqir => ->(a,b,c) {$reg[c]=(a==$reg[b])?1:0}, # (equal immediate/register) sets register C to 1 if value A is equal to register B. Otherwise, register C is set to 0.
:eqri => ->(a,b,c) {$reg[c]=($reg[a]==b)?1:0}, # (equal register/immediate) sets register C to 1 if register A is equal to value B. Otherwise, register C is set to 0.
:eqrr => ->(a,b,c) {$reg[c]=($reg[a]==$reg[b])?1:0}, # (equal register/register) sets register C to 1 if register A is equal to register B. Otherwise, register C is set to 0.
}
$reg = [0,0,0,0]
IO.readlines("d16inputb.txt").each do |entry|
cmd = entry.chomp.split(' ').map {|e|e.to_i}
funcs[ops[cmd[0]]].call(cmd[1], cmd[2], cmd[3])
end
p $reg
▶ No.1009195>>1009196
>>1009126
>S-stop it! Stop writing code.
>Stop reminding me of what I cannot do.
Admit it, you're the LARP.
▶ No.1009196
▶ No.1009203>>1009206
FUCK
I found why my day15 code has these small occasional differences in outcome. I was sure I could delete an element of an array which was doing a for-each loop with it automatically adjusting for it. Apparently not. Apparently it skips one element if the deleted element happened to be before the current one. Probably doesn't even happen all the time, because only one test fails..
Pfff.. more rewriting to be done.. this time hopefully the last time..
▶ No.1009206>>1009208 >>1009227 >>1009333
>>1009203
Meanwhile, people are showing off on reddit with visualizations.
▶ No.1009208
▶ No.1009227
>>1009206
>goblins are brown
Based
▶ No.1009228
>>1009126
For your viewing pleasure. I solved the opcode assignments in part2 last night manually by just deleting more and more from the constraints.
To make it a bit fancier (and automated), I turned into a SAT (https://en.wikipedia.org/wiki/Boolean_satisfiability_problem), and let the solver do all the work.
▶ No.1009244>>1009248
>>1007894
Just happened to #MeToo. I feel violated. I no longer feel safe. I am very shaken right now, still processing what has happened.
▶ No.1009248
>>1009244
kek, I seem to have been kicked off one too.
No idea why. Don't really care either. Hardly see the point of 'm.
▶ No.1009288>>1009311
>>1009126
The kikes that run the competition harvest the optimal solutions that the useful idiots post 4free.
▶ No.1009308>>1009313
God damned, I did that fucking day 15.. Christ what a pile of shit.
>choose enemies based on distance first, then reading order.
>when just one step away from enemy, move and attack
>when next to multiple enemies, attack the one with the lowest HP
There I made the mistake. When I selected a one-step away enemy, I moved and attacked. but I didn't check after that one step if I had gotten in range of another enemy too. I had to recheck, apply the HP rule and switch if necessary.
God damned.. The one case where that was the deciding factor was somewhere 2/3 in of 103 rounds.
Thank god part 2 was a joke.
▶ No.1009311>>1009312
>>1009288
>he's against free and open software
▶ No.1009312
>>1009311
He's probably just against open sores. You are literally devaluing yourself if you sell what you make for $0 than what it is actually worth. Since it's free others can exploit the work you've done an unlimited amount of times.
▶ No.1009313>>1009321
>>1009308
>When I selected a one-step away enemy, I moved and attacked. but I didn't check after that one step if I had gotten in range of another enemy too. I had to recheck, apply the HP rule and switch if necessary.
What the fuck?, why would you ever do it like that?, why not just:
attack (end turn if successful) > move > attack
I'm sorry for bullying (I'm not) but I'm genuinely confused at what went through your mind when you though it was a good idea to look for an enemy 2 tiles away to "move and attack" instead of just moving then trying to attack.
▶ No.1009321>>1009322
>>1009313
Huh? Seems simple to me also your example makes no sense. A one tile away enemy is a special situation. This is about the only turn based game where you can move AND attack in ONE turn. When moving, the choice of enemies has a different rule set then when in range of enemies.
I don't know about you, but selecting an enemy at the start of a turn, then attacking another during that turn isn't something I'd expect to be doing in a turn based game.
▶ No.1009322>>1009323 >>1009335 >>1009427 >>1009436
>>1009321
>A one tile away enemy is a special situation.
No, it's not a special situation, it's always the same.
To move, you find all tiles in the map that are directly adjacent to an enemy, out of those tiles, you move towards the one with the cheapest path, you never "select an enemy" to move to, pic related is literally what the puzzle says, moving is separate from attacking.
▶ No.1009333
>>1009206
And now some guy dumped his into Unity.
▶ No.1009335>>1009344
>>1009323
>>1009322
>then the unit identifies all numbers that are in range of the largest number. This is all the numbers that are below the largest number without having another number larger than them.
>it says you have to find the second largest number
<no it doesn't it says something more verbose but that means the exact same thing
▶ No.1009344
>>1009335
>>then the unit identifies all numbers that are in range of the largest number. This is all the numbers that are below the largest number without having another number larger than them.
...the fuck? What the hell are you even talking about?
▶ No.1009350
>today
oh god it's day 15 all over again
▶ No.1009357>>1009359
>answer's wrong
>I can draw the answer and look at it and it's completely hugging fine
▶ No.1009358>>1009359
>you have to mess with creating multiple concurrent streams of water at once
Well, there goes my entire water flow code; it's useless now.
▶ No.1009359
>>1009357
ok the problem was that I had to ignore the first few lines of the output because my smallest y was > than the location THE WATER STARTS FROM
>>1009358
there's none of that in my input. just one +. Or do you mean where the stream splits?
it's easy to just loop over every single character in the input and apply logic based on the next char down, with a 'contained' check that looks left and right for paths down.
▶ No.1009361
today's not so bad. it's not day 15.
today benefits from it being very easy to visually check your work.
▶ No.1009364>>1009365
>loop over every single character in the input
I think that's what I was doing? (I can't read Ada)
I was just keeping track of the coordinates of the tail end of the water stream, and keeping a list of every split to return to once the current stream hits a dead end.
There's something wrong with my dead end checking though, it almost always works, but certain edge cases seem to break it. I'm currently trying to fix an error at the ~3000th tick.
▶ No.1009365>>1009366 >>1009374
>>1009364
>can't read Ada
phwah, what. It's super readable. I've never written any code so readable.
what you want to do with dead ends is set things up so that on the next tick you'll raise the water level. What the Ada's doing is
<if I'm looking at a | ...
<is the next character down a # or ~ ?
<if so, and if | is 'contained', then draw a line of static water
<if so, and if | isn't 'contained', then overflow '|' to the left and right
meanwhile, the contained check is just: starting at a coord and going right/left, do I find a # before I find a . below
▶ No.1009366
>>1009365
'|' overflow is just one char.
the '~' line drawing I do all at once.
▶ No.1009374>>1009378
>>1009365
>phwah, what. It's super readable. I've never written any code so readable.
Yeah, it is. My own code is many times uglier than yours, I'm just low IQ.
><if so, and if | is 'contained', then draw a line of static water
><if so, and if | isn't 'contained', then overflow '|' to the left and right
Ah. That would make a lot more sense. I just had a fill_water() function that did containment checking on it's own and decided which to draw. Stuffing everything into one function has caused quite literally all of my problems.
On the bright side, I've gotten fill_water() to work. Or at least, I thought I did. Had no errors, but answer is too high anyway.
▶ No.1009378>>1009383
>>1009374
>answer is too high
remember to ignore water outside the min/max coordinates in your input. Especially the Y min.
▶ No.1009382
>ignore tiles with a y coordinate smaller than the smallest y coordinate in your scan data
>my answer was off by 4 the whole time
Allah fucking kill me.
▶ No.1009383>>1009388 >>1009389
>>1009378
Yeah, thanks, I'm retarded holy shit
I'm failing part 2 though, my answer is apparently too low. Anything I should note? My part 2 answer is around 29292, and my part 1 is 35707
▶ No.1009388
>>1009383
Oh never mind, I'm beyond retarded, I accidentally removed my check for the minimum y, so I was >off by one
▶ No.1009389
>>1009383
draw your data and look at it. if you've got the wrong kind of water in a place, it should be pretty easy to see.
the y range is huge but the x range is small enough that you can view it in a terminal well enough, after shrinking the font
▶ No.1009425
Pajeet would have loved my code today.
▶ No.1009427>>1009428
>>1009322
>he still doesn't understand it
Are you literally retarded?
▶ No.1009428>>1009430
>>1009427
>Are you literally retarded?
Are you?
▶ No.1009430>>1009436
>>1009428
>no u
Thanks for the confirmation.
What the hell are you even doing here?
▶ No.1009436>>1009445
>>1009430
I'm not even >>1009322. I just did day 15 the same way he did (attack > else move > attack) and I'm wondering why the hell you seem to think it's different.
▶ No.1009445>>1009479 >>1009573
>>1009436
>I'm not him
Classic
Also, you're explaining it exactly the way I did it. You're just leaving out the most important part here. You just can't refuse to grasp the VERY SIMPLE fact I only did one scan per turn and attacked the same enemy I had moved towards, instead of scanning for HP again after the move.
It's really not that hard to understand if you aren't a complete imbecile. You seem to be autistic enough to follow the directions of this challenge to the letter, which is definitely an advantage for this one, so why you refuse to grasp why anyone would make a simple mistake like this is beyond me. Especially since so many struggled with this problem.
Unless you're just being an asshole because you're that much of a social inept retard and don't know any better. Assuming you're not just a plain retard and actually finished this challenge too.
▶ No.1009479
>>1009445
>hurr durr if you don't lack reading comprehension you're autistic XDDDDDDDDDDDDDDDDDDDDDD
▶ No.1009480>>1009538
Well shit I went the wrong direction with this one.
▶ No.1009538>>1009556
>>1009480
c, 5 ms:
#include <stdlib.h>
#include <stdio.h>
#define NEW(...) ({\
typeof(__VA_ARGS__) * _pt = malloc(sizeof(__VA_ARGS__));\
*_pt = __VA_ARGS__;\
_pt;\
})
#define MX 1600
#define MY 2000
typedef struct flow {
int x;
int y;
struct flow * next;
} flow;
enum {SAND, CLAY, DOWN, SIDE, LEFT, RIGHT, UP} grid[MX][MY];
#define CASE break; case
void pgrid(int a, int b, int c, int d){
for(int y=a; y<b; y++){
for(int x=c; x<d; x++) switch(grid[x][y]){
CASE SAND: printf(".");
CASE CLAY: printf("#");
CASE DOWN: printf("|");
CASE SIDE: printf("~");
CASE UP: printf("^");
CASE LEFT: printf(">");
CASE RIGHT: printf("<");
}
printf("\n");
}
}
int main(int argc, char ** argv){
FILE * f = fopen(argc>1?argv[1]:"17.txt", "r");
int maxy = 0, miny=MY;
char rc, cc;
int ri, ca, cb;
while(fscanf(f, "%c=%d, %c=%d..%d\n", &rc, &ri, &cc, &ca, &cb) == 5)
if(rc == 'x'){
for(int y=ca; y<=cb; y++){
grid[ri][y] = CLAY;
if(y>maxy) maxy = y;
if(y<miny) miny = y;
}
}else{
if(ri>maxy) maxy = ri;
if(ri<miny) miny = ri;
for(int x=ca; x<cb; x++)
grid[x][ri] = CLAY;
}
flow * head, * tail;
grid[500][miny] = DOWN;
head = tail = NEW((flow){.x=500, .y=miny});
int part1 = 0, part2 = 0;
#define GET(X, Y) grid[head->x+X][head->y+Y]
#define SET(X, Y, val) do{ \
if(head->y+Y<=maxy){ \
if(GET(X, Y)==SAND) part1++; \
if(val==UP) part2++; \
GET(X, Y) = val; \
tail = tail->next = NEW((flow){.x=head->x+X, .y=head->y+Y}); \
} \
}while(0)
while(head){
if(GET(0, 0) == DOWN){
if(GET(0, 1) == SAND) SET(0, 1, DOWN);
if(GET(0, 1) == CLAY || GET(0, 1) == UP)
SET(0, 0, SIDE);
}else if(GET(0, 0) == SIDE){
if(GET(0, 1) == SAND){
SET(0, 0, DOWN);
}else{
if(GET(-1, 0) == SAND) SET(-1, 0, SIDE);
if(GET(+1, 0) == SAND) SET(1, 0, SIDE);
if(GET(-1, 0) == CLAY) SET(0, 0, LEFT);
if(GET(+1, 0) == CLAY) SET(0, 0, RIGHT);
}
}else if(GET(0, 0) == LEFT){
if(GET(1, 0) == SIDE || GET(1, 0) == SAND)
SET(1, 0, LEFT);
if(GET(1, 0) == RIGHT || GET(1, 0) == CLAY)
SET(0, 0, UP);
}else if(GET(0, 0) == RIGHT){
if(GET(-1, 0) == SIDE || GET(-1, 0) == SAND)
SET(-1, 0, RIGHT);
if(GET(-1, 0) == LEFT || GET(-1, 0) == CLAY)
SET(0, 0, UP);
}else if(GET(0, 0) == UP){
if(GET(0, -1) == DOWN) SET(0, -1, SIDE);
if(GET(-1, 0) == LEFT) SET(-1, 0, UP);
if(GET(1, 0) == RIGHT) SET(1, 0, UP);
}
flow * next = head->next;
free(head);
head = next;
}
//pgrid(miny, maxy, 400, 600);
printf("%d\n%d\n", part1, part2);
}
pretty ugly code, I thought the transition rules were gonna end up simpler than they did.
▶ No.1009556
>>1009538
I'm not sure if it was possible to do in a really elegant way.
▶ No.1009573>>1009576
>>1009445
>I only did one scan per turn and attacked the same enemy I had moved towards, instead of scanning for HP again after the move.
But why? How spaghetti is your code to end up doing something as ridiculous as this?
>why you refuse to grasp why anyone would make a simple mistake like this is beyond me.
...because you could just read the instructions? Seriously nigger? Is it really so difficult to just focus on a task you're given, and to complete it?
>Unless you're just being an asshole because you're that much of a social inept retard and don't know any better.
Why else would I be on 8chan?
▶ No.1009576>>1009604
>>1009573
most tasks you're given, you're paid for. so if a manager says "move this pile of dirt one mile down the road. I'll only accept the results if it's clear you used a spoon to move the dirt", it's reasonable -- desirable -- that you object: wait, what the fuck? Why is the task only acceptable in that case? I can move the dirt a lot faster if I use a couple of large trucks. Managers know what they want but they don't know everything, so the why matters. Maybe the spoon idea only came up because the pile of dirt is really clumpy and clumpiness needs to be resolved as well as the dirt moved, and "well move it with a spoon" was the best idea the guy could come up with, to move dirt while breaking it up.
day 15's instructions are fucking dumb. only a slave would accept a task like this without balking continuously.
▶ No.1009604
>>1009576
>day 15's instructions are fucking dumb. only a slave would accept a task like this without balking continuously.
says the niggermonkey who did 15 puzzles 4free
▶ No.1009615>>1009651
>2018
>year of the 2d array of char
▶ No.1009616
▶ No.1009618
>think I've done part 1 in 3 seconds
>realise the entire thing is wrong and horribly fails even test input
fug
▶ No.1009619>>1009622 >>1009791
I really hate these "print out obvious pattern and math it out" problems.
▶ No.1009621
>it's another, "what's the answer after 6 gorillion years, goy?" day
pythonfags on suicide watch
▶ No.1009622
>>1009619
>wait 5 minutes again because you have no easy way to verify that your shitty modular math makes sense
>am programmer
▶ No.1009624>>1009628
minute 4972: total resource value: 195789 <--
minute 4973: total resource value: 197050
minute 4974: total resource value: 197532
minute 4975: total resource value: 195300
minute 4976: total resource value: 194856
minute 4977: total resource value: 193050
minute 4978: total resource value: 192765
minute 4979: total resource value: 191700
minute 4980: total resource value: 188682
minute 4981: total resource value: 186017
minute 4982: total resource value: 182320
minute 4983: total resource value: 180687
minute 4984: total resource value: 180348
minute 4985: total resource value: 179820
minute 4986: total resource value: 181440
minute 4987: total resource value: 182910
minute 4988: total resource value: 185433
minute 4989: total resource value: 188020
minute 4990: total resource value: 189405
minute 4991: total resource value: 190704
minute 4992: total resource value: 189660
minute 4993: total resource value: 187074
minute 4994: total resource value: 186186
minute 4995: total resource value: 187000
minute 4996: total resource value: 186238
minute 4997: total resource value: 187152
minute 4998: total resource value: 190494
minute 4999: total resource value: 193328
minute 5000: total resource value: 195789 <--
so it's a 28-length cycle. 1000000000 mod 28 is 20. But the answer is not
minute 4976: total resource value: 194856
although 4976 mod 28 is also 20.
▶ No.1009625
minute 616: total resource value: 180348
minute 617: total resource value: 179820 <-- beginning of cycle
so, bignum - 617 % 28 is 19. So pick the 20th repeating value, starting at 1 = 179820?
I may as well be talking about alchemical reactions here.
▶ No.1009626>>1009627
>wait 5 more minutes
OK waiting for the program to finish.
▶ No.1009627
>>1009626
just going to take 5:30h at this rate.
but the alternative is random fucking guessing even though I have the pattern right in front of my face.
▶ No.1009628
>>1009624
>math was right
>printed 'minute' was off by one
▶ No.1009629>>1009634
Ada, day18, 5.5h runtime.
Count_Around began life as a higher order function, but Ada closures have some restrictions that I ran into
>subprogram must not be deeper than access type
would definitely be faster to loop over inner axes separately from edges, separately from corners.
probably still fast enough to pad the input with a meaningless char.
▶ No.1009632>>1009636
ArrayFilter[] was quite nice here. Second part was just figuring out the pattern, which I did semi-manually.
▶ No.1009634
>>1009629
>subprogram must not be deeper than access type
I remember the Access rules being fairly complex, in the Barnes book that was probably the 'brainlet-filter' chapter. If I recall, it mostly did the obvious thing, but there were some pretty funny edge cases.
▶ No.1009636>>1009638
Ada version that'll only take 3h
Input's padded with !
>>1009632
a missing programming language/environment categorization is 'workspace language'
something immune to complaints like
>wait 22 minutes for part1 output
>part2 just wants some data that the program had, before it exited
>now must wait 22 more minutes
because all of your state is still present in the workspace
seems it's mainly Smalltalk and some mathy languages where people actually do this, even though it should be possible whenever you've a decent repl
▶ No.1009638>>1009640
>>1009636
What puzzle thus far has had a 22 minute part1?
▶ No.1009640>>1009642
>>1009638
some halfchan anon's part1 for day 17 took 22 minutes
▶ No.1009642
>>1009640
Let me guess, scripting language and he didn't terminate early when encountering a stream. Funnily enough, if you did part1 efficiently, it made part2 quite simple.
▶ No.1009651>>1009652
>>1009615
25 days of GRIDS. Feeling pozed yet?
▶ No.1009653
>>1009652
Is he Jewish? Have we been stuck in a Jewish concoction? Think how many families have had their Christmas season ruined as men ignore their children to solve puzzles. (((Play some puzzles goy?)))
▶ No.1009708>>1009710 >>1009712
>value you entered was too low
>literally the highest value in the loop
lmao
▶ No.1009710
>>1009708
>hmm multiplication could have some collisions I better store the tree and lumber values instead
>some time later realise the tree and lumber values could collide
>use the entire grid as key
>works
good stuff
▶ No.1009712
>>1009708
>advent of cellular automata
lmao
▶ No.1009791>>1009801
>>1009619
I wish we had more math involved to be honest. I'd like a few more filters to edge out "web devs."
▶ No.1009801>>1009849 >>1010708
>>1009791
I'd rather see that with clever part2s, "did you cheat on part1? hah, now you've got to start from scratch!" there were several of those in 2017, where people solve part1 with math and then had to start coding for part2, but I'd like it more if part2 punished too-specific coding instead of 'cheating'. I mean the kind of shit you see with Haskell LARPers, where the code is cute as a button but the slightest "could you make this part green instead of red?" change in requirements would require massive rewrites.
also, tasks that are very sensitive to choice of data structure. we've already had a few of those this year, where using normal scripting-language data structures will cause your program to take minutes instead of milliseconds.
rather than "wait five hours or print out a pattern that even a slab of concrete would detect immediately", I'd prefer "wait 30 minutes or notice a subtler pattern". That's short enough that if you screw up a few times on the math, the program can finish and win the race. And that'll still be "wait 5 hours" for a web dev solution.
▶ No.1009849>>1009857
>>1009801
>requirements would require massive rewrites
Hah. B-b-but it was point free!!! I used applicative functors! Now I've got DO monads everywhere KILL ME!!!
>that'll still be "wait 5 hours" for a web dev solution.
I guess that's why you don't see many web devs going past the first 30 or so problems in projecteuler. Bruteforce can take you quite far, but once you get past the first hundred or so, you've really got to have an understanding of math (number theory in particular).
▶ No.1009857>>1009865
>>1009849
>the first hundred
You know you're stretching when math fags get brute forced for over 100 problems by webdevs and no math fags can even make an imageboard.
▶ No.1009865>>1009866
>>1009857
Well webdevs probably die off at around 30 problems in, but the nomath-programmmers might be able to kick get near 100.
I don't want a webdev making an image board either, especially not one which is popular and performant. The last time we tried that, our resident lower-than-webdev produced garbage with O(n^3) loops everywhere and failed to deliver anything.
▶ No.1009866
>>1009865
*kick in bruteforce to get...
▶ No.1010154
▶ No.1010155
Day 19 LADS: No more GRIDS please edition
▶ No.1010157>>1010159
▶ No.1010159>>1010180 >>1010183
>>1010157
means it's another "run this program until 2**128 overflows or else notice the pattern"
▶ No.1010175>>1010180
part2 seems too innocently easy...
▶ No.1010180>>1010182
▶ No.1010182>>1010184
>>1010180
No. It's dissaembly, and remove the loop.
▶ No.1010183
>>1010159
>redefines register type to be mod just-over-the-big-magic-number
>now register 0 is counting up
this would be a nice time to be using a language like lisp, where you could just C-c, change a register value, and resume
▶ No.1010184>>1010186
>>1010182
I was hoping you were wrong, but it's an infinite loop huh.
▶ No.1010186
>>1010184
Not infinite, just inneficient. They had one like this last year. You have to simplify it, and then rerun it. So we have to figure out what it "does" first.
▶ No.1010189>>1010190
is part 1 supposed to loop infinitely? Please help
▶ No.1010190>>1010196
▶ No.1010192
Finally have a strategy to solve part2... i hope this works.
▶ No.1010196>>1010199
>>1010190
>No.
WHAT DO YOU MEAN NO? AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
The test input worked. Is it supposed to finish in 1ms or something? I sincerely thought that the 2**128 thing also referred to part 1, and that you were supposed to figure out a pattern.
▶ No.1010199>>1010204 >>1010207
>>1010196
p1:easy.
p2:write into a higher level synatax, figure wtf is going on, and probably solve it manually.
▶ No.1010204
>>1010199
>p1:easy.
Yeah, it was. It only took 40 minutes to bruteforce
>p2:write into a higher level synatax, figure wtf is going on, and probably solve it manually.
I was trying that, and still am, although I should probably consider myself filtered at this point.
▶ No.1010207>>1010209
>>1010199
>manual disassembly
what I'm trying is fudging the constant until I see a pattern in the final result
▶ No.1010209>>1010211
>>1010207
70 -> register 0: 144
71 -> register 0: 72
72 -> register 0: 195
73 -> register 0: 74
74 -> register 0: 114
75 -> register 0: 124
76 -> register 0: 140
77 -> register 0: 96
78 -> register 0: 168
79 -> register 0: 80
80 -> register 0: 186
81 -> register 0: 121
82 -> register 0: 126
83 -> register 0: 84
84 -> register 0: 224
85 -> register 0: 108
86 -> register 0: 132
87 -> register 0: 120
88 -> register 0: 180
89 -> register 0: 90
90 -> register 0: 234
91 -> register 0: 112
92 -> register 0: 168
93 -> register 0: 128
94 -> register 0: 144
95 -> register 0: 120
96 -> register 0: 252
97 -> register 0: 98
...what
▶ No.1010211>>1010212
>>1010209
I rewrote it in pseudo code, and still don't see the pattern... yet.
▶ No.1010212
>>1010211
Algorithm I mean, not pattern. Once I know what it "does", I can just solve it with a calculator.
▶ No.1010228
Wait, is the entire program seriously just two for loops? No wonder bruteforcing part 1 was possible even on python.
▶ No.1010231
Wew. I passed the filter.
▶ No.1010232
▶ No.1010234>>1010235
Hint: **Delete the last line of your input file (the one which is essentially a GOTO 1) so that your program terminates before going into the loop.
See what value has been assigned to your registers. You can tell from the bottom of the input file which one it has been working on (for me it was R3).
The "algorithm" is an operation on this number.**
▶ No.1010235
>>1010234
Well that screwed up. I guess if you don't want the hint, don't read.
▶ No.1010239
Also above, I should have wrote r5, not r3, but that might vary anyways. The register you're operating on will be in the 3rd last line of your input.
Complete hint: The code puts a large number in a register, and then places the Divisor Sigma of it into r0 (the sum of all its divisors)
▶ No.1010240>>1010241
>your answer for part 2 is too high
AHHHHHHHHHHHHHHHHHHHHHHHH
Is it logical to transform the following code:
uint64_t regist[] = {1,0,0,<input_number+x>,0,<input_number>};
for (regist[4] = 1; regist[4] <= regist[3]; regist[4]++)
for (regist[2] = 1; regist[2] <= regist[3]; regist[2]++)
if (regist[4] * regist[2] == regist[3]) regist[0] += regist[4];
printf("Ans: %llu\n", regist[0]);
into
uint64_t regist[] = {1,0,0,<input_number+x>,0,<input_number>};
for (regist[4] = 1; regist[4] <= regist[3]; regist[4]++) if (regist[3]%regist[4] == 0) regist[0]+=regist[4];
printf("Ans: %llu\n", regist[0]);
It worked for part 1, I don't know why it shouldn't work for 2.
▶ No.1010241>>1010242
>>1010240
The difference in Part2, is that setting A=1 initially, causes the code to operate on a much, much larger value. I don't think you can brute force this.
▶ No.1010242>>1010254
>>1010241
25: GOTO PC+A + 1 ;
26: GOTO 1
27: D = C
28: D = D*PC
29: D = PC+D
30: D = PC*D
31: D = D*14
32: D = D*PC
33: E = E+D
34: A = 0
35: GOTO 1
To explain what I mean, if A is zero, it just goes to 1 directly, instead of computing the large number into what is ultimately E (or R5).
▶ No.1010243>>1010244
Part 2 was so easy
but it took me 2 hours 21 minutes because I'm such a fucking retard
the solution was literally one line of code
I want to kill myself
▶ No.1010244>>1010245 >>1010246
>>1010243
You mean part1? Part2 doesn't really involve much code.
▶ No.1010245>>1010247
>>1010244
no, I meant part 2.
like I said, I'm a fucking retard.
▶ No.1010246
>>1010244
Like, I identified exactly the portion of the assembly that I needed to solve in under 2 minutes
then it took another 2 hours to actually solve it
I don't know why
time literally disappeared
▶ No.1010247>>1010248
>>1010245
You're not on our scoreboard then.
▶ No.1010248>>1010249
>>1010247
I'm here from the other chan because it's been down all day
▶ No.1010249
▶ No.1010254>>1010256 >>1010259
>>1010242
longpost got disappeared by browser. Long story short, I already know what you're talking about, if you read my code (did you quote the wrong person?) I calculated the large initial registers for part 2[1,0,0,10551408,0,10550400] and 1[0,0,0,1008,0,172], and I found out the divisor sigma thing as well, simplifying the code to:
for (regist[4] = 1; regist[4] <= regist[3]; regist[4]++) if (regist[3]%regist[4] == 0) regist[0]+=regist[4];
which works for part 1, but not 2.
▶ No.1010256>>1010377
>>1010254
I just misunderstood it. Your final answer is 39967680 then. I don't see what's wrong with that code...
▶ No.1010259>>1010377
>>1010254
Ah, I think you mean register5 instead of 3?
▶ No.1010355
>advent of reuse problems from last year
lmao
▶ No.1010377
>>1010256
Uh, that answer's too high. Actually, even my answer of 32188417, 20% lower, was too high.
>>1010259
Maybe our important registers are different? My input's 3rd last line stores a value into register 3. The whole thing is here:
#ip 1
addi 1 16 1
seti 1 4 4
seti 1 1 2
mulr 4 2 5
eqrr 5 3 5
addr 5 1 1
addi 1 1 1
addr 4 0 0
addi 2 1 2
gtrr 2 3 5
addr 1 5 1
seti 2 4 1
addi 4 1 4
gtrr 4 3 5
addr 5 1 1
seti 1 1 1
mulr 1 1 1
addi 3 2 3
mulr 3 3 3
mulr 1 3 3
muli 3 11 3
addi 5 7 5
mulr 5 1 5
addi 5 18 5
addr 3 5 3
addr 1 0 1
seti 0 7 1
setr 1 3 5
mulr 5 1 5
addr 1 5 5
mulr 1 5 5
muli 5 14 5
mulr 5 1 5
addr 3 5 3
seti 0 7 0
seti 0 6 1
I converted this into more readable statements manually, and I was going to post the rest, but I just realized why my answer was wrong. At the C code, I set
unsigned long long regist[] = {1,0,0,10551408,0,10550400};
I'd forgotten that at the end of the input, there was this line:
seti 0 7 0 #-> regist[0] = 0
Since the answer is looking for the value of register 0, and I had set it to start at 1 instead of 0, my answer was naturally,
>off by one
Again. Kill me. This is the 3rd day in a row I've gotten an off-by-X.
▶ No.1010404>>1010436
I had to solve part 2 by hand.
▶ No.1010436>>1010438 >>1010441 >>1010453
>>1010404
haha, what?
this is a programming competition
I am content to wait for part2 to finish computing
▶ No.1010438>>1010449
>>1010436
>optimizing a program so it runs faster doesn't count as programming
probably one of the funner challenges tbh. I'd love to see someone cook up a mathematica program to simplify the input down to a couple for loops automatically.
▶ No.1010441
>>1010436
It's like O(n**2).
▶ No.1010449
>>1010438
Well I did use Mathematica to strip out the final loop, does that count?
▶ No.1010453
>>1010436
Hah. Are you this >>1008199 C nigger?
▶ No.1010454
I finally finished day 17 and am complete once again.
▶ No.1010492>>1010626
It looks like Day19 might turn out to be a pretty good filter.
▶ No.1010618
what happened to crypto? so much 2d
▶ No.1010619>>1010621 >>1011087
Day 2.
C noob here. Roast away. (decided to keep fcopy2array for until I go further into K&R or I have more spare time)
#include <stdio.h>
#include <string.h>
#define filename "input.txt"
#define a (250)
#define b (26 + 1 + 1) //wc doesn't count \n. so, +1 for \n, +1 for having a '\0' at the end after filling A[][] w/ the data
void fcopy2array(char fileName[25], int lmax, char A[][lmax]);
int duplicateLetters(int count, int rows, int cols, char A[][cols]);
int compareStr(char s1[], char s2[]);
int main(){
//part 1
char A[a][b] = { '\0' };
fcopy2array(filename, b, A);
int twos = duplicateLetters(2, a, b, A),
threes = duplicateLetters(3, a, b, A);
printf("%d %d %d\n", twos, threes, (twos * threes));
//part 2
int j; //iterate through A[a][b]
int jsave = 0;
for(j = 0; j < a; ++j){
jsave = j;
++j;
for(; j < a; ++j){
if( compareStr(A[jsave], A[j]) == 1 )
printf("%s%s", A[jsave], A[j]);
}
j = jsave;
}
}
/* compareStr --> return number of char differences in the same position for strings stored in s1[] and s2[]. Assumes the sizes of s1 and s2 to be equal*/
int compareStr(char s1[], char s2[])
{
int i, chg = 0; //i to iterate, chg to store num of differences between two strings
for(i = 0; s1[i] != '\0'; ++i){
if(s1[i] != s2[i])
++chg;
}
return chg;
}
/*
duplicateLetters -->in a charray A[][cols], whose rows are strings, count and print those that contain a char exactly 'count' times.
*/
int duplicateLetters(int count, int rows, int cols, char A[][cols])
{
int numPrey = 0; //the number of strings that meet the criterion
char buff[rows][cols];
memcpy(buff, A, (rows * cols * sizeof(char)));
int i, j; //j for rows, i for columns in the 2d array w/ the strings
int k; //to iterate through B[][]
char B[26][2] = { '\0' }; //the input only has lowercase letters. this array will store counts for each lowercase letter.
//fill 0th column with the lowercase letters
for(k = 0; k < 26; ++k){
B[k][0] = 97 + k;
}
for(j = 0; j < rows; ++j){
//reset B's counts to 0
for(k = 0; k < 26; ++k)
B[k][1] = '\0';
for(i = 0; i < cols; ++i){
for(k = 0; k < 26; ++k)
if(buff[j][i] == B[k][0]){
++B[k][1];
}
}
//now we have the letter frequency data for a single string, inside B[][]
//time to check whether this string has any letter exactly 'count' times
for(k = 0; k < 26; ++k)
if(B[k][1] == count){
++numPrey;
k = 26; //to not count "aabbc" twice for both 'a' and 'b', end the process as soon as the row is found to be containing one letter 'count' times.
}
}
return numPrey;
}
/* fcopy2array --> read lines from file 'fileName', populate array A[][] with those lines, one line per one row, until EOF is reached. the dimensions of A[][] need to be determined beforehand by using fmaxlength() and fnumLines()*/
void fcopy2array(char fileName[25], int lmax, char A[][lmax])
{
char c;
FILE *fp;
fp = fopen(fileName, "r");
int i = 0; //column position in A[row][column]
int j = 0; //row position in A[][]
while((c = fgetc(fp)) != EOF){
if(c == '\n'){
A[j][i] = c;
++j;
i = 0;
}
else{
A[j][i] = c;
++i;
}
}
fclose(fp);
}
▶ No.1010621
>>1010619
Day 3
#include <stdio.h>
#include <stdlib.h>
#define fname "input3.txt"
#define a 1293 //number of lines in input
#define b (22 + 1 + 1) //max width of input lines, +2 for \n and '\0'
void fcopy2array(char fileName[], int lmax, char A[][lmax]);
void showFabric(int x, int y, int width, int height, int widthTotal, int fabric[][widthTotal]);
void claimFabric(int row, int cols, int B[][cols], int widthTotal, int fabric[][widthTotal]);
int checkFabric(int row, int cols, int B[][cols], int widthTotal, int fabric[][widthTotal]);
int main(){
char A[a][b] = { '\0' };
fcopy2array(fname, b, A); //copying file into A[][]
int B[a][5] = { 0 }, i = 0; //B holds parsed data. parse w/ sscanf below.
for (i = 0; i < a; ++i)
sscanf(A[i], "#%d @ %d,%d: %dx%d ", &B[i][0], &B[i][1], &B[i][2], &B[i][3], &B[i][4]);
/*each time a claim occupies a coordinate, ++fabric[x][y]. fabric[x][y] holds the number of claims made on (x,y)*/
int fabric[1000][1000] = { '\0' };
//filling out the claims in fabric[][]
for(i = 0; i < a; ++i)
claimFabric(i,5,B,1000,fabric);
//finally, "How many square inches of fabric are within two or more claims?"
int j, k = 0;
for(j = 0; j < 1000; ++j)
for(i = 0; i < 1000; ++i)
if(fabric[j][i] > 1)
++k;
printf("%d\n", k);
//"what is the ID of the only claim that doesn't overlap?"
/* make function that goes through claims, and checks if their coordinates are just 1*/
j = 0;
for(i = 0; i < a; ++i){
j = checkFabric(i, 5, B, 1000, fabric);
if(j > -1)
printf("%d\n", j+1);
}
}
int checkFabric(int row, int cols, int B[][cols], int widthTotal, int fabric[][widthTotal])
{
int j, i; //iterators for y and x coords, respectively
for (j = B[row][2]; j < (B[row][2] + B[row][4]); ++j)
for (i = B[row][1]; i < (B[row][1] + B[row][3]); ++i)
if(fabric[j][i] > 1)
return -1;
return row;
}
/*
claimFabric : claim a piece from fabric[][widthTotal] according to the claim that resides in row 'row' of B[][cols] which is assumed to be holding properly sscanf'd elven claims on chimney entry assistance fabric.
*/
void claimFabric(int row, int cols, int B[][cols], int widthTotal, int fabric[][widthTotal])
{
int i,j; //iterators for x and y coords, respectively
//B columns are 0 to 4 and claim#, x, y, width, height respectively
//row happens to be (claim# - 1)
for (j = B[row][2]; j < (B[row][2] + B[row][4]); ++j)
for (i = B[row][1]; i < (B[row][1] + B[row][3]); ++i)
++fabric[j][i];
}
/* showFabric: print out a certain portion of fabric[1000][1000] or fabric[what][ever] in general. x and y are horizontal and vertical distance from the left and top edges of a given fabric. width and height are horizontal and vertical dimensions of the portion to be printed out. */
void showFabric(int x, int y, int width, int height, int widthTotal, int fabric[][widthTotal]) //use the same system as the puzzle
{
int i, j; //iterators for columns and rows, respectively
for(j = y; j < (y + height); ++j){
for(i = x; i < (x+width); ++i){
printf("%d", fabric[j][i]);
}
putchar('\n');
}
}
/* fcopy2array --> read lines from file 'fileName', populate array A[][] with those lines, one line per one row, until EOF is reached. the dimensions of A[][] need to be determined beforehand by using fmaxlength() and fnumLines()*/
void fcopy2array(char fileName[], int lmax, char A[][lmax])
{
char c;
FILE *fp;
fp = fopen(fileName, "r");
int i = 0; //column position in A[row][column]
int j = 0; //row position in A[][]
while((c = fgetc(fp)) != EOF){
if(c == '\n'){
A[j][i] = c;
++j;
i = 0;
}
else{
A[j][i] = c;
++i;
}
}
fclose(fp);
}
▶ No.1010622>>1010624 >>1010625
Am I being dumb, or is this a hard sentence to parse?
>What is the largest number of doors you would be required to pass through to reach a room? That is, find the room for which the shortest path from your starting location to that room would require passing through the most doors; what is the fewest doors you can pass through to reach it?
▶ No.1010623
>path collisions and tree regexes
Filtered. Why did I even bother waking up today.
▶ No.1010624
>>1010622
you're not dumb, but all it's saying is "what's the largest number of doors required to pass through to reach a room without stupid shit going in a loop forever"
▶ No.1010625
>>1010622
>Am I being dumb, or is this a hard sentence to parse?
You're being dumb.
>What is the largest number of doors you would be required to pass through to reach a room?
This is the general question to find the answer to.
<That is, find the room for which the shortest path from your starting location to that room would require passing through the most doors; what is the fewest doors you can pass through to reach it?
This is the longer, more verbose explanation of what the question entails.
Basically,
1. Find the room that has the highest minimum valid distance from the start point
2. Give the number of doors you need to pass through to get there.
▶ No.1010626
>>1010492
Congratulations, there are 53,786 people smarter than you
▶ No.1010630>>1010633
>program works for test input 3
>"Oh wow, I bet it totally works now!"
<completely fails every other test input, except 1
How the fuck does this even occur? How do you get one test working perfectly while the rest is broken?
▶ No.1010633>>1010635
>>1010630
Oh, nevermind. I naively just split the input at every '|', causing lower (|) nodes to be split as well.
My recursive solution for part 1 has been running for 5 minutes now. How long should this be taking?
▶ No.1010635>>1010638
▶ No.1010638>>1010648
>>1010635
Okay, my recursive plan must be retarded, then. By my calculations, the number of total characters it has to parse is in the hundred millions (or maybe billions? It's still counting).
def branch(s,x,y):
...
if s[i] == '(':
t = s[i+1:]
b_end = find_matching_brace(t)
branches = get_branches(t[:b_end+1])
for b in branches:
branch(b + t[b_end+1:], cx, cy)
break
...
I don't see where the problem is. I would assume that it's because I add +t[b_end+1:] to every branch, but I don't see how else you'd recurse through the input.
▶ No.1010644>>1010646
>raised ADA.STRINGS.INDEX_ERROR : a-strunb.adb:782
it's nice and all to know where exactly in the system library this exception is raised, but where is it raised in my code? Isn't a stack trace obviously necessary when you have exceptions?
▶ No.1010646
>>1010644
found it: https://gcc.gnu.org/onlinedocs/gnat_ugn/Symbolic-Traceback.html#Symbolic-Traceback
however ...
[./day20]
0x427cc5 ada__strings__unbounded__element at ???
day20__trace.11751 at day20.adb.dg:16443
day20__fully_trace.11753 at day20.adb.dg:16569
_ada_day20 at day20.adb.dg:16978
Main at b~day20.adb:290
[/lib64/libc.so.6]
0x7f63d40eb411
[./day20]
0x40534c _start at ???
0xfffffffffffffffe
although it looks like it, there are no actual line numbers for my actual code in this output.
I am disappointed, Ada.
▶ No.1010648>>1010656 >>1010674 >>1010678
>>1010638
find_matching_brace is very suspect
you shouldn't be doing any looking ahead in your recursive code, ever, for any problem where you are using recursion
▶ No.1010650>>1010667
I've been filtered. I give up.
▶ No.1010656
>>1010648
probably problem as well. pic related fails on the last two examples, it doesn't draw them square..
I think this method isn't totally hopeless since it works as well as it does, but I don't want to do the rest of the problem anyway.
I'm clearly filtered by any kind of requirement to search a graph.
I'll work on that for next year.
▶ No.1010658
My prob1 is taking a while to run... it should work...
▶ No.1010662
Finally. I started off stupid, and came out alright.
▶ No.1010667>>1010671
>>1010650
Well if it helps you, here's my solution. Part2 asks you to count doors 1000 away from the start, if you're wondering why that is there.
▶ No.1010671
>>1010667
A cleaned up version:
▶ No.1010674
>>1010648
>find_matching_brace is very suspect
def find_matching_brace(s):
brace = 1
for i in range(len(s)):
if s[i] == '(': brace+=1
elif s[i] == ')': brace-=1
if not brace: break
else: print "no matching brace found" #note that this line has never been triggered in the 2 hours my code has run
return i
>you shouldn't be doing any looking ahead in your recursive code, ever, for any problem where you are using recursion
So I should put the branch separation at the top of branch()? Then I'd need to write special shit for the initial root branch, instead of just writing
branch(s,0,0)
at the end.
Maybe get_branches() is faulty. For your viewing pleasure:
def get_branches(s):
brace, prev = 0, 0
b_list = []
for i in range(len(s)): #last ) uncounted
if s[i] == '(': brace+=1
if s[i] == ')': brace-=1
if s[i] == '|' and not brace:
b_list.append(s[prev:i])
prev+=i+1
b_list.append(s[prev:i])
return b_list
At this point, I'm seriously considering just expanding the entire regex and filling the map in path-by-path that way.
Except that I don't even know how to program that. Even with a helper library. Kill me.
▶ No.1010678
>>1010648
>>you shouldn't be doing any looking ahead in your recursive code, ever,
>Not using the stack frame as a convenient stack.
▶ No.1010690
Alternative version, using the built in Graph functions.
▶ No.1010708>>1010728 >>1010768
>>1009801
>the slightest "could you make this part green instead of red?" change in requirements would require massive rewrites.
Just because you're too dumb to figure out how to fix something doesn't mean everyone else is
▶ No.1010728
>>1010708
Q: what's the sound of a Haskeller falling down the stairs?
A: mostly bumps and shrieks of pain, but distinctively: "I'm smart!"
yeah, massive rewrites aren't a problem of figuring out what to do, bossman. It's a problem of having to do that in the first place. It's a problem of proportionality. Although it's reasonable to convey a sense of cost to a customer when a feature request comes in, you may find it embarrassing to explain that a feature is cheaply done by other people and expensively done by you because your code is pointlessly inflexible. Especially if the customer is your boss.
▶ No.1010744>>1011754
import networkx as nx
def make_graph(t):
G = nx.Graph()
move = {'E':(1,0), 'W':(-1,0), 'N':(0,-1), 'S':(0,1)}
pos = (0,0)
st = []
for c in t:
if c in 'EWSN':
last_pos = pos
pos = tuple(a + b for a, b in zip(pos, move[c])) #lol
G.add_edge(last_pos, pos)
elif c == '(':
st.append(pos)
elif c == '|':
pos = st[-1]
elif c == ')':
pos = st.pop()
elif c == '$':
break
return G
def solve():
f = open('20input.txt', 'r').read()
G = make_graph(f)
start = (0,0)
lens = nx.single_source_shortest_path_length(G, start).values() #from start to all pts
print('P1:', max(lens))
print('P2:', len(list(filter(lambda x: x >= 1000, lens))))
solve()
Today was really hard until I read mathfags code and then thought gee I bet python has some import solution type library. 1 hour later and here we are.
Suck it library-less nerds.
▶ No.1010768>>1010771
>>1010708
This is the sort of retort where you end up insulting yourself instead of the guy you intended. Have you seen how disastrous a change in an algorithm can be to an elegant Haskell solution? You'd be pretty stupid to deny it is disruptive.
▶ No.1010771>>1010773
>>1010768
Here we see the wild haskeller in its natural habitat. The haskeller is a curious animal, who spends most of its time in darkness reading category theory textbooks. Here, we can see the male haskeller attempting to seduce a female haskeller with his proclamation of intellect.
▶ No.1010773
>>1010771
I'm defending the guy who is critiquing Haskell. I was a Haskellfag once, but someday, when I am brave enough, I will tell my story.
▶ No.1010820
I've written some code which gave the correct solution on first try. Upon closer inspection, I found out the code is actually broken and shouldn't work properly, yet it yielded the correct answer. Could anyone try and explain why it works?
namespace ConsoleApp5
{
class Program
{
static void Main(string[] args)
{
string input = @"C:\Users\root\Documents\input.txt";
Map map = new Map();
map.ParseMap(input);
}
}
public class Map
{
StreamReader file;
Dictionary<Coords, List<Coords>> Doors = new Dictionary<Coords, List<Coords>>();
HashSet<Coords> forkedCoords = new HashSet<Coords>() { new Coords(0, 0) };
public void ParseMap(string input)
{
file = new StreamReader(input);
RecurseParsing(new Coords(0, 0));
BreadthFirstSearch();
}
public void RecurseParsing(Coords startCoords)
{
Coords currentCoords = startCoords;
forkedCoords.Remove(currentCoords);
while (!file.EndOfStream)
{
char nextChar = (char)file.Read();
switch (nextChar)
{
case ')':
case '$':
forkedCoords.Add(currentCoords);
return;
case '(':
RecurseParsing(currentCoords);
break;
case '^':
break;
case '|':
forkedCoords.Add(currentCoords);
currentCoords = startCoords;
break;
default:
var newCoords = getNextCoords(nextChar, currentCoords);
if (!Doors.ContainsKey(currentCoords))
{
Doors.Add(currentCoords, new List<Coords>());
}
if (!Doors.ContainsKey(newCoords))
{
Doors.Add(newCoords, new List<Coords>());
}
Doors[newCoords].Add(currentCoords);
Doors[currentCoords].Add(newCoords);
currentCoords = newCoords;
break;
}
}
}
public void BreadthFirstSearch()
{
Dictionary<Coords, int> distances = new Dictionary<Coords, int>();
Queue<Coords> searchQueue = new Queue<Coords>();
searchQueue.Enqueue(new Coords(0, 0));
distances.Add(new Coords(0, 0), 0);
while (searchQueue.Any())
{
var searchedCoords = searchQueue.Dequeue();
foreach (var neighbour in Doors[searchedCoords])
{
if (!distances.ContainsKey(neighbour))
{
searchQueue.Enqueue(neighbour);
distances.Add(neighbour, distances[searchedCoords] + 1);
}
}
}
Console.WriteLine(distances.Count(x => x.Value >= 1000));
Console.ReadLine();
}
private static Coords getNextCoords(char direction, Coords coords)
{
switch (direction)
{
case 'N':
return new Coords(coords.X, coords.Y + 1);
case 'S':
return new Coords(coords.X, coords.Y - 1);
case 'W':
return new Coords(coords.X -1 , coords.Y);
case 'E':
return new Coords(coords.X + 1, coords.Y);
}
throw new Exception("wtf");
}
}
public struct Coords
{
public int X { get; set; }
public int Y { get; set; }
public Coords(int x, int y)
{
X = x;
Y = y;
}
}
I aimed for doing a NFA-style search - keep all current possibilities in forkedCoords. The issue is when adding a new door in the default part of switch, I add the door only to the most recent state and not to all of them. I'm completely confused with my own ability to create a functioning solution and not being able why it works, when it shouldn't.
▶ No.1010842>>1010843 >>1010848
Wow you guys are seriously still doing this. I quit on day 15 but I just noticed day 16's puzzle was about reverse engineering and I couldn't resist.
#include <iostream>
#include <fstream>
#include <algorithm>
#include <array>
#include <vector>
#include <map>
#include <unordered_map>
#include <unordered_set>
using byte = unsigned;
using RegisterSet = std::array<byte, 4>;
enum Opcode: byte {
ADDR, ADDI, MULR, MULI, BANR, BANI, BORR, BORI, SETR, SETI, GTIR, GTRI, GTRR, EQIR, EQRI, EQRR, INS_END
};
struct Instruction {
Opcode op;
byte a, b, c;
};
struct Test {
RegisterSet before, after;
Instruction ins;
};
std::unordered_map<Opcode, std::string> opstr = {
{ADDR, "addr"},
{ADDI, "addi"},
{MULR, "mulr"},
{MULI, "muli"},
{BANR, "banr"},
{BANI, "bani"},
{BORR, "borr"},
{BORI, "bori"},
{SETR, "setr"},
{SETI, "seti"},
{GTIR, "gtir"},
{GTRI, "gtri"},
{GTRR, "gtrr"},
{EQIR, "eqir"},
{EQRI, "eqri"},
{EQRR, "eqrr"},
};
void exe(RegisterSet *regs, const Instruction& i)
{
switch (i.op) {
case ADDR: regs->at(i.c) = regs->at(i.a) + regs->at(i.b); return;
case ADDI: regs->at(i.c) = regs->at(i.a) + i.b; return;
case MULR: regs->at(i.c) = regs->at(i.a) * regs->at(i.b); return;
case MULI: regs->at(i.c) = regs->at(i.a) * i.b; return;
case BANR: regs->at(i.c) = regs->at(i.a) & regs->at(i.b); return;
case BANI: regs->at(i.c) = regs->at(i.a) & i.b; return;
case BORR: regs->at(i.c) = regs->at(i.a) | regs->at(i.b); return;
case BORI: regs->at(i.c) = regs->at(i.a) | i.b; return;
case SETR: regs->at(i.c) = regs->at(i.a); return;
case SETI: regs->at(i.c) = i.a; return;
case GTIR: regs->at(i.c) = i.a > regs->at(i.b); return;
case GTRI: regs->at(i.c) = regs->at(i.a) > i.b; return;
case GTRR: regs->at(i.c) = regs->at(i.a) > regs->at(i.b); return;
case EQIR: regs->at(i.c) = i.a == regs->at(i.b); return;
case EQRI: regs->at(i.c) = regs->at(i.a) == i.b; return;
case EQRR: regs->at(i.c) = regs->at(i.a) == regs->at(i.b); return;
case INS_END: exit(2);
}
}
std::vector<Test> read_a()
{
std::ifstream input("16a.txt");
std::vector<Test> tests;
std::string line;
while (std::getline(input, line)) {
Test t;
std::sscanf(line.c_str(), "Before: [%u, %u, %u, %u]", &t.before[0], &t.before[1], &t.before[2], &t.before[3]);
std::getline(input, line);
std::sscanf(line.c_str(), "%u %u %u %u", &t.ins.op, &t.ins.a, &t.ins.b, &t.ins.c);
std::getline(input, line);
std::sscanf(line.c_str(), "After: [%u, %u, %u, %u]", &t.after[0], &t.after[1], &t.after[2], &t.after[3]);
std::getline(input, line);
tests.push_back(t);
}
return tests;
}
std::vector<Instruction> read_b(const std::unordered_map<byte, Opcode>& opdict)
{
std::ifstream input("16b.txt");
std::vector<Instruction> prog;
std::string line;
while (std::getline(input, line)) {
Instruction i;
byte op;
std::sscanf(line.c_str(), "%u %u %u %u", &op, &i.a, &i.b, &i.c);
i.op = opdict.find(op)->second; // muh qualifiers
prog.push_back(i);
}
return prog;
}
int main()
{
std::vector<Test> tests = read_a();
std::map<byte, std::unordered_set<Opcode>> matches;
// part 1
size_t three_matches = 0;
for (const auto& t: tests) {
size_t nmatches = 0;
for (size_t i = ADDR; i < INS_END; ++i) {
RegisterSet rset = t.before;
Instruction ins = t.ins;
ins.op = static_cast<Opcode>(i);
exe(&rset, ins);
if (rset == t.after) {
matches[static_cast<Opcode>(t.ins.op)].insert(ins.op);
nmatches++;
}
}
if (nmatches >= 3)
three_matches++;
}
printf("part 1: %d\n", three_matches);
// part 2
std::unordered_map<byte, Opcode> opdict;
// figure out the opcodes
while (!matches.empty()) {
for (auto& p: matches) {
if (p.second.size() == 1) {
Opcode op = *(p.second.begin());
opdict[p.first] = op;
for (auto& p1: matches) {
matches[p1.first].erase(op);
}
matches.erase(p.first);
break;
}
}
}
// run the program
std::vector<Instruction> prog = read_b(opdict);
RegisterSet rset {{0, 0, 0, 0}};
for (auto const& i: prog)
exe(&rset, i);
printf("part 2: %d\n", rset[0]);
}
Also r8 and h8.
▶ No.1010843>>1010844
>>1010842
Why would we stop?
▶ No.1010844>>1010847
>>1010843
Well I found day 14 and 15 to be longer than I'd like, it was fun to learn about pathfinding algorithms but it wasn't fun to throw 300+ LOC in a daily puzzle, I don't know how it went from there on though, are they getting longer?
▶ No.1010847
>>1010844
No, none have been anywhere near as long.
▶ No.1010848>>1010978
>>1010842
>reverse engineering
If you liked day 16, you'll really enjoy day 19.
▶ No.1010913>>1011063
Where did all the rustfags go?
▶ No.1010957>>1010958
I thought they might try and throw backtracking in, seeing as it's a regex, but you can literally do a naive recursive LR(1) solution. Isn't it supposed to be day twenty by now? I was thinking part 2 might be that, but I knew they would use the same input, and the only reason there was no backtracking was because of a carefully designed input.
Since I was scared the input would have two paths that lead to the same room (it didn't though) I was storing the shortest distance of every room, so part 2 took me 30 seconds. (slightly more, because I was scared it was a trick and wanted to test it first. it wasn't a trick).
My original code wasted half the lines storing where the doors were, or worrying about collisions - completely unnecessary. Here is the only code you need:
#include <stdio.h>
#define X 400
#define Y 400
bool grid[X][Y];
int max = 0, count = 0;
int parse(FILE * fp, int x, int y, int d){
loop:
switch(fgetc(fp)){
case 'N': y++; break;
case 'E': x++; break;
case 'S': y--; break;
case 'W': x--; break;
case '(': while(parse(fp, x, y, d));
goto loop;
case '|': return 1;
default: return 0;
}
d++;
if(!grid[x][y]){
grid[x][y]=d;
if(d>max) max = d;
if(d>=1000) count ++;
}
goto loop;
}
int main(void){
FILE * fp = fopen("20.txt", "r");
fgetc(fp);
parse(fp, X/2, Y/2, 0);
printf("%d\n%d\n", max, count);
}
▶ No.1010958
>>1010957
My first solution was over-engineered as well. It's a defensive strategy of trying to anticipate some harder variant coming in part2.
▶ No.1010978>>1010980
>>1010848
Interesting, not sure if I'm supposed to make some sort of mini-debugger for my simulated cpu or if I'm supposed to somehow detect long loops and accelerate them.
▶ No.1010980>>1010997
>>1010978
Actually, the later sounds insane after thinking about it again, I guess I'm supposed to make some sort of debugger.
▶ No.1010997
>>1010980
You can probably use your existing code as the debugger (just print register values). The key is to work out what the program 'does' though, and that has to be done with manual inspection.
▶ No.1010998>>1010999
▶ No.1010999
>>1010998
for me it's
>hey remember that totally futile thing you tried for day 19 part 2?
>do that today
▶ No.1011001>>1011003 >>1011004
>You can only control register 0
register 0 is not used in the loop at all?
▶ No.1011003
>>1011001
the one that looks for the next multiple above what's put in the last register is just a time waster I reckon.
also I was wrong. it's rewrite-assembler-in-high-level day again. I skipped this last time, why am I doing it now?
▶ No.1011004>>1011005
>>1011001
I have a line near the bottom. If r2 and r2 were to equal, that would end up terminating.
>eqrr 2 0 3
▶ No.1011005
▶ No.1011006
Rewriting the & op for the second time it runs is clearly a big hint, but I didn't find it that useful.
▶ No.1011007>>1011011
>hooray I've got an input that makes it halt!
>that number is obviously counting down
▶ No.1011011
>>1011007
>correct input delayed by 10 minutes because I didn't realize I'd found it already
this was surprisingly easy.
crucial to skip the loop for speed, and then it's just a few debugging techniques, and confirming the set of possible inputs.
▶ No.1011013>>1011014
I'm guessing you have to solve part 2 by hand again.
▶ No.1011014>>1011021
>>1011013
nah. if you get part 1 in reasonable time due to what hacking you've already done, you don't need any more hand-disassembly.
▶ No.1011017
>>1011016
Actually nm, I don't want to ask for any hints.
▶ No.1011021>>1011022
>>1011014
I must've solved it in some other way than you anon.
▶ No.1011022>>1011029
>>1011021
if you give your program an input for reg0 and then quickly be told that the program halted with a number of instructions, then you've basically done part2.
You just need to loop over all the valid inputs of reg0, and run your program that many times.
▶ No.1011025>>1011027 >>1011032
>That's not the right answer; your answer is too low
But this causes it to halt! what did I do wrong?
▶ No.1011027>>1011028 >>1011030 >>1011032
>>1011025
part1 wants the highest input that causes it to halt after the fewest instructions.
▶ No.1011028
>>1011027
er, the lowest input. But "the fewest instructions" means there's only one answer and its high/low relationship vs. other inputs doesn't matter.
▶ No.1011029>>1011031
>>1011022
It stops quickly because I know the answer. lol I solved it in a way someone could've solved it in 10 seconds.
Guess I need to start over again for part 2 or let it run for 30 mins.
▶ No.1011030
>>1011027
>the highest input that causes it to halt after the fewest instructions
This confused the fuck out of me. Basically just means the fewest instructions. thanks for the help.
▶ No.1011031>>1011035
>>1011029
skipping the loop changes the instruction count but doesn't change the ordering of valid inputs by instruction count.
▶ No.1011032>>1011033 >>1011035
>That's not the right answer; your answer is too low.
>>1011027
I'm not >>1011025, but I'm guessing that he's referring to part 2, as I am too. How can a register 0 value that properly halts the program be too low for part 2?
▶ No.1011033>>1011036
>>1011032
there's a finite set of valid inputs - reg0 values that cause the program to halt.
the program runs through them in order, and halts when reg0 matches.
the first value it halts on is part1
the last value it hatls on is part2
▶ No.1011035
>>1011031
The program only checks reg0 once, to determine if it's the same as reg3 so it can halt. Easy mode for parta is print out the registers after every loop, grep for when the program counters is 28, take the first line (>>1011027
), then check reg3. no instr counting needed.
>>1011032
I was talking about part a
▶ No.1011036>>1011039
>>1011033
>there's a finite set of valid inputs - reg0 values that cause the program to halt.
There are? Does the program loop through the possible values?
>the last value it hatls on is part2
What is this supposed to mean? There can't be a, "last value," for it to halt on if it runs forever.
This isn't even related to my problem. I think I need to state it clearly.
1. I have a reg0 value that successfully halts the program.
2. The same reg0 value is, "too low," for part 2
3. How is this possible?
▶ No.1011039>>1011043
>>1011036
if there's a finite set, and it runs through them in order, then there's a "last value" because every other possible input you can reach with fewer instructions, even if the program might check them an infinite number of times.
>How is this possible?
there's a set of valid inputs. part2 is looking for one of them. Every other member of this set halts the program. Those are all wrong answers. They can be higher, numerically, than the correct answer, but the program reaches them the first time with fewer instructions.
▶ No.1011043>>1011044
>>1011039
>if there's a finite set, and it runs through them in order, then there's a "last value" because every other possible input you can reach with fewer instructions, even if the program might check them an infinite number of times.
Okay, but my program isn't ever reaching there. Am I supposed to math my way to the last value? My C version reaches line 28 a million times per second. Grep is unable to find a repeat of the first value after hundreds of millions of iterations. What was your part2 answer?
>there's a set of valid inputs. part2 is looking for one of them. Every other member of this set halts the program. Those are all wrong answers.
...what?
>They can be higher, numerically, than the correct answer, but the program reaches them the first time with fewer instructions.
So they're wrong? Why are you talking about them, then?
I am even more confused now. What does,
>What is the lowest non-negative integer value for register 0 that causes the program to halt after executing the most instructions?
mean?
▶ No.1011044>>1011046 >>1011065
>>1011043
your program can only fail to reach there if it halts on an earlier input. why are you making it do that?
>What is the lowest non-negative integer value for register 0 that causes the program to halt after executing the most instructions?
What, of the [set of program-halting initial values for register 0], is the value that causes the program to halt later than any of the other members of the set?
▶ No.1011046>>1011050 >>1011065
>>1011044
>no repeats after millions of iterations
wtf?
the halt comes after a test of a reg0 and another register. The value of that other register is always a valid input. I just ran my program for a full minute, dumping the value of that register at the point of the test. After de-duping the lines in that file there were just over 14k inputs. they were repeated thousands of times.
▶ No.1011050>>1011055
>>1011046
fun stuff. My answer for part b:
vals = set()
m = 0
while 1:
a = int(input())
if not m and a in vals:
print(oa)
m = 1
if m and a not in vals:
print("fuck")
vals.add(a)
oa = a
Input should be all the possible values of reg3 in order. It never prints fuck, which means it loops after that point. Now can some anon post how your supposed to do it?
▶ No.1011051
timeout 60 ./day21 0 > inputs.1min
$ wc -l inputs.1min
33382709 inputs.1min
$ perl -lne 'print unless $seen{$_}++' inputs.1min > inputs.dedup
$ wc -l inputs.dedup
13004 inputs.dedup
$ # remove valid-input output from day21
$ time for x in $(cat inputs.dedup); do ./day21 $x; done > inputs.instr-count
real 0m51.803s
user 0m44.186s
sys 0m7.969s
$ sort -nk5 inputs.instr-count > inputs.sorted
$ head -1 inputs.sorted
(part1) -> instruction count: 63
$ tail -1 inputs.sorted
(part2) -> instruction count: 767240
part1 > part2, btw. your instruction count will vary based on how you handled the time-waster loop. naturally you could just keep a hash table and do the min/maxing in program, this is just how I did it while figuring things out.
▶ No.1011055>>1011056
>>1011050
What are you even doing there? looking for dupes in the input?
▶ No.1011056>>1011058
>>1011055
print out the last value before it repeats itself.
▶ No.1011058>>1011059
>>1011056
uh, so how does "a not in vals" make sense?
try
while 1:
a = int(intput())
if a in vals:
print last
vals.add(a)
last = a
▶ No.1011059>>1011060
>>1011058
I didn't know for sure that it looped. It might repeat a value once, then do some original values again. The print just makes sure it doesn't.
▶ No.1011060
>>1011059
ah I see. I thought you meant that you were upset by it "looping after that"
▶ No.1011062
Ada for day 21.
raise Not_Coding;
but I still worked on Dump_Machine a bit to figure out what was going on.
▶ No.1011063
>advent of reuse problems from this year
lmao
>>1010913
There is only one.
▶ No.1011065
>>1011044
>your program can only fail to reach there if it halts on an earlier input. why are you making it do that?
Where is 'there'? I don't halt my input, did you read?
>What, of the [set of program-halting initial values for register 0], is the value that causes the program to halt later than any of the other members of the set?
Thanks, this has cleared up a lot. This would make sense if my input halted. Must be something wrong.
>>1011046
>wtf?
Indeed.
>the halt comes after a test of a reg0 and another register. The value of that other register is always a valid input.
I knew that already. I manually parsed my input again; my other register is reg5.
>I just ran my program for a full minute, dumping the value of that register at the point of the test. After de-duping the lines in that file there were just over 14k inputs. they were repeated thousands of times.
Thanks for telling me anon, apparently my checking system for repeating lines was broken. Fixed it, and got the right answer.
Still filtered by yesterday, though.
▶ No.1011066
That was painful. I had to just write the assembly in python. Took way too long.
Now I'm going to bed.
▶ No.1011085
I think I need to go sit at the brainlet table. I had it worked out, but forgot to include that -1, which gives me the previous result (the n in f(n)). I spent ages double checking things, took a break, came back to it and wasted more time. Mother of god!
▶ No.1011087
>>1010619
>Day 2.
>decided to keep fcopy2array
Just two notes about it, then.
FILE *fp;
fp = fopen(fileName, "r");
is the same as
FILE *fp = fopen(fileName, "r");
Additionally, in
if(c == '\n'){
A[j][i] = c;
++j;
i = 0;
}
else{
A[j][i] = c;
++i;
The two instances of A[i][j] = c; are redundant.
A[j][i++] = c;
if(c == '\n'){
++j;
i = 0;
}
There isn't much wrong with compareStr(); not with how far into K&R you are, anyway. Using pointers, you'd be able to shorten it to
int chg = 0; //chg to store num of differences between two strings
while (*s1) if (*s1++ != *s2++) ++chg;
return chg;
But that's for later. Now for something wonderful. duplicateLetters().
char buff[rows][cols];
memcpy(buff, A, (rows * cols * sizeof(char)));
I'm going to assume that buff[][] had a purpose at some point. In your current code, you can strip those two lines and s/buff/A/g (replace all instances of buff with A).
char B[26][2] = { '\0' }; //the input only has lowercase letters. this array will store counts for each lowercase letter.
I understand what you are trying to do with this; a set that maps lowercase characters to their number of occurrences. It is a bad way to do things.
Let me explain. This is the first alternative I came up with:
char B[26] = { 0 }; //the input only has lowercase letters. this array will store counts for each lowercase letter.
for(j = 0; j < rows; ++j){
memset(B,0,26); //reset B's counts to 0
for(i = 0; i < cols; ++i)
for(k = 0; k < 26; ++k)
if(A[j][i] == k+'a') //constantly adding +'a' could take a few more microseconds
++B[k];
for(k = 0; k < 26; ++k) //check whether this string has any letter exactly 'count' times
if(B[k] == count){
++numPrey;
break; //I guess you haven't seen the break statement yet? //to not count "aabbc" twice for both 'a' and 'b'
}
}
The code is shorter, and more concise.
What I am going to assume is that you felt that using a B[26][2] would slightly reduce the computation required, at the cost of slightly more memory. Either that or you used double the memory for no reason.
Either way, with values this small, neither speed nor memory should be a concern, so if you want to use an array to map lowercase characters to their occurance count---whether for clarity, autism, or whathaveyou—you could just use the array index itself to map to the lowercase characters:
char B[1<<7] = { '\0' };
for(j = 0; j < rows; ++j){
for(k = 'a'; k <= 'z'; ++k)
B[k] = '\0';
for(i = 0; i < cols; ++i)
for(k = 'a'; k <= 'z'; ++k)
if(A[j][i] == k) ++B[k];
for(k = 'a'; k <= 'z'; ++k)
if(B[k] == count){
++numPrey;
break;
}
}
Both of these methods get rid of the first for loop, as well as the gnarly [0]s and [1]s scattered around the loops. Code readability is an important thing.
Onto main().
int j; //iterate through A[a][b]
It's common practice to put initializers for loop variables within the loop itself to limit the variable to within the loop.
for(int j = 0; j < a; ++j)
Also helps for presentation. Doesn't have to be done, though, especially if you prefer having more commenting. Personally, I would have shortened
int j = 0;
int jsave = 0;
for(j = 0; j < a; ++j){
jsave = j;
++j;
for(; j < a; ++j){
if( compareStr(A[jsave], A[j]) == 1 )
printf("%s%s", A[jsave], A[j]);
}
j = jsave;
}
into
for(int j = 0, jsave = 0; j < a; j = ++jsave)
for(jsave = j++; j < a; ++j)
if(compareStr(A[jsave], A[j]) == 1)
printf("%s%s", A[jsave], A[j]);
but readability is important as well.
Will riff day 3 when I get the time. I've not even finished K&R, so it's likely that your ability will catch up to my own quickly enough.
▶ No.1011098
Wew, day 19 done, that was fucking fun, not even being sarcastic, not only finding out what the program was doing (I made an interactive mini debugger with basic functionality such as step and set) but also coming up with a mathematical way to solve it once you know what you have to do really basic math but still fun. Day 21 looks like it's more assembly stuff, definitely going to do it later. /blog
▶ No.1011357
LARP in 2.5 minutes. Hopefully I don't get filtered today.
▶ No.1011360>>1011455
>another grid day
Advent of grid[][]
▶ No.1011364
▶ No.1011368
>part 1: 202 people have solved
>part 2: 5 people have solved
It's annaduh shoah
▶ No.1011370>>1011371
Will BFS work for this?
Please help, I couldn't even figure out path searching for day 15 without searching, how in the hell are you supposed to do this?
▶ No.1011371>>1011372
>>1011370
> couldn't even figure out path searching for day 15 without searching
copy paste your code from day 15
▶ No.1011372
>>1011371
>have a cache size of target_x * target_y for part a
>go up to target_x*10, target_y*10 for part b
>wonder why it runs so slow
▶ No.1011375>>1011397
Ada for part1 of day 22.
part2 requires pathfinding = filtered.
▶ No.1011378
>finish the searching algorithm
>try it out on the test input
<your minimum time is shorter than the test answer
wew time to create an entire map printing function just to figure out where it went wrong
▶ No.1011380
How do you decide which tool to switch to? Do I have to check both options on every switch?
▶ No.1011390
part 2 on this one has just too many possibilities
you need to track the shortest distance to every node using every combination of tools at every step to get there
▶ No.1011394
here's my part a and b:
from collections import defaultdict
from functools import lru_cache
D = 10647
Tx = 7
Ty = 770
@lru_cache((Tx+1)*(Ty+1))
def geologe(x, y):
if(x == Tx and y == Ty) or (x == 0 and y == 0):
return 0
if(y == 0):
return x * 16807
if(x == 0):
return y * 48271
return erose(x-1, y) * erose(x, y-1)
def erose(x, y): return (geologe(x, y) + D) % 20183
def risk(x, y): return erose(x, y) % 3
def ty(x, y): return {0: "rocky", 1: "wet", 2: "narrow"}[risk(x, y)]
R = 0
for x in range(Tx+1):
for y in range(Ty+1):
R += risk(x, y)
print(R) # part a
opts = {"rocky": {"climb", "torch"},
"wet": {"climb", "neither"},
"narrow": {"torch", "neither"}}
def circle(p):
yield (p[0], p[1]-1)
yield (p[0]-1, p[1])
yield (p[0]+1, p[1])
yield (p[0], p[1]+1)
tools = ["climb", "torch", "neither"]
visited = set()
distances = defaultdict(lambda: float("inf"))
distances[(0, 0, "torch")] = 0
to_visit = [(0, 0, "torch")]
while to_visit:
nx = min(to_visit, key=lambda x: distances[x])
if nx in ((Tx, Ty, t) for t in tools):
break
to_visit.remove(nx)
visited.add(nx)
for n in circle(nx):
if(n[0]<0 or n[0]>Tx*10 or n[1]<0 or n[1]>Ty*10):
continue
for tool in tools:
if(tool not in opts[ty(n[0], n[1])] or tool not in opts[ty(nx[0], nx[1])]):
continue
nd = distances[nx] + 1
if tool != nx[2]:
nd += 7
if nd < distances[(n[0], n[1], tool)]:
distances[(n[0], n[1], tool)] = nd
to_visit.append((n[0], n[1], tool))
if nx[2] != "torch":
distances[nx] += 7
print(distances[nx]) # part b
▶ No.1011396
Part2. Through all the move and tool transitions into mathematica. Found an annoying bug in the way Edge properties are specified, but once I sorted that, the code worked well.
One of you got it done really fast though!
▶ No.1011397
>>1011375
>Ada
>Filtered
If you can teach yourself Ada, you can handle pathfinding.
▶ No.1011412>>1011415
>waiting to see my O(N^600000) python """""code""""" find the answer
>After hours of waiting, suddenly a printout appears
>That's not the right answer; your answer is too high. Curiously, it's the right answer for someone else; you're either logged in to the wrong account, unlucky, or cheating.
Have I been reported? I hope I'm not getting banned like Schlomo.
▶ No.1011413>>1011414 >>1011416
I kinda suck at this, but they've forced my hand. The owner doesn't know how torrents work and their "all of them" links in the forums have 404'ed.
Is there any way to clean this up? How would you do it?
for i in nes-apu ym2151 ym2203 etc etc etc
do
mkdir $i && cd $i
curl https://vgmrips.net/packs/chip/$i?p=[0-20] -o "#1.html"
for a in *.html; do cat $a | grep '<a class="download"' | sed 's/<a class="download" href="//g; s/\&\;/\&/g; s/\.zip.*/.zip/' >> 1.txt; done
wget -i 1.txt
rm *.html *.txt
cd ../
done
▶ No.1011414
>>1011413
Take it to the question thread.
▶ No.1011415>>1011441
>>1011412
>Curiously, it's the right answer for someone else
Is this for real? That's quite hilarious.
▶ No.1011416>>1011442
>>1011413
grep -Po '(?<=download" href=")[^"]+' 1.html
▶ No.1011441
>>1011415
https://0x0.st/sda9.png
It's a wonder that I've never gotten it before, with all the >off-by-ones I've had.
▶ No.1011442
>>1011416
My dude, you are a wizard. I've only just realized I've used curl and wget when I could have picked one or the other. Quite retarded.
▶ No.1011455
▶ No.1011526>>1011542 >>1011683
Looked at the global leader board, user #193354 is winning. Noticed that's the same guy winning in the 4/g/ board.
Good lord, /g/ is going to win this.
▶ No.1011542
>>1011526
he got kinda lucky, he fell behind by 40 points 2 days ago
but then simon parent missed the leaderboard entirely for part 1 yesterday costing him 100 points
▶ No.1011683>>1011702
>>1011526
>Looked at the global leader board, user #193354 is winning. Noticed that's the same guy winning in the 4/g/ board.
Guy posts in /g/ as well; as late as two days ago he said he wasn't confidant of winning. Hopefully he'll win, if only to piss off the reddit autists again.
>Good lord, /g/ is going to win this.
Not really /g/, per say. There's not a single other nigger on /g/ even approaching his score.
▶ No.1011702
>>1011683
Well I mean, he's an anon, and he doesn't seem to post here, so the best I can describe the nigger is as a /g/entlemen. I wonder if he stays with /g/ out of force of habit, he can't seriously enjoy the headphone threads.
▶ No.1011754>>1011758 >>1012374
>spend 6 hours trying yesterday's challenge
>fuck it, I don't want another >24h in my stats, I'll just use another anon's code for the answer
<your answer is too high
Whoever posted >>1010744, fuck you
▶ No.1011758
>>1011754
>being more ashamed of your actual performance than about fake performance
good idea anon. but why not just watch the reddit threads and get all the stars without doing any work at all :)
▶ No.1011759>>1011760
GET READY FOR THE GRIDS LADS
▶ No.1011760
>>1011759
nope it's particles day
>numbers too big to fit on a grid
▶ No.1011762>>1011847
Oh. It's not advent of grid[][], but advent of grid[][][] today.
▶ No.1011771
>yfw you were actually dumb enough to try grid[][][]
I spent the last 5 minutes switching on my computer again, after it ran out of swap in 1 ms. Kill me.
▶ No.1011781>>1011783
Create a 3D diamond in space, store coordinates in a dict and add them all up? Only idea I have.
▶ No.1011782
>can't get part 1
what the fuck.
it's just manhattan_distance < a number.
what I've got works for the example.
goddamnit it.
oh, I stripped the negative sign from my input
▶ No.1011783>>1011785 >>1011787
How do you even begin part 2?
>>1011781
...wouldn't that take 10 years to compute?
▶ No.1011784>>1011786
>3D
At least from my right answer, the distance seems to simply be
abs(x0-x1) + abs(y0-y1) + abs(z0-z1)
.
▶ No.1011785>>1011796
>>1011783
only way that occurs to me is shrinking the nanobots somehow, to a scale you can reasonably loop over. you then just need to translate the answer back to the original scale.
▶ No.1011786
▶ No.1011787>>1011788 >>1011789
>>1011783
Only 100 of them.
▶ No.1011788
▶ No.1011789>>1011792 >>1011798
>>1011787
look at the example. the answer isn't one of the nanobot's coordinates.
▶ No.1011792>>1011793
>>1011789
You're adding their radial areas.
▶ No.1011793>>1011796
>>1011792
*volumes. Each nanobot contributes a 1. The cubic bit of air with the highest value is the winner.
▶ No.1011796
>>1011785
Trying this as well, although I don't think it's the right solution, considering how many people have solved it already
>>1011793
>looping through spheres of air of radius 6 billion
I don't need to reboot my computer again.
▶ No.1011798
>>1011789
Ahh nm, these radiuses are too large to calculate it out like that.
▶ No.1011799>>1011801
>after sqrt'ing everything twice
min: pos=<-109,-91,-78>, r=84
max: pos=<124,124,96>, r=100
>still going to take a century to get this wrong answer
▶ No.1011801>>1011805
>>1011799
ok confirming I can't get the right answer from this.
▶ No.1011805
>>1011801
What about starting at a point, and walking around until we find increasing values. Sort of like a gradient descent.
▶ No.1011806
My proposed solution: (haven't tested yet)
check points every now and then. Find the point within the largest number of other points this way. Then compute the point near this point that has the largest value + has the shortest distance from 0,0,0
(ie, in your for loop, replace x++ with x+=1000 or so)
▶ No.1011807
current strategy of "only try axes that some nanobot has in its coordinates" is still going to take 83 minutes.
▶ No.1011810
Filtered again, then. I've tried reading some of the explanations posted elsewhere, I don't understand any of them.
▶ No.1011811>>1011813
annoyingly, it seems like nearness counts are super high. the answer's not going to be only near 5 nanobots. it's going to be near almost all of them.
▶ No.1011813
>>1011811
Yeah I found positions that seemed to be the "best", but then you need the SHORTEST one of those options which works. I guess it goes from a maximazation to minimization problem.
▶ No.1011820
Oh yeah, I really solved this one. Cheers Mathematica.
>That's the right answer! You are one gold star closer to fixing the time stream. You got rank 138.
▶ No.1011821>>1012001
reshrinking to 10000000
min: pos=<-14,-6,-4>, r=7
max: pos=<23,23,19>, r=7
reshrinking to 1000000
fudging best location: pos=<50,40,40>, r=827
min: pos=<40,40,40>, r=0
max: pos=<60,60,60>, r=0
reshrinking to 100000
fudging best location: pos=<460,440,400>, r=884
min: pos=<450,450,450>, r=0
max: pos=<470,470,470>, r=0
reshrinking to 10000
fudging best location: pos=<4700,4700,4500>, r=801
min: pos=<4690,4690,4690>, r=0
max: pos=<4710,4710,4710>, r=0
reshrinking to 1000
fudging best location: pos=<46900,47010,46900>, r=746
min: pos=<46890,46890,46890>, r=0
max: pos=<46910,46910,46910>, r=0
reshrinking to 100
fudging best location: pos=<468900,468900,468900>, r=744
min: pos=<468890,468890,468890>, r=0
max: pos=<468910,468910,468910>, r=0
reshrinking to 10
fudging best location: pos=<4688900,4688900,4688900>, r=744
min: pos=<4688890,4688890,4688890>, r=0
max: pos=<4688910,4688910,4688910>, r=0
reshrinking to 1
fudging best location: pos=<46888900,46888900,46888900>, r=744
min: pos=<46888890,46888890,46888890>, r=0
max: pos=<46888910,46888910,46888910>, r=0
part2: 140666670
^ result of
1. dividing all the points by ten million, looping over that space to get a best point
2. divide all (orig) points by one million, loop over space near best point to get a new best point * 10
3. repeat until focused on a small area using original coordinates
but as you can see with r= (the number of nanobots near the best point in this output) going down, it doesn't hugging work.
▶ No.1011823
Took a look at reddit, and it seems many people used a library with a solver. Some pyfags are using Z3.
▶ No.1011830
>while trying to do something smart, my 'run forever' program finally finishes
>answer is wrong
▶ No.1011840
reddit:
>I used a graph algorithm to figure out the maximum set of overlapping volumes.
OK, it's a graph searching problem. not filtered by anything new.
▶ No.1011845
I can't wait to see the official way to solve this. Most people cannot prove why their solution actually works, at least that's my case. It found the right point, but that was only because I let the search continue for a large amount of iterations. I only know it is right, because it solved my input.
▶ No.1011847
▶ No.1012001>>1012007
>>1011821
-10 to +10 for each iteration is not enough
▶ No.1012007
>>1012001
yeah my last attempt expanded the search until it found something.
▶ No.1012016>>1012037 >>1012040
So what does the winner get? A plaque? Maybe a t-shirt? A sticker? A congratulatory email?
▶ No.1012037
▶ No.1012040>>1012041
>>1012016
everyone in the top 100 leaderboard gets spammed with job offers
▶ No.1012041
>>1012040
oh man what a great reward do a month of free work and get a lifetime of slavery in exchange!
▶ No.1012044
>>1001333 (OP)
>watch as some jap codes the whole thing in assembly naked atop mt. Fuji
What!! How YOU see?!!
Yankee go home !!!
▶ No.1012185>>1012196
For those of you still working on day23, this is one of the cleanest solutions I've seen.
https://github.com/fhinkel/AdventOfCode2018/blob/master/day23.js
Conceptually he's moving a big cube around the 3D space, starting with a cube equal in dimensions to the entire space (although he might as well just start with a size equal to half. The algorithm is then to move the cube around in increments of the cube size, tracking which locations have the most bots in range. Then he shrinks the search space down to the size of his cube (+/- 1 cube in each direction) and then repeats the search with a cube half the size. He terminates once the cube shrinks to a point. It's probably easier to just read the code.
▶ No.1012196>>1012205
>>1012185
Seems almost a line for line copy of this >reddit python solution:
https://old.reddit.com/r/adventofcode/comments/a8s17l/nigger/ecddus1/
▶ No.1012205>>1012206
>>1012196
Ah, so it does. Wonder if he plagiarized that PhD thesis too.
▶ No.1012206
>>1012205
Ahh, upon further investigation it's a female (I think), programmer. https://twitter.com/fhinkel. Now we see why the plagiarism occurred, and the the PhD has to be viewed with skepticism.
I feel bad for the legitimately smart (real) women in tech though, with so many frauds around, everyone will naturally assume you're useless.
▶ No.1012210>>1012212
>day 24
>another day of looking at partial and skipped days
damn. last year was a lot easier. I ended up with 48 stars, missing the 50th "you got the other stars" star and part2 of just one day.
▶ No.1012212
>>1012210
I'm POZitive we'll see more GRIDS.
▶ No.1012213>>1012216
▶ No.1012214>>1012216
>day 15 2.0
Well, at least there's no grid[][] this time.
▶ No.1012216
>>1012213
>>1012214
graph searching though.
▶ No.1012223>>1012225
Well, shit. Looks like after 23 days of splicing hackery, I'll actually be using regex to parse the input this time.
▶ No.1012225
>>1012223
note the sloppy immune/weak ordering
▶ No.1012238
>During the target selection phase, each group attempts to choose one target. In decreasing order of effective power, groups choose their targets
>In decreasing order of effective power
does the order really matter?
▶ No.1012250
>At the end of the target selection phase, each group has selected zero or one groups to attack,
Infection group 1 would deal defending group 1 185832 damage
Infection group 1 would deal defending group 2 185832 damage
... I get it. It changed targets.
but damn you.
▶ No.1012252
>works on test input
>wrong
2018, year of
▶ No.1012253
>Defending groups can only be chosen as a target by one attacking group.
damn you again.
this is the error I got from reading the example above that was actually about changing targets.
▶ No.1012260
>infinite loop as the only remaining groups are unable to damage each other
▶ No.1012267>>1012268
... I guess everyone else went to sleep.
here's Ada. I just did a loop at the shell to find the smallest boost for part2, with a 'timeout 1s' to kill infinite battles.
▶ No.1012268
>>1012267
that orig_immune_system stuff is pointless, from when I was thinking of a different way to solve part2.
of the code as a whole... Group_index and friends were a mistake.
▶ No.1012269
Examples didn't seem correct to me, anyways on to part 2.
▶ No.1012278>>1012281
Did the answer just before the sufficient boost fail to terminate? That was a nasty trick haha.
▶ No.1012280>>1012290
>advent of program this game for me please
lmao
▶ No.1012281>>1012282
>>1012278
two infinite runs for me, right before the answer
▶ No.1012282>>1012288
>>1012281
Probably the most boring problem so far. Basically Day15 light by excluding the pathfinding. Also, would you say this was one of the few days where Ada really helped to avoid mistakes?
▶ No.1012288>>1012289
>>1012282
can't say that any of the days have been great in terms of showing Ada off, but Ada did catch a few range errors. Where I've been most impressed with Ada is, outside of AoC, writing a stack library with pre/post conditions to check for errors.
▶ No.1012289
>>1012288
Oh yeah, on the whole Ada is terrible for these sorts of timed competitions. On the other hand, I found it quite useful for efficiently solving project euler problems. I was quite impressed when some generic number theory routines I wrote "just worked" when I applied them to custom types which carried their own operators (+,* etc.)
▶ No.1012290
>test input is only 4 lines long so the real answer is guaranteed to be wrong
wew
>>1012280
based lmao poster
▶ No.1012298
>program works to round 105
>suddenly one group doesn't attack for whatever reason
<off-by-two
My eternal curse.
▶ No.1012363>>1012423
>agent_who_glows is now a Proud Supporter of the reddit competition as well
WHY?
▶ No.1012374>>1012394
>>1011754
That code is wrong?
▶ No.1012379>>1012394 >>1012427
Should we make our own challenge after this?
▶ No.1012394>>1012395 >>1012411
>>1012374
It was off-by-5 when I tried it at the time. Works On My Machine now, though. Might have deleted a character from the input or something.
>>1012379
>Day 1 - Install gentoo
Realistically, it'd never get enough participants. I also have severe doubts about the problem creation skills of /tech/
▶ No.1012395
>>1012394
We don't have to limit it to here, we just have to find some gimmick.
▶ No.1012411>>1012440 >>1012457 >>1012480
>>1012394
take the initial interest in AoC
+ sustained interest due to /tech/ friendlier material
- interest due to less fame and rougher-cut material
it might work.
How about this variant:
>contest overall is basically "let's make an editor in Lisp"
>day 1: implement 1/10th of an editor
>problem is just a description of what the code should do
>instead of submitting an answer based on input, you submit your code
>you get a star on a scoreboard that's a link to your code
>day 2: implement 2/10th of an editor
and so on. It's a race among /tech/, at the end we've a history of the code people wrote, a nice programming chrestomathy result to review, and instead of points there's discussion about the solutions, and it builds up to something cool.
With the focus on the goal ("an editor", "a roguelike game", "a webserver"), we can have multiple rounds over time, and with some of these a more AoC-like format could still be doable: if the goal's a raytracer that emits a particular file format, then people can submit images as answers.
▶ No.1012423
>>1012363
>Not supporting things you like
▶ No.1012427
>>1012379
Yes. We make our own CPU, OS, and Browser.
▶ No.1012440>>1012580
>>1012411
> >contest overall is basically "let's make an editor in Lisp"
Bad idea, honestly. Reinventing the wheel, especially for a piece of software that already has non-pozzed alternatives, is nothing but a fool's game. Also,
I can safely say right now that I will be unable to accomplish a single one of the challenges in a /tech/AoC. Not an eternally cucked lispfag or anything, just an incompetent programmer.
I'd try doing it anyway, obviously, but I don't see a single /tech/ user actually doing the challenge, not even a NEET like me with shitloads of free time.
Sage for blackpilling.
▶ No.1012457
>>1012411
lmao let's do this
▶ No.1012480>>1012482
>>1012411
>AoC
>fame
AHAAAAAHAAAAAAAAAAHAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAHAAAAAAAHAHAHAHAHAHAAAAAAAAAAAHAHAHAHAHAHAHHAHAHAHAHAHAHAHAHAHAHAHAHAAAAAAAHAHAHAHAHAHAAAAAAAAAAAHAHAHAHAHAHAHHAHAHAHAHAHAHAHAHAHAHAHAHAAAAAAAHAHAHAHAHAHAAAAAAAAAAAHAHAHAHAHAHAHHAHAHAHAHAHAHAHAHAHAHAHAHAAAAAAAHAHAHAHAHAHAAAAAAAAAAAHAHAHAHAHAHAHHAHAHAHAHAHAHAHAHAHAHAHA
▶ No.1012482>>1012496
>>1012480
>he professes to have more interest in engaging in what draws less interest in others
>he is professing this here instead of exclusively in a 45-year-old woman's vagina
▶ No.1012496>>1012511
>>1012482
>he wants to be famous for working on pointless puzzles 4 free
▶ No.1012511
>>1012496
>he reads 'fame' as anything but a synonym of 'popularity'
>he thinks that other people are fags
▶ No.1012580>>1012581
Less than 30 minutes to go.
Did you already get all of the other stars?
Two or three of you might get get all 50 stars tonight.
>>1012440
OK, that's a harsh trade-off. Dropping the Q&A format means that one-shot solutions involving math and Mathematica are no longer options. And although I never really liked the "do this SIX MILLION TIMES or else notice the pattern" puzzles, I took advantage of ad-hoc solutions all the time, including always preprocessing the input instead of parsing it direct from the text, or (like yesterday) solving the problem with a bash loop that timed out infinite runs.
A ray-tracing theme with verified pictures would still work, though.
▶ No.1012581
>>1012580
>ray-tracing
>floating point
>verified pictures
>floating point
nevermind :(
▶ No.1012582>>1012586 >>1012656
2 minutes till LARP.
Calling it now, the final challenge is going to be grid[][][][].
▶ No.1012583
Final night, hopefully something nice and quick. Total the numbers up in a GRID.
▶ No.1012584
elves vs. goblins, round 3
▶ No.1012585
▶ No.1012586>>1012587 >>1012588 >>1012656
>>1012582
>YFW I WAS RIGHT
AHAHAHHAHAHHAHA
▶ No.1012587
>>1012586
hug I didn't even notice that you also predicted the number of dimensions
▶ No.1012588
▶ No.1012596>>1012600
a rare correct-on-first-try-without-bothering-with-examples
Ada, 245ms, just brute-forcing it.
▶ No.1012600
>>1012596
here's a version that frees all those constellations
I think a different container will let me use actual constellations (rather than pointers to them) as list elements, and in that case memory there'd be no explicit memory management.
▶ No.1012601>>1012602
Day25 sucks for you #365713.
▶ No.1012602
>>1012601
Day25 partB, that is.
▶ No.1012603
I'm mad because I know mathematica has clustering analysis built in, but I didn't know exactly how to feed it this exact criteria. Ah well, I'll find the one line solution later. Merry Christmas fellow Adventurers!
▶ No.1012645
Scoring days:
-------Part 1-------- -------Part 2--------
Day Time Rank Score Time Rank Score
21 00:51:03 316 0 00:59:08 92 9
17 01:05:21 56 45 01:07:51 58 43
1 00:01:56 205 0 00:04:05 44 57
day 17 is nuts. I spent about ten minutes manually flowing the water in vim, before I wrote any code. I probably only scored on that one because people looked at it and said "fuck this, not another day 15" and went to bed.
▶ No.1012649
▶ No.1012653>>1012654
I still wonder what happened to verax, seeing as he was keen enough to make the leaderboard. He must still lurk /tech/ (implying you can ever leave), but never explained why he just quit.
▶ No.1012654>>1012669 >>1012681
>>1012653
he used Rust I think, so some common hazards might've gotten him:
<sent to gulag for telling a joke
<died while waiting in line for bread
<super GRIDS
<sneeze, thereby delaying your own j'accuse long enough for a fellow revolutionary to accuse you first
<#metoo
▶ No.1012656
▶ No.1012659
>>1012657
well to be fair it was extremely rude and off-putting of him to congratulate the winner of the contest like that.
▶ No.1012666>>1012668 >>1013283
>>1012657
How can such an innocuous comment be removed? What a faggot. Are they that butthurt that /g/ beat out their trannies (who they probably fed answers to).
▶ No.1012667
>>1012657
Ah there was a bit more to it. Still harmless.
>0GoY
▶ No.1012668>>1012673
>>1012666
it probably wasn't actually removed until the "Faggot." follow up.
But replying like that, he may as well have been trolling specifically for that response so that he could justify removing the comment. Overt motivation: this guy just swore at me for no reason what an asshole. Covert motivation: Nobody must know.
▶ No.1012669
>>1012654
Probably got sick of typing .unrap()
▶ No.1012673
--------Part 2--------
Day Time Rank Score
25 03:14:22 641 0
24 10:00:24 948 0
23 07:03:21 548 0
22 >24h 2218 0
21 02:59:33 567 0
20 >24h 2147 0
19 07:29:49 1307 0
Feels good to be a free man. Getting hyperfiltered every day was painful.
>>1012668
>it probably wasn't actually removed until the "Faggot." follow up.
Nope. The comment alone was deleted, and the mod was naturally called a faggot in return.
▶ No.1012681
>>1012654
>he used Rust I think
wrong
▶ No.1012974
▶ No.1012994>>1012995 >>1013056
▶ No.1012995
>>1012994
do 2015 and 2016 and lmao about how shitty 2018 was.
▶ No.1013056>>1013059 >>1013218
>>1012994
Work on your side projects. Project euler is also an option if you like math.
▶ No.1013059>>1013088
>>1013056
>side projects
LARPers don't have side project lmao
▶ No.1013088>>1013097
>>1013059
Two people on /tech/ completed all the days, so there are at least a couple real-players.
▶ No.1013097>>1013106
>>1013088
yeah. But the rest of /tech/ are LARPers
▶ No.1013106>>1013111
>>1013097
Or they were too busy developing an operating system kernel to participate in the reddit challenge /s XDDDDDDD ¯\_(ツ)_/¯
▶ No.1013111
▶ No.1013122
I'm sure there are a lot of other gamedevvers who would appreciate your free labor if you looked.
▶ No.1013218
>>1013056
I've been doing project euler and working on my instagram bot but what I was looking for is a project with you guys.
▶ No.1013283>>1013332
>>1012666
You should see their Linux board; mod bans anyone who questions his deletions and locks threads about controversial topics that aren't full of soy in the comments.
That entire site literally can't handle having an actual discussion; banter is literally harassment to them.
▶ No.1013332>>1013339 >>1013345
>>1013283
If you want to discuss, then lay out the facts clearly. Banter doesn't do that, it's just spam making more noise and reducing the real signal.
▶ No.1013339
>>1013332
facts are racist
▶ No.1013345
>>1013332
>reddit mods actually post on hatechan
How did you even get here?
Also, in case you're serious, the entire of leddit is filled with """""memes""""" repeated ad infinitum. You can't claim to be better than here.
▶ No.1014711>>1014718
>last post 4 days ago
/tech/ is full of LARPers
▶ No.1014718>>1014719
>>1014711
The constest is over faggot, there's no reason to keep talking about it.
▶ No.1014719
▶ No.1018479>>1018506
▶ No.1018506>>1018543
>>1018479
Do you have a mental illness?
▶ No.1018543>>1018594
▶ No.1018594
>>1018543
Nah, it's just you.
▶ No.1020219>>1020232
Why is no one posting anymore? Are you all LARPers?
▶ No.1020232>>1020235
>>1020219
Perhaps because the competition ended on December 25th?
▶ No.1020235>>1020236 >>1020237 >>1020244
>>1020232
So? How about optimizing? Or golfing?
I guess /tech/ is full of LARPers, huh?
▶ No.1020236
>>1020235
Instead of that, how about you actually complete all 25 days first, then worry about optimizations. Alternatively, consider working on a personal hobby or your business, there's no need to spend an exorbitant amount of time on this one challenge.
▶ No.1020237
>>1020235
>golfing
"You're all LARPers" poster confirmed for LARPing as productive.
▶ No.1020244
>>1020235
Spending time optimizing programs that you're probably never going to even use sounds pretty fucking LARPy tbh
▶ No.1027261>>1027267
▶ No.1027267
▶ No.1027589>>1027591 >>1027597 >>1027599 >>1027602 >>1027603
So, what font do y'all use while coding?
▶ No.1027591
▶ No.1027597
▶ No.1027599
▶ No.1027602
▶ No.1027603
>>1027589
whatever's default