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.

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:

Aetherus

Aetherus

I heard that when running a -- b, the Erlang runtime will first convert b to a red-black tree if b is long enough (maybe when length(b) > 32). If that’s the case, then a -- a -- b can be as performant as MapSet.intersection(set1, set2).

Aetherus

Aetherus

Learned Map.get_and_update.

Where Next?

Popular in Challenges Top

Aetherus
This topic is about Day 16 of the Advent of Code 2020 . Thanks to @egze, we have a private leaderboard: https://adventofcode.com/2020/l...
New
bjorng
Note: This topic is to talk about Day 25 of the Advent of Code 2019. There is a private leaderboard for elixirforum members. You can joi...
New
sb8244
Note: This topic is to talk about Day 10 of the Advent of Code 2019 . There is a private leaderboard for elixirforum members. You can jo...
New
bjorng
My solution finishes both parts in 5 seconds on my computer. That time should be possible to reduce by optimizing my rather naive tilt/2 ...
New
stevensonmt
Trying to get more facility with dynamic programming concepts on Leetcode and having an issue I can’t find a way around. It’s a chutes an...
New
shritesh
This was way too easy after the last few days. Simple map, filter and count.
New
New
bjorng
This topic is about Day 9 of the Advent of Code 2021 . We have a private leaderboard (shared with users of Erlang Forums): https://adve...
New
cblavier
Hey there :wave: No magic or algorithmic finesse today, I just finished the challenge and I my code is quite slow (1sec for part1, 3se...
New
Aetherus
Today’s problem is really tense. I don’t think I can do it without libgraph.
New

Other popular topics Top

Qqwy
Update: How to use the Blogs &amp; Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
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
AstonJ
by Lance Halvorsen Elixir and Phoenix are generating tremendous excitement as an unbeatable platform for building modern web application...
460 27162 124
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New

We're in Beta

About us Mission Statement