0votos

numero aleatorio con sumas de sus digitos en Haskell

por josejuan hace 4 años

Sencillo y bonito problema.

lista de numeros

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import Criterion.Main 
import Data.Vector.Unboxed ((!)) 
import qualified Data.Vector.Unboxed as U 
import qualified Data.List as L 
 
-- Solución ingenua (la de "sin pensar") 
naiveSolution :: Int -> Bool 
naiveSolution n | n < 0     = False 
                | n > 100   = False 
                | otherwise = (a + b + c) == 10 
                              where a = (n `div` 100) `mod` 10 
                                    b = (n `div`  10) `mod` 10 
                                    c = (n `div`   1) `mod` 10 
 
-- (6.6 veces más rápida que la primera) 
-- Analizando un poco el problema se ve que las soluciones son equidistantes 
bestLowMemory :: Int -> Bool 
bestLowMemory n = n > 10 && n < 100 && (n - 19) `mod` 9 == 0 
 
-- (10.25 veces más rápida que la primera y 1.56 más que la segunda) 
-- En cualquier caso, este tipo de problemas son siempre más rápidos precalculando 
bestFaster :: Int -> Bool 
bestFaster n = c!n 
               where c :: U.Vector Bool 
                     c = U.fromList $ map naiveSolution [0..100] -- un poquito mejor usando 
                                                                 -- bestLowMemory, claro 
 
 
-- === comparando soluciones =========================================== 
 
-- Se usa para calcular el coste base de hacer un test 
nullSolution :: Int -> Bool 
nullSolution _ = True 
 
-- Un test cualquiera 
test :: (Int -> Bool) -> Int 
test f = L.foldl' (\c n -> if f n then c + 1 else c) 0 $ take 1000000 $ cycle [0..100] 
 
-- Con Criterion 
main = defaultMain [ 
  bgroup "Sum10" [ bench "Null"        $ whnf test nullSolution 
                 , bench "Naive"       $ whnf test naiveSolution 
                 , bench "Low memory"  $ whnf test bestLowMemory 
                 , bench "Faster"      $ whnf test bestFaster 
 
{-- 
 
El resultado de la ejecución es: 
 
benchmarking Sum10/Null 
time                 8.030 ms   (7.885 ms .. 8.198 ms) 
                     0.998 R²   (0.997 R² .. 1.000 R²) 
mean                 7.936 ms   (7.884 ms .. 8.034 ms) 
std dev              193.8 μs   (105.2 μs .. 324.4 μs) 
 
benchmarking Sum10/Naive 
time                 70.71 ms   (70.61 ms .. 70.85 ms) 
                     1.000 R²   (1.000 R² .. 1.000 R²) 
mean                 70.73 ms   (70.67 ms .. 70.80 ms) 
std dev              105.5 μs   (79.32 μs .. 139.0 μs) 
 
benchmarking Sum10/Low memory 
time                 17.54 ms   (17.45 ms .. 17.66 ms) 
                     1.000 R²   (1.000 R² .. 1.000 R²) 
mean                 17.45 ms   (17.42 ms .. 17.49 ms) 
std dev              88.67 μs   (67.47 μs .. 134.9 μs) 
 
benchmarking Sum10/Faster 
time                 14.16 ms   (14.07 ms .. 14.30 ms) 
                     1.000 R²   (0.999 R² .. 1.000 R²) 
mean                 14.06 ms   (14.02 ms .. 14.14 ms) 
std dev              157.3 μs   (100.8 μs .. 275.4 μs) 
 
 
 
Que pasando al origen los tiempos quedan: 
 
    Naive       70.73 - 7.936 = 62.794 ms 
    Low memory  17.45 - 7.936 =  9.514 ms 
    Faster      14.06 - 7.936 =  6.124 ms 
 
    Naive / Low memory  =  6.60 speed up 
    Naive / Faster      = 10.25 speed up 
    Low memory / Faster =  1.56 speed up 
 
--} 
4 comentarios
0votos

Escrito por rblack hace 4 años

que buen lenguaje todavía no lo he ocupado se ve interesante.
0votos

Escrito por rblack hace 4 años

hola josejuan,
mira tengo una duda, tengo esto en java que es el numero aleatorio pero nose como guardarlo si me puedes ayudar porfavor ??

import java.util.Random;
public class trabajo {
public static void main (String []args ){

Random mono = new Random ();

int rbd=0,hola=0,a,b,c=0,max=100,min=10;

for(a=0;a<5;a++){

rbd= (int) (Math.random()* (max -min +1)+min);
System.out.println(rbd);

}


hola=rbd; //// mi pregunta es como guardar todo los números aleatorios para poder sumarlos después y dejar //solo los números que sumen 10
0votos

Escrito por josejuan hace 4 años

"mi pregunta es como guardar todo los números aleatorios para poder sumarlos después y dejar //solo los números que sumen 10"

Hola @rblack, para hacer lo que pides, debes crear primero algún sitio en el que guardar los números aleatorios, hay varias formas: vectores, listas, ... una forma fácil en java usando arrays puede ser:
int[] anArray;
// allocates memory for 10 integers
anArray = new int[10];

Allí puedes meter cada rbd (ej. anArray[a] = rbd;).

Para dejar los que sólo sumen 10 no es bueno usar un array, porque para crear un array necesitas saber cuantos elementos necesitas, pero puedes usar una lista.

;)
0votos

Escrito por rblack hace 4 años

muchas gracias josejuan :)

Comenta la solución

Tienes que identificarte para poder publicar tu comentario.