billylanchantin

billylanchantin

Care to prove you're more useful than an LLM?

I read an interesting post 2 days ago on HN:

Essentially, Peter Norvig found that no major LLM was able to produce a solution to the Cheryl’s Birthday logic puzzle that could handle other dates. He goes on to conjecture about what we may infer about the current limits of LLMs from that fact.

That discussion is interesting but I don’t necessarily want to wade into it here (though if you have strong thoughts feel free to share!). Instead, I found the idea that I could solve a simple logic and prove that I was more useful than an LLM captivating in a self-aggrandizing sort of way :stuck_out_tongue:

First, here’s my solution to that problem in Elixir:

Show/Hide Solution
defmodule CherylsBirthday do
  # 0. A knows M and B knows D
  # 1. A doesn't know D:          M has more than one day
  # 2. A knows B doesn't know M:  M must have no unique days
  # 3. B didn't know M at first:  D found in at least two months
  # 4. B knows M after 2.:        D must be in only one of the remaining months
  # 5. A knows D after 4.:        M must have only one unshared day among remaining months
  def solve(dates) do
    day_to_months = Enum.group_by(dates, &day/1, &month/1)
    month_to_days = Enum.group_by(dates, &month/1, &day/1)

    possibilities = %{days: Map.keys(day_to_months), months: Map.keys(month_to_days)}

    possibilities
    # 1. M has more than one day
    |> Map.update!(:months, fn months -> Enum.filter(months, &(length(month_to_days[&1]) > 1)) end)
    # 2. M must have no unique days
    |> Map.update!(:months, fn months ->
      Enum.filter(months, fn month ->
        Enum.all?(month_to_days[month], fn day -> length(day_to_months[day]) != 1 end)
      end)
    end)
    # 3. D found in at least two months
    |> Map.update!(:days, fn days -> Enum.filter(days, &(length(day_to_months[&1]) > 1)) end)
    # 4. D must be in only one of the remaining months
    |> then(fn %{days: days, months: months} = possibilities ->
      days = Enum.filter(days, fn day -> Enum.count(months, &(day in month_to_days[&1])) == 1 end)
      %{possibilities | days: days}
    end)
    # 5. M must have only one unshared day among remaining months
    |> then(fn %{months: months} = possibilities ->
      {months, days} =
        months
        |> Enum.map(fn month ->
          unshared_days =
            Enum.filter(month_to_days[month], fn day ->
              Enum.all?(months -- [month], &(day not in month_to_days[&1]))
            end)

          {month, unshared_days}
        end)
        |> Enum.filter(fn {_month, unshared_days} -> length(unshared_days) == 1 end)
        |> Enum.unzip()

      %{possibilities | days: List.flatten(days), months: months}
    end)
    |> then(fn %{days: [day], months: [month]} -> {month, day} end)
  end

  def day({_month, day}), do: day
  def month({month, _day}), do: month

  def original_dates do
    may = {"May", [15, 16, 19]}
    jun = {"Jun", [17, 18]}
    jul = {"Jul", [14, 16]}
    aug = {"Aug", [14, 15, 17]}
    for {month, days} <- [may, jun, jul, aug], day <- days, do: {month, day}
  end

  def alternate_dates do
    jan = {"Jan", [4, 15]}
    mar = {"Mar", [13, 24]}
    may = {"May", [11, 17, 30]}
    jul = {"Jul", [13, 24, 30]}
    for {month, days} <- [jan, mar, may, jul], day <- days, do: {month, day}
  end
end

CherylsBirthday.original_dates()
|> CherylsBirthday.solve()
|> IO.inspect()
#=> {"Jul", 16}

CherylsBirthday.alternate_dates()
|> CherylsBirthday.solve()
|> IO.inspect()
#=> {"Jul", 30}

This was a fun distraction for a Sunday morning. But the reason I’m making this post is that when I finally peeked at his solution, it was wildly different from my own. (And honestly more “functional” despite being in Python which annoyed me :sweat_smile:)

Now I’m curious how other Elixir programmers would approach this problem! I discourage everyone from cheating of course. That would defeat the point of the exercise. But if you’re looking for a distraction too, I recommend giving this a shot!


To get you started, here are two sets of dates each with their expected answer:

  • Original
    • Dates: May 15, May 16, May 19, June 17, June 18, July 14, July 16, August 14, August 15, August 17
    • Answer: July 16
  • Alternate
    • Dates: January 4, January 15, March 13, March 24, May 11, May 17, May 30, July 13, July 24, July 30
    • Answer: July 30

Where Next?

Popular in Discussions Top

pillaiindu
In django there is a cache framework backed by memcached. Rails also puts a lot of emphasis on caching, and even the idea of russian-doll...
New
Ankhers
Just a little information upfront. Generally speaking, if I feel like I need to either break a pipe chain or use an anonymous function in...
New
Crowdhailer
I’ve been hearing much about the new formatter and it’s something I have been keen to try. I find examples buy far the most illuminating...
248 19327 150
New
PragTob
Hey everyone, this has been on my mind for some time and I’d love your input on it! TLDR: I feel like maps are superioer for storing and...
New
rms.mrcs
A couple of days ago I was discussing with a friend about different approaches to write microservices. He said that if he was going to w...
New
AstonJ
If so I (and hopefully others!) might have some tips for you :slight_smile: But first, please say which area you’re finding most challen...
New
Owens
Hello all, I am developing a new mobile app with Flutter frontend and Phoenix backend. The mobile app has real-time task management and c...
New
fireproofsocks
This is more of a general question, but I’m wondering how other people in the community think about the pattern matching in function sign...
New
axelson
Decided against including more info in the title, but the gist is that Plataformatec sponsored projects will continue with the assets bei...
New
Markusxmr
Since Drab has been developed for a while in the open, introducing the Liveview functionality in a way it happend appears to undermine th...
New

Other popular topics Top

hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a &gt; b) do {:ok, "a"} end if (a &lt; b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
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
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement