Skip to content

Commit

Permalink
Add armstrong numbers (#12)
Browse files Browse the repository at this point in the history
* Clarify message in case of Grapheme.split error

* Add armstrong-numbers exercise and add to_roc_bool filter
  • Loading branch information
ageron authored Aug 25, 2024
1 parent f6ccae1 commit e01cbe2
Show file tree
Hide file tree
Showing 11 changed files with 165 additions and 2 deletions.
5 changes: 5 additions & 0 deletions bin/generate_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ def to_camel(string: str) -> str:
del i


def to_roc_bool(b: bool) -> str:
return "Bool.true" if b else "Bool.false"


def to_roc_string(string: str) -> str:
"""
Return a Roc representation of a Python string
Expand Down Expand Up @@ -483,6 +487,7 @@ def generate(
env.filters["to_snake"] = to_snake
env.filters["to_pascal"] = to_pascal
env.filters["to_camel"] = to_camel
env.filters["to_roc_bool"] = to_roc_bool
env.filters["to_roc_string"] = to_roc_string
env.filters["wrap_overlong"] = wrap_overlong
env.filters["regex_replace"] = regex_replace
Expand Down
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@
"practices": [],
"prerequisites": [],
"difficulty": 1
},
{
"slug": "armstrong-numbers",
"name": "Armstrong Numbers",
"uuid": "da8055c2-c2f0-43ad-85f2-dd55f10e84be",
"practices": [],
"prerequisites": [],
"difficulty": 1
}
]
},
Expand Down
14 changes: 14 additions & 0 deletions exercises/practice/armstrong-numbers/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Instructions

An [Armstrong number][armstrong-number] is a number that is the sum of its own digits each raised to the power of the number of digits.

For example:

- 9 is an Armstrong number, because `9 = 9^1 = 9`
- 10 is _not_ an Armstrong number, because `10 != 1^2 + 0^2 = 1`
- 153 is an Armstrong number, because: `153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153`
- 154 is _not_ an Armstrong number, because: `154 != 1^3 + 5^3 + 4^3 = 1 + 125 + 64 = 190`

Write some code to determine whether a number is an Armstrong number.

[armstrong-number]: https://en.wikipedia.org/wiki/Narcissistic_number
16 changes: 16 additions & 0 deletions exercises/practice/armstrong-numbers/.meta/Example.roc
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module [isArmstrongNumber]

listDigits = \number ->
if number < 10 then
[number]
else
(listDigits (number // 10)) |> List.append (number % 10)

isArmstrongNumber = \number ->
digits = listDigits number
len = List.len digits
candidate =
digits
|> List.map (\digit -> digit |> Num.powInt len)
|> List.sum
candidate == number
19 changes: 19 additions & 0 deletions exercises/practice/armstrong-numbers/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"authors": [
"ageron"
],
"files": {
"solution": [
"ArmstrongNumbers.roc"
],
"test": [
"armstrong-numbers-test.roc"
],
"example": [
".meta/Example.roc"
]
},
"blurb": "Determine if a number is an Armstrong number.",
"source": "Wikipedia",
"source_url": "https://en.wikipedia.org/wiki/Narcissistic_number"
}
11 changes: 11 additions & 0 deletions exercises/practice/armstrong-numbers/.meta/template.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{%- import "generator_macros.j2" as macros with context -%}
{{ macros.canonical_ref() }}
{{ macros.header() }}

import {{ exercise | to_pascal }} exposing [isArmstrongNumber]

{% for case in cases -%}
# {{ case["description"] }}
expect {{ case["property"] | to_camel }} {{ case["input"]["number"] }} == {{ case["expected"] | to_roc_bool }}

{% endfor %}
45 changes: 45 additions & 0 deletions exercises/practice/armstrong-numbers/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# 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.

[c1ed103c-258d-45b2-be73-d8c6d9580c7b]
description = "Zero is an Armstrong number"

[579e8f03-9659-4b85-a1a2-d64350f6b17a]
description = "Single-digit numbers are Armstrong numbers"

[2d6db9dc-5bf8-4976-a90b-b2c2b9feba60]
description = "There are no two-digit Armstrong numbers"

[509c087f-e327-4113-a7d2-26a4e9d18283]
description = "Three-digit number that is an Armstrong number"

[7154547d-c2ce-468d-b214-4cb953b870cf]
description = "Three-digit number that is not an Armstrong number"

[6bac5b7b-42e9-4ecb-a8b0-4832229aa103]
description = "Four-digit number that is an Armstrong number"

[eed4b331-af80-45b5-a80b-19c9ea444b2e]
description = "Four-digit number that is not an Armstrong number"

[f971ced7-8d68-4758-aea1-d4194900b864]
description = "Seven-digit number that is an Armstrong number"

[7ee45d52-5d35-4fbd-b6f1-5c8cd8a67f18]
description = "Seven-digit number that is not an Armstrong number"

[5ee2fdf8-334e-4a46-bb8d-e5c19c02c148]
description = "Armstrong number containing seven zeroes"
include = false

[12ffbf10-307a-434e-b4ad-c925680e1dd4]
description = "The largest and last Armstrong number"
include = false
4 changes: 4 additions & 0 deletions exercises/practice/armstrong-numbers/ArmstrongNumbers.roc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module [isArmstrongNumber]

isArmstrongNumber = \number ->
crash "Please implement the 'isArmstrongNumber' function"
41 changes: 41 additions & 0 deletions exercises/practice/armstrong-numbers/armstrong-numbers-test.roc
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# These tests are auto-generated with test data from:
# https://github.com/exercism/problem-specifications/tree/main/exercises/armstrong-numbers/canonical-data.json
# File last updated on 2024-08-25
app [main] {
pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.12.0/Lb8EgiejTUzbggO2HVVuPJFkwvvsfW6LojkLR20kTVE.tar.br",
}

import pf.Task exposing [Task]

main =
Task.ok {}

import ArmstrongNumbers exposing [isArmstrongNumber]

# Zero is an Armstrong number
expect isArmstrongNumber 0 == Bool.true

# Single-digit numbers are Armstrong numbers
expect isArmstrongNumber 5 == Bool.true

# There are no two-digit Armstrong numbers
expect isArmstrongNumber 10 == Bool.false

# Three-digit number that is an Armstrong number
expect isArmstrongNumber 153 == Bool.true

# Three-digit number that is not an Armstrong number
expect isArmstrongNumber 100 == Bool.false

# Four-digit number that is an Armstrong number
expect isArmstrongNumber 9474 == Bool.true

# Four-digit number that is not an Armstrong number
expect isArmstrongNumber 9475 == Bool.false

# Seven-digit number that is an Armstrong number
expect isArmstrongNumber 9926315 == Bool.true

# Seven-digit number that is not an Armstrong number
expect isArmstrongNumber 9926314 == Bool.false

2 changes: 1 addition & 1 deletion exercises/practice/leap/.meta/template.j2
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ import Leap exposing [isLeapYear]

{% for case in cases -%}
# {{ case["description"] }}
expect (isLeapYear {{ case["input"]["year"] }}) == Bool.{{- case ["expected"] | lower }}
expect (isLeapYear {{ case["input"]["year"] }}) == {{ case ["expected"] | to_roc_bool }}

{% endfor %}
2 changes: 1 addition & 1 deletion exercises/practice/reverse-string/.meta/Example.roc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ reverse = \string ->
graphemes = string |> Grapheme.split
when graphemes is
Ok gs -> gs |> List.reverse |> Str.joinWith ""
Err _ -> "Ooops"
Err _ -> "Unexpected error: could not split the string into graphemes"


## This function reverses the input string, e.g., "hello" -> "olleh". It is
Expand Down

0 comments on commit e01cbe2

Please sign in to comment.