Aetherus

Aetherus

Advent of Code 2020 - Day 4

This topic is about Day 4 of the Advent of Code 2020 .

Thanks to @egze, we have a private leaderboard:
https://adventofcode.com/2020/leaderboard/private/view/39276

The join code is:
39276-eeb74f9a

Most Liked

aaronnamba

aaronnamba

Observations:

  • Woof, data validation… kinda tedious. A lot like work, and I do AoC to take a break from work…
  • I anticipated having to look up things, so I parsed into a map, but that ended up being entirely unnecessary.
  • Thank goodness for pattern matching.

Excerpt:

  def all_fields_valid?(record) do
    Enum.all?(record, fn {field, value} -> valid?(field, value) end)
  end

  def valid?(field, year) when field in ["byr", "eyr", "iyr"] and is_binary(year),
    do: valid?(field, String.to_integer(year))

  def valid?("byr", year) when year in 1920..2002, do: true
  def valid?("iyr", year) when year in 2010..2020, do: true
  def valid?("eyr", year) when year in 2020..2030, do: true
  def valid?("hgt", {cm, "cm"}) when cm in 150..193, do: true
  def valid?("hgt", {inch, "in"}) when inch in 59..76, do: true
  def valid?("hgt", {_, _}), do: false
  def valid?("hgt", height), do: valid?("hgt", Integer.parse(height))

  def valid?("hcl", color), do: Regex.match?(~r/^#[0-9a-f]{6}$/, color)

  def valid?("ecl", color) when color in ["amb", "blu", "brn", "gry", "grn", "hzl", "oth"],
    do: true

  def valid?("pid", pid), do: Regex.match?(~r/^[0-9]{9}$/, pid)
  def valid?("cid", _), do: true
  def valid?(_, _), do: false
Aetherus

Aetherus

A straightforward solution for Part 2:

#!/usr/bin/env elixir

defmodule Validator do

  def valid?({"byr", value}) do
    value
    |> String.to_integer()
    |> Kernel.in(1920..2002)
  end

  def valid?({"iyr", value}) do
    value
    |> String.to_integer()
    |> Kernel.in(2010..2020)
  end

  def valid?({"eyr", value}) do
    value
    |> String.to_integer()
    |> Kernel.in(2020..2030)
  end

  def valid?({"hgt", value}) do
    case String.split(value, ~r/(?<=\d)(?=[a-z])/) do
      [num, unit] ->
        valid_height?(String.to_integer(num), unit)
      _ -> false
    end
  end

  def valid?({"hcl", value}) do
    value =~ ~r/^\#[0-9a-f]{6}$/
  end

  def valid?({"ecl", value}) do
    value in ~w[amb blu brn gry grn hzl oth]
  end

  def valid?({"pid", value}) do
    value =~ ~r/^\d{9}$/
  end

  def valid?({_key, _value}) do
    true
  end

  defp valid_height?(num, "cm"), do: num in (150..193)
  defp valid_height?(num, "in"), do: num in (59..76)
  defp valid_height?(_, _), do: false
end

required_fields = ~w[
  byr
  iyr
  eyr
  hgt
  hcl
  ecl
  pid
]

to_passport = fn(fields)->
  fields
  |> Stream.map(&String.split(&1, ":"))
  |> Stream.map(&List.to_tuple/1)
  |> Map.new()
end

valid? = fn(passport)->
  has_all_required_keys? = Enum.all?(required_fields, &Map.has_key?(passport, &1))
  all_values_are_valid? = Enum.all?(passport, &Validator.valid?/1)
  has_all_required_keys? and all_values_are_valid?
end

"day4.txt"
|> File.read!()
|> String.split("\n\n")
|> Stream.map(&String.split/1)
|> Enum.map(to_passport)
|> Enum.count(valid?)
|> IO.puts()
Damirados

Damirados

As this is typical day to day work I just imported Ecto in my solution

aaronnamba

aaronnamba

I see some pattern matching in there, but you could do a lot more of it. Also, Integer.parse is your friend on the height field.

Where Next?

Popular in Challenges Top

LostKobrakai
This topic is about Day 9 of the Advent of Code 2020 . Thanks to @egze, we have a private leaderboard: https://adventofcode.com/2020/le...
New
New
igorb
I found today a bit tedious: advent-of-code-2024/lib/advent_of_code2024/day15.ex at main · ibarakaiev/advent-of-code-2024 · GitHub.
New
maennchen
Ok, that was a rough one today. I haven’t found a way to improve the algorithm further. Part 1 runs in .5 seconds, Part 2 in ~ 5 minutes...
New
NobbZ
Note by the Moderators: This topic is to talk about the Day 2 of the Advent of Code. For general discussion about the Advent of Code 201...
New
bjorng
Note: This topic is to talk about Day 3 of the Advent of Code 2019 . There is a private leaderboard for elixirforum members. You can jo...
New
bjorng
Note: This topic is to talk about Day 23 of the Advent of Code. For general discussion about the Advent of Code 2018 and links to topics...
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
bjorng
Note: This topic is to talk about Day 6 of the Advent of Code 2019. There is a private leaderboard for elixirforum members. You can join...
New
liamcmitchell
A frustrating one for me. I spent a long time trying to understand why some combinations resulted in fewer presses and struggled to keep ...
New

Other popular topics Top

Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
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
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
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
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
273 38985 115
New

We're in Beta

About us Mission Statement