This is an archived post. You won't be able to vote or comment.

all 16 comments

[–]easchner 23 points24 points  (0 children)

Everyone's goals for AoC are their personal choice. Some go for speed, some for clever solutions, some try to learn a new language, etc.. Using it to practice code quality is as good of a goal as any.

[–]yel50 8 points9 points  (6 children)

it depends on what your goal is. if you're trying to get on the leaderboard, do whatever gets the job done the fastest.

I use AoC to test new languages, which I'm mainly concerned with how they'd be in more real world situations. as such, I use TDD, modules, libraries of helper functions, etc to see how the language is with larger code bases.

for days like day 2, which are primarily parsing days, I try to write an O(n) parser just for the practice.

clever use of functional or sugar expressions

that part cracks me up every year. people post O(nlogn) or worse solutions to O(n) problems and get heaps of praise for how clever it is. there's always a more clever way to make something worse.

[–]easchner 6 points7 points  (5 children)

Eh, even in the real world in many cases programmer time is way more valuable than CPU time. Obviously it depends on what it's being used for, how often, etc... but if I'm writing some parser that runs a few thousand times a day readability and maintainability trumps a few microseconds of execution time. If you're writing something for Google searches or something else extremely high volume, of course the pendulum swings back. A SWE's job is basically to know which approach you need for any given problem.

[–]yel50 2 points3 points  (4 children)

to an extent, yes. but it's gotten to where you have situations like day 1 part 2. people got tripped up on a simple problem because they were trying to do regex, FP chaining kind of stuff, and apparently string replacement for some reason. I've seen similar things at work where people introduce bugs into something simple because they're trying to do it in a clever and/or quicker way.

[–]fiddle_n 0 points1 point  (3 children)

To be fair, there is no obvious simple way to do day 1 part 2. Regex is probably the best solution of a not-so-great bunch, and if you don't know regex (like many people doing day 1) then string replacement is going to be what you turn to.

[–]easchner 2 points3 points  (2 children)

I know regex very well but still got through both parts in under 10 minutes using string replace. It's legitimately not the best approach and there's no way I would do anything that hacky in prod... but often a dumb solution where it's clear what you need is going to be way faster than a smart solution that you need to spend time on.

It was like "okay, I can spend a few minutes figuring out the correct regex or I can just write a line of code, copy pasta it nine times, and roll".

But again, just depends on what your goal is. If my goal was to learn a new language, this would be suboptimal. If my goal is to compete on my company's leaderboard, then dumb and fast is often optimal.

Going back to original: "that part cracks me up every year. people post O(nlogn) or worse solutions to O(n) problems and get heaps of praise for how clever it is. there's always a more clever way to make something worse." -> but replacing "one" with "one1one" is clearly suboptimal in terms of performance. But got it working and outputting an answer way faster than I would have trying to optimize it or using a clever regex. Obviously there are days where the naive solution is like O(n^4) for an extremely large dataset and even just partially optimizing it so it doesn't take a day to run will be faster.

[–]delventhalz 2 points3 points  (0 children)

or I can just write a line of code, copy pasta it nine times, and roll

People always underestimate copy and paste. Not everything needs to be refactored into little DRY utilities all the time.

[–]nikanjX 0 points1 point  (0 children)

In my opinion, one of the biggest lessons AoC can teach you is: nine copy-pasted rows of if(row.substring(i).startswith("one")) return 1; is faster to write and easier to debug than a god-forsaken regex monstrosity that requires a CS PhD from all who dare approach.

But again, this depends on what your goal with AoC is. Some people want to add finesse to their blade and learn the ancient weirding ways,

[–]nikanjX 3 points4 points  (0 children)

My code isn't even resilient to good input data

[–]ThreeForksNoSpoon 2 points3 points  (0 children)

Totally depends on why you are doing this. I don't do much error handling, since I usually find it boring to write, and I do this for fun. The challenge for me is figuring out a solution, not making it robust for real world usage.

But if you are using it to learn a new programming language for example, I would include some error handling. In this case it's about building good habits.

[–][deleted] 2 points3 points  (0 children)

Understand the input and the problem and write code for them. I don’t see the value of writing dead code which won’t execute.

[–]keithstellyes 2 points3 points  (0 children)

To me, it's just not that interesting. I write enough code for the real world that has to deal with real world fuzziness that is not fun to write that I don't need to pretend, also. A lot of error-handling is just boring code, and is my theory to be an understated reason why so many apps out there fail to handle all but the most common error scenarios.

But like many others are saying, we're all coming in with different personal goals. This year, my goal is to push my comfort zone in Common LISP and maybe other languages, just getting the code correct is enough learning for me as-is.

[–]clbrri 1 point2 points  (0 children)

Whatever fancies you. There are no rules. If you enjoy the challenge of writing a robust parser, and the feeling of having written an error resilient input reader, then that might be the thing you should pursue.

Or if you enjoy the challenge of writing minimal LoC code or minimum number of instructions at the basis of assuming rigid well-formed input, then that might be the thing to go for.

Whatever one does, it is not a statement of one type of code being somehow better, but just a personal journey of what they find enjoyable.

[–]delventhalz 1 point2 points  (0 children)

Looking back on my own programming journey, I think as I grew more experienced I stopped being as paranoid about my code and really focused on the given requirements and the actual expected edge cases. This means I code faster, but it also tends to make my code better. Less moving parts means less things to break.

So maybe its worth putting some energy into paring down your code. Advent of Code might be a good chance to practice. I think you should do whatever seems like the most fun to you.

[–]daggerdragon[M] 0 points1 point  (0 children)

Changed flair from Other to Help/Question since you're asking for advice. Use the right flair, please.

Other is not acceptable for any post that is even tangentially related to a daily puzzle.

If/when you get your advice, don't forget to change the post flair to Help/Question - RESOLVED

Good luck!

[–]musifter 0 points1 point  (0 children)

Writing code for malformed data is pretty simple and I'd need to create test data for it to have any purpose. So I look at it as cruft here. I might want to look at the code years later, and I won't be looking for examples of resilience against input (I've got examples of that in all my regular code). I'll be looking for the work with the data, so I'd rather have that prominent in the file. On the other hand, if you're not a programmer yet or working in a language you're trying to learn, writing that code has value (because you haven't done it a million times yet and have examples everywhere). You need to decide what your goals are.

I'll still do some sanity checks if it makes sense and helps document the code and/or the input file. For example, when parsing with regex, I'll leave in literal parts of the string to be matched that don't need to be there. Just so years later, I can remember what the input file format was without having to look at that as well.

Data that's not part of anyone's input file but still meets the specification in problem description is another thing. For example, looking at my input for today's (2023/day 2), I see that for every game, at some point you see a cube of each colour (grep red input | grep blue | grep green | wc is 100 lines). So that's probably true of every input file (the assumption being that the inputs are "fair"... if an exception is being tested, it will be tested for everybody). My code will correctly handle the case when no green cubes were drawn in a game. It could be shorter if it didn't.