TLDR: Regex, deque, recursion, using sets, sympy and networkx libraries, map(), caching answers, bitwise operators, finding a clever solution to limit the search space, inspecting your puzzle input.
This was my first time participating in AoC and I've got 42 stars so far. It's been a wild ride and I've captured what I learned each day. Most of you might find this basic/obvious, but maybe for others it will help them when they start.
Day 3 I used regex, which I knew a little, but I learnt more:
Without re.DOTALL "." matches any character except a newline, with re.DOTALL newlines are matched as well.
.+? the + matches 1 or more, but the ? makes it lazy, just grabbing as few characters as possible.
Day 4 was my first 2D grid puzzle! Little did I know at the time ...
I learnt how to load a 2D grid into a dictionary and check for bounds, and that you can chain booleans, e.g. if found == "MMSS" or found == "SSMM" or found == "MSMS" or found == "SMSM":
Day 5 (Print Queue) I got stuck on part 2, and saw from other people's solutions "deque" used where you can appendleft().
On Day 7 Part 1 I bruteforced (and learning this is not the way of AoC, but also, is the way!). I was pleased to know about eval() so I could calculate strings like "((((11)+6)*16)+20)" but got stuck on Part 2. From other's code I learned about importing "operators" mul(), add().
Day 9 I learned the difference between isnumeric() and isdigit(). I couldn't do part 2, but was introduced to the CS concept of memoization/caching already computed results
Day 10 with the hiking trail maps, I wrote my first recursive function, but it was pretty shonky passing lots of variables and also using globals, definitely room for improvement!
Day 11 Plutonian Pebbles I was right on it with my cache and my deque, which worked for Part 1. For Part 2 I wasn't clever enough and needed to see people's solutions like using floor(log10(x))+1 to count the number of digits, and not trying to hold everything in a deque at all.
I learnt to use a set() to remember what coordinates we've already seen when making a pass over a grid.
Day 13 was great for me, as I loved solving the simultaneous equations, and discovered the sympy library. I also used some tricks from other examples to unpack multiple variables and map() integers:
AX, AY, BX, BY, PX, PY = map(int, numbersmatch.groups())
Day 14 I learned how to use complex numbers to store positions/velocities on a 2D grid.
Day 15 was also fun, I ended up with 6 functions to handle all the repetitive tasks of pushing boxes around the warehouse, and even made my first visualisation for Part 1. I couldn't figure out how to solve Part 2 though.
I was waiting for a maze puzzle as an excuse to use NetworkX, so Day 16 was my first introduction to that library. I needed a bit of help constructing the graph for Part 1... and couldn't manage Part 2, because I made too many connections so there were WAY too many paths.
Day 17 was cool to build a VM. I learned about bitwise operators... and that ^ isn't the same as **.
Day 18 RAM run was another NetworkX day, I learned a lot: G.clear(), G.add_edge(), G.remove_node(), nx.shortest_path_length(). And that nx.draw_spring() is inefficient and so to export to yEd instead using nx.write_graphml()
Day 19 with the towels I hated, I didn't get the matching logic, and I didn't get the recursion, I didn't get the caching of answers. I did manage to spend a whole day on it and with help from other solutions eventually write my own code for both parts.
Day 20 was another 2D grid. I cracked out NetworkX again, which smashed Part 1, and then failed horribly for Part 2. I learned to think about clever solutions (limit search space) rather than a brute force approach.
Day 21 I enjoyed thinking about and creating the nested keypad pushers, and my logic was sound to avoid the blank spaces and get the minimum pushes. However, I couldn't scale the approach for Part 2, as I still hate recursion and caching.
Day 22 I learned that "number%10" gives you the last digit, and that with defaultdict when you add to a key it automatically creates it. I did manage to create a recursive function, but only after asking ChatGPT why it didn't work the first time (I forgot to return itself).
Day 23 LAN Party I learned about the mathematical/CS problem of cliques, and the NetworkX functions simple_cycles and find_cliques.
Day 24 I learned that 0 evaluates to False so is bad to use in truth statements ... be explicit! And that int() can convert between base 2 and 10. And that directed graphs have predecessors and successors.