defmodule Allergies do @allergens %{ "eggs" => 1, "peanuts" => 2, "shellfish" => 4, "strawberries" => 8, "tomatoes" => 16, "chocolate" => 32, "pollen" => 64, "cats" => 128 } @doc """ List the allergies for which the corresponding flag bit is true. """ @spec list(non_neg_integer) :: [String.t()] def list(flags) do for {allergen, mask} <- @allergens, allergic_to?(mask, flags), do: allergen end @doc """ Returns whether the corresponding flag bit in 'flags' is set for the item. """ @spec allergic_to?(non_neg_integer, String.t() | non_neg_integer) :: boolean def allergic_to?(flags, mask) when is_integer(mask), do: Bitwise.band(mask, flags) > 0 def allergic_to?(flags, allergen) when is_binary(allergen), do: allergic_to?(@allergens[allergen], flags) end