## The challenge

A child is playing with a ball on the nth floor of a tall building. The height of this floor, *h*, is known.

He drops the ball out of the window. The ball bounces (for example), to two-thirds of its height (a bounce of 0.66).

His mother looks out of a window 1.5 meters from the ground.

How many times will the mother see the ball pass in front of her window (including when it’s falling *and* bouncing?

**Three conditions must be met for a valid experiment:**

- Float parameter “h” in meters must be greater than 0
- Float parameter “bounce” must be greater than 0 and less than 1
- Float parameter “window” must be less than h.

*If all three conditions above are fulfilled, return a positive integer, otherwise return -1.*

**Note:**

The ball can only be seen if the height of the rebounding ball is strictly *greater* than the window parameter.

**Examples:**

```
- h = 3, bounce = 0.66, window = 1.5, result is 3
- h = 3, bounce = 1, window = 1.5, result is -1
(Condition 2) not fulfilled).
```

## The solution in C

Option 1:

```
#include <stdio.h>
#include <stdlib.h>
int bouncingBall(double h, double bounce, double window) {
if ((h <= 0) || (window >= h) || (bounce <= 0) || (bounce >= 1))
return -1;
int seen = -1;
while (h > window) {
seen += 2;
h = h * bounce;
}
return seen;
}
```

Option 2:

```
#include <math.h>
int bouncingBall(double h, double bounce, double window) {
if (h <= 0 || bounce <= 0 || bounce >= 1 || window >= h) {
return -1;
}
return 2*ceil(log(window/h)/log(bounce)) - 1;
}
```

Option 3:

```
int bouncingBall(double h, double bounce, double window) {
if(!(h>0 && bounce>0 && bounce<1 && window<h)) return -1;
int times=1; double k;
for(k=h*bounce; k>window; k*=bounce) times+=2;
return times;
}
```

## Test cases to validate our solution

```
#include <stdlib.h>
#include <time.h>
#include <criterion/criterion.h>
extern int bouncingBall (double h, double bounce, double window);
static void testequal(double h, double bounce, double window, int expected) {
int actual = bouncingBall(h, bounce, window);
cr_assert_eq(actual, expected,
"for h = %f, bounce = %f, window = %f\n"
"expected %d, but got %d",
h, bounce, window,
expected, actual
);
}
static int solution (double h, double bounce, double window) {
if ((h <= 0) || (window >= h) || (bounce <= 0) || (bounce >= 1))
return -1;
int seen = -1;
while (h > window) {
seen += 2;
h = h * bounce;
}
return seen;
}
static int randomGen(int a, int b){
int r = rand();
return r % (b - a) + a;
}
Test(bouncingBall, randomTests) {
srand(time(NULL));
enum {N = 30};
const double someheights[N] = {
12, 10.5, 144, 233, 15.25, 61, 98, 15.9, 25.8, 41.8, 67, 109, 17, 28, 46,
7.5, 12.20, 19, 3, 5, 83, 13, 21, 35.5, 57, 92, 14, 24, 39, 6.5
};
const double someBounces[N] = {
0.6, 0.6, 0.6, 0.6, 0.6, 1.1, 9, 1, 0.6, 0.6, 0.6, 0.75, 0.75, 0.75, 0.75,
0.75, 12.20, 0.75, 0.75, 0.83, 0.13, 0.21, 0.35, 0.57, 0.9, 0.14, 0.24, 0.39, 0.65, 0.65
};
const double somewin[N] = {
1.5, 1.5, 1.44, 2.33, 1, 6.1, 9.8, 1.9, 2.8, 4.8, 3, 1.09, 1.7, 2.8, 46, 7.5,
12.20, 1.9, 3, 5, 0.83, 1.3, 2.1, 3.5, 0.57, 0.92, 1.4, 2.4, 3.9, 6.5
};
for (int k = 0; k < 100; k++) {
int i = randomGen(0, N - 1);
double h = someheights[i];
double b = someBounces[i];
double w = somewin[i];
testequal(h, b, w, solution(h, b, w));
}
}
Test(bouncingBall, sampleTests) {
testequal(2, 0.5, 1.0, 1);
testequal(3, 0.66, 1.5, 3);
testequal(30, 0.66, 1.5, 15);
testequal(30, 0.75, 1.5, 21);
testequal(30, 0.4, 10, 3);
testequal(40, 0.4, 10, 3);
testequal(10, 0.6, 10, -1);
testequal(40, 1, 10, -1);
testequal(-5, 0.66, 1.5, -1);
testequal(5, -1, 1.5, -1);
testequal(4, 0.25, 1.0, 1);
}
```