From aefb29d12e052e4ec954bd762daf882adcee62dd Mon Sep 17 00:00:00 2001 From: Kah Goh Date: Fri, 27 Oct 2023 22:21:45 +0800 Subject: [PATCH 1/5] Add Pop Count practice exercise --- config.json | 12 +++++ .../practice/pop-count/.docs/instructions.md | 8 ++++ .../practice/pop-count/.docs/introduction.md | 47 +++++++++++++++++++ exercises/practice/pop-count/.formatter.exs | 4 ++ exercises/practice/pop-count/.gitignore | 24 ++++++++++ .../practice/pop-count/.meta/config.json | 19 ++++++++ exercises/practice/pop-count/.meta/example.ex | 17 +++++++ exercises/practice/pop-count/.meta/tests.toml | 23 +++++++++ exercises/practice/pop-count/lib/pop_count.ex | 8 ++++ exercises/practice/pop-count/mix.exs | 28 +++++++++++ .../pop-count/test/pop_count_test.exs | 24 ++++++++++ .../practice/pop-count/test/test_helper.exs | 2 + 12 files changed, 216 insertions(+) create mode 100644 exercises/practice/pop-count/.docs/instructions.md create mode 100644 exercises/practice/pop-count/.docs/introduction.md create mode 100644 exercises/practice/pop-count/.formatter.exs create mode 100644 exercises/practice/pop-count/.gitignore create mode 100644 exercises/practice/pop-count/.meta/config.json create mode 100644 exercises/practice/pop-count/.meta/example.ex create mode 100644 exercises/practice/pop-count/.meta/tests.toml create mode 100644 exercises/practice/pop-count/lib/pop_count.ex create mode 100644 exercises/practice/pop-count/mix.exs create mode 100644 exercises/practice/pop-count/test/pop_count_test.exs create mode 100644 exercises/practice/pop-count/test/test_helper.exs diff --git a/config.json b/config.json index 1cf97c9b61..5cfe524258 100644 --- a/config.json +++ b/config.json @@ -1701,6 +1701,18 @@ ], "difficulty": 3 }, + { + "slug": "pop-count", + "name": "Pop Count", + "uuid": "8a9d6e1e-9188-44c9-8681-ade84d340dd0", + "practices": [ + "bit-manipulation" + ], + "prerequisites": [ + "bit-manipulation" + ], + "difficulty": 3 + }, { "slug": "word-count", "name": "Word Count", diff --git a/exercises/practice/pop-count/.docs/instructions.md b/exercises/practice/pop-count/.docs/instructions.md new file mode 100644 index 0000000000..b0c2df593c --- /dev/null +++ b/exercises/practice/pop-count/.docs/instructions.md @@ -0,0 +1,8 @@ +# Instructions + +Your task is to count the number of 1 bits in the binary representation of a number. + +## Restrictions + +Keep your hands off that bit-count functionality provided by your standard library! +Solve this one yourself using other basic tools instead. diff --git a/exercises/practice/pop-count/.docs/introduction.md b/exercises/practice/pop-count/.docs/introduction.md new file mode 100644 index 0000000000..49eaffd8bc --- /dev/null +++ b/exercises/practice/pop-count/.docs/introduction.md @@ -0,0 +1,47 @@ +# Introduction + +Your friend Eliud inherited a farm from her grandma Tigist. +Her granny was an inventor and had a tendency to build things in an overly complicated manner. +The chicken coop has a digital display showing an encoded number representing the positions of all eggs that could be picked up. + +Eliud is asking you to write a program that shows the actual number of eggs in the coop. + +The position information encoding is calculated as follows: + +1. Scan the potential egg-laying spots and mark down a `1` for an existing egg or a `0` for an empty spot. +2. Convert the number from binary to decimal. +3. Show the result on the display. + +Example 1: + +```text +Chicken Coop: + _ _ _ _ _ _ _ +|E| |E|E| | |E| + +Resulting Binary: + 1 0 1 1 0 0 1 + +Decimal number on the display: +89 + +Actual eggs in the coop: +4 +``` + +Example 2: + +```text +Chicken Coop: + _ _ _ _ _ _ _ _ +| | | |E| | | | | + +Resulting Binary: + 0 0 0 1 0 0 0 0 + +Decimal number on the display: +16 + +Actual eggs in the coop: +1 +``` diff --git a/exercises/practice/pop-count/.formatter.exs b/exercises/practice/pop-count/.formatter.exs new file mode 100644 index 0000000000..d2cda26edd --- /dev/null +++ b/exercises/practice/pop-count/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/exercises/practice/pop-count/.gitignore b/exercises/practice/pop-count/.gitignore new file mode 100644 index 0000000000..f655aa4a95 --- /dev/null +++ b/exercises/practice/pop-count/.gitignore @@ -0,0 +1,24 @@ +# The directory Mix will write compiled artifacts to. +/_build/ + +# If you run "mix test --cover", coverage assets end up here. +/cover/ + +# The directory Mix downloads your dependencies sources to. +/deps/ + +# Where third-party dependencies like ExDoc output generated docs. +/doc/ + +# Ignore .fetch files in case you like to edit your project deps locally. +/.fetch + +# If the VM crashes, it generates a dump, let's ignore it too. +erl_crash.dump + +# Also ignore archive artifacts (built via "mix archive.build"). +*.ez + +# Ignore package tarball (built via "mix hex.build"). +isogram-*.tar + diff --git a/exercises/practice/pop-count/.meta/config.json b/exercises/practice/pop-count/.meta/config.json new file mode 100644 index 0000000000..a1290bb192 --- /dev/null +++ b/exercises/practice/pop-count/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "kahgoh" + ], + "files": { + "solution": [ + "lib/pop_count.ex" + ], + "test": [ + "test/pop_count_test.exs" + ], + "example": [ + ".meta/example.ex" + ] + }, + "blurb": "Count the 1 bits in a number", + "source": "Christian Willner, Eric Willigers", + "source_url": "https://forum.exercism.org/t/new-exercise-suggestion-pop-count/7632/5" +} diff --git a/exercises/practice/pop-count/.meta/example.ex b/exercises/practice/pop-count/.meta/example.ex new file mode 100644 index 0000000000..dc88836468 --- /dev/null +++ b/exercises/practice/pop-count/.meta/example.ex @@ -0,0 +1,17 @@ +import Bitwise + +defmodule PopCount do + @doc """ + Given the number, count the number of eggs. + """ + @spec eggCount(number :: integer()) :: non_neg_integer() + def eggCount(number) do + do_count(number, 0) + end + + defp do_count(0, acc), do: acc + + defp do_count(number, acc) when number > 0 do + do_count(number >>> 1, acc + (number &&& 1)) + end +end diff --git a/exercises/practice/pop-count/.meta/tests.toml b/exercises/practice/pop-count/.meta/tests.toml new file mode 100644 index 0000000000..8ac0149e79 --- /dev/null +++ b/exercises/practice/pop-count/.meta/tests.toml @@ -0,0 +1,23 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[559e789d-07d1-4422-9004-3b699f83bca3] +description = "0 eggs" +include = false + +[97223282-f71e-490c-92f0-b3ec9e275aba] +description = "1 egg" + +[1f8fd18f-26e9-4144-9a0e-57cdfc4f4ff5] +description = "4 eggs" + +[0c18be92-a498-4ef2-bcbb-28ac4b06cb81] +description = "13 eggs" diff --git a/exercises/practice/pop-count/lib/pop_count.ex b/exercises/practice/pop-count/lib/pop_count.ex new file mode 100644 index 0000000000..ea413f40f6 --- /dev/null +++ b/exercises/practice/pop-count/lib/pop_count.ex @@ -0,0 +1,8 @@ +defmodule PopCount do + @doc """ + Given the number, count the number of eggs. + """ + @spec eggCount(number :: integer()) :: non_neg_integer() + def eggCount(number) do + end +end diff --git a/exercises/practice/pop-count/mix.exs b/exercises/practice/pop-count/mix.exs new file mode 100644 index 0000000000..3f65937ce2 --- /dev/null +++ b/exercises/practice/pop-count/mix.exs @@ -0,0 +1,28 @@ +defmodule PopCount.MixProject do + use Mix.Project + + def project do + [ + app: :pop_count, + version: "0.1.0", + # elixir: "~> 1.8", + start_permanent: Mix.env() == :prod, + deps: deps() + ] + end + + # Run "mix help compile.app" to learn about applications. + def application do + [ + extra_applications: [:logger] + ] + end + + # Run "mix help deps" to learn about dependencies. + defp deps do + [ + # {:dep_from_hexpm, "~> 0.3.0"}, + # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"} + ] + end +end diff --git a/exercises/practice/pop-count/test/pop_count_test.exs b/exercises/practice/pop-count/test/pop_count_test.exs new file mode 100644 index 0000000000..b5c7f470dd --- /dev/null +++ b/exercises/practice/pop-count/test/pop_count_test.exs @@ -0,0 +1,24 @@ +defmodule PopCountTest do + use ExUnit.Case + + describe "egg count" do + test "0 eggs" do + assert PopCount.eggCount(0) == 0 + end + + @tag :pending + test "1 egg" do + assert PopCount.eggCount(16) == 1 + end + + @tag :pending + test "4 eggs" do + assert PopCount.eggCount(89) == 4 + end + + @tag :pending + test "13 eggs" do + assert PopCount.eggCount(2_000_000_000) == 13 + end + end +end diff --git a/exercises/practice/pop-count/test/test_helper.exs b/exercises/practice/pop-count/test/test_helper.exs new file mode 100644 index 0000000000..35fc5bff82 --- /dev/null +++ b/exercises/practice/pop-count/test/test_helper.exs @@ -0,0 +1,2 @@ +ExUnit.start() +ExUnit.configure(exclude: :pending, trace: true) From 99878dab871f6f7d55ee8e129d862a03494425c2 Mon Sep 17 00:00:00 2001 From: Kah Goh Date: Fri, 27 Oct 2023 22:57:47 +0800 Subject: [PATCH 2/5] Tidy up Pop Count practice exercise - Use snake case for function names - Fix exercise order --- config.json | 24 +++++++++---------- exercises/practice/pop-count/.meta/example.ex | 4 ++-- exercises/practice/pop-count/lib/pop_count.ex | 4 ++-- .../pop-count/test/pop_count_test.exs | 8 +++---- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/config.json b/config.json index 5cfe524258..d1859ffad0 100644 --- a/config.json +++ b/config.json @@ -1582,6 +1582,18 @@ ], "difficulty": 3 }, + { + "slug": "pop-count", + "name": "Pop Count", + "uuid": "8a9d6e1e-9188-44c9-8681-ade84d340dd0", + "practices": [ + "bit-manipulation" + ], + "prerequisites": [ + "bit-manipulation" + ], + "difficulty": 3 + }, { "slug": "prime-factors", "name": "Prime Factors", @@ -1701,18 +1713,6 @@ ], "difficulty": 3 }, - { - "slug": "pop-count", - "name": "Pop Count", - "uuid": "8a9d6e1e-9188-44c9-8681-ade84d340dd0", - "practices": [ - "bit-manipulation" - ], - "prerequisites": [ - "bit-manipulation" - ], - "difficulty": 3 - }, { "slug": "word-count", "name": "Word Count", diff --git a/exercises/practice/pop-count/.meta/example.ex b/exercises/practice/pop-count/.meta/example.ex index dc88836468..5c42817c9b 100644 --- a/exercises/practice/pop-count/.meta/example.ex +++ b/exercises/practice/pop-count/.meta/example.ex @@ -4,8 +4,8 @@ defmodule PopCount do @doc """ Given the number, count the number of eggs. """ - @spec eggCount(number :: integer()) :: non_neg_integer() - def eggCount(number) do + @spec egg_count(number :: integer()) :: non_neg_integer() + def egg_count(number) do do_count(number, 0) end diff --git a/exercises/practice/pop-count/lib/pop_count.ex b/exercises/practice/pop-count/lib/pop_count.ex index ea413f40f6..317bb05b8a 100644 --- a/exercises/practice/pop-count/lib/pop_count.ex +++ b/exercises/practice/pop-count/lib/pop_count.ex @@ -2,7 +2,7 @@ defmodule PopCount do @doc """ Given the number, count the number of eggs. """ - @spec eggCount(number :: integer()) :: non_neg_integer() - def eggCount(number) do + @spec egg_count(number :: integer()) :: non_neg_integer() + def egg_count(number) do end end diff --git a/exercises/practice/pop-count/test/pop_count_test.exs b/exercises/practice/pop-count/test/pop_count_test.exs index b5c7f470dd..d9eb229366 100644 --- a/exercises/practice/pop-count/test/pop_count_test.exs +++ b/exercises/practice/pop-count/test/pop_count_test.exs @@ -3,22 +3,22 @@ defmodule PopCountTest do describe "egg count" do test "0 eggs" do - assert PopCount.eggCount(0) == 0 + assert PopCount.egg_count(0) == 0 end @tag :pending test "1 egg" do - assert PopCount.eggCount(16) == 1 + assert PopCount.egg_count(16) == 1 end @tag :pending test "4 eggs" do - assert PopCount.eggCount(89) == 4 + assert PopCount.egg_count(89) == 4 end @tag :pending test "13 eggs" do - assert PopCount.eggCount(2_000_000_000) == 13 + assert PopCount.egg_count(2_000_000_000) == 13 end end end From d4715974d7c1fe83ee1b91820c1152f9b97018cf Mon Sep 17 00:00:00 2001 From: Kah Goh Date: Sat, 28 Oct 2023 21:10:55 +0800 Subject: [PATCH 3/5] Update prerequisites Co-authored-by: Angelika Tyborska --- config.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/config.json b/config.json index d1859ffad0..57460163e0 100644 --- a/config.json +++ b/config.json @@ -1590,7 +1590,10 @@ "bit-manipulation" ], "prerequisites": [ - "bit-manipulation" + "bit-manipulation", + "multiple-clause-functions", + "pattern-matching", + "recursion" ], "difficulty": 3 }, From 4e9f63320872435363b49cd31cf124dae7ff17c6 Mon Sep 17 00:00:00 2001 From: Kah Goh Date: Sat, 28 Oct 2023 21:17:13 +0800 Subject: [PATCH 4/5] Add large integer test case Co-authored-by: Angelika Tyborska --- exercises/practice/pop-count/test/pop_count_test.exs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/exercises/practice/pop-count/test/pop_count_test.exs b/exercises/practice/pop-count/test/pop_count_test.exs index d9eb229366..c2a171e60c 100644 --- a/exercises/practice/pop-count/test/pop_count_test.exs +++ b/exercises/practice/pop-count/test/pop_count_test.exs @@ -20,5 +20,10 @@ defmodule PopCountTest do test "13 eggs" do assert PopCount.egg_count(2_000_000_000) == 13 end + + @tag :pending + test "100 eggs" do + assert PopCount.egg_count(1_267_650_600_228_229_401_496_703_205_375) == 100 + end end end From e04a58879e23d383b85eccfee7bfa8025ae86cd8 Mon Sep 17 00:00:00 2001 From: Kah Goh Date: Sat, 28 Oct 2023 21:21:48 +0800 Subject: [PATCH 5/5] Fix formatting in pop-count --- exercises/practice/pop-count/test/pop_count_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/practice/pop-count/test/pop_count_test.exs b/exercises/practice/pop-count/test/pop_count_test.exs index c2a171e60c..9b26aa513c 100644 --- a/exercises/practice/pop-count/test/pop_count_test.exs +++ b/exercises/practice/pop-count/test/pop_count_test.exs @@ -20,7 +20,7 @@ defmodule PopCountTest do test "13 eggs" do assert PopCount.egg_count(2_000_000_000) == 13 end - + @tag :pending test "100 eggs" do assert PopCount.egg_count(1_267_650_600_228_229_401_496_703_205_375) == 100