Advent of Code 2020 - Day 1

Since 2015, Eric Wastl creates 25 two-part programming puzzles, all connected together by a cute story about needing to save Christmas. The puzzles start easy and get trickier, sometimes needing a little research to find the right algorithm. This set of puzzles varies in its complexity, but they are good to stretch your muscles in different parts of our brains that might not be as fit as they could be.

You can use any language you want, every method you need to solve the puzzles and earn your golden starts. Many people use it to compete/work with cooworkers, job interview, but looking to the AoC community, people join just to have some fun. That said, I put some rules to myself. Gonna solve AoC 2020 in the most pythonic way possible.

Check it out at https://adventofcode.com/2020

Pythonic Way?!

Write code in Python in pythonic way is to exploit the features of the Python language to produce code that is clear, concise and maintainable. Pythonic means code that doesn’t just get the syntax right but that follows the conventions of the Python community and uses the language in the way it is intended to be used.

This is maybe easiest to explain by negative example, as in the linked article from the other answers. Examples of unpythonic code often come from users of other languages, who instead of learning a Python programming patterns such as list comprehensions or generator expressions, attempt to crowbar in patterns more commonly used in C or java. Loops are particularly common examples of this.

1for i in (i; i < items.length ; i++)
2 {
3	 n = items[i];
4	 n.runMethod();
5 }
javascript

In Python you can have a clean code like:

1for n in items:
2	n.run_method()
javascript

Or better:

1(n.public_attribute for n in items if n.public_attribute is not None)
javascript

Day 1 - Report Repair

Long story short, you gonna travel to a resort, but, the “Elves” in accounting just need you to fix your expense report. All details are on the day 1 link (https://adventofcode.com/2020/day/1)

I receive my “expenses report” with a lot of integers and the first task is find the two entries that sum to 2020. And the second task is find the tree entries that sum to 2020.

First try on task 1

Well, the biggest number I have in my list is 2010, I believe the probability of both addends greater then 1000 is almost 0. Let’s get all numbers lower then 1000 in a separated list (list_3digits) and generate another list (list_2020) with the difference. After that, it’s all about a search for the existance of each number in list_2020 in the original list.

 1list_3digits = [num for num in list if len(str(num)) < 4]
 2list_2020  = [2020 - num for num in list_3digits]
 3list_2020
 4
 5i = 0
 6for num in list_2020:
 7  if num in list:
 8    print(f'{num}+{list_3digits[i]}={num+list_3digits[i]}')
 9    print(f'{num}*{list_3digits[i]}={num*list_3digits[i]}')
10  i += 1
python

It works, but, 1010 + 1010 is also 2020, I have a problem here.

Pythonic, dude… PYTHONIC!

After a small research, python already provide us an awesome library to handle Iterator types, the itertools lib. From official documentation: “The module standardizes a core set of fast, memory efficient tools that are useful by themselves or in combination. Together, they form an “iterator algebra” making it possible to construct specialized tools succinctly and efficiently in pure Python.”

So, with this superpower, it’s just a matter of get all non repeatable combinations from the original list and search for the combination that sum to 2020.

1from itertools import combinations
2
3for x in combinations(list, 2):
4  if sum(x) == 2020:
5    print(f'{x}')
6
7for x in combinations(list, 3):
8  if sum(x) == 2020:
9    print(x)
python

We solved, in a quasi full Pythonic way. But.. we can do better. List comprehensions.

1from itertools import combinations
2print([resp for resp in combinations(list, 2) if sum(resp) == 2020])
3print([resp for resp in combinations(list, 3) if sum(resp) == 2020])
python

List comprehensions are great to use when you want to save some space. They’re also handy when you just need to process a list quickly to do some repetitive work on that list.

But if all you could do is work straight through a list, list comprehensions wouldn’t be all that useful. Thankfully, they can be used with conditions.

One line for each task. It was fun! Let’s see the AoC Day 2.

Z

Comments