this post was submitted on 01 Dec 2023
11 points (100.0% liked)

Advent Of Code

763 readers
1 users here now

An unofficial home for the advent of code community on programming.dev!

Advent of Code is an annual Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language you like.

AoC 2023

Solution Threads

M T W T F S S
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25

Rules/Guidelines

Relevant Communities

Relevant Links

Credits

Icon base by Lorc under CC BY 3.0 with modifications to add a gradient

console.log('Hello World')

founded 1 year ago
MODERATORS
 

I'm using this starter kit for the scaffolding so I can simply run mix test for the example and mix d01.p2 to run the solution for my specific data set.

I've got the following code that passes p1 completely and the p2 example but not my specific data set. I can't find any bugs but the result fails for being "too high" and I'm really not sure why this is not being accepted. I have the debug output for each step and running through it manually everything seems right to me.

Is anyone able to point me in the right direction on what I'm missing?

https://pastebin.com/US8ikNLx

defmodule AdventOfCode.Day01 do
  def part1(args) do
    args
    |> String.split(~r/\n/, trim: true)
    |> Enum.map(&line_calibration_value/1)
    |> Enum.sum()
  end

  def part2(args) do
    args
    |> String.split(~r/\n/, trim: true)
    |> Enum.map(&words_to_numbers/1)
    |> Enum.map(&line_calibration_value/1)
    |> Enum.sum()
  end

  defp words_to_numbers(string) do
    numbers = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]

    String.replace(string, numbers, fn x ->
      (Enum.find_index(numbers, &(&1 == x)) + 1)
      |> Integer.to_string()
    end)
  end

  # TODO: doesn't work if the string has no numbers
  defp line_calibration_value(string) do
    # remove any non-numeric characters
    number_from_string = String.replace(string, ~r/[^\d]/, "")

    calibration_number = [
      # first number
      String.at(number_from_string, 0),
      # last number, or first number is string has length of 1
      String.at(number_from_string, -1)
    ]

    calibration_number
    |> List.to_string()
    |> String.to_integer()
  end
end

you are viewing a single comment's thread
view the rest of the comments
[–] [email protected] 1 points 11 months ago

I arrived at the following solution for Day #1:

https://pastebin.com/u1SYJ4tY

defmodule AdventOfCode.Day01 do
  def part1(args) do
    number_regex = ~r/([0-9])/

    args
    |> String.split(~r/\n/, trim: true)
    |> Enum.map(&first_and_last_number(&1, number_regex))
    |> Enum.map(&number_list_to_integer/1)
    |> Enum.sum()
  end

  def part2(args) do
    number_regex = ~r/(?=(one|two|three|four|five|six|seven|eight|nine|[0-9]))/

    args
    |> String.split(~r/\n/, trim: true)
    |> Enum.map(&first_and_last_number(&1, number_regex))
    |> Enum.map(fn number -> Enum.map(number, &replace_word_with_number/1) end)
    |> Enum.map(&number_list_to_integer/1)
    |> Enum.sum()
  end

  defp first_and_last_number(string, regex) do
    matches = Regex.scan(regex, string)
    [_, first] = List.first(matches)
    [_, last] = List.last(matches)

    [first, last]
  end

  defp number_list_to_integer(list) do
    list
    |> List.to_string()
    |> String.to_integer()
  end

  defp replace_word_with_number(string) do
    numbers = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]

    String.replace(string, numbers, fn x ->
      (Enum.find_index(numbers, &(&1 == x)) + 1)
      |> Integer.to_string()
    end)
  end
end