From 69db9766262910dd556a164734febedd45005ee8 Mon Sep 17 00:00:00 2001 From: Yrahcaz7 <74512479+Yrahcaz7@users.noreply.github.com> Date: Wed, 3 Jun 2026 18:18:01 -0400 Subject: [PATCH 1/5] add first approach --- .../eliuds-eggs/.approaches/config.json | 15 ++++ .../eliuds-eggs/.approaches/introduction.md | 46 +++++++++++ .../parameter-modification/content.md | 80 +++++++++++++++++++ .../parameter-modification/snippet.txt | 6 ++ 4 files changed, 147 insertions(+) create mode 100644 exercises/practice/eliuds-eggs/.approaches/config.json create mode 100644 exercises/practice/eliuds-eggs/.approaches/introduction.md create mode 100644 exercises/practice/eliuds-eggs/.approaches/parameter-modification/content.md create mode 100644 exercises/practice/eliuds-eggs/.approaches/parameter-modification/snippet.txt diff --git a/exercises/practice/eliuds-eggs/.approaches/config.json b/exercises/practice/eliuds-eggs/.approaches/config.json new file mode 100644 index 00000000000..36d652d6973 --- /dev/null +++ b/exercises/practice/eliuds-eggs/.approaches/config.json @@ -0,0 +1,15 @@ +{ + "introduction": { + "authors": ["yrahcaz7"], + "contributors": [] + }, + "approaches": [ + { + "uuid": "27fb20ed-a4c2-4f73-a8fc-86ba384c7b35", + "slug": "parameter-modification", + "title": "Modify the Parameter in a Loop", + "blurb": "Modify the Parameter in a while-loop to Calculate the Number of Eggs.", + "authors": ["yrahcaz7"] + } + ] +} diff --git a/exercises/practice/eliuds-eggs/.approaches/introduction.md b/exercises/practice/eliuds-eggs/.approaches/introduction.md new file mode 100644 index 00000000000..101f76bcf0d --- /dev/null +++ b/exercises/practice/eliuds-eggs/.approaches/introduction.md @@ -0,0 +1,46 @@ +# Introduction + +There are many Pythonic approaches to solving the Eliud's Eggs exercise: + +- Using a `while-loop`, modifying the parameter on each iteration +- Looping over every binary digit _without_ modifying the parameter +- Converting the `int` to a binary string and counting the ones + +There are also some approaches that aren't recommended: + +- Using the bit-count functionality from the Python standard library, as the instructions forbid it +- Breaking up the proccess into many functions, overcomplicating the solution + + +## General guidance + +The goal of the Eliud's Eggs exercise is to count the number of ones in the binary representation of a number. +In essence, this requires you to loop over each bit (binary digit) of the number in some way. + +The approaches below represent categories of the most common ways of accomplishing this. + + +## Approach: Modifying the Parameter in a `while-loop` + +```python +def egg_count(display_value): + eggs = 0 + while display_value: + eggs += display_value % 2 + display_value //= 2 + return eggs +``` + +This approach uses a `while-loop` to count up all of the ones. +In the loop, we increment `eggs` by `display_value % 2`. +This adds the least significant bit (the rightmost digit in the binary representation) of `display_value` to `eggs`. + +Next, we divide `display_value` by `2`, discarding any remainder. +This essentially removes the least significant bit of `display_value`, setting up `display_value` for processing the next bit. + +The loop repeats until `display_value` reaches `0` (which indicates that we have no more bits to check), and then we return `eggs`. + +To see more variants of this solution, see the [modify the parameter in a loop][parameter-modification] approach. + + +[parameter-modification]: https://exercism.org/tracks/python/exercises/eliuds-eggs/approaches/parameter-modification diff --git a/exercises/practice/eliuds-eggs/.approaches/parameter-modification/content.md b/exercises/practice/eliuds-eggs/.approaches/parameter-modification/content.md new file mode 100644 index 00000000000..5e63df050e4 --- /dev/null +++ b/exercises/practice/eliuds-eggs/.approaches/parameter-modification/content.md @@ -0,0 +1,80 @@ +# Modify the Parameter in a Loop + +```python +def egg_count(display_value): + eggs = 0 + while display_value: + eggs += display_value % 2 + display_value //= 2 + return eggs +``` + +This approach uses a `while-loop` to count up all of the ones. +In the loop, we increment `eggs` by `display_value % 2`. +This adds the least significant bit (the rightmost digit in the binary representation) of `display_value` to `eggs`. + +Next, we divide `display_value` by `2`, discarding any remainder. +This essentially removes the least significant bit of `display_value`, setting up `display_value` for processing the next bit. + +The loop repeats until `display_value` reaches `0` (which indicates that we have no more bits to check), and then we return `eggs`. + + +## Variation #1: Using Boolean Operators + +```python +def egg_count(display_value): + eggs = 0 + while display_value > 0: + if display_value % 2 == 1: + eggs += 1 + display_value //= 2 + return eggs +``` + +This is essentially just a more verbose formulation of the previous version. +Instead of relying on Python converting `int`s to `bool`s, this solution manually compares `display_value` to `0`. +It also uses an `if` statement to check if `eggs` should be incremented by `1`, instead of directly using the result of `display_value % 2`. + +Even though this variant is more verbose, some may consider it to be more readable. + + +## Variation #2: Using Bitwise Operators + +```python +def egg_count(display_value): + eggs = 0 + while display_value > 0: + eggs += display_value & 1 + display_value >>= 1 + return eggs +``` + +This variant replaces the modulo (`%`) and floor division (`//`) with [bitwise operators][bitwise-operators]. +`&` is the bitwise AND operator, which results in a number whose binary representation only has ones where _both_ of its arguments has ones. +(All other bits are zeros.) + +For example, if we used the numbers `3` (`11` in binary) and `1` (`1` in binary), we get `1`: + +```python +0b011 & 0b001 +#=> 0b001 +``` + +This is because the only bit in both numbers that is `1` is least significant bit. +This property lets us extract the least significant bit of `display_value` by using `display_value & 1`. + +For the next step, we use `>>`, the [right-shift operator][right-shift-operator]. +The expression `a >> b` shifts all of `a`'s bits to the right by `b` places, and returns the resulting number. + +For example, if we used the numbers `5` (`101` in binary) and `1`, we get `2` (`10` in binary): + +```python +0b101 >> 1 +#=> 0b010 +``` + +You can see how `& 1` and `>>= 1` perform the same function as the `% 2` and `//= 2` used in earier variants. + + +[bitwise-operators]: https://www.w3schools.com/programming/prog_operators_bitwise.php +[right-shift-operator]: https://www.geeksforgeeks.org/software-engineering/right-shift-operator-in-programming/ diff --git a/exercises/practice/eliuds-eggs/.approaches/parameter-modification/snippet.txt b/exercises/practice/eliuds-eggs/.approaches/parameter-modification/snippet.txt new file mode 100644 index 00000000000..c3d5eeb7bf4 --- /dev/null +++ b/exercises/practice/eliuds-eggs/.approaches/parameter-modification/snippet.txt @@ -0,0 +1,6 @@ +def egg_count(display_value): + eggs = 0 + while display_value: + eggs += display_value % 2 + display_value //= 2 + return eggs \ No newline at end of file From 849a4e5dc247bcd03394f1388163057e1eea3376 Mon Sep 17 00:00:00 2001 From: Yrahcaz7 <74512479+Yrahcaz7@users.noreply.github.com> Date: Wed, 3 Jun 2026 21:02:18 -0400 Subject: [PATCH 2/5] add second approach --- .../eliuds-eggs/.approaches/config.json | 9 +- .../eliuds-eggs/.approaches/introduction.md | 30 +++++- .../no-parameter-modification/content.md | 91 +++++++++++++++++++ .../no-parameter-modification/snippet.txt | 7 ++ .../parameter-modification/content.md | 2 +- 5 files changed, 135 insertions(+), 4 deletions(-) create mode 100644 exercises/practice/eliuds-eggs/.approaches/no-parameter-modification/content.md create mode 100644 exercises/practice/eliuds-eggs/.approaches/no-parameter-modification/snippet.txt diff --git a/exercises/practice/eliuds-eggs/.approaches/config.json b/exercises/practice/eliuds-eggs/.approaches/config.json index 36d652d6973..22b9f975c58 100644 --- a/exercises/practice/eliuds-eggs/.approaches/config.json +++ b/exercises/practice/eliuds-eggs/.approaches/config.json @@ -8,7 +8,14 @@ "uuid": "27fb20ed-a4c2-4f73-a8fc-86ba384c7b35", "slug": "parameter-modification", "title": "Modify the Parameter in a Loop", - "blurb": "Modify the Parameter in a while-loop to Calculate the Number of Eggs.", + "blurb": "Modify the parameter in a while-loop to calculate the number of eggs.", + "authors": ["yrahcaz7"] + }, + { + "uuid": "65fd717c-0e50-444b-a4b2-b51862f1f810", + "slug": "no-parameter-modification", + "title": "Loop Without Modifying the Parameter", + "blurb": "Loop over the bits without modifying the parameter to determine the number of eggs.", "authors": ["yrahcaz7"] } ] diff --git a/exercises/practice/eliuds-eggs/.approaches/introduction.md b/exercises/practice/eliuds-eggs/.approaches/introduction.md index 101f76bcf0d..35ddfde82e3 100644 --- a/exercises/practice/eliuds-eggs/.approaches/introduction.md +++ b/exercises/practice/eliuds-eggs/.approaches/introduction.md @@ -40,7 +40,33 @@ This essentially removes the least significant bit of `display_value`, setting u The loop repeats until `display_value` reaches `0` (which indicates that we have no more bits to check), and then we return `eggs`. -To see more variants of this solution, see the [modify the parameter in a loop][parameter-modification] approach. +To see more variations of this solution, see the [modify the parameter in a loop][approach-parameter-modification] approach. -[parameter-modification]: https://exercism.org/tracks/python/exercises/eliuds-eggs/approaches/parameter-modification +## Approach: Looping Without Modifying the Parameter + +```python +from math import ceil, log2 + +def egg_count(display_value): + eggs = 0 + for bit_position in range(ceil(log2(display_value + 1))): + eggs += (display_value >> bit_position) & 1 + return eggs +``` + +This solution uses a `for-loop` with `range()` to iterate over all of the bits in `display_value`. +To determine how many bits `display_value` has, this solution imports `ceil` and `log2` from the `math` module. +It then feeds this number into `range()` to make the `for-loop` iterate over all the `bit_position`s. + +For each `bit_position`, we determine the value of the bit at that position by using the [right-shift operator][right-shift-operator] and the bitwise AND operator. +Once we determine the bit's value, we increment `eggs` by that number. + +After the loop ends, we know that we have checked all of the bits in `display_value`, thus we return `eggs`. + +For more details and variations, read the [loop without modifying the parameter][approach-no-parameter-modification] approach. + + +[approach-parameter-modification]: https://exercism.org/tracks/python/exercises/eliuds-eggs/approaches/parameter-modification +[approach-no-parameter-modification]: https://exercism.org/tracks/python/exercises/eliuds-eggs/approaches/no-parameter-modification +[right-shift-operator]: https://www.geeksforgeeks.org/software-engineering/right-shift-operator-in-programming/ diff --git a/exercises/practice/eliuds-eggs/.approaches/no-parameter-modification/content.md b/exercises/practice/eliuds-eggs/.approaches/no-parameter-modification/content.md new file mode 100644 index 00000000000..a2a93c01b37 --- /dev/null +++ b/exercises/practice/eliuds-eggs/.approaches/no-parameter-modification/content.md @@ -0,0 +1,91 @@ +# Loop Without Modifying the Parameter + +```python +from math import ceil, log2 + +def egg_count(display_value): + eggs = 0 + for bit_position in range(ceil(log2(display_value + 1))): + eggs += (display_value >> bit_position) & 1 + return eggs +``` + +This approach uses a loop with `range()` to iterate over all of the bits in `display_value`. + +To determine how many bits `display_value` has, this solution imports `ceil` and `log2` from the `math` module. +We then calculate the base 2 logarithm of `display_value` (plus 1) and round it up. +(Rounding up is neccessary because `range()` excludes the value of `` from its returned values.) + +Once we have the bit length of `display_value`, we feed this number into `range()` to make the `for-loop` iterate over all of `display_value`'s `bit_position`s. + +For each `bit_position`, we determine the value of the bit at that position by using the [right-shift operator][right-shift-operator] and the bitwise AND operator. +We do this by right-shifting `display_value` by `bit_position`, making the bit at `bit_position` become the least significant bit. +Then we use the bitwise AND operator with `1` to remove all bits that are not the least significant bit. + +~~~~exercism/note +You could also calculate the bit's value by using arithmetic operators instead of bitwise ones: + +```python +eggs += (display_value // (2 ** bit_position)) % 2 +``` +~~~~ + +Once we determine the bit's value, we increment `eggs` by that number. + +After the loop ends, we know that we have checked all of the bits in `display_value`, thus we return `eggs`. + + +## Variation #1: Using an `if` Statement + +```python +from math import ceil, log2 + +def egg_count(display_value): + eggs = 0 + for bit_position in range(ceil(log2(display_value + 1))): + if display_value & (1 << bit_position): + eggs += 1 + return eggs +``` + +In this variant, the loop uses an `if` statement to check if the digit at `display_value` is `1`. + + +## Variation #2: Using `sum()` with a Generator Expression + +```python +from math import ceil, log2 + +def egg_count(display_value): + return sum( + (display_value >> bit_position) & 1 + for bit_position in range(ceil(log2(display_value + 1))) + ) +``` + +This variant is actually a one-liner, it is just split up here for readability. +Here, we replace the `for-loop` with a [generator expression][generator-expression] and use `sum()` to collect the values into the result. + + +## Variation #3: Manually Tracking the Place Value + +```python +def egg_count(display_value): + eggs = 0 + place_value = 1 + while place_value <= display_value: + if display_value & place_value: + eggs += 1 + place_value <<= 1 + return eggs +``` + +This variant avoids `import`s by manually tracking the `place_value` of the current bit position. +This way, the `while-loop` can end when `place_value` becomes greater than `display_value`. + +The operations in the loop are rather similar to the "using an `if` statement" variant. +The main differences are not having to calculate the `place_value` from the bit position, and having to manually progress the iteration by left-shifting `place_value` by `1` (which is the same as multiplying `place_value` by `2`). + + +[generator-expression]: https://dbader.org/blog/python-generator-expressions +[right-shift-operator]: https://www.geeksforgeeks.org/software-engineering/right-shift-operator-in-programming/ diff --git a/exercises/practice/eliuds-eggs/.approaches/no-parameter-modification/snippet.txt b/exercises/practice/eliuds-eggs/.approaches/no-parameter-modification/snippet.txt new file mode 100644 index 00000000000..b2a163f2f28 --- /dev/null +++ b/exercises/practice/eliuds-eggs/.approaches/no-parameter-modification/snippet.txt @@ -0,0 +1,7 @@ +from math import ceil, log2 + +def egg_count(display_value): + eggs = 0 + for bit_position in range(ceil(log2(display_value + 1))): + eggs += (display_value >> bit_position) & 1 + return eggs \ No newline at end of file diff --git a/exercises/practice/eliuds-eggs/.approaches/parameter-modification/content.md b/exercises/practice/eliuds-eggs/.approaches/parameter-modification/content.md index 5e63df050e4..b1765f865d3 100644 --- a/exercises/practice/eliuds-eggs/.approaches/parameter-modification/content.md +++ b/exercises/practice/eliuds-eggs/.approaches/parameter-modification/content.md @@ -35,7 +35,7 @@ This is essentially just a more verbose formulation of the previous version. Instead of relying on Python converting `int`s to `bool`s, this solution manually compares `display_value` to `0`. It also uses an `if` statement to check if `eggs` should be incremented by `1`, instead of directly using the result of `display_value % 2`. -Even though this variant is more verbose, some may consider it to be more readable. +Even though this variant is more verbose than the others, some may consider it to be more readable. ## Variation #2: Using Bitwise Operators From f16365664259c5c5e0d42c138a833e492ea110f5 Mon Sep 17 00:00:00 2001 From: Yrahcaz7 <74512479+Yrahcaz7@users.noreply.github.com> Date: Sat, 6 Jun 2026 22:04:03 -0400 Subject: [PATCH 3/5] add third approach --- .../eliuds-eggs/.approaches/config.json | 7 ++ .../convert-to-binary-string/content.md | 111 ++++++++++++++++++ .../convert-to-binary-string/snippet.txt | 6 + .../eliuds-eggs/.approaches/introduction.md | 26 +++- 4 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 exercises/practice/eliuds-eggs/.approaches/convert-to-binary-string/content.md create mode 100644 exercises/practice/eliuds-eggs/.approaches/convert-to-binary-string/snippet.txt diff --git a/exercises/practice/eliuds-eggs/.approaches/config.json b/exercises/practice/eliuds-eggs/.approaches/config.json index 22b9f975c58..eff40e6cf9a 100644 --- a/exercises/practice/eliuds-eggs/.approaches/config.json +++ b/exercises/practice/eliuds-eggs/.approaches/config.json @@ -17,6 +17,13 @@ "title": "Loop Without Modifying the Parameter", "blurb": "Loop over the bits without modifying the parameter to determine the number of eggs.", "authors": ["yrahcaz7"] + }, + { + "uuid": "df202fa9-3757-4808-a416-7ec3ee1e9680", + "slug": "convert-to-binary-string", + "title": "Convert to a Binary String", + "blurb": "Convert the parameter to a binary string and count its ones to determine the number of eggs.", + "authors": ["yrahcaz7"] } ] } diff --git a/exercises/practice/eliuds-eggs/.approaches/convert-to-binary-string/content.md b/exercises/practice/eliuds-eggs/.approaches/convert-to-binary-string/content.md new file mode 100644 index 00000000000..854a6e097c3 --- /dev/null +++ b/exercises/practice/eliuds-eggs/.approaches/convert-to-binary-string/content.md @@ -0,0 +1,111 @@ +# Convert to a Binary String + +```python +def egg_count(display_value): + binary_value = bin(display_value)[2:] + eggs = 0 + for digit in binary_value: + eggs += int(digit) + return eggs +``` + +This approach uses [`bin()`][bin-built-in] to convert `display_value` to a binary string. +Then, the first two characters of the binary string are removed, as the string has "0b" prefixed before the binary digits. + +After the binary digits are obtained, this solution loops across all of them, turning each one into an integer and adding it to `eggs`. +This effectively counts up all of the instances of "1" in the binary string, as 0 and 1 are the only valid binary digits. + +Those less familiar with binary may find this approach to be simpler than the others. +However, it does have the added overhead of converting to and from a string. + +~~~~exercism/note +There are three other Pythonic ways of obtaining the binary string. One is to use an [`f-string`][f-string]: + +```python +binary_value = f"{display_value:b}" +``` + +Another is to use [`str.format()`][str-format]: + +```python +binary_value = "{:b}".format(display_value) +``` + +Lastly, you could use the [`format()` built-in][format-built-in]: + +```python +binary_value = format(display_value, "b") +``` + +These methods have the added benefit of not producing the "0b" prefix that then needs to removed. +However, some variations of this approach use other ways to get around the prefix. + +[format-built-in]: https://docs.python.org/3/library/functions.html#format +[f-string]: https://docs.python.org/3/reference/lexical_analysis.html#f-strings +[str-format]: https://docs.python.org/3/library/stdtypes.html#str.format +~~~~ + + +## Variation #1: Using `sum()` with a Generator Expression + +```python +def egg_count(display_value): + return sum(int(digit) for digit in bin(display_value)[2:]) +``` + +This variant uses a [generator expression][generator-expression] with the `sum()` built-in to collect the digits into the result. +Otherwise, it is the same as the previous version. + + +## Variation #2: Using `sum()` Without String Slicing + +```python +def egg_count(display_value): + return sum(1 for digit in bin(display_value) if digit == "1") +``` + +Similar to the previous variant, this one uses `sum()` with a generator expression. +The main difference is that it avoids slicing the binary string by using an `if` clause in the generator expression. + + +## Variation #3: Using `len()` Instead of `sum()` + +```python +def egg_count(display_value): + return len([True for digit in bin(display_value) if digit == "1"]) +``` + +This variant replaces the generator expression with a [list comprehension][list-comprehension]. +This way, it can simply use `len()` to get the number of ones, after the comprehension filters the other digits out. + +Here, `True` is used for the list elements, but we could any other value as well, as we only care about the length of the list. + + +## Variation #4: Using `map()` Instead of a Generator Expression + +```python +def egg_count(display_value): + return sum(map(int, bin(display_value)[2:])) +``` + +Here, we directly `map` the elements of the binary string to `int`s without using a generator expression or a list comprehension. + +This variant is the most concise of them all, but it may be not very comprehensible to those unfamilar with functional programming. + + +## Variation #5: Using `filter()` with a `lambda` + +```python +def egg_count(display_value): + return len(list(filter(lambda digit: digit == "1", bin(display_value)))) +``` + +Another alternative to a generator expression (or list comprehension) is to use the `filter()` built-in along with a [`lambda` expression][lambda-expression]. +However, the creation and repeated calling of the `lambda` adds unnecessary overhead to the solution. + + +[bin-built-in]: https://docs.python.org/3/library/functions.html#bin +[f-string]: https://docs.python.org/3/reference/lexical_analysis.html#f-strings +[generator-expression]: https://dbader.org/blog/python-generator-expressions +[lambda-expression]: https://docs.python.org/3/tutorial/controlflow.html#lambda-expressions +[list-comprehension]: https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions diff --git a/exercises/practice/eliuds-eggs/.approaches/convert-to-binary-string/snippet.txt b/exercises/practice/eliuds-eggs/.approaches/convert-to-binary-string/snippet.txt new file mode 100644 index 00000000000..01d46f1baea --- /dev/null +++ b/exercises/practice/eliuds-eggs/.approaches/convert-to-binary-string/snippet.txt @@ -0,0 +1,6 @@ +def egg_count(display_value): + binary_value = bin(display_value)[2:] + eggs = 0 + for digit in binary_value: + eggs += int(digit) + return eggs \ No newline at end of file diff --git a/exercises/practice/eliuds-eggs/.approaches/introduction.md b/exercises/practice/eliuds-eggs/.approaches/introduction.md index 35ddfde82e3..2b490a0b69b 100644 --- a/exercises/practice/eliuds-eggs/.approaches/introduction.md +++ b/exercises/practice/eliuds-eggs/.approaches/introduction.md @@ -1,6 +1,6 @@ # Introduction -There are many Pythonic approaches to solving the Eliud's Eggs exercise: +There are many different approaches to solving the Eliud's Eggs exercise: - Using a `while-loop`, modifying the parameter on each iteration - Looping over every binary digit _without_ modifying the parameter @@ -67,6 +67,30 @@ After the loop ends, we know that we have checked all of the bits in `display_va For more details and variations, read the [loop without modifying the parameter][approach-no-parameter-modification] approach. +## Approach: Converting the Parameter to a Binary String + +```python +def egg_count(display_value): + binary_value = bin(display_value)[2:] + eggs = 0 + for digit in binary_value: + eggs += int(digit) + return eggs +``` + +This approach uses [`bin()`][bin-built-in] (or some other means, such as an [`f-string`][f-string]) to convert `display_value` to a binary string. +Then, the first two characters of the binary string are removed, as the string has "0b" prefixed before the binary digits. + +After the binary digits are obtained, this solution loops across all of them, turning each one into an integer and adding it to `eggs`. +This effectively counts up all of the instances of "1" in the binary string, as 0 and 1 are the only valid binary digits. + +Many variations of this approach use a built-in function like `sum()` to make the iteration more concise. +For more details, check out the [convert to a binary string][approach-convert-to-binary-string] approach. + + [approach-parameter-modification]: https://exercism.org/tracks/python/exercises/eliuds-eggs/approaches/parameter-modification [approach-no-parameter-modification]: https://exercism.org/tracks/python/exercises/eliuds-eggs/approaches/no-parameter-modification +[approach-convert-to-binary-string]: https://exercism.org/tracks/python/exercises/eliuds-eggs/approaches/convert-to-binary-string +[bin-built-in]: https://docs.python.org/3/library/functions.html#bin [right-shift-operator]: https://www.geeksforgeeks.org/software-engineering/right-shift-operator-in-programming/ +[f-string]: https://docs.python.org/3/reference/lexical_analysis.html#f-strings From 12c7b6eab611e2abb9c4d038c3e1a26ca7bd7bda Mon Sep 17 00:00:00 2001 From: Yrahcaz7 <74512479+Yrahcaz7@users.noreply.github.com> Date: Sat, 6 Jun 2026 22:49:51 -0400 Subject: [PATCH 4/5] add two more variations to the first approach --- .../eliuds-eggs/.approaches/introduction.md | 3 +- .../parameter-modification/content.md | 43 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/exercises/practice/eliuds-eggs/.approaches/introduction.md b/exercises/practice/eliuds-eggs/.approaches/introduction.md index 2b490a0b69b..141b10157a4 100644 --- a/exercises/practice/eliuds-eggs/.approaches/introduction.md +++ b/exercises/practice/eliuds-eggs/.approaches/introduction.md @@ -14,7 +14,7 @@ There are also some approaches that aren't recommended: ## General guidance -The goal of the Eliud's Eggs exercise is to count the number of ones in the binary representation of a number. +The goal of the Eliud's Eggs exercise is to count the number of ones in the binary representation of a [number][concept-numbers]. In essence, this requires you to loop over each bit (binary digit) of the number in some way. The approaches below represent categories of the most common ways of accomplishing this. @@ -92,5 +92,6 @@ For more details, check out the [convert to a binary string][approach-convert-to [approach-no-parameter-modification]: https://exercism.org/tracks/python/exercises/eliuds-eggs/approaches/no-parameter-modification [approach-convert-to-binary-string]: https://exercism.org/tracks/python/exercises/eliuds-eggs/approaches/convert-to-binary-string [bin-built-in]: https://docs.python.org/3/library/functions.html#bin +[concept-numbers]: https://exercism.org/tracks/python/concepts/numbers [right-shift-operator]: https://www.geeksforgeeks.org/software-engineering/right-shift-operator-in-programming/ [f-string]: https://docs.python.org/3/reference/lexical_analysis.html#f-strings diff --git a/exercises/practice/eliuds-eggs/.approaches/parameter-modification/content.md b/exercises/practice/eliuds-eggs/.approaches/parameter-modification/content.md index b1765f865d3..444d75efbc7 100644 --- a/exercises/practice/eliuds-eggs/.approaches/parameter-modification/content.md +++ b/exercises/practice/eliuds-eggs/.approaches/parameter-modification/content.md @@ -76,5 +76,48 @@ For example, if we used the numbers `5` (`101` in binary) and `1`, we get `2` (` You can see how `& 1` and `>>= 1` perform the same function as the `% 2` and `//= 2` used in earier variants. +## Variation #3: Using a `list` + +```python +def egg_count(display_value): + egg_positions = [] + + while display_value: + egg_positions.append(display_value % 2) + display_value //= 2 + + return egg_positions.count(1) +``` + +Here, we append the binary digits to a `list` and then count the number of ones using [`list.count()`][sequence-count]. +This solution would make sense if the positions of the eggs mattered, but since we only need the amount here, tracking the positions just adds unecessary overhead. + + +## Variation #4: Using `divmod()` + +```python +def egg_count(display_value): + eggs = 0 + while display_value: + display_value, remainder = divmod(display_value, 2) + eggs += remainder + return eggs +``` + +This variant uses the [`divmod()`][divmod-built-in] built-in instead of `%` and `//`. +(For `int` arguments, `divmod(a, b)` returns a [`tuple`][concept-tuples] of `(a // b, a % b)`.) + +In the loop, we use `divmod(display_value, 2)` to get both the quotient and the remainder of the division. +The `tuple` returned by `divmod()` is [unpacked][concept-unpacking-and-multiple-assignment] into `display_value` and `remainder` using [multiple assignment][concept-unpacking-and-multiple-assignment]. +Then, we increment `eggs` by `remainder`. + +As `display_value` is updated in the multiple assignment expression, we don't need to do anything else inside the loop. +Just like the previous variations, the loop will continue until `display_value` reaches 0, and then we return `eggs`. + + [bitwise-operators]: https://www.w3schools.com/programming/prog_operators_bitwise.php +[concept-tuples]: https://exercism.org/tracks/python/concepts/tuples +[concept-unpacking-and-multiple-assignment]: https://exercism.org/tracks/python/concepts/unpacking-and-multiple-assignment +[divmod-built-in]: https://docs.python.org/3/library/functions.html#divmod [right-shift-operator]: https://www.geeksforgeeks.org/software-engineering/right-shift-operator-in-programming/ +[sequence-count]: https://docs.python.org/3/library/stdtypes.html#sequence.count From eddb8922bb3dfb651572d7ea0e739d21062602b8 Mon Sep 17 00:00:00 2001 From: Yrahcaz7 <74512479+Yrahcaz7@users.noreply.github.com> Date: Sun, 7 Jun 2026 15:01:48 -0400 Subject: [PATCH 5/5] add fourth approach --- .../.approaches/built-in-bit-count/content.md | 54 +++++++++++++++++++ .../built-in-bit-count/snippet.txt | 2 + .../eliuds-eggs/.approaches/config.json | 11 +++- .../convert-to-binary-string/content.md | 1 - .../eliuds-eggs/.approaches/introduction.md | 25 +++++++-- 5 files changed, 87 insertions(+), 6 deletions(-) create mode 100644 exercises/practice/eliuds-eggs/.approaches/built-in-bit-count/content.md create mode 100644 exercises/practice/eliuds-eggs/.approaches/built-in-bit-count/snippet.txt diff --git a/exercises/practice/eliuds-eggs/.approaches/built-in-bit-count/content.md b/exercises/practice/eliuds-eggs/.approaches/built-in-bit-count/content.md new file mode 100644 index 00000000000..941c6c4141e --- /dev/null +++ b/exercises/practice/eliuds-eggs/.approaches/built-in-bit-count/content.md @@ -0,0 +1,54 @@ +# Use the Built-In Bit-Count Functionality + +~~~~exercism/caution +This approach does _not_ follow the instructions, as it uses the bit-count functionality from the standard library. +It is only described here to show what an idiomatic way of counting bits in a _different context_ would be. +~~~~ + +```python +def egg_count(display_value): + return display_value.bit_count() +``` + +This approach uses [`int.bit_count()`][int-bit_count] from the Python standard library to count the number of ones in the binary representation of `display_value`. + +This works because Python does _not_ have separate types for binary, octal, or hexadecimal numbers. +Even if a binary literal is declared with the `0b` prefix, Python still stores it as an `int`. +Due to this, all of the methods that work with binary numbers in the standard library just operate on `int`s. + + +## Variation #1: Using `str.count()` + +```python +def egg_count(display_value): + return bin(display_value).count("1") +``` + +This variant uses [`bin()`][bin-built-in] (or any other method discussed in the [convert to a binary string][approach-convert-to-binary-string] approach) to convert `display_value` to a binary string. +Then, [`str.count()`][sequence-count] is used to count how many times "1" appears in the string. + +Though one could argue that this _technically_ doesn't use the built-in bit-count functionality, the solution still defeats the purpose of the exercise. + + +## Variation #2: Using Function Aliasing + +```python +egg_count = int.bit_count +``` + +This solution is the shortest of them all, but it can also be rather confusing (and it still does not follow the instructions). + +This variant makes clever use of [function aliasing][function-aliasing], which creates a new name that refers to the same exact function. +However, you should be careful when using function aliasing, as it often makes code _less_ readable, and it doesn't have many practical applications outside of backward compatibility. + +This solution works because `int.bit_count()` is just another way of saying `.bit_count()`, as instance methods of a class have `self` implicitly passed as the first parameter when calling them on an instance (but not when calling them directly on the class). +See the [Classes Concept in the Syllabus][concept-classes: methods] or the [Official Python Classes Tutorial][class-method-objects-tutorial] for more detail on how this works. + + +[approach-convert-to-binary-string]: https://exercism.org/tracks/python/exercises/eliuds-eggs/approaches/convert-to-binary-string +[bin-built-in]: https://docs.python.org/3/library/functions.html#bin +[class-method-objects-tutorial]: https://docs.python.org/3/tutorial/classes.html#method-objects +[concept-classes: methods]: https://exercism.org/tracks/python/concepts/classes#h-methods +[function-aliasing]: https://tutorialreference.com/python/examples/faq/python-how-to-use-function-aliasing +[int-bit_count]: https://docs.python.org/3/library/stdtypes.html#int.bit_count +[sequence-count]: https://docs.python.org/3/library/stdtypes.html#sequence.count diff --git a/exercises/practice/eliuds-eggs/.approaches/built-in-bit-count/snippet.txt b/exercises/practice/eliuds-eggs/.approaches/built-in-bit-count/snippet.txt new file mode 100644 index 00000000000..96be0c4e833 --- /dev/null +++ b/exercises/practice/eliuds-eggs/.approaches/built-in-bit-count/snippet.txt @@ -0,0 +1,2 @@ +def egg_count(display_value): + return display_value.bit_count() \ No newline at end of file diff --git a/exercises/practice/eliuds-eggs/.approaches/config.json b/exercises/practice/eliuds-eggs/.approaches/config.json index eff40e6cf9a..240b5ec6c45 100644 --- a/exercises/practice/eliuds-eggs/.approaches/config.json +++ b/exercises/practice/eliuds-eggs/.approaches/config.json @@ -8,14 +8,14 @@ "uuid": "27fb20ed-a4c2-4f73-a8fc-86ba384c7b35", "slug": "parameter-modification", "title": "Modify the Parameter in a Loop", - "blurb": "Modify the parameter in a while-loop to calculate the number of eggs.", + "blurb": "Modify the parameter in a while-loop to determine the number of eggs.", "authors": ["yrahcaz7"] }, { "uuid": "65fd717c-0e50-444b-a4b2-b51862f1f810", "slug": "no-parameter-modification", "title": "Loop Without Modifying the Parameter", - "blurb": "Loop over the bits without modifying the parameter to determine the number of eggs.", + "blurb": "Loop over the bits without modifying the parameter to calculate the number of eggs.", "authors": ["yrahcaz7"] }, { @@ -24,6 +24,13 @@ "title": "Convert to a Binary String", "blurb": "Convert the parameter to a binary string and count its ones to determine the number of eggs.", "authors": ["yrahcaz7"] + }, + { + "uuid": "97b06094-7ce8-4874-b66a-af7391adc853", + "slug": "built-in-bit-count", + "title": "Use the Built-In Bit-Count Functionality", + "blurb": "Use Python's Built-In Bit-Count Functionality to calculate the number of eggs.", + "authors": ["yrahcaz7"] } ] } diff --git a/exercises/practice/eliuds-eggs/.approaches/convert-to-binary-string/content.md b/exercises/practice/eliuds-eggs/.approaches/convert-to-binary-string/content.md index 854a6e097c3..23f19182a7f 100644 --- a/exercises/practice/eliuds-eggs/.approaches/convert-to-binary-string/content.md +++ b/exercises/practice/eliuds-eggs/.approaches/convert-to-binary-string/content.md @@ -105,7 +105,6 @@ However, the creation and repeated calling of the `lambda` adds unnecessary over [bin-built-in]: https://docs.python.org/3/library/functions.html#bin -[f-string]: https://docs.python.org/3/reference/lexical_analysis.html#f-strings [generator-expression]: https://dbader.org/blog/python-generator-expressions [lambda-expression]: https://docs.python.org/3/tutorial/controlflow.html#lambda-expressions [list-comprehension]: https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions diff --git a/exercises/practice/eliuds-eggs/.approaches/introduction.md b/exercises/practice/eliuds-eggs/.approaches/introduction.md index 141b10157a4..8ffe58e7aaf 100644 --- a/exercises/practice/eliuds-eggs/.approaches/introduction.md +++ b/exercises/practice/eliuds-eggs/.approaches/introduction.md @@ -88,10 +88,29 @@ Many variations of this approach use a built-in function like `sum()` to make th For more details, check out the [convert to a binary string][approach-convert-to-binary-string] approach. -[approach-parameter-modification]: https://exercism.org/tracks/python/exercises/eliuds-eggs/approaches/parameter-modification -[approach-no-parameter-modification]: https://exercism.org/tracks/python/exercises/eliuds-eggs/approaches/no-parameter-modification +## Approach: Using the Built-In Bit-Count Functionality + +~~~~exercism/caution +This approach does _not_ follow the instructions, as it uses the bit-count functionality from the standard library. +It is only described here to show what an idiomatic way of counting bits in a _different context_ would be. +~~~~ + +```python +def egg_count(display_value): + return display_value.bit_count() +``` + +This approach uses [`int.bit_count()`][int-bit_count] from the Python standard library to count the number of ones in the binary representation of `display_value`. + +For more details and variations, read the [built-in bit-count][approach-built-in-bit-count] approach. + + +[approach-built-in-bit-count]: https://exercism.org/tracks/python/exercises/eliuds-eggs/approaches/built-in-bit-count [approach-convert-to-binary-string]: https://exercism.org/tracks/python/exercises/eliuds-eggs/approaches/convert-to-binary-string +[approach-no-parameter-modification]: https://exercism.org/tracks/python/exercises/eliuds-eggs/approaches/no-parameter-modification +[approach-parameter-modification]: https://exercism.org/tracks/python/exercises/eliuds-eggs/approaches/parameter-modification [bin-built-in]: https://docs.python.org/3/library/functions.html#bin [concept-numbers]: https://exercism.org/tracks/python/concepts/numbers -[right-shift-operator]: https://www.geeksforgeeks.org/software-engineering/right-shift-operator-in-programming/ [f-string]: https://docs.python.org/3/reference/lexical_analysis.html#f-strings +[int-bit_count]: https://docs.python.org/3/library/stdtypes.html#int.bit_count +[right-shift-operator]: https://www.geeksforgeeks.org/software-engineering/right-shift-operator-in-programming/