From 8f1ec3d282c67a2c871c768553494547d0b45380 Mon Sep 17 00:00:00 2001 From: Gonzalo Diaz Date: Thu, 5 Dec 2024 17:17:12 -0300 Subject: [PATCH 1/2] [Hacker Rank]: Warmup: Plus Minus. WIP. --- docs/hackerrank/warmup/plus_minus.md | 80 +++++++++++++++++++ .../exercises/hackerrank/warmup/plus_minus.h | 12 +++ .../src/hackerrank/warmup/plus_minus.c | 65 +++++++++++++++ .../lib/hackerrank/warmup/plus_minus.test.cpp | 37 +++++++++ .../warmup/plus_minus.testcases.json | 7 ++ 5 files changed, 201 insertions(+) create mode 100644 docs/hackerrank/warmup/plus_minus.md create mode 100644 src/lib/exercises/include/exercises/hackerrank/warmup/plus_minus.h create mode 100644 src/lib/exercises/src/hackerrank/warmup/plus_minus.c create mode 100644 src/tests/unit/lib/hackerrank/warmup/plus_minus.test.cpp create mode 100644 src/tests/unit/lib/hackerrank/warmup/plus_minus.testcases.json diff --git a/docs/hackerrank/warmup/plus_minus.md b/docs/hackerrank/warmup/plus_minus.md new file mode 100644 index 0000000..ae601cd --- /dev/null +++ b/docs/hackerrank/warmup/plus_minus.md @@ -0,0 +1,80 @@ +# [Plus Minus](https://www.hackerrank.com/challenges/plus-minus) + +Difficulty: #easy +Category: #warmup + +Given an array of integers, calculate the ratios of its elements +that are positive, negative, and zero. Print the decimal value of +each fraction on a new line with 6 places after the decimal. + +**Note**: This challenge introduces precision problems. +The test cases are scaled to six decimal places, though answers +with absolute error of up to $ 10^{-4} $ are acceptable. + +## Example + +$ arr = [1, 1, 0, -1, -1] $ + +There are $ n = 5 $ elements, two positive, two negative and one zero. +Their ratios are $ 2/5 = 0.400000 $, $ 2/5 = 0.400000 $ and $ 1/5 = 0.200000 $. +Results are printed as: + +```text +0.400000 +0.400000 +0.200000 +``` + +## Function Description + +Complete the plusMinus function in the editor below. +plusMinus has the following parameter(s): + +- int arr[n]: an array of integers + +## Print + +Print the ratios of positive, negative and zero values in the array. +Each value should be printed on a separate line with $ 6 $ digits after +the decimal. The function should not return a value. + +## Input Format + +The first line contains an integer, `n`, the size of the array. +The second line contains `n` space-separated integers that describe `arr[n]`. + +## Constraints + +$ 0 < n \leq 100 $ \ +$ -100 \leq arr[i] \leq 100 $ + +## Output Format + +**Print** the following lines, each to decimals: + +1. proportion of positive values +2. proportion of negative values +3. proportion of zeros + +## Sample Input + +```text +STDIN Function +----- -------- +6 arr[] size n = 6 +-4 3 -9 0 4 1 arr = [-4, 3, -9, 0, 4, 1] +``` + +## Sample Output + +```text +0.500000 +0.333333 +0.166667 +``` + +## Explanation + +There are $ 3 $ positive numbers, negative numbers, and $ 1 $ zero in the array. +The proportions of occurrence are positive: $ 3/6 = 0.500000 $, +negative: $ 2/6 = 0.333333 $ and zeros: $ 1/6 = 0.166667 $. diff --git a/src/lib/exercises/include/exercises/hackerrank/warmup/plus_minus.h b/src/lib/exercises/include/exercises/hackerrank/warmup/plus_minus.h new file mode 100644 index 0000000..4a1526d --- /dev/null +++ b/src/lib/exercises/include/exercises/hackerrank/warmup/plus_minus.h @@ -0,0 +1,12 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +char **HACKERRANK_WARMUP_plusMinusCalculate(int arr_count, int *arr); +void HACKERRANK_WARMUP_plusMinus(int arr_count, int *arr); + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/src/lib/exercises/src/hackerrank/warmup/plus_minus.c b/src/lib/exercises/src/hackerrank/warmup/plus_minus.c new file mode 100644 index 0000000..3de58b8 --- /dev/null +++ b/src/lib/exercises/src/hackerrank/warmup/plus_minus.c @@ -0,0 +1,65 @@ +#include + +/** + * @link Problem definition [[docs/hackerrank/warmup/plus_minus.md]] + */ + +#include // malloc +#include // snprintf + +const int BUFFER_MAX_SIZE = 10; + +char *format_result(double number) { + char *buffer = malloc(BUFFER_MAX_SIZE * sizeof(char)); + + snprintf(buffer, BUFFER_MAX_SIZE, "%0.6lf", number); + return buffer; +} + +char **HACKERRANK_WARMUP_plusMinusCalculate(int arr_count, int *arr) { + int positives = 0; + int negatives = 0; + int zeros = 0; + + int i = 0; + + while (i < arr_count) { + int value = arr[i]; + + if (value > 0) { + positives += 1; + } + if (value < 0) { + negatives += 1; + } + if (value == 0) { + zeros += 1; + } + + i += 1; + } + + double const results[3] = {(double)positives / arr_count, + (double)negatives / arr_count, + (double)zeros / arr_count}; + + int n = 3; // NĂºmero de strings (puede ser arbitrario) + char **answer = malloc(n * sizeof(char *)); // Array de punteros + + for (i = 0; i < n; i++) { + char *formatted = format_result(results[i]); + answer[i] = formatted; + } + + return answer; +} + +void HACKERRANK_WARMUP_plusMinus(int arr_count, int *arr) { + char **output = HACKERRANK_WARMUP_plusMinusCalculate(arr_count, arr); + + for (int i = 0; i < arr_count; i++) { + printf("%s", output[i]); + } + + free(output); +} diff --git a/src/tests/unit/lib/hackerrank/warmup/plus_minus.test.cpp b/src/tests/unit/lib/hackerrank/warmup/plus_minus.test.cpp new file mode 100644 index 0000000..effeeee --- /dev/null +++ b/src/tests/unit/lib/hackerrank/warmup/plus_minus.test.cpp @@ -0,0 +1,37 @@ +#include + +#include +#include +#include +#include + +#include +#include +#include +using json = nlohmann::json; + +TEST_CASE("plusMinus JSON Test Cases", "[hackerrank] [jsontestcase] [warmup]") { + std::filesystem::path cwd = std::filesystem::current_path(); + std::string path = + cwd.string() + "/unit/lib/hackerrank/warmup/plus_minus.testcases.json"; + + INFO("plusMinus JSON test cases FILE: " << path); + + std::ifstream f(path); + json data = json::parse(f); + + for (auto testcase : data) { + auto input_size = static_cast(testcase["input"].size()); + std::vector input_vector = testcase["input"]; + int *input_array = input_vector.data(); + + HACKERRANK_WARMUP_plusMinus(input_size, input_array); + + char **result = + HACKERRANK_WARMUP_plusMinusCalculate(input_size, input_array); + + std::vector result_as_vector(result, result + input_size); + + CHECK(result_as_vector == testcase["expected"]); + } +} diff --git a/src/tests/unit/lib/hackerrank/warmup/plus_minus.testcases.json b/src/tests/unit/lib/hackerrank/warmup/plus_minus.testcases.json new file mode 100644 index 0000000..84bdf98 --- /dev/null +++ b/src/tests/unit/lib/hackerrank/warmup/plus_minus.testcases.json @@ -0,0 +1,7 @@ +[ + { + "title": "test case 0", + "input": [-4, 3, -9, 0, 4, 1], + "expected": ["0.500000", "0.333333", "0.166667"] + } +] From 46a38a0495407f5ce5153769902af8edbed36f34 Mon Sep 17 00:00:00 2001 From: Gonzalo Diaz Date: Sun, 8 Dec 2024 21:32:24 -0300 Subject: [PATCH 2/2] =?UTF-8?q?[Hacker=20Rank]:=20Warmup:=20Plus=20Minus.?= =?UTF-8?q?=20Solved=20=E2=9C=85.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exercises/hackerrank/warmup/plus_minus.h | 6 ++++-- .../exercises/src/hackerrank/warmup/plus_minus.c | 7 ++++--- .../lib/hackerrank/warmup/plus_minus.test.cpp | 15 +++++++++++---- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/lib/exercises/include/exercises/hackerrank/warmup/plus_minus.h b/src/lib/exercises/include/exercises/hackerrank/warmup/plus_minus.h index 4a1526d..6f8f9d1 100644 --- a/src/lib/exercises/include/exercises/hackerrank/warmup/plus_minus.h +++ b/src/lib/exercises/include/exercises/hackerrank/warmup/plus_minus.h @@ -4,8 +4,10 @@ extern "C" { #endif -char **HACKERRANK_WARMUP_plusMinusCalculate(int arr_count, int *arr); -void HACKERRANK_WARMUP_plusMinus(int arr_count, int *arr); +const int HACKERRANK_WARMUP_PLUSMINUS_LIMIT_ANSWERS = 3; + +char **HACKERRANK_WARMUP_plusMinusCalculate(int arr_count, const int *arr); +void HACKERRANK_WARMUP_plusMinus(int arr_count, const int *arr); #ifdef __cplusplus } // extern "C" diff --git a/src/lib/exercises/src/hackerrank/warmup/plus_minus.c b/src/lib/exercises/src/hackerrank/warmup/plus_minus.c index 3de58b8..3468126 100644 --- a/src/lib/exercises/src/hackerrank/warmup/plus_minus.c +++ b/src/lib/exercises/src/hackerrank/warmup/plus_minus.c @@ -16,7 +16,7 @@ char *format_result(double number) { return buffer; } -char **HACKERRANK_WARMUP_plusMinusCalculate(int arr_count, int *arr) { +char **HACKERRANK_WARMUP_plusMinusCalculate(int arr_count, const int *arr) { int positives = 0; int negatives = 0; int zeros = 0; @@ -54,11 +54,12 @@ char **HACKERRANK_WARMUP_plusMinusCalculate(int arr_count, int *arr) { return answer; } -void HACKERRANK_WARMUP_plusMinus(int arr_count, int *arr) { +void HACKERRANK_WARMUP_plusMinus(int arr_count, const int *arr) { char **output = HACKERRANK_WARMUP_plusMinusCalculate(arr_count, arr); - for (int i = 0; i < arr_count; i++) { + for (int i = 0; i < HACKERRANK_WARMUP_PLUSMINUS_LIMIT_ANSWERS; i++) { printf("%s", output[i]); + free(output[i]); } free(output); diff --git a/src/tests/unit/lib/hackerrank/warmup/plus_minus.test.cpp b/src/tests/unit/lib/hackerrank/warmup/plus_minus.test.cpp index effeeee..3070522 100644 --- a/src/tests/unit/lib/hackerrank/warmup/plus_minus.test.cpp +++ b/src/tests/unit/lib/hackerrank/warmup/plus_minus.test.cpp @@ -23,15 +23,22 @@ TEST_CASE("plusMinus JSON Test Cases", "[hackerrank] [jsontestcase] [warmup]") { for (auto testcase : data) { auto input_size = static_cast(testcase["input"].size()); std::vector input_vector = testcase["input"]; - int *input_array = input_vector.data(); - - HACKERRANK_WARMUP_plusMinus(input_size, input_array); + const int *input_array = input_vector.data(); char **result = HACKERRANK_WARMUP_plusMinusCalculate(input_size, input_array); - std::vector result_as_vector(result, result + input_size); + std::vector result_as_vector; + + for (int i = 0; i < HACKERRANK_WARMUP_PLUSMINUS_LIMIT_ANSWERS; i++) { + result_as_vector.emplace_back(result[i]); + free(result[i]); + } + free(result); CHECK(result_as_vector == testcase["expected"]); + + // Just call void function, to collect coverage + HACKERRANK_WARMUP_plusMinus(input_size, input_array); } }