Learning TypeScript by working my way through Advent of Code 2021.
- TypeScript Notes
- Daily Impressions
- Day 1: Sonar Sweep
- Day 2: Dive!
- Day 3: Binary Diagnostic
- Day 4: Giant Squid
- Day 5: Hydrothermal Venture
- Day 6: Lanternfish
- Day 7: The Treachery of Whales
- Day 8: Seven Segment Search
- Day 9: Smoke Basin
- Day 10: Syntax Scoring
- Day 11: Dumbo Octopus
- Day 12: Passage Pathing
- Day 13: Transparent Origami
- Day 14: Extended Polymerization
- Day 15: Chiton
- Day 16: Packet Decoder
- Day 17: Trick Shot
- Day 18: Snailfish
- Use spread syntax to iterate over Map and Set
[... myMap].map(item => item * 2)
[... mySet].map(([key, value]) => value)
- get better at handling 2D arrays and adjacent neighbors without having to handle undefined issues
- created a Grid type; also check if x and y are between a certain range
- write up helpers for Set operations
- how to perform a step in function programming
- do we have to pass a ton of information to the function to keep track?
- write down all information you know and then test each step separately, if possible
- have a way to log output at each stage without having to use the debugger
I spent some time after work setting up a TypeScript development environment so this wasn't as bad as doing things from scratch. Learning TypeScript is not like Python when it comes to element-wise array-maps.
Got the problem done, don't think it's the nicest solution, but we are learning. What more do I want?
Spent a couple of hours improving my TypeScript development environment by making it easier to run scripts / debug. This was a worthwhile exercise as I was able to focus on writing code versus struggling with developer tooling.
I need to figure out a better way of parsing input to reduce code duplication. Will work on that tomorrow.
Part 1 was pretty straight-forward. Part 2 took a bit of time to get. Had to calculate it in the REPL vs coming up with a clean solution; it's hard to think in TypeScript... hopefully will get easier as we move along.
Created a BingoBoard class to handle the logic of playing Bingo. Using for loops which does not feel right in TypeScript... but it works 🤷
TIL: Can enumerate the index of a for loop as follows: for (const [idx, item] of items.entries())
Cut down on the number of loops I've used which feels good. Not a fan of JavaScript / TypeScript Maps and their lack of iterable methods; really would love a my_dict.items()
I can map and filter through.
Playing catchup... doing this a day later. Part 1 was done in a naive way. Used a better data structure for Part 2. Can probably replace my for loops with reduce calls, but it works so no point.
Used the formula for calculating the sum of an infinite series of natural numbers. High school math came in handy!
This was challenging, especially for being in the middle of the week. Brute forced an algorithm to deduce the numbers... not pretty but gets the job done.
Found a great solution which uses the Set data type from Immutable.js.
This is a simple problem in Python, but not so much in JavaScript. I initially tried to use functional programming techniques, but I'm still getting the hang of FP and mapping through a double array wasn't making a lot of sense.
I tried using immutable.js, but it looks like JavaScript has some issues with doing a ===
check for Maps and Sets which is fine. Ended up installing typescript-collections
to have Python-esque Data Structures... but even then the Set type does not have a way to pop a random element off.
Also had some problems where 0
is treated like false so when I'm doing a check for undefined
, i.e. Map.getValue(xyz) || 10
, 0
is treated like false
and the result is 10.
Still... got things done by hacking together a solution by stuffing 2D points into a (x, y) coordinate string to have the native Map work as expected.
Fought the language for 2-3 hours... don't feel like I won. Really missed Python today, but definitely learned a lot. At least my part1()
and part2()
functions look sort of functional!
Look forward to seeing how experienced TypeScript programmers completed today.
Update: Refactored my solution to use builtin data structures. Have to do a little bit of hacking to store points into dictionaries, but it's better than depending on libraries that don't exactly do what I need so I have to hack anyways.
This was fairly straight-forward. Feels like I used for loops a bit too much since this is the bracket matching problem and that's my normal way of doing it. Looking forward to seeing other people's better solutions.
Another fairly straight-forward puzzle. Only trick was making sure the process was done in the right order. Learned that []
is not a falsy value in JavaScript.
Complete List of JavaScript Falsy Values
My part 2 solution is very slow since I just brute forced it. Takes around 32 seconds to run which is way too long. If I was using Python, I would just use pypy to speed things up and call it a day... but for JS I need some better optimizations.
I cracked out a piece of paper and figured out the algorithm required to get the answer. Wrote up a console logger to visualize the solution to part 2. Not too bad, but felt a bit messy. Getting better at TypeScript though.
Started this late as I was playing catchup on previous days so I only got part 1 done in a naive way before I went to bed. Woke up this morning with an idea about keep track of pair counts as we don't really care what the string looks like. Refactored part 1 solution into a solution that works for part 2. Used lodash and a class; fairly happy with my solution.
I feel like I'm over-dependent on tuples since that's what I'm used to in Python. I need to start thinking JSON objects every time I think tuple
. Thinking in JSON will also let me take advantage of lodash and other fun map-reduce things.
Update: Refactored by making it more functional and taking advantage of JSON objects. Looks a lot nicer. Also making better use of lodash
Straight-forward application of pathfinding: used heap + Dijkstra's Algorithm. My part 2 solution runs in 1.2 seconds which is good enough for me. I created a TypeScript utilities module to simplify working with grids using the builtin Map and Set data types.
Todo: implement A* and write up a custom implementation of a heap / priority queue.
I had to re-read part 1 a bunch of times before I was able to solve it. Hacked together a solution which created a flat array and then I summed over the version numbers to get the answer.
I knew for part 2, I would need to create a nested data structure to make it easier to solve. I went down the route of creating classes for Operators and Literals and then using functional programming techniques to get the final answer.
Found myself struggling against TypeScript types. Used an interface and class to get to the final solution.
After looking at a TypeScript solution I found on Reddit, I noticed that I was on the right track but didn't know I could use the as
keyword to cast union types into a more strict type. I think I like my approach of combining classes and recursion versus doing straight up JSON manipulation and recursion. Feels more readable and easier to extend for other types.
TIL: parseInt() has an optional radix
parameters that can be used to convert between bases
I just brute-forced this once. I think there is a trick involving reducing the search space, but I just played with my for loop ranges until the answer converged. Sometimes it's not worth it.
This one took a bit of time since I didn't really design the solution in a clean way; everything is a giant spaghetti mess. Used eval
to convert each line into an array and then stored the data in a tree-like format.
Don't think I had the best structure for my tree -- left / right can reference either a number or another Node. This required me to add a bunch of guard clauses with type checks to stop TypeScript from complaining.
Todo
- how to store binary trees in an idiomatic TypeScript way?
- look at other people's solutions / watch videos
- solution I can learn from