From 3b008d7ffbc9975c3932ffa8798fb84dd93cee29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nenad=20Misi=C4=87?= Date: Tue, 18 Jun 2024 14:04:59 +0200 Subject: [PATCH] add armstrong_numbers (#9) --- concepts/enums/.meta/config.json | 7 ++ concepts/enums/about.md | 1 + concepts/enums/introduction.md | 1 + concepts/enums/links.json | 1 + concepts/match-basics/.meta/config.json | 7 ++ concepts/match-basics/about.md | 1 + concepts/match-basics/introduction.md | 1 + concepts/match-basics/links.json | 1 + config.json | 37 ++++++++++ .../armstrong-numbers/.docs/instructions.md | 14 ++++ .../armstrong-numbers/.meta/config.json | 20 ++++++ .../armstrong-numbers/.meta/example.cairo | 40 +++++++++++ .../armstrong-numbers/.meta/tests.toml | 43 ++++++++++++ .../practice/armstrong-numbers/Scarb.toml | 4 ++ .../practice/armstrong-numbers/src/lib.cairo | 6 ++ .../armstrong-numbers/src/tests.cairo | 69 +++++++++++++++++++ 16 files changed, 253 insertions(+) create mode 100644 concepts/enums/.meta/config.json create mode 100644 concepts/enums/about.md create mode 100644 concepts/enums/introduction.md create mode 100644 concepts/enums/links.json create mode 100644 concepts/match-basics/.meta/config.json create mode 100644 concepts/match-basics/about.md create mode 100644 concepts/match-basics/introduction.md create mode 100644 concepts/match-basics/links.json create mode 100644 exercises/practice/armstrong-numbers/.docs/instructions.md create mode 100644 exercises/practice/armstrong-numbers/.meta/config.json create mode 100644 exercises/practice/armstrong-numbers/.meta/example.cairo create mode 100644 exercises/practice/armstrong-numbers/.meta/tests.toml create mode 100644 exercises/practice/armstrong-numbers/Scarb.toml create mode 100644 exercises/practice/armstrong-numbers/src/lib.cairo create mode 100644 exercises/practice/armstrong-numbers/src/tests.cairo diff --git a/concepts/enums/.meta/config.json b/concepts/enums/.meta/config.json new file mode 100644 index 00000000..52914445 --- /dev/null +++ b/concepts/enums/.meta/config.json @@ -0,0 +1,7 @@ +{ + "blurb": "", + "authors": [ + "misicnenad" + ], + "contributors": [] +} diff --git a/concepts/enums/about.md b/concepts/enums/about.md new file mode 100644 index 00000000..ece8d08a --- /dev/null +++ b/concepts/enums/about.md @@ -0,0 +1 @@ +# Enums diff --git a/concepts/enums/introduction.md b/concepts/enums/introduction.md new file mode 100644 index 00000000..e10b99d0 --- /dev/null +++ b/concepts/enums/introduction.md @@ -0,0 +1 @@ +# Introduction diff --git a/concepts/enums/links.json b/concepts/enums/links.json new file mode 100644 index 00000000..fe51488c --- /dev/null +++ b/concepts/enums/links.json @@ -0,0 +1 @@ +[] diff --git a/concepts/match-basics/.meta/config.json b/concepts/match-basics/.meta/config.json new file mode 100644 index 00000000..52914445 --- /dev/null +++ b/concepts/match-basics/.meta/config.json @@ -0,0 +1,7 @@ +{ + "blurb": "", + "authors": [ + "misicnenad" + ], + "contributors": [] +} diff --git a/concepts/match-basics/about.md b/concepts/match-basics/about.md new file mode 100644 index 00000000..3b42f2c2 --- /dev/null +++ b/concepts/match-basics/about.md @@ -0,0 +1 @@ +# Match Basics diff --git a/concepts/match-basics/introduction.md b/concepts/match-basics/introduction.md new file mode 100644 index 00000000..e10b99d0 --- /dev/null +++ b/concepts/match-basics/introduction.md @@ -0,0 +1 @@ +# Introduction diff --git a/concepts/match-basics/links.json b/concepts/match-basics/links.json new file mode 100644 index 00000000..fe51488c --- /dev/null +++ b/concepts/match-basics/links.json @@ -0,0 +1 @@ +[] diff --git a/config.json b/config.json index 769620f6..bfe57dbe 100644 --- a/config.json +++ b/config.json @@ -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" + ] } ] }, @@ -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": [ diff --git a/exercises/practice/armstrong-numbers/.docs/instructions.md b/exercises/practice/armstrong-numbers/.docs/instructions.md new file mode 100644 index 00000000..5e56bbe4 --- /dev/null +++ b/exercises/practice/armstrong-numbers/.docs/instructions.md @@ -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 diff --git a/exercises/practice/armstrong-numbers/.meta/config.json b/exercises/practice/armstrong-numbers/.meta/config.json new file mode 100644 index 00000000..4724d3dd --- /dev/null +++ b/exercises/practice/armstrong-numbers/.meta/config.json @@ -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" +} diff --git a/exercises/practice/armstrong-numbers/.meta/example.cairo b/exercises/practice/armstrong-numbers/.meta/example.cairo new file mode 100644 index 00000000..4c426fd5 --- /dev/null +++ b/exercises/practice/armstrong-numbers/.meta/example.cairo @@ -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 = 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; diff --git a/exercises/practice/armstrong-numbers/.meta/tests.toml b/exercises/practice/armstrong-numbers/.meta/tests.toml new file mode 100644 index 00000000..b3f09e4c --- /dev/null +++ b/exercises/practice/armstrong-numbers/.meta/tests.toml @@ -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" diff --git a/exercises/practice/armstrong-numbers/Scarb.toml b/exercises/practice/armstrong-numbers/Scarb.toml new file mode 100644 index 00000000..18fcc7f8 --- /dev/null +++ b/exercises/practice/armstrong-numbers/Scarb.toml @@ -0,0 +1,4 @@ +[package] +name = "armstrong_numbers" +version = "0.1.0" +edition = "2023_11" diff --git a/exercises/practice/armstrong-numbers/src/lib.cairo b/exercises/practice/armstrong-numbers/src/lib.cairo new file mode 100644 index 00000000..76f3b347 --- /dev/null +++ b/exercises/practice/armstrong-numbers/src/lib.cairo @@ -0,0 +1,6 @@ +fn is_armstrong_number(num: u32) -> bool { + panic!("true if {num} is an armstrong number") +} + +#[cfg(test)] +mod tests; diff --git a/exercises/practice/armstrong-numbers/src/tests.cairo b/exercises/practice/armstrong-numbers/src/tests.cairo new file mode 100644 index 00000000..00341f90 --- /dev/null +++ b/exercises/practice/armstrong-numbers/src/tests.cairo @@ -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)); +}