Monday, January 09, 2012

Concurso para programadores reales


Se supone que los programadores reales, los de verdad, son tan capaces que casi casi no necesitan herramientas de software para sus labores. Esto por supuesto es una exageración que se ha llevado ya al extremo del folklore urbano (*) en esta rama de la ciencia.

Pues bien, Facebook lanzó la segunda versión de su concurso "hacker-cup", para aquellos interesados en pasar a la historia como uno de los mejores programadores del planeta. El concurso está abierto a todo aquel que quiera participar, en cualquier parte del mundo y hasta donde he entendido no hay ninguna restricción sobre qué lenguaje de programación usar.

La justa se hará en sucesivas fechas, en las cuales se irá obteniendo a los ganadores. Por ejemplo, en la primera etapa se plantean tres problemas., Si se resuelve al menos uno, se pasa a la siguiente prueba. ¿Qué tipo de pruebas se exigen en el concurso? No lo sé, pero he aquí un ejemplo del año pasado: se trata de hallar dos números enteros, del 1 al cien, que pongan todas las posibles combinaciones de estos números en la forma A^2 + B^2.

Por ejemplo, 25 puede ponerse como 3^2 + 4^2 o bien, 0^2 + 5^2.

No pienso entrar en el concurso, porque francamente no tengo tiempo y seguro hay programadores mil veces más clavados que yo. Sin embargo, este pequeño problema, se me ocurre, se puede resolver fácilmente en Prolog. He aquí mi código, el cual probaré a la brevedad:

predicates
   suma (integer,integer,integer)
   num(integer)
   prueba

clauses
    suma(R, A, B) :- R = (A^2) + (B^2).
    num(0).
    num(1).
    num(2).
    num(3).
        .
        .
        .
    num(99).
    num(100).

    prueba :-
      num(A),
      num(B),
      R = A,         
      suma(R,A,B),
      write("Los valores de los números son ", A, " y  ", B), nl,
      fail.

 goal
    prueba.         


Ahora que pruebe mi código pondré las reflexiones del caso.
_____
(*) El término "programador real" describe a esos programadores "duros" que prácticamente reniegan de todas las herramientas y lenguajes modernos para hacerlo todo desde una manera más directa y efectiva, muchas veces relacionada con el hardware. El arquetipo de los programadores reales es sin duda Mel Kaye, de la McBee Computer Corporation, quien está inmortalizado en "La Historia de Mel", en la cual se dice que "escribió en código de máquina, sin adornos, todo su código en el inescrutable código hexadecimal. Directamente".

7 comments:

Emmanuel Garces said...

Con Mathematica, una solución sería esta:

