Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions docs/hackerrank/warmup/plus_minus.md
Original file line number Diff line number Diff line change
@@ -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 $.
14 changes: 14 additions & 0 deletions src/lib/exercises/include/exercises/hackerrank/warmup/plus_minus.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

#ifdef __cplusplus
extern "C" {
#endif

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"
#endif
66 changes: 66 additions & 0 deletions src/lib/exercises/src/hackerrank/warmup/plus_minus.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include <exercises/hackerrank/warmup/plus_minus.h>

/**
* @link Problem definition [[docs/hackerrank/warmup/plus_minus.md]]
*/

#include <stdio.h> // malloc
#include <stdlib.h> // 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, const 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, const int *arr) {
char **output = HACKERRANK_WARMUP_plusMinusCalculate(arr_count, arr);

for (int i = 0; i < HACKERRANK_WARMUP_PLUSMINUS_LIMIT_ANSWERS; i++) {
printf("%s", output[i]);
free(output[i]);
}

free(output);
}
44 changes: 44 additions & 0 deletions src/tests/unit/lib/hackerrank/warmup/plus_minus.test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include <catch2/catch_test_macros.hpp>

#include <exercises/hackerrank/warmup/plus_minus.h>
#include <iostream>
#include <stdexcept>
#include <vector>

#include <filesystem>
#include <fstream>
#include <nlohmann/json.hpp>
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<int>(testcase["input"].size());
std::vector<int> input_vector = testcase["input"];
const int *input_array = input_vector.data();

char **result =
HACKERRANK_WARMUP_plusMinusCalculate(input_size, input_array);

std::vector<std::string> 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);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[
{
"title": "test case 0",
"input": [-4, 3, -9, 0, 4, 1],
"expected": ["0.500000", "0.333333", "0.166667"]
}
]
Loading