Un niño está jugando con una pelota en el noveno piso de un edificio alto. La altura de este piso, h, es conocida. Deja caer la pelota por la ventana. La pelota rebota una r-ésima parte de su altura (por ejemplo, dos tercios de su altura). Su madre mira por una ventana a w metros del suelo (por ejemplo, a 1.5 metros). ¿Cuántas veces verá la madre a la pelota pasar frente a su ventana incluyendo cuando está cayendo y rebotando?
Se deben cumplir tres condiciones para que el experimento sea válido:
La altura “h” debe ser mayor que 0
El rebote “r” debe ser mayor que 0 y menor que 1
La altura de la ventana debe ser mayor que 0 y menor que h.
tal que (numeroAvistamientos h r v) es el número de avistamientos de la pelota si se cumplen las tres condiciones anteriores y es -1 en caso contrario. Por ejemplo,
import Data.List (genericLength)-- 1ª solución-- ============
numeroAvistamientos ::Double->Double->Double->Integer
numeroAvistamientos h r v
| adecuados h r v =2* n -1|otherwise=-1where n = genericLength (takeWhile(>=v)(iterate(*r) h))-- (adecuados h r v) se verifica si los datos cumplen las condiciones-- para que el experimento sea válido.
adecuados ::Double->Double->Double->Bool
adecuados h r v =
h >0&&0< r && r <1&&0< v && v < h
-- 2ª solución-- ===========
numeroAvistamientos2 ::Double->Double->Double->Integer
numeroAvistamientos2 h r v
| adecuados h r v =2+ numeroAvistamientos2 (h * r) r v
|otherwise=-1-- 3ª solución
numeroAvistamientos3 ::Double->Double->Double->Integer
numeroAvistamientos3 h r v
| adecuados h r v =1+2*floor(logBase r (v / h))|otherwise=-1
import Data.List (genericLength)
-- 1ª solución
-- ============
numeroAvistamientos :: Double -> Double -> Double -> Integer
numeroAvistamientos h r v
| adecuados h r v = 2 * n - 1
| otherwise = -1
where n = genericLength (takeWhile (>=v) (iterate (*r) h))
-- (adecuados h r v) se verifica si los datos cumplen las condiciones
-- para que el experimento sea válido.
adecuados :: Double -> Double -> Double -> Bool
adecuados h r v =
h > 0 && 0 < r && r < 1 && 0 < v && v < h
-- 2ª solución
-- ===========
numeroAvistamientos2 :: Double -> Double -> Double -> Integer
numeroAvistamientos2 h r v
| adecuados h r v = 2 + numeroAvistamientos2 (h * r) r v
| otherwise = -1
-- 3ª solución
numeroAvistamientos3 :: Double -> Double -> Double -> Integer
numeroAvistamientos3 h r v
| adecuados h r v = 1 + 2 * floor (logBase r (v / h))
| otherwise = -1
Otras soluciones
Se pueden escribir otras soluciones en los comentarios.
El código se debe escribir entre una línea con <pre lang="haskell"> y otra con </pre>
Pensamiento
“Los patrones del matemático, como los del pintor o el poeta deben ser hermosos; las ideas, como los colores o las palabras deben encajar de manera armoniosa. La belleza es la primera prueba: no hay lugar permanente en este mundo para las matemáticas feas.”
(graficas xs) dibuja las gráficas de los números de dígitos del factorial de k (para k en xs) y de la recta y = 5.5 x. Por ejemplo, (graficas [0,500..10^6]) dibuja
Nota: Este ejercicio está basado en el problema How many digits? de Kattis en donde se impone la restricción de calcular, en menos de 1 segundo, el número de dígitos de los factoriales de 10.000 números del rango [0,1.000.000].