/aocg/ - Advent of Code 2017 General #13

Square peg in a hexagonal hole 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:

pastebin.com/wMfyX41N
keekerdc.com/2011/03/hexagon-grids-coordinate-systems-and-distance-calculations/
redblobgames.com/grids/hexagons/#axes
youtube.com/watch?v=cjUPVKEN9tI&list=PLBP6fxwqR14h22zocF7pbvJdulXVhAr-M&index=3
github.com/DuSTman31/AoC2017/blob/master/AoC11.cpp
github.com/kuanyui/moe-theme.el
redblobgames.com/grids/hexagons
redblobgames.com/grids/hexagons/
w3schools.com/js/js_numbers.asp
redblobgames.com/grids/hexagons/#distances
twitter.com/NSFWRedditGif

yo fuck dis geometry shit

steps = PUZZLE_INPUT.split(",")

# -1, 0 | 0, 1 | 1, 1
# 0, 0
# -1, -1 | 0, -1 | 1, 0

coords = {
"n": (0,1),
"ne": (1,1),
"se": (1,0),
"s": (0,-1),
"sw": (-1,-1),
"nw": (-1,0)
}

path = [(0,0)]
for step in steps:
path.append((path[-1][0]+coords[step][0], path[-1][1]+coords[step][1]))

def dist(coord):
f = max if coord[0]*coord[1]>0 else sum
return f(map(abs, coord))

print dist(path[-1])
print max([dist(p) for p in path])

Guaranteed™ to work.

Well, one more reason to get rid of them. We can clearly see day 3 filtered out a bunch, now there's nothing more to learn and having them replaced with active users from the other leaderboard would show with higher resolution where the other bumps might be.

Kinda sucks that we're split like that for no sensible reason.

...

Yo, I might be confused, but I implemented my solution nearly the same way. However, my offsets for south east were (1, -1) and north west was (-1, 1). How come you have (-1, 0) and (1,0)?

make your own leaderboard and govern it how you want
otherwise stfu

As an user pointed out in the old thread, i might have my offsets wrong. I came upon these independently on a piece of scrap paper and they seem to work. I imagine different offsets will work so long as they're consistent and the distance function is correct.

It appears from the second leaderboard that day 3 and day 7 were the two casual filters.

You can see that on the public leaderboard for how long it takes for it to fill up.

Good point, looks like #10 was a miniboss too.

Is it considered cheating if I googled "hexgrid coordinates system"?

You're not scoring any points for this puzzle, so at this point you're doing this to learn. And it's fair to use whatever you want to learn.

Na

K

Should have joined on day 1 instead of being inactive :^)

Rb

>tfw tasks are starting to become more tedious than anything
>tfw no longer having fun

Meh.

I don't care about how it is in production, but for these puzzles, ruby is wonderful.

You can rotate your labeling, as long as its consistent.

If it's stupid and it works it ain't stupid.
pastebin.com/wMfyX41N

>If it's stupid and it works it ain't stupid.
Not if it's as stupid as the code you shat out

When you consider to implement a class to solve these shits you should absolutely stop.
Cool, learn something everyday.

who are you quoting?

what's hard about d10 ? It's literally a step by step recipe.
Normies rather spend their w-e on something more exciting than a 2hours read.

I didn't come here to procedurally parse poorly structured walls of text, I came here for interesting, abstract, concise, open-ended challenges

>hexgrid coordinates system

very cool explanation of hexgrid coords here...
keekerdc.com/2011/03/hexagon-grids-coordinate-systems-and-distance-calculations/

Yeah, and I came here to get laid by some qt in programming socks. We can't always have what we want, user, it's up to you to make the best out of it anyway.

Pretty easy once I found a guide on Hexagonal Coordinate systems. This cube coordinate stuff is neat.

this is the first rust program I see that doesn't look like complete garbage.

Not to downplay your solution, but I think 3d coordinates are overkill for this puzzle.

Cube coords are just a nicer way of dealing with Axial coords
redblobgames.com/grids/hexagons/#axes

Thread theme: youtube.com/watch?v=cjUPVKEN9tI&list=PLBP6fxwqR14h22zocF7pbvJdulXVhAr-M&index=3

Comfy color scheme, what is it?

I am the world's greatest hacker.

github.com/DuSTman31/AoC2017/blob/master/AoC11.cpp

github.com/kuanyui/moe-theme.el
Your editor theme needs a comfy waifu mascot

...

Does it work?
Path done 3493 of 8223

Yes. I ended up multithreading it because it was taking ages.
Still took a couple hours, but it did get me the star once finished.

>I ended up multithreading it because it was taking ages.
Wtf

bfs at the core?

Astar based search.

Fucking why?

day10
(defn rev [coll pos length]
(reduce
#(assoc %1 (mod (+ pos %2) (count %1)) (nth coll (mod (- (+ pos length) (inc %2)) (count coll))))
coll
(range 0 length)))

(defn hsh [[coll position skip] len] [(rev coll position len) (+ position len skip) (inc skip)])

(defn hsh-round [round-data lengths] (reduce hsh round-data lengths))

(defn run-rounds [lengths]
(let [h (first (reduce (fn [d _] (hsh-round d lengths)) [(vec (range 256)) 0 0] (range 64)))]
(String/format (apply str (repeat 16 "%02x")) (object-array (map #(apply bit-xor %) (partition 16 h))))))

(def input11 (.trim (slurp "input11.txt")))
(def mapping {"n" [0 1 -1] "ne" [1 0 -1] "se" [1 -1 0] "s" [0 -1 1] "sw" [-1 0 1] "nw" [-1 1 0]})
(def parsed-input11 (map mapping (.split input11 ",")))
(defn dist [v1 v2] (/ (reduce + (map #(Math/abs ^int (- %1 %2)) v1 v2)) 2))
(defn vecsum [v1 v2] (mapv + v1 v2))

(defn find-path [in]
(dist (reduce vecsum [0 0 0] in) [0 0 0]))

(defn find-furthest [in]
(apply max (map #(dist [0 0 0] %1) (reductions vecsum [0 0 0] in))))

>A* search to get the answer
absolute madman

>come up with a shitty way to reduce the path without computing coordinates for part 1
>part 2 wants me compute coordinates
oh well

Same here, and it's not the first solution I'we rewritten halfway through.. I need to start to think ahead.

I still haven't done part 2 of day3

Top tier python solution
from collections import defaultdict

with open("day11input.txt") as inputData:
directions = [data for data in inputData.read().split(",")]

class Position():
x = 0
y = 0
z = 0

def __init__(self, x = 0, y = 0, z = 0):
self.x = x
self.y = y
self.z = z

def __add__(self, other):
self.x += other.x
self.y += other.y
self.z += other.z
return self

def maxCoordAbsDif(pos1, pos2):
res = []
res.append(abs(pos1.x - pos2.x))
res.append(abs(pos1.y - pos2.y))
res.append(abs(pos1.z - pos2.z))

return max(res)

possibleMoves = defaultdict(Position)

possibleMoves['n'] = Position(1, 0, -1)
possibleMoves['s'] = Position(-1, 0, 1)

possibleMoves['ne'] = Position(1, -1, 0)
possibleMoves['sw'] = Position(-1, 1, 0)

possibleMoves['nw'] = Position(0, 1, -1)
possibleMoves['se'] = Position(0, -1, 1)

currentPos = Position()
center = Position()

maxDist = 0
currDist = 0

for move in directions:
currentPos += possibleMoves[move]
currDist = maxCoordAbsDif(currentPos, center)
if (currDist > maxDist):
maxDist = currDist

print("Part 1 answer:", currDist)
print("Part 2 answer:", maxDist)

val moves = io.Source.fromFile("in").mkString.trim.split(',')

// using the flat topped cube coordinate system from
// redblobgames.com/grids/hexagons
var x, y, z = 0

for (move y += 1; z -= 1
case "ne" => x += 1; z -= 1
case "se" => x += 1; y -= 1
case "s" => z += 1; y -= 1
case "sw" => z += 1; x -= 1
case "nw" => y += 1; x -= 1
}

import math.abs
println((abs(x) + abs(y) + abs(z))/2)

Knowing (about hex coord systems) is half (make that 95%) the battle.

Knowing how to format code on 4chins is the other 95%

test:

print "hello world"

print "line 2"

end of test

I'm on day 3, the manhatten distance one

is there a 'clever' way to do this or do i just have to do it the brainlet ways?

I feel like a fucking idiot. I just wasted a few minutes not because of an error in the code, but because of one in a fucking multi-line comment.
I was having some difficulty wrapping my head around the coordinate system, so I quickly made a diagram in a comment.
"""
+y-z
_____
-z+x /z- y+\ +y-x
/__\ / \
\x+ /
-y+x \_____/ +z-x

-y+z
"""

It turns out that having a \x in exclusively multi-line comments in python will produce an error immediately without reporting a line number. Fucking hell.

There is nothing wrong with generating the spiral

Part 1 can be done with math.

Part 2 should be done by generating the spiral.

>It turns out that having a \x in exclusively multi-line comments in python will produce an error immediately without reporting a line number. Fucking hell.

I have never seen a statement that describes python better than this.

part 1 can be done with pure fucking math, and it's absolutely easy to do
part 2 requires you to generate the spiral. If you're too much of a brainlet to code an algorithm for it you can just open excel and fucking generate it manually, won't take you more than 5 minutes since on average you add a digit every 300° or so

...

It's OK user I was getting absurd distances because one of my offsets was (+ z) instead of (+ 1). Of course it was for NW so it didn't show up in the test inputs :^)

>he doesn't get angry about everything
how do you get out of bed, anime poster?

val moves = io.Source.fromFile("in").mkString.trim.split(',')

// using the flat topped cube coordinate system from
// redblobgames.com/grids/hexagons
var x, y, z = 0

for (move y += 1; z -= 1
case "ne" => x += 1; z -= 1
case "se" => x += 1; y -= 1
case "s" => z += 1; y -= 1
case "sw" => z += 1; x -= 1
case "nw" => y += 1; x -= 1
}

import math.abs
println((abs(x) + abs(y) + abs(z))/2)

>haskal doesn't have a standard function for splitting a string on a delimiter
> not even one that splits a string on a predicate

I love it but it really is a meme lang

What language is this?

I'm guessing Scala.

I think I have found the most elegant solution to problem 11
def AOC11(string):
def reduc(x,y,z):
mid = sorted((x,y,z))[1]
return (x-mid, y-mid, z-mid)
x,y,z, MAX = [0]*4
dist = lambda: sum(map(abs, reduc(x,y,z)))
for step in string.strip().split(','):
if step == 'sw': x += 1
elif step == 'ne': x -= 1
elif step == 'se': y += 1
elif step == 'nw': y -= 1
elif step == 'n': z += 1
elif step == 's': z -= 1
MAX = max(MAX, dist())
yield dist()
yield MAX
Although there may be a prettier way to write the switch

An alternative using reduce and a map, you may notice the similarities with // using the flat topped cube coordinate system from
// redblobgames.com/grids/hexagons
case class P3(x: Int, y: Int, z: Int) {
def +(p: P3) = P3(x + p.x, y + p.y, z + p.z)
def manDist() = { import math.abs; (abs(x) + abs(y) + abs(z))/2 }
}

val toOffset = Map(
"n" -> P3( 0, 1, -1),
"ne" -> P3( 1, 0, -1),
"se" -> P3( 1, -1, 0),
"s" -> P3( 0, -1, 1),
"sw" -> P3(-1, 0, 1),
"nw" -> P3(-1, 1, 0))

val moves = io.Source.fromFile("in").mkString.trim
.split(',').map(toOffset)

import language.postfixOps
println(moves reduce {_+_} manDist)

>tfw two stupid for hexagonal coordinates

redblobgames.com/grids/hexagons/

Alternative approaches, you may start noticing similarities with 1. Case classes, take a bit more space:
// flat top, cube coord sys:
// redblobgames.com/grids/hexagons
case class P3(x: Int, y: Int, z: Int) {
def +(p: P3) = P3(p.x+x, p.y+y, p.z+z)
def manDist =
Array(x,y,z).map(math.abs).sum/2
}

val moves = io.Source.fromFile("in")
.mkString.trim.split(',').map(Map(
"n" -> P3( 0, 1, -1),
"ne" -> P3( 1, 0, -1),
"se" -> P3( 1, -1, 0),
"s" -> P3( 0, -1, 1),
"sw" -> P3(-1, 0, 1),
"nw" -> P3(-1, 1, 0)))

import language.postfixOps
println(moves reduce {_+_} manDist)


2. Terse, more code-golfy and less readable due to less data modelling:
// flat top, cube coord sys:
// redblobgames.com/grids/hexagons
val moves = io.Source.fromFile("in")
.mkString.trim.split(',').map(Map(
"n" -> Array( 0, 1, -1),
"ne" -> Array( 1, 0, -1),
"se" -> Array( 1, -1, 0),
"s" -> Array( 0, -1, 1),
"sw" -> Array(-1, 0, 1),
"nw" -> Array(-1, 1, 0)))

val pos = moves reduce
{(_,_).zipped map {_+_}}

println(pos.map(math.abs).sum/2)

What's the "correct" way of doing this one? My solution was to make a matrix and spiral around from the center until I got something bigger than my input.

U

>using excel

now that's truly a brainlet way to do it

day 3 here

how do you generate the spiral? do you just have to make 5 ifs or what?

I used excel but I wrote a formula to sum neighbors and copy pasted it around the origin

If you really need to be spoonfed, you can just repeatedly trace a line and turn at the end, with the distance increasing by two for every two sides.

It literally tells you the error is in the comment.

Perl solution for Day 8 Part 1.
Using eval power. Blazing. Fucking. Fast.

use strict;
use warnings;

my %registers;

while () {
chomp;
m/(\w+).*if\s(\w+)/;
$registers{$1} = 0 if ! defined($registers{$1});
$registers{$2} = 0 if ! defined($registers{$2});
s/dec/\-=/;
s/inc/\+=/;
s/(\w+)(.*)if\s(\w+)/\$registers\{$1\}$2if \$registers\{$3\}/;
eval $_;

}

my ($max) = sort { $b $a } values %registers;
print "$max\n";


real 0m0.025s
user 0m0.019s
sys 0m0.004s

Daily Python3 solution coming through.

from util import get_input_string_list, test, run

def main():
input = get_input_string_list(11, ',')

DIRECTIONS = {
'ne': ( 1, 0, -1),
'n': ( 0, 1, -1),
'nw': (-1, 1, 0),
'sw': (-1, 0, 1),
's': ( 0, -1, 1),
'se': ( 1, -1, 0),
}

def move(position, direction):
return tuple(sum(x) for x in zip(position, DIRECTIONS.get(direction, (0, 0, 0, ))))

def get_distance(position):
return sum(map(abs, position)) // 2

def get_last_dist(distances):
return distances[-1]

def get_max_dist(distances):
return max(distances)

def solve(input, fun):
position = (0, 0, 0, )
distances = []

for direction in input:
position = move(position, direction)
distances.append(get_distance(position))

return fun(distances)

run([
(solve, input, get_last_dist, ),
(solve, input, get_max_dist, ),
])

if __name__ == '__main__':
main()

package main

import (
"fmt"
"io/ioutil"
"os"
"strings"
)

func max(a, b int) int {
if a > b {
return a
}
return b
}

func abs(a int) int {
if a < 0 {
return -a
}
return a
}

func dist(x, y int) int {
if (x < 0 && y < 0) || (x >= 0 && y >= 0) {
return abs(x + y)
}
return max(abs(x), abs(y))
}

func main() {
b, _ := ioutil.ReadAll(os.Stdin)
t := strings.TrimSpace(string(b))
x, y := 0, 0
for _, f := range strings.Split(t, ",") {
switch f {
case "n":
y++
case "ne":
x++
case "nw":
x--
y++
case "s":
y--
case "se":
x++
y--
case "sw":
x--
}
fmt.Println(dist(x, y))
}
}
and find max with piping it into sort -n

What if I don't know how to code.
Should I die?

>having to write your own max and abs functions
absolutely horrible. i don't get how go got so popular.

and also can't use ternary (a < b) ? a : b over 4 line if statement

>no generics
>no abs
>pipe into sort -n
lmao

can't you do this?
if a > b { return a; } else { return b; }

Solve then in Scratch

math.Min
math.Max
math.Abs

fucking mong

>func Min(x, y float64) float64
LOL

>func Max(x, y float64) float64
>float64
>int(math.Max(math.Abs(float64(a)), math.Abs(float64(b))))
no

change x and y to float64s WHOAAAA

>we javascript now
how horrifying

>mfw this puzzle

I think I'm done with this shit
I will skip it and return later
,ay be

what?

w3schools.com/js/js_numbers.asp
>JavaScript Numbers are Always 64-bit Floating Point

func max(a, b int) int { if a > b { return a }; return b }

but auto-formatter still splits it to 5 lines

...

i thought fmt preserves one-liners

no, float64s are float64s

Yeah nah mate, the flat topped grid + cube coordinate system + Manhattan distance are a 1-to-1 match with the problem.

redblobgames.com/grids/hexagons/#distances - click on one of the "flat topped" buttons first tho

Tell me how I did 2015 Day 15 terribly:

data = '''
Sprinkles: capacity 2, durability 0, flavor -2, texture 0, calories 3
Butterscotch: capacity 0, durability 5, flavor -3, texture 0, calories 3
Chocolate: capacity 0, durability 0, flavor 5, texture -1, calories 8
Candy: capacity 0, durability -1, flavor 0, texture 5, calories 8
'''
data = data.strip()

def part(total,n):
if n>1:
for i in range(0,total+1):
for j in part(total-i,n-1):
yield (i,)+j
else:
yield (total,)


import re
from functools import reduce
from operator import mul
from collections import defaultdict

pattern = r'(\w+): \w+ (?P-?\d+), \w+ (?P-?\d+), \w+ '\
'(?P-?\d+), \w+ (?P-?\d+), \w+ (?P-?\d+)'
things = dict()
ingredients = list()
properties = list()
for m in re.finditer(pattern,data):
ingredient = m[1]
vals = m.groupdict()
things[ingredient]={k:int(j) for k,j in vals.items()}
for prop in vals:
if prop not in properties:
properties.append(prop)
if ingredient not in ingredients:
ingredients.append(ingredient)

properties.remove('calories')
tots = defaultdict(dict)
mmmm = 0
for par in part(100,len(things)):
#if True = part 2
if True and not 500 == sum([par[n]*things[ingredient]['calories'] for
n,ingredient in enumerate(ingredients)]):
continue
for prop in properties:
sss = sum([par[n]*things[ingredient][prop] for
n,ingredient in enumerate(ingredients)])
tots[par][prop] = (sss if sss > 0 else 0)
gggg = reduce(int.__mul__,tots[par].values())
mmmm = max(mmmm,gggg)
print(mmmm)

>have to cast to double to get the abs of an int
only the quacks behind C could come up with that