Since I know that a few of you are engineers and/or programmers, is there anyone who’s participating in this year’s adventofcode?
Sadly my skills in coding have deteriorated quite a bit, as I haven’t been coding a lot during the last few years. Time is also a factor.
I wish I had enough skill and time to do such things again. 15 years ago I was all over that kind of stuff.
If any of you want to talk about implementations or just want to backseat drive with me, I’m uploading my sources at GitHub - yetyetanotherusername/adventofcode2022: solutions for the 2022 edition of adventofcode.
Nice.
I haven’t got a compiler active on anything at the minute so will gladly come along for the ride. I marvel at the ingenuity some people have to create things for fun on the internet. I checked some of the scenarios and they are quite complicated.
Some of the examples seemed to click with me for potential solutions, some I struggled to even think of a starting point, but I guess a lot is based on our experience
These coding challenges are really humbling. The quickest I managed on one of the easier problems was 26 minutes and I barely made the top 11000. The winner for that day took barely over a minute to solve it. That is insane, I can’t even read the damn problem statement that quick.
Never heard of this, but looks cool! I’ll check out the site later
Checked out the site - really cool idea/game. Questions remind me of my interview with Garmin…
Too much work to do before Christmas to get involved, but next year I will have a lot of time
Well the good part is, you don’t have to solve them the day they come out, unless you really care about what place you finish on. You can still do the puzzles from, say, 2016, there’s really no stress to it unless you pressure yourself.
Nice and challenging. Just completed todays puzzle.
Took me many hours, but it was welcome training for my now bit rusty problem solving skills in Python. Just going to paste it here for review
The code was developed/run in Jupyter Notebook, so no input data loading. Instead it has to be preloaded in input_data
variable.
from collections import namedtuple, Counter
from itertools import chain, product, starmap, islice
import math
from functools import partial
Coords = namedtuple('Coords', 'x y')
def process_row(row):
direction, count = row.split(" ")
return direction * int(count)
input_rows = input_data.strip().splitlines()
head_directions = chain.from_iterable(map(process_row, input_rows))
OFFSETS = {
'R': Coords(1, 0),
'L': Coords(-1, 0),
'U': Coords(0, 1),
'D': Coords(0, -1),
}
def location_in_dir(origin: Coords, direction):
offset = OFFSETS[direction]
return Coords(origin.x + offset.x, origin.y + offset.y)
def directed_locations(origin: Coords, directions):
loc = origin
yield loc
for d in directions:
loc = location_in_dir(loc, d)
yield loc
def neighbours(center: Coords):
neighbors = starmap(Coords, product(*[[-1, 0, 1]] * 2))
return {Coords(center.x - n.x, center.y - n.y) for n in neighbors}
def aligned(loc1, loc2):
return loc1.x == loc2.x or loc1.y == loc2.y
def follow_locations(origin: Coords, lead_locations):
loc = origin
for lead_loc in lead_locations:
if lead_loc not in neighbours(loc):
contacts = neighbours(loc) & neighbours(lead_loc)
contacts = sorted(contacts, reverse=True, key=partial(aligned, lead_loc))
loc = contacts[0]
yield loc
def knots_generator(origin, locations):
while True:
locations = follow_locations(origin, locations)
yield locations
head_locations = directed_locations(Coords(0, 0), head_directions)
knots = knots_generator(Coords(0, 0), head_locations)
tail, = islice(knots, 8, 9)
len(Counter(tail))
Holy cow did I make this hard on myself. I shouldn’t do these in the evening after hacking c++ all day. I had to put the training wheels on and make this as readable as possible so my brain could still comprehend it.
import math
class Coordinate:
def __init__(self):
self.x = 0
self.y = 0
class State:
def __init__(self):
self.state = [Coordinate() for _ in range(10)]
def parse(filename: str) -> list[str]:
with open(filename, "r") as file:
return file.read().split("\n")
def euclidean_distance(this: Coordinate, other: Coordinate) -> float:
return math.sqrt((this.x - other.x) ** 2 + (this.y - other.y) ** 2)
def norm(num: int):
if num == 0:
return 0
elif num > 0:
return 1
else:
return -1
def follow(state: State):
for idx in range(0, 9):
d2 = euclidean_distance(state.state[idx + 1], state.state[idx])
if d2 > math.sqrt(2):
pull_vector = (
state.state[idx].x - state.state[idx + 1].x,
state.state[idx].y - state.state[idx + 1].y,
)
state.state[idx + 1].x += norm(pull_vector[0])
state.state[idx + 1].y += norm(pull_vector[1])
def up(state: State):
state.state[0].x += 1
def left(state: State):
state.state[0].y -= 1
def down(state: State):
state.state[0].x -= 1
def right(state: State):
state.state[0].y += 1
def apply_command(state: State, command: str, tail_positions: list[tuple[int, int]]):
direction, distance = command.split(" ")
match direction:
case "U":
function = up
case "L":
function = left
case "D":
function = down
case "R":
function = right
case _:
raise Exception("Unknown direction!")
for _ in range(int(distance)):
function(state)
follow(state)
tail_positions.append((state.state[9].x, state.state[9].y))
def main():
state = State()
tail_positions = [(0, 0)]
lines = parse("data.txt")
for line in lines:
if line == "":
break
apply_command(state, line, tail_positions)
print(len(list(set(tail_positions))))
if __name__ == "__main__":
main()
@UncleZam Nice usage of builtins, you certainly made this very concise and elegant.
Thanks, I have been trying to do data driven solving with all kinds of language features available (iterators, generators, functional tools, etc.)
From your Github repo I noticed your nice use of Numpy features. Numpy (with all its accessories) is so powerful in expression and also performance. For me it is just so easy to forget all the Numpy tricks and programming style if not using it for a while
Yeah, though it can get very hard to read. I tried solving last year’s puzzles completely vectorized in numpy but I gave up after 4 because it got too hard to do without writing tests. This year I’ve been following the KISS paradigm and it’s been much more fun that way, though I do like making stuff performant, but at a certain point it just takes too much time.
Just quickly read your solution in the comment and for me it seems very nice and concise.
Nowadays I really appreciate code that’s to the point without unnecessary boilerplate. I think you managed that very well
One thing that I’ve really come to appreciate at my new company (and since getting back into c++) is using pyright together with type hints. Untyped python is the devils plaything.
True in that. It is kind of must for professional development. I have the most experience in Mypy, which use to be the goto type checker. Probably should give pyright a spin too.
My C++ skills date back to 2005, I bet a lot has changed since. Now, Rust could be interesting competition to C++ as I heard even Linux community is embracing it.
Yeah, although the learning curve is supposed to be steep, but memory safety! We’re kind of locked into C++ at work because we use JUCE. But even so, were at C++17 and that’s a completely different animal with all the RAII stuff going on. Smartpointers asf. It really has gotten a lot better. But the syntax is just kind of borked in so many ways.
That’s why I’m really curious about how carbon will turn out. Google wants it to be what TypeScript is to JS.
I’d say today’s puzzle was the best so far. You have to simulate a CRT monitor, that was a nice touch. Would have been over quickly too if I hadn’t put in a stupid off-by-one error.
Good to hear, I will take a look at it in the evening.
What I nice puzzle the number 10 was. I guess mixing of 0 and 1 based indexing was done intentionally to confuse poor coder . CRT part was fun, but I had to read the instructions ten times to get all the details right.
I wanted to experiment and export the Jupyter Notebook as markdown and paste here in its whole glory to show off how nice Jupyter is. The exported markdown seems to work perfectly on this messaging platform (below):
Framework
from copy import copy
from itertools import repeat, islice
from pathlib import Path
from types import SimpleNamespace
def noop(regs):
yield
def addx(regs, value: int):
yield
yield
regs.x += value
def cpu(program):
registers = SimpleNamespace(x=1)
yield copy(registers) # Zero step padding
def execute(instruction):
for cycle in instruction:
yield copy(registers)
for line in program:
match line.split():
case ['noop']:
yield from execute(noop(registers))
case ['addx', value]:
yield from execute(addx(registers, int(value)))
case _:
raise RuntimeError
Puzzles
Input data
program_txt = Path("program.txt").read_text()
program_lines = program_txt.strip().splitlines()
Solution 1
states = cpu(program_lines)
sum(cycle*state.x for cycle, state in islice(enumerate(states), 20, None, 40))
13180
Solution 2
states = cpu(program_lines)
next(states) # ignore zero index state
for _ in range(6):
row_states = islice(states, 40)
crt_char = lambda crt_x, sprite_x: '#' if abs(crt_x - sprite_x) < 2 else '.'
print("".join(crt_char(crt, sprite.x) for crt, sprite in enumerate(row_states)))
####.####.####..##..#..#...##..##..###..
#.......#.#....#..#.#..#....#.#..#.#..#.
###....#..###..#....####....#.#..#.###..
#.....#...#....#....#..#....#.####.#..#.
#....#....#....#..#.#..#.#..#.#..#.#..#.
####.####.#.....##..#..#..##..#..#.###..
So what exactly is Jupyter? Web based IDE? Don’t laugh, but as embedded guy I still use ‘C’. Well, last project was in rust, but jury still out on that.
Congrats on solving puzzle. Nice solution from what I read.