diff --git a/config.json b/config.json index 809ea702..dffba7f3 100644 --- a/config.json +++ b/config.json @@ -747,6 +747,14 @@ "practices": [], "prerequisites": [], "difficulty": 2 + }, + { + "slug": "sum-of-multiples", + "name": "Sum of Multiples", + "uuid": "60b963b1-5c4a-4eb5-8f8e-a5e1ba9faa2f", + "practices": [], + "prerequisites": [], + "difficulty": 1 } ], "foregone": [ diff --git a/exercises/practice/sum-of-multiples/.docs/instructions.md b/exercises/practice/sum-of-multiples/.docs/instructions.md new file mode 100644 index 00000000..d69f890e --- /dev/null +++ b/exercises/practice/sum-of-multiples/.docs/instructions.md @@ -0,0 +1,27 @@ +# Instructions + +Your task is to write the code that calculates the energy points that get awarded to players when they complete a level. + +The points awarded depend on two things: + +- The level (a number) that the player completed. +- The base value of each magical item collected by the player during that level. + +The energy points are awarded according to the following rules: + +1. For each magical item, take the base value and find all the multiples of that value that are less than the level number. +2. Combine the sets of numbers. +3. Remove any duplicates. +4. Calculate the sum of all the numbers that are left. + +Let's look at an example: + +**The player completed level 20 and found two magical items with base values of 3 and 5.** + +To calculate the energy points earned by the player, we need to find all the unique multiples of these base values that are less than level 20. + +- Multiples of 3 less than 20: `{3, 6, 9, 12, 15, 18}` +- Multiples of 5 less than 20: `{5, 10, 15}` +- Combine the sets and remove duplicates: `{3, 5, 6, 9, 10, 12, 15, 18}` +- Sum the unique multiples: `3 + 5 + 6 + 9 + 10 + 12 + 15 + 18 = 78` +- Therefore, the player earns **78** energy points for completing level 20 and finding the two magical items with base values of 3 and 5. diff --git a/exercises/practice/sum-of-multiples/.docs/introduction.md b/exercises/practice/sum-of-multiples/.docs/introduction.md new file mode 100644 index 00000000..69cabeed --- /dev/null +++ b/exercises/practice/sum-of-multiples/.docs/introduction.md @@ -0,0 +1,6 @@ +# Introduction + +You work for a company that makes an online, fantasy-survival game. + +When a player finishes a level, they are awarded energy points. +The amount of energy awarded depends on which magical items the player found while exploring that level. diff --git a/exercises/practice/sum-of-multiples/.meta/config.json b/exercises/practice/sum-of-multiples/.meta/config.json new file mode 100644 index 00000000..e706b33f --- /dev/null +++ b/exercises/practice/sum-of-multiples/.meta/config.json @@ -0,0 +1,22 @@ +{ + "authors": [ + "Falilah" + ], + "files": { + "solution": [ + "src/lib.cairo" + ], + "test": [ + "tests/sum_of_multiples.cairo" + ], + "example": [ + ".meta/example.cairo" + ], + "invalidator": [ + "Scarb.toml" + ] + }, + "blurb": "Given a number, find the sum of all the multiples of particular numbers up to but not including that number.", + "source": "A variation on Problem 1 at Project Euler", + "source_url": "https://projecteuler.net/problem=1" +} diff --git a/exercises/practice/sum-of-multiples/.meta/example.cairo b/exercises/practice/sum-of-multiples/.meta/example.cairo new file mode 100644 index 00000000..073deca6 --- /dev/null +++ b/exercises/practice/sum-of-multiples/.meta/example.cairo @@ -0,0 +1,39 @@ +pub fn sum(limit: u32, factors: Array) -> u32 { + let mut multiples: Array = array![]; + + for f in factors { + if f > 0 { + let mut multiplier = 1; + let mut x = f; + + while x < limit { + if !contains(@multiples, x) { + multiples.append(x); + }; + + multiplier += 1; + x = f * multiplier; + } + } + }; + + let mut total_sum = 0; + for m in multiples { + total_sum += m; + }; + + total_sum +} + +fn contains(arr: @Array, value: u32) -> bool { + let mut i = 0; + let mut result = false; + while i < arr.len() { + if arr[i] == @value { + result = true; + break; + } + i += 1; + }; + result +} diff --git a/exercises/practice/sum-of-multiples/.meta/tests.toml b/exercises/practice/sum-of-multiples/.meta/tests.toml new file mode 100644 index 00000000..89e441c0 --- /dev/null +++ b/exercises/practice/sum-of-multiples/.meta/tests.toml @@ -0,0 +1,59 @@ +# 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. + +[54aaab5a-ce86-4edc-8b40-d3ab2400a279] +description = "no multiples within limit" + +[361e4e50-c89b-4f60-95ef-5bc5c595490a] +description = "one factor has multiples within limit" + +[e644e070-040e-4ae0-9910-93c69fc3f7ce] +description = "more than one multiple within limit" + +[607d6eb9-535c-41ce-91b5-3a61da3fa57f] +description = "more than one factor with multiples within limit" + +[f47e8209-c0c5-4786-b07b-dc273bf86b9b] +description = "each multiple is only counted once" + +[28c4b267-c980-4054-93e9-07723db615ac] +description = "a much larger limit" + +[09c4494d-ff2d-4e0f-8421-f5532821ee12] +description = "three factors" + +[2d0d5faa-f177-4ad6-bde9-ebb865083751] +description = "factors not relatively prime" + +[ece8f2e8-96aa-4166-bbb7-6ce71261e354] +description = "some pairs of factors relatively prime and some not" + +[624fdade-6ffb-400e-8472-456a38c171c0] +description = "one factor is a multiple of another" + +[949ee7eb-db51-479c-b5cb-4a22b40ac057] +description = "much larger factors" + +[41093673-acbd-482c-ab80-d00a0cbedecd] +description = "all numbers are multiples of 1" + +[1730453b-baaa-438e-a9c2-d754497b2a76] +description = "no factors means an empty sum" + +[214a01e9-f4bf-45bb-80f1-1dce9fbb0310] +description = "the only multiple of 0 is 0" + +[c423ae21-a0cb-4ec7-aeb1-32971af5b510] +description = "the factor 0 does not affect the sum of multiples of other factors" + +[17053ba9-112f-4ac0-aadb-0519dd836342] +description = "solutions using include-exclude must extend to cardinality greater than 3" +comment = "decreased the limit input value to fit into Cairo's runtime limitation" diff --git a/exercises/practice/sum-of-multiples/Scarb.toml b/exercises/practice/sum-of-multiples/Scarb.toml new file mode 100644 index 00000000..9c7265c8 --- /dev/null +++ b/exercises/practice/sum-of-multiples/Scarb.toml @@ -0,0 +1,7 @@ +[package] +name = "sum_of_multiples" +version = "0.1.0" +edition = "2024_07" + +[dev-dependencies] +cairo_test = "2.8.2" diff --git a/exercises/practice/sum-of-multiples/src/lib.cairo b/exercises/practice/sum-of-multiples/src/lib.cairo new file mode 100644 index 00000000..960cb7ac --- /dev/null +++ b/exercises/practice/sum-of-multiples/src/lib.cairo @@ -0,0 +1,3 @@ +pub fn sum(limit: u32, factors: Array) -> u32 { + panic!("implement `sum_of_multiples`") +} diff --git a/exercises/practice/sum-of-multiples/tests/sum_of_multiples.cairo b/exercises/practice/sum-of-multiples/tests/sum_of_multiples.cairo new file mode 100644 index 00000000..a60be78a --- /dev/null +++ b/exercises/practice/sum-of-multiples/tests/sum_of_multiples.cairo @@ -0,0 +1,144 @@ +use sum_of_multiples::sum; + +#[test] +fn no_multiples_within_limit() { + let factors: Array = array![3, 5]; + let limit = 1; + let output = sum(limit, factors); + assert_eq!(output, 0); +} + +#[test] +#[ignore] +fn one_factor_has_multiples_within_limit() { + let factors: Array = array![3, 5]; + let limit = 4; + let output = sum(limit, factors); + assert_eq!(output, 3); +} + +#[test] +#[ignore] +fn more_than_one_multiple_within_limit() { + let factors: Array = array![3]; + let limit = 7; + let output = sum(limit, factors); + assert_eq!(output, 9); +} + +#[test] +#[ignore] +fn more_than_one_factor_with_multiples_within_limit() { + let factors: Array = array![3, 5]; + let limit = 10; + let output = sum(limit, factors); + assert_eq!(output, 23); +} + +#[test] +#[ignore] +fn each_multiple_is_only_counted_once() { + let factors: Array = array![3, 5]; + let limit = 100; + let output = sum(limit, factors); + assert_eq!(output, 2318); +} + +#[test] +#[ignore] +fn a_much_larger_limit() { + let factors: Array = array![3, 5]; + let limit = 1000; + let output = sum(limit, factors); + assert_eq!(output, 233168); +} + +#[test] +#[ignore] +fn three_factors() { + let factors: Array = array![7, 13, 17]; + let limit = 20; + let output = sum(limit, factors); + assert_eq!(output, 51); +} + +#[test] +#[ignore] +fn factors_not_relatively_prime() { + let factors: Array = array![4, 6]; + let limit = 15; + let output = sum(limit, factors); + assert_eq!(output, 30); +} + +#[test] +#[ignore] +fn some_pairs_of_factors_relatively_prime_and_some_not() { + let factors: Array = array![5, 6, 8]; + let limit = 150; + let output = sum(limit, factors); + assert_eq!(output, 4419); +} + +#[test] +#[ignore] +fn one_factor_is_a_multiple_of_another() { + let factors: Array = array![5, 25]; + let limit = 51; + let output = sum(limit, factors); + assert_eq!(output, 275); +} + +#[test] +#[ignore] +fn much_larger_factors() { + let factors: Array = array![43, 47]; + let limit = 10000; + let output = sum(limit, factors); + assert_eq!(output, 2203160); +} + +#[test] +#[ignore] +fn all_numbers_are_multiples_of_1() { + let factors: Array = array![1]; + let limit = 100; + let output = sum(limit, factors); + assert_eq!(output, 4950); +} + +#[test] +#[ignore] +fn no_factors_means_an_empty_sum() { + let factors: Array = array![]; + let limit = 10000; + let output = sum(limit, factors); + assert_eq!(output, 0); +} + +#[test] +#[ignore] +fn the_only_multiple_of_0_is_0() { + let factors: Array = array![0]; + let limit = 1; + let output = sum(limit, factors); + assert_eq!(output, 0); +} + +#[test] +#[ignore] +fn the_factor_0_does_not_affect_the_sum_of_multiples_of_other_factors() { + let factors: Array = array![3, 0]; + let limit = 4; + let output = sum(limit, factors); + assert_eq!(output, 3); +} + +#[test] +#[ignore] +fn solutions_using_include_exclude_must_extend_to_cardinality_greater_than_3() { + let factors: Array = array![2, 3, 5, 7, 11]; + let limit = 1500; + let output = sum(limit, factors); + assert_eq!(output, 888403); +}