DEV Community

Caleb Weeks
Caleb Weeks

Posted on

3

Advent of Code #1 (in Gleam)

It's that time of the year again! Advent of Code is my favorite coding challenge, and I enjoy talking about the problems with friends and coworkers.

This year, I really wanted to try doing the puzzles in Roc. I've been following the development of the language for a while, but I've never really tried using it. Unfortunately, I had a hard time getting started with it. Advent of Code is challenging enough on its own, and I didn't want to add too much to that challenge.

I really enjoyed using Crystal last year. It is a very ergonomic language with a featureful standard library. I was tempted to use it again this year, but I figured I should use this opportunity to try something new. After considering several languages including Go, F#, Nim, and Raku, I decided to go with Gleam.

It took me a bit of time to find a proper package for reading files, but I settled on simplifile.

Without further ado, here's my solution:

import gleam/int
import gleam/io
import gleam/list
import gleam/string
import simplifile as file

const example = "
3   4
4   3
2   5
1   3
3   9
3   3
"

pub fn main() {
  let assert Ok(input) = file.read("input")
  let assert 11 = part1(example)
  let assert 31 = part2(example)
  part1(input) |> int.to_string |> io.println
  part2(input) |> int.to_string |> io.println
}

fn parse_lists(input: String) -> #(List(Int), List(Int)) {
  input
  |> string.trim
  |> string.split("\n")
  |> list.fold(#([], []), fn(acc, line) {
    let #(left_list, right_list) = acc
    let assert [left, right] = string.split(line, "   ")
    let assert Ok(left) = int.parse(left)
    let assert Ok(right) = int.parse(right)
    #([left, ..left_list], [right, ..right_list])
  })
}

fn part1(input: String) -> Int {
  let #(left_list, right_list) = parse_lists(input)
  let left_list = list.sort(left_list, by: int.compare)
  let right_list = list.sort(right_list, by: int.compare)

  list.zip(left_list, right_list)
  |> list.fold(0, fn(sum, pair) {
    let #(left, right) = pair
    sum + int.absolute_value(left - right)
  })
}

fn part2(input: String) -> Int {
  let #(left_list, right_list) = parse_lists(input)

  list.fold(left_list, 0, fn(sum, left) {
    sum + list.count(right_list, fn(right) { left == right }) * left
  })
}
Enter fullscreen mode Exit fullscreen mode

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (0)

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay