0votos

Emulando a Dik T. Winter en C#

por josejuan hace 5 años

Traslación directa de la de javascript. En C# corre mucho más rápido (x29) que la de F# (algo debe haber mal ahí). Ésta corre mejor con x64 que `Any CPU` (debería, puesto que se usan longs). En un Athlon a 2Ghz, n=9 toma 62mS.

Un número de N dígitos es narcisista si la suma de las potencias N-ésimas de sus dígitos es él mismo.

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
class Program { 
 
    static IEnumerable<long> Narcisistas(int N) { 
        var P = Enumerable.Range(0, 10).Select(i => (long) Math.Pow(i, N)).ToArray(); 
        var R = new List<long>(); 
 
        Func<long, bool> isN = z => { 
            long q = z, s = 0, r; 
            do { 
                q = Math.DivRem(q, 10, out r); 
                s += P [r]; 
            } while(q > 0); 
            return z == s; 
        }; 
 
        Action<long, long, long> C = null; 
        C = (acc, d, ds) => { 
            if(d == 10) { 
                if(isN(acc)) 
                    R.Add(acc); 
            } else { 
                long p = P [d], b = d + 1, a = acc, n = 0, dss = ds; 
                while(n <= ds) { 
                    C(a, b, dss); 
                    n++; 
                    a += p; 
                    dss--; 
        }; 
 
        C(0, 0, N); 
        var L = (long) Math.Pow(10, N - 1); 
        return R.Where(z => z >= L).Distinct(); 
 
    static void Main(string [] args) { 
        var t0 = DateTime.UtcNow; 
        var ns = Narcisistas(int.Parse(args [0])); 
        var t1 = DateTime.UtcNow; 
        ns.ToList().ForEach(Console.WriteLine); 
        Console.WriteLine("{0} mS", (t1 - t0).TotalMilliseconds); 
 
3 comentarios
0votos

Escrito por jmgomez hace 5 años

Qué exagerado! Por defecto let hace algo similar a "static" no? (los métodos estáticos son como 5 veces más rápidos en .net). De todas formas, viendo el source de FSharp no me extrañaría que algo "común" se ejecute muuucho más lento, no es que lo yo lo hubiera hecho mejor xD Pero no estoy seguro de que la implementación de ciertas cosas del lenguaje sea la mejor, es lo que tienen los wrappers vs implementación directa :S
0votos

Escrito por josejuan hace 5 años

La diferencia es enorme lo mires por donde lo mires (la misma implementación). Realmente yo esperaba que la versión lenta fuera la de mono.

En cuanto a "es lo que tienen los wrappers" no tiene porqué, en teoría sí, claro, pero en la práctica hay muchos buenos compiladores que usan otros lenguajes intermedios (entre ellos Haskell).

Por cierto, mi ultima versión de haskell queda a la par en rendimiento que la de C# ;)
0votos

Escrito por jmgomez hace 5 años

EL IL generado en CSharp son 99 líneas mientras que el de FSharp son 556 :-S

Comenta la solución

Tienes que identificarte para poder publicar tu comentario.