From 8a6d72fd5b9348ac8cefea478b8acae516c9e8ee Mon Sep 17 00:00:00 2001 From: GideonBature Date: Sat, 26 Apr 2025 05:01:11 +0100 Subject: [PATCH] Implement fizzbuzz in cairo --- .../cairo/scripts/fizzbuzz/.tool-versions | 1 + examples/cairo/scripts/fizzbuzz/Scarb.lock | 6 +++ examples/cairo/scripts/fizzbuzz/Scarb.toml | 11 +++++ .../scripts/fizzbuzz/src/fizz_buzz.cairo | 32 +++++++++++++++ examples/cairo/scripts/fizzbuzz/src/lib.cairo | 4 ++ .../fizzbuzz/src/utils/number_converter.cairo | 41 +++++++++++++++++++ .../fizzbuzz/tests/test_fizzbuzz.cairo | 39 ++++++++++++++++++ 7 files changed, 134 insertions(+) create mode 100644 examples/cairo/scripts/fizzbuzz/.tool-versions create mode 100644 examples/cairo/scripts/fizzbuzz/Scarb.lock create mode 100644 examples/cairo/scripts/fizzbuzz/Scarb.toml create mode 100644 examples/cairo/scripts/fizzbuzz/src/fizz_buzz.cairo create mode 100644 examples/cairo/scripts/fizzbuzz/src/lib.cairo create mode 100644 examples/cairo/scripts/fizzbuzz/src/utils/number_converter.cairo create mode 100644 examples/cairo/scripts/fizzbuzz/tests/test_fizzbuzz.cairo diff --git a/examples/cairo/scripts/fizzbuzz/.tool-versions b/examples/cairo/scripts/fizzbuzz/.tool-versions new file mode 100644 index 0000000..fb22047 --- /dev/null +++ b/examples/cairo/scripts/fizzbuzz/.tool-versions @@ -0,0 +1 @@ +scarb 2.11.2 diff --git a/examples/cairo/scripts/fizzbuzz/Scarb.lock b/examples/cairo/scripts/fizzbuzz/Scarb.lock new file mode 100644 index 0000000..1a04bb1 --- /dev/null +++ b/examples/cairo/scripts/fizzbuzz/Scarb.lock @@ -0,0 +1,6 @@ +# Code generated by scarb DO NOT EDIT. +version = 1 + +[[package]] +name = "fizzbuzz" +version = "0.1.0" diff --git a/examples/cairo/scripts/fizzbuzz/Scarb.toml b/examples/cairo/scripts/fizzbuzz/Scarb.toml new file mode 100644 index 0000000..cdc4735 --- /dev/null +++ b/examples/cairo/scripts/fizzbuzz/Scarb.toml @@ -0,0 +1,11 @@ +[package] +name = "fizzbuzz" +version = "0.1.0" +edition = "2024_07" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html + +[dependencies] + +[dev-dependencies] +cairo_test = "2.11.2" diff --git a/examples/cairo/scripts/fizzbuzz/src/fizz_buzz.cairo b/examples/cairo/scripts/fizzbuzz/src/fizz_buzz.cairo new file mode 100644 index 0000000..9142ba1 --- /dev/null +++ b/examples/cairo/scripts/fizzbuzz/src/fizz_buzz.cairo @@ -0,0 +1,32 @@ +use core::array::ArrayTrait; +use crate::utils::number_converter::u32_to_felt252; + +/// Implementation of the classic FizzBuzz problem. +/// Takes a number n and returns an array of strings from 1 to n, where: +/// - Numbers divisible by 3 are replaced with "Fizz" +/// - Numbers divisible by 5 are replaced with "Buzz" +/// - Numbers divisible by both 3 and 5 are replaced with "FizzBuzz" +/// - Otherwise, the number itself is included as a string +pub fn fizzbuzz(n: u32) -> Array { + let mut result: Array = ArrayTrait::new(); + let mut i: u32 = 1; + + loop { + if i % 3 == 0 && i % 5 == 0 { + result.append('FizzBuzz'); + } else if i % 3 == 0 { + result.append('Fizz'); + } else if i % 5 == 0 { + result.append('Buzz'); + } else { + // Convert integer to string representation using our utility function + result.append(u32_to_felt252(i)); + } + + i += 1; + if i > n { + break; + } + } + result +} diff --git a/examples/cairo/scripts/fizzbuzz/src/lib.cairo b/examples/cairo/scripts/fizzbuzz/src/lib.cairo new file mode 100644 index 0000000..58c2aa6 --- /dev/null +++ b/examples/cairo/scripts/fizzbuzz/src/lib.cairo @@ -0,0 +1,4 @@ +pub mod fizz_buzz; +pub mod utils { + pub mod number_converter; +} diff --git a/examples/cairo/scripts/fizzbuzz/src/utils/number_converter.cairo b/examples/cairo/scripts/fizzbuzz/src/utils/number_converter.cairo new file mode 100644 index 0000000..508d012 --- /dev/null +++ b/examples/cairo/scripts/fizzbuzz/src/utils/number_converter.cairo @@ -0,0 +1,41 @@ +/// Converts a u32 integer to its string representation as felt252. +/// This function works for any u32 value, not just small numbers. +pub fn u32_to_felt252(mut num: u32) -> felt252 { + // Handle 0 separately + if num == 0 { + return '0'; + } + + // For single-digit numbers (1-9), return the ASCII directly + if num < 10 { + return num.into() + '0'; + } + + // For multi-digit numbers, build the string from right to left + let mut reversed_digits: Array = ArrayTrait::new(); + + loop { + let digit = (num % 10).into() + '0'; + reversed_digits.append(digit); + num /= 10; + + if num == 0 { + break; + } + } + + // Convert the array of digits to a single felt252 string + let mut result: felt252 = 0; + + // Start from the end (least significant digit) and build the number + let len = reversed_digits.len(); + let mut i: usize = 0; + while i != len { + let index = len - i - 1; + let digit = *reversed_digits.at(index); + result = result * 256 + digit; // Shift left by 8 bits (1 byte) and add the next digit + i += 1; + } + + result +} diff --git a/examples/cairo/scripts/fizzbuzz/tests/test_fizzbuzz.cairo b/examples/cairo/scripts/fizzbuzz/tests/test_fizzbuzz.cairo new file mode 100644 index 0000000..6f42b5f --- /dev/null +++ b/examples/cairo/scripts/fizzbuzz/tests/test_fizzbuzz.cairo @@ -0,0 +1,39 @@ +use fizzbuzz::fizz_buzz; + +#[test] +fn fizzbuzz_test_n3() { + let mut result = fizz_buzz::fizzbuzz(3); + assert(*result[0] == '1', 'First element should be 1'); + assert(*result[1] == '2', 'Second element should be 2'); + assert(*result[2] == 'Fizz', 'Third element should be Fizz'); +} + +#[test] +fn fizzbuzz_test_n5() { + let result = fizz_buzz::fizzbuzz(5); + assert(*result[0] == '1', 'First element should be 1'); + assert(*result[1] == '2', 'Second element should be 2'); + assert(*result[2] == 'Fizz', 'Third element should be Fizz'); + assert(*result[3] == '4', 'Fourth element should be 4'); + assert(*result[4] == 'Buzz', 'Fifth element should be Buzz'); +} + +#[test] +fn fizzbuzz_test_n15() { + let result = fizz_buzz::fizzbuzz(15); + assert(*result[0] == '1', 'Element at index 0'); + assert(*result[1] == '2', 'Element at index 1'); + assert(*result[2] == 'Fizz', 'Element at index 2'); + assert(*result[3] == '4', 'Element at index 3'); + assert(*result[4] == 'Buzz', 'Element at index 4'); + assert(*result[5] == 'Fizz', 'Element at index 5'); + assert(*result[6] == '7', 'Element at index 6'); + assert(*result[7] == '8', 'Element at index 7'); + assert(*result[8] == 'Fizz', 'Element at index 8'); + assert(*result[9] == 'Buzz', 'Element at index 9'); + assert(*result[10] == '11', 'Element at index 10'); + assert(*result[11] == 'Fizz', 'Element at index 11'); + assert(*result[12] == '13', 'Element at index 12'); + assert(*result[13] == '14', 'Element at index 13'); + assert(*result[14] == 'FizzBuzz', 'Element at index 14'); +}