/aocg/ - Advent of Code General #9

Don't drop the dinnerware 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.

The new leaderboard with empty space is
join-code: 43046-941b8011

The old (full) leaderboard is
join-code: 194764-c554ff91

Other urls found in this thread:

ghostbin.com/paste/stsza
projecteuler.net/problem=2),
pastebin.com/BcbqviyV
pastebin.com/FG8AL6Bb
github.com/Smatchcube/Advent-of-Code-2017/blob/master/day7.py
youtube.com/watch?v=dO5ZauOP2BA
pastebin.com/raw/wRRMCMDH
pastebin.com/jeHW3kCd
twitter.com/SFWRedditGifs

has anybody tried a recursive approach on python for part 2? Does it work or do you hit the recursion limit?

I used recursion for finding weights and constructing a tree (which I didn't need), without any problems.

This works for me.

I'm still not sure where on a scale of brainlet to pajeet this places me, because this code looks ugly as fuck at first glance.

Whoops, forgot the first function

Yes, here:
ghostbin.com/paste/stsza

with open('adv7.txt') as tree:
names = []
weights = []
subbranches = []
for line in tree:
names.append(line.split(" (")[0])
weights.append(int(line.split("(")[1].split(")")[0]))
if "->" in line:
subbranches.append(line.split("-> ")[1].split("\n")[0].split(", "))
else:
subbranches.append(" ")

discs = dict(zip(names, weights))
subdiscs = dict(zip(names,subbranches))
namestorage = names[:]

flag = False
while names:
if flag:
break

for x in names:
if flag:
break

if subdiscs[x] == " ":
names.remove(x)

flag2 = True
else:
for y in subdiscs[x]:
if subdiscs[y] != " ":
flag2 = False
break
if flag2:
check = min([discs[z] for z in subdiscs[x]])
for z in subdiscs[x]:
if discs[z] > check:
flag = True
print weights[namestorage.index(z)] - (discs[z] - check)
break
discs[x] = discs[x] + discs[z]
subdiscs[x] = " "

Don't ask me how long this took.

I just spent two hours debugging why my solution for day 7 problem 1 didn't work.
It turns out I forgot about the ',' at the end of some words.

It hurts to be a brainlet.

It's okay m8, as I said in previous thread, I spent 30 minutes wondering why all my weights are 10 digits numbers and I thought I fucked up the recursion, until I realized I forgot to convert it to int, so it was concatenating the numbers instead of adding them together.

Spent hours trying to figure out why my code was reporting loads of unbalanced nodes that had no relation to each other. Turns out I'd assumed the weights in the data file included the weights of everything above, instead of just the node's weight.

Shit, I don't have any single dumb mistake I made, I was just dumb overall and slow to figure out how to solve it

I don't know why I bothered checking, but there's a comment in the page source for anyone who bothered to check.
Oh, hello! Funny seeing you here.

I appreciate your enthusiasm, but you aren't going to find much down here.
There certainly aren't clues to any of the puzzles. The best surprises don't
even appear in the source until you unlock them for real.

Please be careful with automated requests; I'm not Google, and I can only take
so much traffic. Please be considerate so that everyone gets to play.

If you're curious about how Advent of Code works, it's running on some custom
Perl code. Other than a few integrations (auth, analytics, ads, social media),
I built the whole thing myself, including the design, animations, prose, and
all of the puzzles.

The puzzles probably took the longest; the easiest ones took an hour or two
each, but the harder ones took 4-5 hours, and a few even longer than that. A
lot of effort went into building this thing - I hope you're enjoying playing it
as much as I enjoyed making it for you!

If you'd like to hang out, I'm @ericwastl on Twitter.

- Eric Wastl

So on the topic of programming challenges (which I haven't done before AoC), I figured I'd try Project Euler.
For Problem 2 (projecteuler.net/problem=2), I got the following code:
def fib(x,y):
yield x
yield y
while True:
z=x+y
yield z
x=y
y=z

sum = 0
for y in fib(1,2):
if y%2==0:
sum +=y
if y>4000000:
break
print(sum)


It just feels wrong somehow, but I'm not sure how. I mean it got me the right answer, but I feel there's definitely a better way.

Eric we love U

can people explain their coding strategies in plain english? What algos are you using? Traversing tree bottom-up or top-down? Recursively? etc

Have a recursive function that calculates the total weight of a node (as its own weight plus total weight of its direct children, if any).

During the calculation process, if this function finds that children's weight is unbalanced, it stops execution and alerts the user.

Call this function on the root node.

That's it.

Stackoverflow is offline. How am I supposed to solve this puzzles?

Up for me.

pajeet, my son...

thanks, I was going about it the wrong way... Was gonna build the whole tree, then calculate every tower weight, etc

Yeah it went into maintenance for a second

Python's yield is really nice.

>coding challenge
>have to balance a fucking TREE
fuck this math bullshit

Balancing a tree actually means something else entirely.

who told you that

>math is hard

So what is the right answer for the test input? 243 or 60?

Is it asking you for the weight of the program or the weight of the program and all its children programs?

60

I'm a filthy ESL so I got confused.

Thanks.

module DaySeven where

import AOC
import qualified Data.Set as S
import qualified Data.List as L

import Data.Ord

data Task = Task String Int [Task] deriving Show

-- here we only identify tasks by their name
instance Eq Task where
(Task n _ _) == (Task b _ _) = n == b
instance Ord Task where
(Task n _ _) `compare` (Task b _ _) = n `compare` b

getWeight (Task n w _) = w

simpleTask str = Task str 0 []

parseTask :: [String] -> Task
parseTask [] = Task "bad" 0 []
parseTask (n : w : rem) =
let t sub = Task n (read w) sub
in case rem of
("->": subs) -> t (map simpleTask subs)
[] -> t []

breakLine = wordsWhen (`elem` " ,()\t")
breakFile str = breakLine lines str

lookupInSet v set =
let idx = S.findIndex v set
in S.elemAt idx set

parse str = parseTask breakFile str

-- This is n log(n) which is far better than the previous n^2
part1' tasks = L.sortBy (comparing snd) $ countOccurences $ concatMap getSubs tasks
where getSubs t@(Task _ _ subs) = t:subs

part1 = fst . head . part1' . parse

makeTree :: Task -> S.Set Task -> Task
makeTree (Task n w subs) set = Task n w (map recur subs)
where recur t = makeTree (lookupInSet t set) set

getBalance :: Task -> Either Int Int
getBalance tsk = case tsk of
Task _ w [] -> return w
Task n w subs -> do
nSubs do
let weight = maybe 0 id $ L.lookup bad mapping
offBy = good - bad
Left (weight + offBy)
_ -> return (w + sum nSubs)


part2 str = getBalance tree
where start = part1 str
tree = makeTree start (S.fromList $ parse str)

I should have used a map instead of a set and weird Eq/Ord instances, but oh well.

finally did it, now I have to go back and do yesterday's challenges, was too lay to do them

>test input gives the right answer but the real one doesn't

60, the stack needs to weigh 243 and to achieve the thing you need to go from 68 to 60 so that the children weight with the disc's weight goes down from 251 to 243

>hang on, the stack weight of all the children is equal... how can I adjust that without unbalancing the rest
>mfw I forgot that nodes themselves have weight

[laughs in code]

>sort
>log n

>Given that exactly one program is the wrong weight
Then why all these five nodes have different sums? Can someone check my input? What is the answer?
pastebin.com/BcbqviyV

so day 7 can be sorting in log n time

did you seriously draw your graph out by hand you fucking ape

>>from advent import *
>What is advent here?
A collection of random helper functions.
pastebin.com/FG8AL6Bb
Most useful so far have been get1 and get2 for reading in 1D and 2D arrays of data.

I'm trying to figure out what's wrong with it. I'm getting a node where all childrens sums are different (including the parent node).

Weight of a stack includes the weight of EVERYTHING in the stack, not just the base. All children of ifyja have total weight 412.

Fuck.

def getSumLeg(data, value_pair, parent):
ret_v = 0
if data[parent] != None:
for v in data[parent]:
ret_v += getSumLeg(data, value_pair, v) + value_pair[v]
else:
return value_pair[parent]
return ret_v


data is a dict with the key/value pair data[parent = (children), if a parent has no children it's value is None.

value_pair is a dict with the key/value pair value_pair[parent] = int(parent value).

If I run this once for every child of the topmost parent I am supposed to get the total value of that child and all it's children and children's children.

I am not used to recursive functions, what is wrong with my implementation? Because it's giving me completely different values for all the topmost parent's children.

Well fuck the entire file with tests and runninig won't fit in the reply so here's the relevant part, any idea how to tidy it up?

from util import to_string_rows, get_input_string_rows, test, run
from itertools import combinations
from re import compile

def main():
input = get_input_string_rows(7)

RE_DISC = compile(r'(\S+) \((\d+)\)( -> ([\S ]+))?')

class Disc(object):
def __init__(self, name, weight, children):
self.name = name
self.weight = int(weight)
self.children = [] if children is None else children.strip().split(', ')
self.parent = None

def get_children(discs, disc):
return [discs.get(child) for child in disc.children]

def get_weight(discs, disc):
return disc.weight + sum([get_weight(discs, child) for child in get_children(discs, disc)])

def get_root_name(discs, root):
return root.name

def get_weight_correction(discs, root):
prev = dict()
while True:
weights = {child.name: get_weight(discs, child) for child in get_children(discs, root)}
values = weights.values()

diff = max(values) - min(values)
if diff == 0:
return root.weight - (max(prev.values()) - min(prev.values()))

prev = weights
root = discs.get(list(weights.keys())[list(values).index(max(values))])

return 0

def solve(input, fun):
discs = {
m.group(1): Disc(m.group(1), m.group(2), m.group(4))
for m in [RE_DISC.match(row) for row in input]
}

for disc in discs.values():
for child in get_children(discs, disc):
child.parent = disc

root = list(filter(lambda disc: not disc.parent, discs.values()))[0]
return fun(discs, root)

What if a disk hold only two subtowers ?
If this is the case we can't know wich tower is unbalanced ?

Doesn't matter. The disks will become balanced if you adjust either.

def getSumLeg2(data, value_pair, parent, tier):
ret_v = 0
if tier == 0:
ret_v += value_pair[parent]
tier += 1
if data[parent] != None:
for v in data[parent]:
ret_v += getSumLeg2(data, value_pair, v, tier) + value_pair[v]
else:
return 0
return ret_v

I sovled it myself, however its pajeet tier.

Daily pajeet code in Python:
github.com/Smatchcube/Advent-of-Code-2017/blob/master/day7.py
Part one only, i will solve part two later.

Cleaned it up a bit, not sure how I can make it any better, I guess I'll leave it at that.

Aaand I'm a fucking retard.

got all my starts so far. Just finished day 6 cause I was too lazy yesterday, and fuck me, part 2 was the stupidest thing ever.

youtube.com/watch?v=dO5ZauOP2BA

If you guys didnt't score top 10 global today you're worse than a literal pajeet.

I improved the calendar image

Don't think I'm worse than someone who sits there refreshing a page until midnight desu

...

Do you want us Europeans to stay up past 6 am or go up before 6 am?

took me a bit to figure out how to recurse

Every American gets up before 6 am you lazy eurocuck

Ah, and then stays up past midnight I presume?
So all Americans get less than 6 hours of sleep.
Land of the free

iktf user ()

this, didn't sign up for math shit

...

What's the deal with day 5 and 6 part 2? Day three and today are definitely harder, and the part 2 sections are just tiny extensions of the original problems. What's everyone having such an issue with?

Nevermind, I'm an idiot. Silver are people who have completed only part 1, I got it backwards.

I dont get, what does part2 wants me to find?

I found faulty program name inside the children of root, it weights +8 more than needed. I deduct the weight from the faulty value and submit but it says wrong

You need to also check the entire tree recursively (each branch that weight more or less than others) because the weight can be unbalanced at any branch of the tree.

I mean, that you need to find where the tree begin to be unbalanced.
The problem is really hard to explain.

Yeah I still dont get it.

you have to compute the weight of the whole subtree

So I did
avpklqy:48284
tytbgx:48284
bdohoaa:48284
smaygo:48292
pvvbn:48284
hgizeb:48284
tchfafn:48284

just check the unbalanced branch to see if there is an unbalanced branch inside.
In your example you should check the 'smaygo' branch

Oh I see

Is there really only 1 unbalanced node?

Am I looking for the deepest node that has an unbalanced weight?

Correct and correct.

I've never written a tree data structure or learned how to traverse one using recursion.

every single branch seems to have a mismatched weight and I know that's wrong

what am I doing wrong?

unsigned node_weight(struct prog *node, unsigned weight)
{
if (!node)
return 0;
unsigned i;
for (i = 0; i < node->deps; i++)
{
weight += node->sub[i]->weight;
node_weight(node->sub[i], weight);
}
return weight + node->weight;
}

>stuck on day 3
>tfw brainlet

you're not storing the return of node_weight() anywhere in your loop, not exactly sure what you're trying to do. Also, you should store the weight of each node above a node in the node itself, you won't be able to do much with just the total in the end, or if you're running it every time you traverse down a branch, you're wasting a lot of cycles.

>too lazy to write a function to retrurn the unbalanced node.
>type the unbalanced branch manually until the the rest of the tree is balanced.
>calcule the difference in the python interpreter manually to find what the weight should be.
>this "just" work
>i hate being a brainlet, i want to kill myself
>knowing that genuises solve can solve the problem under 3 minutes make me even more sad.

Ok I think I finally solved it, was busy all day

Can someone give me their input and answeers to double-check?

Keep at it my friend

pastebin.com/raw/wRRMCMDH
Part One: dgoocsw
Part Two: 1275

post kode for the node struct,
don't pass weight since the way you use it doesn't really make sense
don't directly grab the child node weight, get it indirectly from the return value of your recursive func
return only cur node weight + sum of children weight
in the loop you still need an accumulator but should be initialized to 0 before looping; acc+=node_weight(node->sub[i]);
...
return node->weight + acc;

>only one program needs to have its weight changed to balance the tower
>every subtower supported by the bottom program has a distinct weight for me

The example input checked out, unless I'm misunderstanding balancing here there's no way changing one weight is gonna balance the tree.

>Faulty lowest child: szmnwnx, its weight: 3808, correct weight will be 3800

I know why, I even left a comment that the logic for deviant sum must be revisited later. Unfortunately no time left for today

What's your input?

I don't know how your programm work but the difference is 8 as in your output, maybe your programm is not counting the end of the tree ?

pastebin.com/jeHW3kCd

Nah it is this shit:

if (lweight > 0 && curWeight != lweight) // this is wrong, the check does not account first encounter of bad weight!
{
steps = map[name].Value.Length-1; deltaW = lweight; faulty = curProg = name; lweight = 0;
continue;
}

My code correctly finds only one fitting program, are you sure you're understanding the problem correctly? There's been a lot of goofy mistakes in today's challenge.

That's a fucking brainlet error man.
But i'm also a brainlet so that's why i runed the programm manually. I'm now trying to find the solution in python.

The example worked out as it should, but I'll check my recursion to see if something funky happened.

Well i wont have any time to fix today and tomororw as well and by next day I will move on

All your branches except one should have the cumulative weight "119424". Hope that helps.

I think the fact that the example has even weights for all the children is confusing people trying to complete part 2

Refactored my problem 7 code from this morning but it barely got any simpler

You are just a brainlet

can part2 be done without nodes?

What data structure did you use for part 1?