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

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

Top comments (0)

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay