Skip to content

Commit

Permalink
add armstrong_numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
Nenad committed Jun 18, 2024
1 parent 897af00 commit aa76e81
Show file tree
Hide file tree
Showing 16 changed files with 253 additions and 0 deletions.
7 changes: 7 additions & 0 deletions concepts/enums/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"blurb": "<todo>",
"authors": [
"misicnenad"
],
"contributors": []
}
1 change: 1 addition & 0 deletions concepts/enums/about.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Enums
1 change: 1 addition & 0 deletions concepts/enums/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Introduction
1 change: 1 addition & 0 deletions concepts/enums/links.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
7 changes: 7 additions & 0 deletions concepts/match-basics/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"blurb": "<todo>",
"authors": [
"misicnenad"
],
"contributors": []
}
1 change: 1 addition & 0 deletions concepts/match-basics/about.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Match Basics
1 change: 1 addition & 0 deletions concepts/match-basics/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Introduction
1 change: 1 addition & 0 deletions concepts/match-basics/links.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
37 changes: 37 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,23 @@
"topics": [
"conditionals"
]
},
{
"slug": "armstrong-numbers",
"name": "Armstrong Numbers",
"uuid": "4aaa153d-3416-4101-8143-35b068a15451",
"practices": [
"functions",
"integers",
"enums"
],
"prerequisites": [],
"difficulty": 1,
"topics": [
"math",
"option_type",
"result_type"
]
}
]
},
Expand All @@ -76,10 +93,30 @@
"slug": "integers",
"name": "Integers"
},
{
"uuid": "fe33b75a-8064-419d-9e09-16b49e6a5c6d",
"slug": "felts",
"name": "Felt Type"
},
{
"uuid": "de254443-42ee-4787-bc1e-3d0d2039c4f5",
"slug": "booleans",
"name": "Booleans"
},
{
"uuid": "6ba0e79b-9e70-4116-8f26-cce676a7b05e",
"slug": "functions",
"name": "Functions"
},
{
"uuid": "cff7568f-423e-4d6b-b238-1ebbce31d991",
"slug": "enums",
"name": "Enums"
},
{
"uuid": "2cc6431d-fc19-47f3-b7f1-999ed16e5244",
"slug": "match-basics",
"name": "Match Basics"
}
],
"key_features": [
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
20 changes: 20 additions & 0 deletions exercises/practice/armstrong-numbers/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"authors": [
"misicnenad"
],
"files": {
"solution": [
"src/lib.cairo",
"Scarb.toml"
],
"test": [
"src/tests.cairo"
],
"example": [
".meta/example.cairo"
]
},
"blurb": "Determine if a number is an Armstrong number.",
"source": "Wikipedia",
"source_url": "https://en.wikipedia.org/wiki/Narcissistic_number"
}
40 changes: 40 additions & 0 deletions exercises/practice/armstrong-numbers/.meta/example.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use core::integer::{u32_overflowing_add};

fn is_armstrong_number(num: u32) -> bool {
let s = format!("{}", num);
let l = s.len();
let mut result: Option<u32> = Option::Some(0);
let mut i = l;
while i != 0 {
if let Option::None = result {
break;
}

i -= 1;

// ByteArray.at returns the ASCII representation of the character,
// so we need to subtract the position of the decimal '0' in ASCII
// (ASCII 48 == 0)
let digit: u8 = s.at(i).into().unwrap() - 48;

result = match u32_overflowing_add(result.unwrap(), pow(digit, l)) {
Result::Ok(val) => Option::Some(val),
Result::Err(_) => Option::None,
};
};

result == Option::Some(num)
}

fn pow(base: u8, exponent: u32) -> u32 {
let mut result: u32 = 1;
let mut i = exponent;
while i != 0 {
result *= base.into(); // cast u8 into u32
i -= 1;
};
result
}

#[cfg(test)]
mod tests;
43 changes: 43 additions & 0 deletions exercises/practice/armstrong-numbers/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# 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"

[12ffbf10-307a-434e-b4ad-c925680e1dd4]
description = "The largest and last Armstrong number"
4 changes: 4 additions & 0 deletions exercises/practice/armstrong-numbers/Scarb.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
name = "armstrong_numbers"
version = "0.1.0"
edition = "2023_11"
6 changes: 6 additions & 0 deletions exercises/practice/armstrong-numbers/src/lib.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fn is_armstrong_number(num: u32) -> bool {
panic!("true if {num} is an armstrong number")
}

#[cfg(test)]
mod tests;
69 changes: 69 additions & 0 deletions exercises/practice/armstrong-numbers/src/tests.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use armstrong_numbers::is_armstrong_number;

#[test]
fn zero_is_an_armstrong_number() {
assert!(is_armstrong_number(0))
}

#[test]
fn single_digit_numbers_are_armstrong_numbers() {
assert!(is_armstrong_number(5))
}

#[test]
fn there_are_no_2_digit_armstrong_numbers() {
assert!(!is_armstrong_number(10))
}

#[test]
fn three_digit_armstrong_number() {
assert!(is_armstrong_number(153))
}

#[test]
fn three_digit_non_armstrong_number() {
assert!(!is_armstrong_number(100))
}

#[test]
fn four_digit_armstrong_number() {
assert!(is_armstrong_number(9474))
}

#[test]
fn four_digit_non_armstrong_number() {
assert!(!is_armstrong_number(9475))
}

#[test]
fn seven_digit_armstrong_number() {
assert!(is_armstrong_number(9_926_315))
}

#[test]
fn seven_digit_non_armstrong_number() {
assert!(!is_armstrong_number(9_926_316))
}

#[test]
fn nine_digit_armstrong_number() {
assert!(is_armstrong_number(912_985_153));
}

#[test]
fn nine_digit_non_armstrong_number() {
assert!(!is_armstrong_number(999_999_999));
}

#[test]
fn ten_digit_non_armstrong_number() {
assert!(!is_armstrong_number(3_999_999_999));
}

// The following number has an Armstrong sum equal to 2^32 plus itself,
// and therefore will be detected as an Armstrong number if you are
// incorrectly using wrapping arithmetic.
#[test]
fn properly_handles_overflow() {
assert!(!is_armstrong_number(4_106_098_957));
}

0 comments on commit aa76e81

Please sign in to comment.