El reto
Un niño está jugando con una pelota en el piso n de un edificio alto. La altura de este piso, hes conocida.
Deja caer la pelota por la ventana. La pelota rebota (por ejemplo), a dos tercios de su altura (un rebote de 0,66).
Su madre mira por una ventana a 1,5 metros del suelo.
¿Cuántas veces verá la madre pasar la pelota frente a su ventana (incluso cuando está cayendo y ¿rebote?
Se deben cumplir tres condiciones para que un experimento sea válido:
- El parámetro flotante “h” en metros debe ser mayor que 0
- El parámetro flotante “rebote” debe ser mayor que 0 y menor que 1
- El parámetro flotante “ventana” debe ser menor que h.
Si se cumplen las tres condiciones anteriores, devuelva un número entero positivo; de lo contrario, devuelva -1.
Nota:
La pelota solo se puede ver si la altura de la pelota que rebota es estrictamente mayor que que el parámetro de la ventana.
Ejemplos:
- h = 3, bounce = 0.66, window = 1.5, result's 3
- h = 3, bounce = 1, window = 1.5, result's -1
(Situation 2) not fulfilled).
La solución en C
Opción 1:
#embody <stdio.h>
#embody <stdlib.h>
int bouncingBall(double h, double bounce, double window) {
if ((h <= 0) || (window >= h) || (bounce <= 0) || (bounce >= 1))
return -1;
int seen = -1;
whereas (h > window) {
seen += 2;
h = h * bounce;
}
return seen;
}
Opcion 2:
#embody <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;
}
Opción 3:
int bouncingBall(double h, double bounce, double window) {
if(!(h>0 && bounce>0 && bounce<1 && window<h)) return -1;
int instances=1; double okay;
for(okay=h*bounce; okay>window; okay*=bounce) instances+=2;
return instances;
}
Casos de prueba para validar nuestra solución
#embody <stdlib.h>
#embody <time.h>
#embody <criterion/criterion.h>
extern int bouncingBall (double h, double bounce, double window);
static void testequal(double h, double bounce, double window, int anticipated) {
int precise = bouncingBall(h, bounce, window);
cr_assert_eq(precise, anticipated,
"for h = %f, bounce = %f, window = %fn"
"anticipated %d, however bought %d",
h, bounce, window,
anticipated, precise
);
}
static int answer (double h, double bounce, double window) {
if ((h <= 0) || (window >= h) || (bounce <= 0) || (bounce >= 1))
return -1;
int seen = -1;
whereas (h > window) {
seen += 2;
h = h * bounce;
}
return seen;
}
static int randomGen(int a, int b){
int r = rand();
return r % (b - a) + a;
}
Check(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 okay = 0; okay < 100; okay++) {
int i = randomGen(0, N - 1);
double h = someheights(i);
double b = someBounces(i);
double w = somewin(i);
testequal(h, b, w, answer(h, b, w));
}
}
Check(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);
}