Sunday, December 26, 2021

Advent of Code Is Done For The Year

We've come to the end of another year of Advent of Code. Apparently this year AoC saw the 10 millionth star issued since it began in 2015! Pretty impressive. Not sure of any final numbers yet, but I've heard there was again more participation this year than the previous year. The stats show that on Day 1, 190,118 people completed both parts and 22,274 additional people completed Part 1. And on Day 25, 7227 completed both parts with 4701 completing Part 1. Last year, more people stuck around to the end (quarantine-related?), but this year had far more participants. 

Pretty cool. 

I started the season with the framework I had begun building to quickly parse the inputs into a usable format, but I quickly realized that the inputs this year were a bit more complex than I was previously working on. I bailed on my framework and just resorted to simple day-by-day processing. I'll go back and refactor my earlier framework to include this year's processing needs. 

I'm not one of the Competitive Programmers who always top the AoC Leaderboard, but I did participate this year with a few other programmers from the Working Code Podcast's Discord server. Some used Python, and a couple of us used CFML. I created a Private Leaderboard for us so that we could at least see how we were doing against some of our peers. Considering that most of the Top 100 Public Leaderboard spots were filled within just a few minutes of puzzle release, I'm glad I did it. 

I didn't finish as many days as I wished I had. I only made it through Part 1 of Day 9 before time ran out. I ran into a huge stumbling block on Day 4 that really hung me up and killed my motivation. I gave it a few tries a couple of times, but kept getting wrong answers. I watched myself getting further and further behind, and just kinda set the whole thing aside for a few days. I finally went back to it and solved it, much easier than I thought I would, and realized I had been way over-thinking it. I tried to blast through as many as I could before time ran out, but stumbled again on Day 8. I managed to get the solution and knocked out Part 1 of Day 9, but struggled with Part 2 until I ran out of time. The biggest lesson I learned was to not try to do these late in the evening. And also, Off-By-One errors suck. 

Oh, and Python (which has been on my Things I Want To Learn list for way too long) is much more capable of handling these types of problems. ColdFusion can do it, but some of the processing seemed to be much more straightforward in some of the other language answers. 

I took notes on the days I did, and I need to finish writing them all up. 

A big thank you to Eric Wastl for creating this, and another big thank you to all who participated. I look forward to doing this again next year. 👍


Working Code Podcast Group 2021 Private Leader Board


Tuesday, December 7, 2021

Today I (re)Learned

Mark this up as a TI(re)L:

I've been working on the Advent of Code daily puzzles with some of the people on the Working Code Podcast Discord channel, and I said that one of the challenges I've had with some of these puzzles was simply parsing the Inputs into the format I planned to work with in CFML. Tim Cunningham (t) mentioned some code that would parse a CSV file:


private function setParseSettings(
    required string localFilePath,
    required string lineSeperator=CRLF,
    required string quoteEscape="\",
    required boolean parseUnescapedQuotes=true,
    required boolean keepFirstRow=false
) { ..... }

I looked at the code and thought "Why would you have a default value if the parameter is required?", so I asked. A long time ago I learned that a required parameter couldn't have a default value; that's what optional parameters are for. At least that's what I thought. I guess I haven't ever really thought about the way it works. 

In SQL Server, functions don't really have a concept of optional parameters. Stored Procedures do, but there isn't an explicit required attribute in either one. You simply define an optional parameter by giving it an "= something". There are a few gotchas with parameters in SQL functions and sprocs, but those are beyond the scope of my thoughts here. And since most of my current work is in SQL and not CFML, I never really came across it enough to think about it.

Back to what I didn't realize I had forgotten.... 

You CAN have both required and a default value in your parameter definitions, in CFML and in many, if not most, other languages.

I knew that, conceptually, if a parameter was required, then it didn't matter if it had a default value. You had to pass the parameter, and if you did, then the default value was replaced anyway. But that's where my thinking was backwards. When the function is evaluated, if an optional value is defined, the required definition is ignored. So even though an argument is labeled as required, it doesn't have to be passed if there is a default value.

I didn't think that made any sense, so I verified it.

<cfscript>
function testme( required String param1, required Boolean param2 = false ) {
    return {"param1":param1,"param2":param2}
}

writedump( testme("Bill") )
writedump( testme("Ted",true) )
writedump( testme(param2=true, param1="Rufus") )
writedump( testme() )
</cfscript>

Which gave me: 

Huh... I stand corrected. This was something that I used to know, but had completely forgotten, or at least overwrote my original memory with my later assumption of how it all went together. 

Apparently it's perfectly fine to not pass a "required" parameter as long as it has a default value. If no parameter is passed, the default is evaluated and the required is ignored. Which is probably why I got backwards in the first place. Why label a parameter as required if it isn't really?

I'm sure the old gods of programming had a legitimate reason for doing it that way, but it escapes me. 

Oh well.