Author Topic: Advent of Code  (Read 116419 times)

vorsprung

  • Opposites Attract
    • Audaxing
Re: Advent of Code
« Reply #1025 on: 17 December, 2020, 08:17:10 am »
I see day 17 is a 3-d Conway's Life

Re: Advent of Code
« Reply #1026 on: 17 December, 2020, 08:17:30 am »
(click to show/hide)
"Yes please" said Squirrel "biscuits are our favourite things."

Re: Advent of Code
« Reply #1027 on: 17 December, 2020, 08:30:02 am »
I see day 17 is a 3-d Conway's Life

(click to show/hide)
"Yes please" said Squirrel "biscuits are our favourite things."

Re: Advent of Code
« Reply #1028 on: 17 December, 2020, 08:38:42 am »
Have implemented what I think is the fastest O(n^2) algorithm for day 15 part 2. So far:-

Code: [Select]
$ time ./15slow 2 1 3
t=4 turn=300000
t=17 turn=600000
t=39 turn=900000
t=68 turn=1200000
t=106 turn=1500000
t=153 turn=1800000
t=208 turn=2100000
t=272 turn=2400000
t=347 turn=2700000

Each one of those lines represents 1% of the number of turns with the t value being the time in seconds it has been running.

Extrapolating I'd be happy if it's done in <24 hours.

[EDIT] The rate of change of the rate of change is about 10 seconds per 1%.

So extrapolating that gives 10 * 100 * 99 / 2 = 49500 seconds =~ 14h

It's exciting (and that updated prediction is looking quite accurate). Should be done inside an hour.

Code: [Select]
...
t=41498 turn=28800000
t=42355 turn=29100000
t=43223 turn=29400000
t=44095 turn=29700000

(The question is whether it will give the right answer! [Which should be 3544142 for the input I gave it.])

And ...

Code: [Select]
$ time ./15slow 2 1 3
t=4 turn=300000
t=17 turn=600000
t=39 turn=900000
t=68 turn=1200000
...
t=42355 turn=29100000
t=43223 turn=29400000
t=44095 turn=29700000
3544142

real    749m39.241s
user    750m18.228s
sys     0m1.734s

That is the right answer! You are one gold star closer to saving your vacation.

750m = 12 hours and 30 minutes

Source:-

Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int mem[30000000];

int main( int argc, char **argv) {
        int turn=0;
        int last=-1;
        time_t start;
        time(&start);
        while( argv[turn+1] ) {
                last=atoi(argv[turn+1]);
                mem[turn]=last;
                turn++;
        }
        while( turn < 30000000 ) {
                int say=0;
                int f;
                if( turn % 300000 == 0 ) {
                        time_t now;
                        time(&now);
                        printf( "t=%d turn=%d\n", (int)(now-start), turn );
                }
                f=turn-2;
                while( f >= 0 ) {
                        if( mem[f] == last )
                                break;
                        f--;
                }
                if( f >= 0 ) {
                        say = turn-f-1;
                }
                /* printf( "turn=%d last=%d say=%d f=%d\n", turn, last, say, f ); */
                mem[turn-1]=last;
                last=say;
                turn++;
        }
        printf( "%d\n", last );
        return(0);
}
"Yes please" said Squirrel "biscuits are our favourite things."

Re: Advent of Code
« Reply #1029 on: 17 December, 2020, 10:49:00 am »
Source:-

Code: [Select]
                while( f >= 0 ) {
                        if( mem[f] == last )
                                break;
                        f--;
                }

If you stick the value of last into mem[0] (and shuffle the other numbers up) you only need to do one comparison per loop and it will run considerably quicker. And turn and f will no longer be 1 different.

Re: Advent of Code
« Reply #1030 on: 17 December, 2020, 02:24:18 pm »
If you stick the value of last into mem[0] (and shuffle the other numbers up) you only need to do one comparison per loop and it will run considerably quicker. And turn and f will no longer be 1 different.

Good point...

Old:-

t=347 turn=2700000

New:-

t=191 turn=2700000

So almost twice as fast (so far, although I don't see why that shouldn't continue). Surprised me as I would have thought the infrequent negatives would have trained the branch predictor to err on the side of looping (and then only having to occasionally buck the pipeline), and also that it would have been mostly memory bound given the fact that a ~100MB array isn't going to be very cache friendly.

So, likely to finish take 5-6 hours.
"Yes please" said Squirrel "biscuits are our favourite things."

tonycollinet

  • No Longer a western province of Númenor
Re: Advent of Code
« Reply #1031 on: 17 December, 2020, 03:22:26 pm »
So day 17:

Part 1 took me about 2.5 hours to sort out, mainly finding a way to efficiently represent infinite 3d space**, with one abortive start***, and a number of stupid typo type bugs. Fortunately I'd structured it in a way that suited part 2. Part 2 took an additional 5 minutes.

(click to show/hide)

(click to show/hide)

vorsprung

  • Opposites Attract
    • Audaxing
Re: Advent of Code
« Reply #1032 on: 17 December, 2020, 03:42:53 pm »
I see day 17 is a 3-d Conway's Life

(click to show/hide)

doesn't bother me coz I am still at work and have plenty of programming puzzles to figure out

Re: Advent of Code
« Reply #1033 on: 17 December, 2020, 03:45:06 pm »
"Yes please" said Squirrel "biscuits are our favourite things."

Re: Advent of Code
« Reply #1034 on: 17 December, 2020, 04:22:59 pm »
(click to show/hide)

Re: Advent of Code
« Reply #1035 on: 17 December, 2020, 04:42:21 pm »
So almost twice as fast (so far, although I don't see why that shouldn't continue). Surprised me as I would have thought the infrequent negatives would have trained the branch predictor to err on the side of looping (and then only having to occasionally buck the pipeline),

The branch predictor just keeps the pipline full. The operations for each compare (a compare and a conditional branch) will still take up their normal number of cycles, even if the branch predictor is perfect.

Quote
and also that it would have been mostly memory bound given the fact that a ~100MB array isn't going to be very cache friendly.

It ought to load a whole block into cache at once, so I'd expect it to spend very little time waiting for memory loads.

I reckon it's entirely CPU bound.

tonycollinet

  • No Longer a western province of Númenor
Re: Advent of Code
« Reply #1036 on: 17 December, 2020, 06:00:19 pm »
(click to show/hide)

But:
(click to show/hide)

tonycollinet

  • No Longer a western province of Númenor
Re: Advent of Code
« Reply #1037 on: 17 December, 2020, 06:03:59 pm »
So day 17:

That's pretty similar to mine:


Ive just done a simple optimisation that...

(click to show/hide)

Re: Advent of Code
« Reply #1038 on: 17 December, 2020, 09:53:32 pm »
For day 16, I created a sort routine for the 20 fields against the 20 columns, but it was really slow and took half an hour or so. That actually gave me the answer.

Then I realised that one field only worked with one column, that allowed all other fields to be eliminated as option for that column. Columns and rows could be thinned out to the final solution that way, and the code ran in a fraction of a second.

I don't know if the thinning out method will always work when there is a unique solution.
Quote from: Kim
Paging Diver300.  Diver300 to the GSM Trimphone, please...

Re: Advent of Code
« Reply #1039 on: 18 December, 2020, 12:16:00 am »
Day 17 remains spreadsheetable, although it has so many rows it was immensely crashy on recalculation:
https://docs.google.com/spreadsheets/d/1vb2HE64SbJN3acZpFipF3T01m-ABLNuUje7UEQpx_C4/edit?usp=sharing

(click to show/hide)

I don't know if the thinning out method will always work when there is a unique solution.

It ought to. I did worry they might have made it extra hard as you don't need to figure out which departure field is which for the answer they want.

Ben T

Re: Advent of Code
« Reply #1040 on: 18 December, 2020, 12:24:40 pm »
Day 18 quite interesting
(click to show/hide)

Re: Advent of Code
« Reply #1041 on: 18 December, 2020, 12:52:18 pm »
(click to show/hide)
"Yes please" said Squirrel "biscuits are our favourite things."

Re: Advent of Code
« Reply #1042 on: 18 December, 2020, 12:58:59 pm »
Day 18 part 1:
https://docs.google.com/spreadsheets/d/1SmJDMWM0QfYyfTanZWOrZEGvkDF6yA8EabCrKCAXtdc/edit?usp=sharing

(click to show/hide)

ETA: Part 2
https://docs.google.com/spreadsheets/d/1r78qCZenNR7SrqM1HmzznSoJcvQ4im_SmbZ1TcKr0UY/edit?usp=sharing