In[38]:= Flatten[Table[With[{sum=Last/@Select[Table[IntegerQ[Sqrt[i]]&&IntegerQ[Sqrt[n-i]]->ToString[Sqrt[i]]~~"^2 + "~~ToString[Sqrt[n-i]]~~"^2",{i,0,n}],First[#]&]},If[Length[sum]>0,Row[{ToString[n]~~" = ",Row[Last/@Select[Table[IntegerQ[Sqrt[i]]&&IntegerQ[Sqrt[n-i]]->ToString[Sqrt[i]]~~"^2 + "~~ToString[Sqrt[n-i]]~~"^2",{i,0,n}],First[#]&], ", "]}],{}]],{n,1,100}]]//Column
Out[38]= 1 = 0^2 + 1^2, 1^2 + 0^2
2 = 1^2 + 1^2
4 = 0^2 + 2^2, 2^2 + 0^2
5 = 1^2 + 2^2, 2^2 + 1^2
8 = 2^2 + 2^2
9 = 0^2 + 3^2, 3^2 + 0^2
10 = 1^2 + 3^2, 3^2 + 1^2
13 = 2^2 + 3^2, 3^2 + 2^2
16 = 0^2 + 4^2, 4^2 + 0^2
17 = 1^2 + 4^2, 4^2 + 1^2
18 = 3^2 + 3^2
20 = 2^2 + 4^2, 4^2 + 2^2
25 = 0^2 + 5^2, 3^2 + 4^2, 4^2 + 3^2, 5^2 + 0^2
26 = 1^2 + 5^2, 5^2 + 1^2
29 = 2^2 + 5^2, 5^2 + 2^2
32 = 4^2 + 4^2
34 = 3^2 + 5^2, 5^2 + 3^2
36 = 0^2 + 6^2, 6^2 + 0^2
37 = 1^2 + 6^2, 6^2 + 1^2
40 = 2^2 + 6^2, 6^2 + 2^2
41 = 4^2 + 5^2, 5^2 + 4^2
45 = 3^2 + 6^2, 6^2 + 3^2
49 = 0^2 + 7^2, 7^2 + 0^2
50 = 1^2 + 7^2, 5^2 + 5^2, 7^2 + 1^2
52 = 4^2 + 6^2, 6^2 + 4^2
53 = 2^2 + 7^2, 7^2 + 2^2
58 = 3^2 + 7^2, 7^2 + 3^2
61 = 5^2 + 6^2, 6^2 + 5^2
64 = 0^2 + 8^2, 8^2 + 0^2
65 = 1^2 + 8^2, 4^2 + 7^2, 7^2 + 4^2, 8^2 + 1^2
68 = 2^2 + 8^2, 8^2 + 2^2
72 = 6^2 + 6^2
73 = 3^2 + 8^2, 8^2 + 3^2
74 = 5^2 + 7^2, 7^2 + 5^2
80 = 4^2 + 8^2, 8^2 + 4^2
81 = 0^2 + 9^2, 9^2 + 0^2
82 = 1^2 + 9^2, 9^2 + 1^2
85 = 2^2 + 9^2, 6^2 + 7^2, 7^2 + 6^2, 9^2 + 2^2
89 = 5^2 + 8^2, 8^2 + 5^2
90 = 3^2 + 9^2, 9^2 + 3^2
97 = 4^2 + 9^2, 9^2 + 4^2
98 = 7^2 + 7^2
100 = 0^2 + 10^2, 6^2 + 8^2, 8^2 + 6^2, 10^2 + 0^2

Morsa said...

Muy bueno, tocayo... De hecho, en mi códig R= A está mal. Hay que hacer un loop del 1 al 100 y hacer la prueba para cada número. Lo reprogramaré al rato.

saludos
Manuel

Geomod said...

Mmm no entendí muy bien el problema, ¿se trata de realizar la descomposición de los enteros del 1 al 100 en suma de cuadrados?

Morsa said...

Si, tomas los números de 0 al 100 y tratas de encontrar dos enteros, de 0 a 100 también, que cumplan con que el número que buscas es la suma de los cuadrados de esos dos enteros.

saludos
Manuel

Anuar said...

En java se me ocurre:
Son tres for anidados, el primero recorre la lista de 0 a 100; el segundo y el tercero del 0 al 10, y si la suma de los cuadrados resulta el numerito se imprimen.
Faltaria omitir las repeticiones, excepcionar los primos y detalles.

for(int res = 0; res <= 100; res++{
System.out.println(res + " se puede ver como la suma de los cuadrados de:");
for(int a = 0; a <= 10; a++){
for(int b = 0; b <= 10; b++){
if(a*a + b*b == res)
System.out.println(a + " y " + b);
}
}
}

Krazy Vivaldon said...

¿Quieres soluciones elegantes?
Como ves esta en Haskell:

busca :: Int -> [(Int,Int)]
busca n = [(a,b) | a <- [1..100], b <- [1..100], n == (a*a) + (b*b)]

No hace falta explicar tanto que es lo que hace, ya que es un lenguaje parecido al matemático. Sólo haría falta quitar repeticiones (que de hecho es muy sencillo)

Morsa said...

Por algo, Vivaldi, eres mi ayudante. Muy elegante tu solución. Haskell no me gusta por muchas razones, pero para estas cosas se pinta solo.