Avistamientos de la pelota
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.
Definir la función
1 |
numeroAvistamientos :: Double -> Double -> Double -> Integer |
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,
1 2 3 4 5 6 7 |
numeroAvistamientos 3 0.66 1.5 == 3 numeroAvistamientos 30 0.66 1.5 == 15 numeroAvistamientos (-3) 0.66 1.5 == -1 numeroAvistamientos 3 (-1) 1.5 == -1 numeroAvistamientos 3 2 1.5 == -1 numeroAvistamientos 3 0.5 (-1) == -1 numeroAvistamientos 3 0.5 4 == -1 |
Soluciones
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
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.»
En Python
En Julia
En Maxima con la fórmula:
Existen consideraciones prácticas de interés (podemos entender el problema como contar las veces que un detector óptico detecta la bola) pero como mínimo, si hay un máximo local en w, entonces no debería contarse dos veces ese rebote.
Supongamos que nuestra pelota tiene radio p (que puede ser nulo), entonces (usamos Data.Ratio para evitar fácilmente imprecisión en logaritmos):
Entonces es:
Uhm… ¿será posible que haya puesto ese código dos veces? xD (menos mal que no lo borré) bueno, ahí va
(Ahora lo veo arriba otra vez ¡pero al revés! xD xD que lío)
En Mathematica con la definición de Antonio:
En Mathematica con la definición de Fernando: