/aocg/ - Advent of Code 2018 General #20

Fixing the pasta edition

Previous thread

adventofcode.com/
>Advent of Code is a series of small programming puzzles for a variety of skill levels. They are self-contained and are just as appropriate for an expert who wants to stay sharp as they are for a beginner who is just learning to code. Each puzzle calls upon different skills and has two parts that build on a theme.
You need to register with an account but you can appear as anonymous.

Private leaderboard join code (currently full):
368748-e33dcae3
People who are inactive for 5 days will be kicked, but other leaderboards can be made if desired.

Alternative leaderboard for those waiting for inactives to be kicked from the first:
208834-4a1a9383

Attached: 1544095329655.png (960x640, 580K)

Other urls found in this thread:

en.wikipedia.org/wiki/Fortune's_algorithm
my.mixtape.moe/rburaz.txt
play.rust-lang.org/?gist=352fb67fe54dff7fc8f1aa1d830b622a
twitter.com/SFWRedditGifs

>NO ONE has posted a clever solution yet
fug

en.wikipedia.org/wiki/Fortune's_algorithm

You have no idea how proud I am to be in op picture. I can fucking stop with this already.

>petertseng slips up
>part 6 conveniently becomes worth no points on the global leaderboard
He can't keep getting away with this.

BIG BOY: my.mixtape.moe/rburaz.txt
12.6M, 1 million points, in an area of the low tens of thousands to keep part 2 at least doable, although it's best for part 1.

That's for a continuous plane, discretizing it would be fucking awful

Tough luck user

I need more AoC memes!

he fucked up because the input was bad, dum dum

Attached: 1543668392691.png (3282x2475, 1.51M)

Isn't part 2 just nothing, since it's a million points with a max total distance of 10000?

low tens of thousands != 10000

If you completely brute force it, it'll take 900000000000000 iterations, no joke.

I mean the statement of part 2 is that the total distance from all points has to be less than 10000, which is impossible for >10000 points at least 1 square away each. You'd need something more like a max total distance of a few billion to have any squares at all in part 2

>he can't do math on manhattan parabolas
the absolute brainlet

u smart

the metric of the space isn't the issue it's the topology

I've been working with Go the first 5 days. turns out it's an awful language for these kinds of problems / solutions.

Did day 6 in F# and it was very nice, but I've been eyeing Nim as well. Is Nim worth learning, outside AoC?

>"Because of the number of users affected by this issue, I'm going to nullify the global leaderboard scores from day 6."
Lucky me, I'm too dumb for this anyway ;_;
So you build up a grid, occupy each coordinate with the minimum manhattan distance and than I'm drawing a blank.

I guess it would form a far away infinite ring with 10000, rendering that part moot. Well, with 10^(14) iterations I'm not even sure if a fancy algo would make it possible to begin with. It's clearly intended mainly for part 1

Keep thinking! Use the example input and visualize it

yes, I've been using AoC to learn Nim. It's a very great language. It has been used in ML/embedded/backends. I also found multi-threading more enjoyable in nim than Go

play.rust-lang.org/?gist=352fb67fe54dff7fc8f1aa1d830b622a

rust is disgusting

Attached: 1544123276970s.jpg (250x250, 6K)

Is Nim taking off? I looked at it a while ago but wrote it off as a meme that would fade into obscurity. How does it compare to crystal?

Nim is to Python what Crystal is to Ruby.

What are your runtimes like Haskell bros? Mine is half a second and I wanna know if I can squeeze some more speed out of it.

estranged siblings?

Post runtimes.

$ time ./distance < input
first: 3620
second: 39930

real 0m0.069s
user 0m0.065s
sys 0m0.004s

Post code
p1: 1.08s
p2: 0.1s

Don't get me wrong, I do enjoy writing stuff in Go. But sometimes I wish I just could have a bit more flexibility. Maybe in v2

crystal has a CoC, nim doesn't

$ time ./part1
55

real 0m0.003s
user 0m0.001s
sys 0m0.001s

$ time ./part2
46462

real 0m0.042s
user 0m0.041s
sys 0m0.000s

| => time ./six.py 10000 < input
Part 1: 3449
Part 2: 44868

real 0m13.004s
user 0m12.332s
sys 0m0.349s

trying to use jquery to make star counters

Day 2 of debugging, finally come across this after realizing my code logic is sound:
print(grid[0])
grid[0][0][0] = 1
print(grid[0])

[[None, None, None, False], [None, None, None, False], ...
[[1, None, None, False], [1, None, None, False], [1, None, None, False], ...
Fuck my life.

Attached: 1458872142395.png (645x1260, 197K)

pprint is your friend if you're using python or it it's available in your language.

Is using -O3 considered cheating?
$ gcc c.c -o c.a -O3 && time ./c.a input.txt
Answer (1): 3260
Answer (2): 42535
real 0m0.017s
user 0m0.017s
sys 0m0.000s

$ time ./day6.py

real 0m5.116s
user 0m5.085s
sys 0m0.004s

>REDACTED

$ time ./day6 < input
part 1: 3909
part 2: 36238

real 0m0,037s
user 0m0,033s
sys 0m0,004s

;^)

grid = [[[None, None, None, False]]*max_x for i in range(max_y)]
Here is the initializer code in question. Why in the fuck is the nested list copied into every element instead of a new one created? Python is such garbage.

Day 4; after I sort the list by date, is it better to try and go for the test visualization, or just count how much minutes each guard is asleep?

so what turned out to be the best way to filter out infinite points from the list?

My code isn't as aesthetic today

import qualified Data.IntMap as M
import Data.List

type Grid = M.IntMap Int
type Bound = (Int, Int, Int, Int)
type Pt = (Int, Int)

parse :: [String] -> Pt
parse xs = (read (xs !! 0), read (xs !! 1))

bounds :: [Pt] -> Bound
bounds pts = (minimum xs, minimum ys, maximum xs, maximum ys)
where
xs = map fst pts
ys = map snd pts

l1 :: Pt -> Pt -> Int
l1 (a, b) (c, d) = abs(a - c) + abs(b - d)

closest :: Pt -> [Pt] -> Int
closest pt xs = if length idx == 1 then head idx else -1
where
dists = map (l1 pt) xs
min = minimum dists
idx = elemIndices min dists

hash :: Pt -> Int
hash (a, b) = a * 1000 + b

addPt :: [Pt] -> Pt -> Grid -> Grid
addPt pts pt g = M.insert (hash pt) (closest pt pts) g

onEdge :: Bound -> Grid -> [Int]
onEdge (x0, y0, x1, y1) g = nub $ map ((M.!) g . hash) edge
where edge = [(a, b) | a =) d . sum . flip map pts . l1) $ rect b

main = do
input

based Nim
5626
46554

real 0m0.038s
user 0m0.035s
sys 0m0.003s

Anything that occurs on the boundary is infinite

crazy. with pypy: 3.32s

>compile with -O3
>runtime is as much as 700% faster
Feels good.

Attached: 1538444607666.png (500x500, 17K)

If that point is at the edge of the grid then the area it belongs to is infinite.

Every region that owns a square on the bounding box is infinite (since if you draw a line outward from that point, it will own all of those points as well)

While iterating
if not 0 < x < max_x - 1 and not 0 < y < max_y - 1:
# disqualify coord at (x, y)
Anything not infinite will be within bounds of the grid for every point.

anything on the edge is bad
the proof is left as an exercise to the reader :^)

wait till you discover -Ofast

Does the bug has to do with the fact that my
while(fgets (..))

is utterly fucked?

Can you post code? I've been doing them in go so far but considering switching to something else

That just means your code is shit. Good code can't be optimized much because you already optimized while writing.

it's not the most elegant solution...
import intsets, sequtils, strutils, tables

proc man_dist(p, q: tuple[x, y: int]): int =
return abs(p[0] - q[0]) + abs(p[1] - q[1])


proc part_one(indexs: seq[tuple[x, y: int]]): int =
var ceil: array[2, int]
var min_index: int
var values = newSeq[int](indexs.len)
var inf_set = initIntSet()
var counter = initCountTable[int]()

for i in 0..indexs.high:
ceil[0] = max(ceil[0], indexs[i][0])
ceil[1] = max(ceil[1], indexs[i][1])

for i in 0..ceil[0]:
for j in 0..ceil[1]:
for xy in 0..indexs.high:
values[xy] = man_dist((i, j), indexs[xy])
if xy > 0:
min_index = if values[min_index] > values[xy]: xy else: min_index
if i == 0 or j == 0 or i == ceil[0] or j == ceil[1]:
if values.count(values[min_index]) == 1:
if counter.hasKey(min_index): counter[min_index] = 0
inf_set.incl(min_index)

elif not inf_set.contains(min_index):
if not counter.hasKey(min_index):
counter[min_index] = 1
else:
counter[min_index] += 1
min_index = 0
return counter.largest[1]


proc part_two(indexs: seq[tuple[x, y: int]], limit: int): int =
var ceil: array[2, int]
var sum: int
for i in 0..indexs.high:
ceil[0] = max(ceil[0], indexs[i][0])
ceil[1] = max(ceil[1], indexs[i][1])
for i in 0..ceil[0]:
for j in 0..ceil[1]:
for idx in indexs: sum += man_dist((j, i), idx)
if sum < limit: result += 1
sum = 0


let input = map(readFile("input.txt").strip.splitLines,
proc(s: string): tuple[x, y:int] =
let tmp = s.split({',', ' '})
(parseInt(tmp[2]), parseInt(tmp[0])))

echo part_one(input)
echo part_two(input, 10000)

>indexs
indices?

So far I've got shitty perf mostly esp. on day 5... But oh well...
ChronalCalibration: [1/25] ChronalCalibration
ChronalCalibration: Part 1 -> [587] (8 ms)
ChronalCalibration: Part 2 -> [83130] (40 ms)
InventoryManagementSystem: [2/25] InventoryManagementSystem
InventoryManagementSystem: Part 1 -> [7533] (5 ms)
InventoryManagementSystem: Part 2 -> [mphcuasvrnjzzkbgdtqeoylva] (10 ms)
NoMatterHowYouSliceIt: [3/25] NoMatterHowYouSliceIt
NoMatterHowYouSliceIt: Part 1 -> [111266] (22 ms)
NoMatterHowYouSliceIt: Part 2 -> [266] (10 ms)
ReposeRecord: [4/25] ReposeRecord
ReposeRecord: Part 1 -> [48680] (48 ms)
ReposeRecord: Part 2 -> [94826] (20 ms)
AlchemicalReduction: [5/25] AlchemicalReduction
AlchemicalReduction: Part 1 -> [10878] (295 ms)
AlchemicalReduction: Part 2 -> [6874] (4488 ms)
ChronalCoordinates: [6/25] ChronalCoordinates
ChronalCoordinates: Part 1 -> [4016] (672 ms)
ChronalCoordinates: Part 2 -> [46306] (160 ms)

>tfw to smart too spell

I'm a js/jquery brainlet, what am I doing wrong?
document.querySelectorAll(".privboard-position").forEach(function(){
var count = $(this).parents('.privboard-row').children('privboard-star-both').length*2 + $(this).parents('.privboard-row').children('privboard-star-both').length;
var total = ($(this).parents('.privboard-row').children('privboard-star-both').length + $(this).parents('.privboard-row').children('privboard-star-firstonly').length + $(this).parents('.privboard-row').children('privboard-star-unlocked').length)*2
$(this).append(' ',count,'/',total,' ');
});

>Because of a bug in the day 6 puzzle that made it unsolvable for some users until about two hours after unlock, day 6 is worth no points on the global leaderboard.

no no No NO NOOOOOOOOOOOO

kek

298 ms here. using Data.Matrix and finding infinites by border checking

it's good to see the IntMap solution since I used Matrix. what's the running time look like?
mine is

The worst part of C is that sometimes the compiler does weird stuff in the code structure, so debugging without gdb turns into a mess.

sounds like you're doing it wrong

240ms with O2 and optc-O3

the majority of the runtime is spent parsing the file. what's the most efficient method of parsing in nim?

I had a while loop that read the lines of the input file.

Outside of it I had a printf and then a function that inserted the initial values in the matrix. In the end of the loop, that printf was never called, and the code always halted. The problem was that this function AFTER the printf would execute forever. I thought that the problem was in the while loop. When I noticed the problem on this function that is executed once after the printf, I fixed it, now the code runs correctly.

Copy pasting the input

pls respond

Rust seems pretty popular, let's see how Jow Forums posters are using immutable data structures and zero cost abstractions in AoC problems--
>let mut let mut let mut let mut let mut let mut

Attached: 1371841989263.jpg (350x346, 22K)

What do you mean by test visualization?

The grid that is shown in the description; sleep/awake patterns by minute, grouped by days.

The way I did the first part was first find out what guard sleeps the most. Then do the grid for him. Second part you will have to make the grid for all guards.

rust tries so hard to be systems haskell but it practice it's used as c++
scratch that, in practice it's not used. gottem

How did you do it? I think I pajeeted my code, using python I first sorted the list, then sliced each line to get guards, sleep and wake times and then calculated those.

It was probably because printf was called, but the buffer was never flushed to stdout because your program immediately locked up in an infinite loop.

Can anyone confirm that for day 6 part 1 the sample-grid is wrong? The dot on the first line is closer to A than it is to C?

>The dot on the first line is closer to A than it is to C?
I thought the same thing at first, but it's actually equidistant to A and E.

Attached: 1539265991349.jpg (550x550, 170K)

Is there any benefit to using this kind of loop for the solution?
while altered:

proposedNodes = {}
altered = False

