{
  "$type": "site.standard.document",
  "canonicalUrl": "https://unnecessary.tech/posts/aoc-2024-day1",
  "path": "/posts/aoc-2024-day1",
  "publishedAt": "2024-12-01T19:42:39.000Z",
  "site": "at://did:plc:jx54v4rmscfwzit7fmgz24ba/site.standard.publication/3mnrsqmzz3w2e",
  "tags": [
    "gleam",
    "programming"
  ],
  "textContent": "It's time once again for Advent of Code. This time\nI am trying to use it as an opportunity to get better writing Gleam. \n\nToday's problem involved taking two lists\nof integers, presented in an input file with one entry from each list separated\nby three spaces on each line of input, and manipulating these lists to answer a\nfew questions. The first question required we sort the lists and then find the\nabsolute value of the difference between the elements of each list in sorted\norder. The second part require that we count up the number of occurances of each\nelement from the first list in the second list and sum up the multiple of the\nvalue from the first list with the number of occurances in the second list.\n\nMy initial solution is shown here. I separated it into three parts. First, the parse_line function\nwill transform a line of text from the input file into a list of integers, splitting\non one or more spaces. The second part is to use this function in the\nparse_lines function to create a list of lists of integers, one per input\ntext file line and then pull out the first element from each sublist to create\nthe first list, and the second element from each sublist to create the second\nlist. You can see my first attempt at this function was a little clunky. I\nused a separate let statement for each list and went through the combined\nlist of lists twice, once for each list. In the end I return a tuple containing\nthe two separate lists. \n\nFinally, in the solve_p1 and solve_p2 functions you can see how I used the\nresulting lists to either find the different in the sorted pairs, or to count\nthe occurances from one list in the next. I went to bed and left refactoring to\nthe morning.\n\nThe changes I made during refactoring can be seen in this code comparison.\nI made a new function called solve_p2b which contains my refactored solution\nfor counting occurances in the second list. I used a dictionary to count up all\nthe elements in the second list first, and then iterated through the first list\nlooking up counts from the dictionary. This is much more efficient. I also first\nfound it a little difficult to deal with the Result from using dict.get to\nsee if there was an existing entry in the dictionary or if I should just assume\nthere were 0 entries. One thing I\nmissed from Go is the idea that maps will always return a\ndefault 0 value, however I quickly found that I could get similar results in\nGleam by using the result.unwrap function to replace an Error type with a\nliteral 0. Effectively this means that if you care if an entry is present in a\nmap or dictionary in Go you would write\n\nand in Gleam that would be\n\nHowever, if you just want to assume any value not found is 0, then in Go it is\n\nand in Gleam is it as simple as\n\nIn both cases the language lets you set a default value very concisely, but in\nthe Gleam language it is much more explicitly set.\n\nThe other thing I didn't like was the way I parsed the lines from the input.\nI ended up refactoring this quite a bit, which can be seen in the comparison of\nlines 57-79 of the initial code to lines 77-86 of the final code.\nI had used list.fold to build the dictionary in the prior refactoring, and I\nrealized that I could similarly build up the tuple of separate lists from the\ncombined list using fold as well. In order to do some error checking, namely that\neach line had exactly two integers, I used list.try_fold which would return\nan error if it encountered any and I used a case statement to match on lines\nwith two integer entries. The resulting parse_lines function is much more\nconcise and I believe more readable to someone who is used to functional\nprogramming.\n\nOverall I find I tend to still think very procedurally, which at times leads me\nto more complex solutions. I hope that as I work through the rest of Advent of\nCode I can get better at recognizing the best way to perform the data manipulation\nin a more functional way.",
  "title": "Advent of Code 2024 - Day1"
}