tonycollinet

  • No Longer a western province of Númenor
Re: Advent of Code
« Reply #1043 on: 18 December, 2020, 09:20:20 pm »
Excuse my French, but Holy Hell day 18 (part 1) was a fucking BASTARD.

I could not get my head round parsing the brackets, and then calculating in parsed order. I have a serious headache now. And that was *with*
(click to show/hide)
I'm also certain that there must be a more elegant recursive approach, but I just couldn't get there.


Part two was a doddle - just a minor change to the 'calculate flat string' function.

Code here has a metric shedload of diagnostic print statements that I am not going to remove  ;)

(click to show/hide)

Re: Advent of Code
« Reply #1044 on: 19 December, 2020, 03:31:01 am »
For day 18 my first attempt tried to have recursion for both brackets and for dealing with left to right precedence but it all got a bit mixed up, and didn't get the precedence correct for operators after brackets. It was a bit frustrating that it was fine for shorter lines in my puzzle input, but fell over with the longer ones.

My working attempt used recursion on the brackets. The function found if there were any brackets, and if so, found the highest level of brackets, and then found the first instance of that level. The function would then call itself twice, in the form f( [part before bracket] . f( [part inside bracket] . [part after bracket]).

I just seemed to make lots of mistakes like not calculating [part before bracket] or [part after bracket] correctly, especially when one was zero length.

My code also had lots of diagnostic print statements, although I only used them on single lines of the puzzle input.

Quote from: Kim
Paging Diver300.  Diver300 to the GSM Trimphone, please...

Re: Advent of Code
« Reply #1045 on: 19 December, 2020, 10:26:05 am »
My spreadsheets finds the last opening bracket in the string and finds the first closing bracket after it. That's guaranteed to never contain any other brackets. Process the calculation inside, substitute it in the string with the answer and do it all again. No recursion required.

For part 2 only processing the calculation changed. I checked if the string contained a mix of additions and multiplications. If not, I used the formulae from part 1. If yes, I processed only the additions and gave the unfinished calculation as the result string, still with brackets. The multiplications would be processed on the next iteration of processing brackets. The latter is largely a limitation of doing it with a spreadsheet.

Day 19 part 1:
(click to show/hide)

Re: Advent of Code
« Reply #1046 on: 19 December, 2020, 12:59:25 pm »
Day 19, late to start it as I had family stuff to do in the morning.

Expected my initial semi-naive algorithm to require rework to speed it up or prevent it wasting time going down dead ends but it gave me the right answer for part 1 in under a second.

Also lucky that the way I'd implemented it meant that part 2 was a doddle. According to the stats I got the second star just 75 seconds after the first. All I did was tweak my input accordingly and the right answer for part 2 popped out straight away.
"Yes please" said Squirrel "biscuits are our favourite things."

Re: Advent of Code
« Reply #1047 on: 19 December, 2020, 05:09:22 pm »
I think Day 19 (and maybe Day 18) has seen a big slow down in people completing.

This could be for several reasons:-
* There's a natural daily drop-off of people completing each day
* Many people have started their holidays at this point (my last working day for this year was yesterday for example)
* Natural weekend slowdown

But the biggest reason, I'd suggest, is that day 18 and Day 19 are the first problems that weren't just (IMHO) "simple" programming problems. By this I mean "programming" in terms of knowing what to tell the computer to do in order to solve the problem, i.e. procedural programming.

Whereas day 18 and 19 it's not so obvious what the procedure for solving the problem actually is. It's not a case of "for each point in 3D/4D space calculate the number of neighbours and iterate" or "parse the list of passwords and test them against these rules".
"Yes please" said Squirrel "biscuits are our favourite things."

Re: Advent of Code
« Reply #1048 on: 19 December, 2020, 05:38:51 pm »
Excuse my French, but Holy Hell day 18 (part 1) was a fucking BASTARD.

I could not get my head round parsing the brackets, and then calculating in parsed order.

(click to show/hide)
Quote from: tiermat
that's not science, it's semantics.

Davef

Re: Advent of Code
« Reply #1049 on: 19 December, 2020, 06:07:42 pm »
Had a catch up after 3 days off. Need to go back to multi dimensional life as my cunning several dimensions all in one integer is not quite  working.