for ownerNode in currentNodes:
selfAddedNodes = set()
checkNodes = set()
for node in currentNodes[ownerNode]:
checkNodes.add((node[0]+1,node[1]))
checkNodes.add((node[0]-1,node[1]))
checkNodes.add((node[0],node[1]+1))
checkNodes.add((node[0],node[1]-1))
for checkNode in checkNodes: #Check all branch nodes
if not( (checkNode in testedNodes) or (checkNode in selfAddedNodes)
or (checkNode[0] > rightBound) or (checkNode[0] < leftBound)
or (checkNode [1] < bottomBound) or (checkNode[1] > topBound) ):
if checkNode in proposedNodes:
proposedNodes.pop(checkNode)
testedNodes.add(checkNode)
else:
selfAddedNodes.add(checkNode)
proposedNodes[checkNode] = ownerNode
altered = True

currentNodes = {}
for sourceKey in keyCoordsDict:
currentNodes[sourceKey] = set()

for newNode in proposedNodes:
testedNodes.add(newNode)
keyCoordsDict[proposedNodes[newNode]].add(newNode)
currentNodes[proposedNodes[newNode]].add(newNode)

i7-6500u code: 13469
0

real 5m51.539s
user 5m51.299s
sys 0m0.003s

Ah, you are right. Thank you!

Attached: 1534596228469.jpg (1280x720, 133K)

...

> being mad at documented semantics

You're in the right way.

I thought about doing it like that, seemed to easy to screw up with my pajeet tier skills though, there's a lot of things to check and I didn't want to have to figure it out if I missed something. My guess is it's quicker for big boy input though.

We have two options: calculating the distance for all starting points for each square of the matrix, or looping a infection pattern. I feel like the first is quicker for smaller inputs, but I feel like the complexity of the second grows slower. What you guys think?

I implemented the first for big boy, and after 15 minutes I still have no answer.

But I'm sure there is a faster way to find zone for each point.

I'm not mad, I'm livid. It's not documented at all. Consider:
for i in range(10):
l = [1, 2, 3]
"l" is a new list each loop.
Therefore [[[None, None, None, False]]*max_x for i in range(max_y)] should create a new list each loop. And it does, except the inner list is copied max_x times.

#include
#include

typedef struct Point {
int x;
int y;
} Point;

int dist(Point p, Point q) {
return abs(p.x - q.x) + abs(p.y - q.y);
}

int area(Point *points, size_t n) {
int const SEARCH_DIST = 10000;
int min_x = __INT_MAX__;
int max_x = -1;
int min_y = __INT_MAX__;
int max_y = -1;

for (size_t i = 0; i < n; ++i) {
Point p = points[i];
if (p.x < min_x) {
min_x = p.x;
}
if (p.x > max_x) {
max_x = p.x;
}
if (p.y < min_y) {
min_y = p.y;
}
if (p.y > max_y) {
max_y = p.y;
}
}

int w = max_x - min_x + 2 * SEARCH_DIST;
int h = max_y - min_y + 2 * SEARCH_DIST;
Point startPoint = {.x = min_x - SEARCH_DIST, .y = min_y - SEARCH_DIST};

int area = 0;
for (int x = startPoint.x; x < startPoint.x + w; ++x) {
for (int y = startPoint.y; y < startPoint.y + h; ++y) {
Point p = {.x = x, .y = y};
int total_dist = 0;
for (size_t i = 0; i < n; ++i) {
total_dist += dist(p, points[i]);
if (total_dist >= SEARCH_DIST) {
break;
}
}
if (total_dist < SEARCH_DIST) {
area += 1;
}
}
}
return area;
}


int main(int argc, char** argv) {
FILE *f = fopen("input6", "r");
if (!f)
return 1;
int x, y;
size_t const BUF_SIZE = 1000; // i never know how much to allocate...
Point points[BUF_SIZE];
size_t point_count = 0;

while (fscanf(f, "%d, %d\n", &x, &y) != EOF) {
if (point_count >= BUF_SIZE) {
printf("Points exceed bufsize\n");
return 1;
}
Point p = {.x = x, .y = y};
points[point_count] = p;
++point_count;
}
fclose(f);
printf("area: %d\n", area(points, point_count));
return 0;
}

Attached: one hour python vs 7 seconds C.png (1430x926, 169K)

What is an infection pattern?

Ive been compiling without optimizations in clang all week, no fucking wonder I was slower my day4 just went from 5.2s to 0.85s on the bigboye input....

en.wikipedia.org/wiki/Fortune's_algorithm

I made this mistake a couple of days ago - tried to use [[0]*1000]*1000 to create a zero array. Didn't realise that python wasn't going to bother creating the last 999 lists. Luckily I'm not a brainlet so it didn't take me two days to try printing the array to see what was going on.

>clang

Attached: 1427712471525.jpg (250x250, 8K)

gcc is deprecated and msvc is windows-only

>gcc is deprecated
Citation needed.