seeplusplus

seeplusplus

Advent of Code 2023 - Day 4

Hello all, hopefully I post this before someone else does and I don’t dupe.

IMO Day 4 was much easier than Day 3 (yay, I can sleep before work!)

My set-up:

defmodule Card do
  defp to_list_numbers(str) do
    str 
    |> String.split(" ")
    |> Enum.filter(fn s -> String.length(s) !== 0 end)
    |> Enum.map(fn u ->
      {i, _} = Integer.parse(u)
      i
    end)
  end
  def parse("Card " <> rest) do
    [_, numbers] = rest |> String.split(":")
    [winning, player] = numbers |> String.split("|")
    [winning |> String.trim() |> to_list_numbers(), player |> String.trim() |> to_list_numbers()]
  end
end

cards = for card <- input |> String.split("\n"),
[winning_numbers, our_numbers] = Card.parse(card) do
  [winning_numbers, our_numbers]
end

Then part 1 was really simple (10 minutes from start for me to get here):


for [winning_numbers, our_numbers] <- cards
do
  case count_winning_cards.(our_numbers, winning_numbers) do
    n when n > 0 -> 2**(n-1)
    0 -> 0
  end
end |> Enum.sum()

Part 2 slightly less so (40 minutes from start to get here):


cards 
  |> Enum.with_index()
  |> Enum.reduce(
    List.duplicate(1, cards |> Enum.count()),
    fn {[winning, player], idx}, copies ->
      self_copies = Enum.at(copies, idx)
      won = count_winning_cards.(player, winning)
      slice = if won > 0, do: (idx+1)..(idx+won), else: ..
      copies |> Enum.with_index() |> Enum.map(
        fn {count, idx} ->
          if idx in slice, do: count + self_copies, else: count
        end
      )
    end
  ) |> Enum.sum()

The biggest time sink for me was remembering that 1..1 is a non-empty range in Elixir, so I needed to write the slice to be:

      slice = if won > 0, do: (idx+1)..(idx+won), else: ..

Most Liked

bjorng

bjorng

Erlang Core Team

I also found today’s puzzle much easier than yesterday’s.

https://github.com/bjorng/advent-of-code-2023/blob/main/day04/lib/day04.ex

nico.t

nico.t

It seems many people don’t know that we can pass a list of characters as 2nd argument of String.split/2.
It is pretty useful when parsing your input.
Think about it in the coming days. :wink:

iex(1)> line = "Card 1: 41 48 83 86 17 | 83 86  6 31 17  9 48 53"
"Card 1: 41 48 83 86 17 | 83 86  6 31 17  9 48 53"
iex(2)> ["Card " <> id, winning, mine] = String.split(line, [":", "|"])
["Card 1", " 41 48 83 86 17 ", " 83 86  6 31 17  9 48 53"]
iex(3)> winning = String.split(winning)
["41", "48", "83", "86", "17"]
iex(4)> mine = String.split(mine)
["83", "86", "6", "31", "17", "9", "48", "53"]
iex(5)> id
"1"
Aetherus

Aetherus

You don’t have to convert those numeric strings to integers.

Here’s my code:

https://github.com/Aetherus/advent-of-code/blob/master/2023/day-04.livemd

Last Post!

APB9785

APB9785

Creator of ECSx

Nothing too complicated today. Core logic for part 2:

defp generate_copies(original_cards) do
  starting_card_stack = original_cards |> Enum.map(& &1.id) |> Map.new(&{&1, 1})

  Enum.reduce(original_cards, starting_card_stack, fn card, stack ->
    card
    |> get_payout(stack)
    |> Map.merge(stack, fn _k, v1, v2 -> v1 + v2 end)
  end)
end

Full solution here on Github

Where Next?

Popular in Challenges Top

bjorng
Note: This topic is to talk about Day 5 of the Advent of Code 2019. There is a private leaderboard for elixirforum members. You can join...
New
Aetherus
Finished Day 1 with Elixir :tada: Here’s my code: #!/usr/bin/env elixir defmodule Combination do @doc "Yields each combination of 2...
New
New
Aetherus
Hello, guys. I’m back again, but only for the weekends, maybe. This topic is about Day 13 of the Advent of Code 2020 . Thanks to @egze,...
New
LostKobrakai
This one has been quite the ride. Struggled at first to find a good data format to suite the problem. I really like how that turned out b...
New
bjorng
Here is my solution for day 4: https://github.com/bjorng/advent-of-code/blob/main/2024/day04/lib/day04.ex
New
New

Other popular topics Top

vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 40165 209
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

We're in Beta

About us Mission Statement