Posts: 361
Threads: 5
Joined: Jun 2019
Reputation:
64
Likes received: 84
Hi everybody! In case you did not know about Advent of Code yet:
Quote:Advent of Code is an Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language you like. People use them as a speed contest, interview prep, company training, university coursework, practice problems, or to challenge each other.
You don't need a computer science background to participate  just a little programming knowledge and some problem solving skills will get you pretty far. Nor do you need a fancy computer; every problem has a solution that completes in at most 15 seconds on tenyearold hardware.
The first puzzles will unlock on December 1st at midnight Eastern Time, which is very soon.
Looking forward to exchange thoughts and small hints ( NO FULL SOLUTIONS ).
If YOU think you MUST show us your code, otherwise you would die, PLEASE use the [spoiler ][/spoiler ] tags!
snippsat likes this post
Posts: 2,588
Threads: 31
Joined: Jan 2018
Reputation:
246
Likes received: 606
What's the point of solving the puzzles if you don't share your solutions?
Posts: 1,436
Threads: 7
Joined: Jun 2018
Reputation:
145
Likes received: 315
Dec012019, 08:39 AM
(This post was last modified: Dec012019, 08:39 AM by perfringo. Edited 1 time in total.)
I would say that first day tasks were very basic.
It's good to remember that no need for .strip() if converting single integer on row:
>>> int('5\n')
5
I'm not 'in'sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy
Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Posts: 361
Threads: 5
Joined: Jun 2019
Reputation:
64
Likes received: 84
(Dec012019, 04:08 AM)Gribouillis Wrote: What's the point of solving the puzzles if you don't share your solutions?
Sharing is fine but i don´t want to be immediately spoilered opening this thread.
So everybody is invited to share their code but please use spoiler tags. :)
Posts: 1,436
Threads: 7
Joined: Jun 2018
Reputation:
145
Likes received: 315
My solutions for day # 1
I tried to scrape data directly from input page ( https://adventofcode.com/2019/day/1/input) however I was getting 400 so I just copied data into text file.
Puzzle # 1:
'sum calculation result for every row in file'
with open('day_1_1_data.txt', 'r') as f:
print(sum(int(line) // 3  2 for line in f))
Puzzle # 2 (used Python 3.8 and walrus operator)
'sum calculation results which are greater than zero for every row in file'
with open('day_1_1_data.txt', 'r') as f:
total = 0
for num in f:
while 0 < (num := int(num) // 3  2):
total += num
print(total)
ThomasL and snippsat like this post
I'm not 'in'sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy
Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Posts: 361
Threads: 5
Joined: Jun 2019
Reputation:
64
Likes received: 84
I did puzzle one same way as perfringo.
For puzzle 2 i used a recursive approach as i´m still on python 3.7
My solutions for day 1:
# part 1
with open("input.txt") as file:
masses = [int(mass) for mass in file]
print(sum(mass // 3  2 for mass in masses))
# part 2
def calc_fuel(mass):
if mass < 9: return 0
fuel = mass // 3  2
return fuel + calc_fuel(fuel)
print(sum(calc_fuel(mass) for mass in masses))
snippsat and perfringo like this post
Posts: 4,786
Threads: 92
Joined: Sep 2016
Reputation:
401
Likes received: 1436
Dec022019, 01:17 PM
(This post was last modified: Dec022019, 01:17 PM by snippsat. Edited 2 times in total.)
(Dec022019, 12:51 PM)perfringo Wrote: I tried to scrape data directly from input page (https://adventofcode.com/2019/day/1/input) however I was getting 400 so I just copied data into text file.
There is a way,could be a puzzle this to
When logged in the session cookie will be same for all days input.
Find session cookie in browser(inspect header).
Example:
import requests
cookies = {'session': '536xxxxxxxxxx'}
day_1 = requests.post('https://adventofcode.com/2019/day/1/input', cookies=cookies)
result = sum(int(int(fuel) / 3  2) for fuel in day_1.text.strip().split('\n'))
print(result)
Posts: 1,436
Threads: 7
Joined: Jun 2018
Reputation:
145
Likes received: 315
(Dec022019, 01:17 PM)snippsat Wrote: There is a way,could be a puzzle this to
Thank you!
Day #2 puzzles I did in the copypaste style but next days will access data directly.
Puzzle #1:
'for every slice of four check for opcode and break or apply calculation'
import operator
def find_answer(data):
calculate = {1: operator.add, 2: operator.mul}
lst = data[:]
for start in range(0, len(lst) + 1, 4):
opcode, inp_1, inp_2, output = lst[start:start + 4]
if opcode == 99:
break
else:
lst[output] = calculate[opcode](lst[inp_1], lst[inp_2])
return lst[0]
Puzzle #2:
'find permutation pair producing target output and return calculated value'
import operator
from itertools import permutations
def find_answer(data, target):
calculate = {1: operator.add, 2: operator.mul}
for (noun, verb) in permutations(range(100), 2):
lst = data[:]
lst[1], lst[2] = noun, verb
for pointer in range(0, len(lst) + 1, 4):
opcode, par_1, par_2, par_3 = lst[pointer:pointer+4]
if opcode == 99:
break
else:
lst[par_3] = calculate[opcode](lst[par_1], lst[par_2])
if lst[0] == target:
return noun * 100 + verb
I'm not 'in'sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy
Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Posts: 1,436
Threads: 7
Joined: Jun 2018
Reputation:
145
Likes received: 315
Dec042019, 07:56 AM
(This post was last modified: Dec042019, 07:56 AM by perfringo. Edited 1 time in total.)
Day #3
I was in real hurry with this one. So I decided to approach this 'systematically' in topdown style. I wanted to do some generator chaining but in order to get ready before my time was up I didn't follow this initial thought. Also  I did vectors decades ago, so I let shapely and numpy to do heavy lifting. This is bruteforce and probably there is some math which allows to reach same result with less work.
Puzzel # 1:
'find intersection point with smallest Manhattan distance from start (0,0)'
For that:
 read data from webpage
 calculate relative moves
 calculate path using relative moves
 convert into shapely LineString
 find all intersections
 find smallest Manhattan distance from intersections
 output smallest Manhattan distance
import requests
from shapely.geometry import LineString
import numpy as np
def main():
moves_1, moves_2 = read_page(day=3) # read moves from page
wire_1, wire_2 = LineString(wire_path(moves_1)), LineString(wire_path(moves_2)) # calculate paths, convert to LineString
wires_cross = wire_1.intersection(wire_2) # find intersections
closest_cross = get_closest(wires_cross) # get smallest Manhattan distance
print(f'Smallest Manhattan distance is {closest_cross} ') # output distance
fewest_steps = shortest_distance(wire_1, wire_2, wires_cross) # find shortest distance to intersection
print(f'Fewest steps to intersection is {fewest_steps}') # output shortest distance
def read_page(*,day):
"""
Read data from webpage, convert to relative moves
and yield two streams of moves.
"""
cookie = {'session': '536****'} # replace with your own cookie
content = requests.post(f'https://adventofcode.com/2019/day/{day}/input', cookies=cookie)
series = (serie.split(',') for serie in content.text.split())
yield from ((rel_move(item) for item in serie) for serie in series)
def rel_move(move):
"""
Calculate relative moves.
"""
replacements = str.maketrans('RULD', ' ')
if move.startswith(('R', 'L')):
return np.array([0, int(move.translate(replacements))])
else:
return np.array([int(move.translate(replacements)), 0])
def wire_path(moves):
"""
Based on moves calculate wire path.
Start with central port and add moves to last coordinate.
"""
central_port = np.array([0, 0])
path = [central_port]
for move in moves:
path.append(path[1] + move)
return path
def get_closest(coords):
"""
Return Manhattan distance closest to central port (0, 0) which is not
central port itself.
"""
closest = min(abs(coord.x) + abs(coord.y) for coord in coords if all([coord.x != 0, coord.y !=0]))
return int(closest)
def shortest_distance(first, second, intersections):
"""
Calculate shortest distance excluding starting point.
"""
distances = [first.project(intersection) + second.project(intersection) for intersection in intersections]
return int(np.partition(distances, 1)[1])
if __name__ == '__main__':
main()
Puzzle # 2:
Intersection points were already found. So:
'Find smallest distance to intersection point' (function 'shortest_distance' in code above)
I'm not 'in'sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy
Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Posts: 1,034
Threads: 0
Joined: Apr 2017
Reputation:
74
Likes received: 209
Dec152019, 10:54 AM
(This post was last modified: Dec152019, 10:54 AM by ndc85430. Edited 1 time in total.)
I've been doing the problems in Clojure, but broadly my solution for day 3 is in the same vein as described above. The solution for day 4 was pretty short, too. Clojure is a functional language, so my solutions have lots of recursion and higher order functions ( map and reduce have featured, for example).
