DEV Community

Caleb Weeks
Caleb Weeks

Posted on

Advent of Code #3 (in Gleam)

Regex is doing a lot of the heavy lifting in today's puzzles. That is one of the main reasons why I ended up not using Roc for Advent of Code this year. There is no regex library, and I just couldn't quite wrap my head around the parser combinator library in time for this year. Maybe I'll get around to it next year.

Pattern matching is a powerful tool in general, and really excels at handling the regex matches. I find it a little strange that you can't pattern match in function parameter definitions like you can in most languages with pattern matching. I'm sure there is a good reason for it, but I'm not sure what that is at the moment.

Anyway, here's how I solved today's puzzles:

import gleam/int
import gleam/io
import gleam/list
import gleam/pair
import gleam/option.{Some}
import gleam/regexp.{Match}
import simplifile as file

const example1 = "
xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))
"

const example2 = "
xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))
"

pub fn main() {
  let assert Ok(input) = file.read("input")
  let assert 161 = part1(example1)
  let assert 48 = part2(example2)
  part1(input) |> int.to_string |> io.println
  part2(input) |> int.to_string |> io.println
}

fn mult_pair(x: String, y: String) -> Int {
  let assert Ok(x) = int.parse(x)
  let assert Ok(y) = int.parse(y)
  x * y
}

fn part1(input: String) -> Int {
  let assert Ok(re) = regexp.from_string("mul\\((\\d+),(\\d+)\\)")
  regexp.scan(re, input)
  |> list.fold(0, fn(sum, match) {
    let assert Match(_, [Some(x), Some(y)]) = match
    sum + mult_pair(x, y)
  })
}

fn part2(input: String) -> Int {
  let assert Ok(re) = regexp.from_string("mul\\((\\d+),(\\d+)\\)|do\\(\\)|don't\\(\\)")
  regexp.scan(re, input)
  |> list.fold(#(0, True), fn(state, match) {
    case match, state {
      Match(_, [Some(x), Some(y)]), #(sum, True) -> #(sum + mult_pair(x, y), True)
      Match("do()", _), #(sum, _) -> #(sum, True)
      Match("don't()", _), #(sum, _) -> #(sum, False)
      _, _ -> state
    }
  })
  |> pair.first
}
Enter fullscreen mode Exit fullscreen mode

Billboard image

Imagine monitoring that's actually built for developers

Join Vercel, CrowdStrike, and thousands of other teams that trust Checkly to streamline monitor creation and configuration with Monitoring as Code.

Start Monitoring

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

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay