Vientos de Libertad el blog de Juanjo Conti – en borrador permanente – abstracto, lúdico y digital
Browsing all posts in: Problemas de programación

21 días – Aprendé a programar en 10 años – ES_AR

Diciembre 27

Esta es una traducción al español Argentino del famoso artículo de Peter Norvig Teach Yourself Programming in Ten Years. Hay una versión en español de España pero está desactualizada. Creo que es un artículo que cualquiera que gusta de la programación debería leer.

Aprendé a programar en diez años

Por Peter Norvig.  Teach Yourself Programming in Ten Years.

Traducción libre al español Argentino por Juan José Conti – actualizado con el original a Diciembre de 2009
Originalmente basado en la versión de Calos Rueda

¿Por qué están todos tan apurados?

Entrá a cualquier librería y vas a encontrar  Aprende Java en 7 Días y demás variaciones interminables ofreciendo enseñar Visual Basic, Windows, Internet, etc., en unos pocos días u horas. Yo hice la siguiente búsqueda avanzada (power search) en Amazon.com :

pubdate: after 1992 and title: days and (title: learn or title: teach yourself)

y obtuve 248 ítems de resultado. Los primeros 78 fueron libros de computación (el número 79 era Aprende Bengali en 30 días Learn Bengali in 30 days ). Remplacé “days” (días) por “hours” (horas) y sorprendentemente obtuve resultados similares: 253 libros más, con 77 libros de computación seguidos de Aprende Gramática y Estilo en 24 horas (Teach Yourself Grammar and Style in 24 Hours) en el número 78. Del total de los primeros 200, el  96% fueron libros de computación.

La conclusión es que, o bien la gente está muy apurada por saber de computadoras, o bien las computadoras son algo fabulosamente fácil de aprender, más que cualquiera otra cosa. No hay libros sobre cómo aprender Beethoven, o Física Cuántica, o incluso Estética Perruna en pocos días. Felleisen et al. asienten esta tendencia en su libro How to Design Programs, cuando dicen “La programación mala es fácil. Los idioitas pueden aprenderla en 21 días, incluso si son tontos” (original: “Bad programming is easy. Idiots can learn it in 21 days, even if they are dummies.)

Analicemos lo que podría significar un título como Aprende C++ en Tres Días (Learn C++ in Three Days):

  • Aprende: En 3 días no vas a tener tiempo de escribir varios programas significativos, y de aprender de tus aciertos y errores con ellos. No vas a tener tiempo de trabajar con un programador experimentado y entender lo que es vivir en un ambiente de C++. En resumen, no vas a tener tiempo de aprender mucho. Así que esos libros sólo podrán lograr una familiaridad superficial, no un entendimiento profundo. Como dijo Alexander Pope, poco aprendizaje es una cosa peligrosa.
  • C++: En 3 días puedes aprender la sintaxis de C++ (si ya sabés otro lenguaje), pero no vas a poder aprender mucho sobre cómo usar el lenguaje. En síntesis, si fueras, digamos, un programador Basic, podrías aprender a escribir programas en el estilo de Basic usando la sintaxis de C++, pero no aprenderías para qué C++ es realmente bueno (o malo). Entonces ¿cuál es el punto? Alan Perlis dijo alguna vez: “Un lenguaje que no afecte tu manera de pensar acerca de la programación, no merece ser aprendido”. Un objetivo posible es que tienes que aprender un poco de C++ (o más probablemente, algo como Visual Basic o JavaScript) porque necesitas tener una interface con una herramienta existente para realizar una cierta tarea. Pero entonces no estás aprendiendo cómo programar; estás aprendiendo
    cómo realizar esa tarea.
  • en Tres Días: Desafortunadamente, no son suficientes, como se describe en la siguiente sección.

Read the rest of this entry »

Primera vez con Ruby

Diciembre 6

El viernes por la tarde salí del trabajo y me fuí a escuchar la charla de César Ballardini, El modelo de objetos de Ruby, reflexiones sobre la reflexión. La daba en el marco del evento acts_as_rubylit, el cual se llevó a cabo en la Facultad de Ingeniería y Ciencias Hídricas, Universidad Nacional del Litoral de la ciudad de Santa Fe.

Nunca antes vi nada de Ruby. Bueno, casi, pero la última vez no pasé del Hola Mundo!juanjo_ruby_800

César empezó su charla explicando la Paradoja de Blub, de Paul Graham. Blub es un lenguaje de programación hipotético. No es el lenguaje de programación más poderoso, pero tampoco es Cobol o lenguaje de máquina. Un programador Blub está parado más o menos en el medio de la ladera de una montaña; hacia abajo están los lenguajes menos poderosos que Blub, él se da cuenta de esto, por supuesto, a todos esos lenguajes le faltan distintas características que nuestro programador usa en Blub para resolver sus problemas. En cambio, cuando mira para arriba (y ve lenguajes más poderosos que Blub), en realidad no se da cuenta que está mirando hacia arriba, simplemente piensa que está mirando a unos locos, hippies de pelos parados haciendo cosas raras. Cuando los programadores que están más arriba en la montaña miran hacia Blub se pregunta, ¿cómo puede alguien estar usando Blub? Ni siquiera tiene la funcionalidad X tan útil para resolver Y!

Por inducción se concluye que solo el programador que esté en la punta de la montaña, es decir el que conoce el lenguaje más poderoso, es capaz de distinguir las distintas posibilidades que se tienen con diferentes lenguajes. El programador Blub no puede verlo, por lo que solo sabe pensar en Blub, no se a enfrentado a problemas que le permitan pensar diferente.

La moraleja de la historia es que uno debería aprender lenguajes que lo obliguen a cambiar su forma de pensar y de resolver problemas (Alan J. Perlis).

Con esto terminó la primera parte de la charla, luego César hizo una explicación de pizarrón sobre qué es la Programación Orientada a Objetos ( y escribió con su fibrón: un objeto tiene Identidad, encapsula Estado y define Comportamiento). Según César, es un error que en la enseñanza de la POO se empiece por las Clases. ¿En qué parte de “Programación Orientada a Objetos” dice “Clase”? Las clases son solo una forma de crear objetos, pero hay muchas otras. Por ejemplo, existen muchos lenguajes OO basados en prototipos, como JavaScript.

Después de haber shockeado a la audiencia desarrollando estas dos ideas en un tono casi de declaración de principios, estábamos listos para ver cómo el Modelo de Objetos de Ruby podía cambiar nuestra forma de pensar.
Lo que sigue no son los ejemplos exactos que desrrolló César con su notebook, solo los que recuerdo. Mezclo los recuerdos de su sesión interactiva de Ruby con mi propio camino de aprendizaje, que arranca ni siquiera teniendo el intérprete instalado :)
Read the rest of this entry »

Ejercicio 16 – proyecto Euler

Septiembre 18

De vez en cuando se me da por hacer saries de posts en el blog. Sagas. Una de las últimas fue la saga sobre resoluciones a problemas del proyecto Euler. Lo que intentaba era resolverlos con alguna característica interesante de Python y luego explicarla. Luego de los primeros, los ejercisios se volvieron más matemáticos y encontraba menos cosas interesantes de Python que comentar, así que dejé de postear mis soluciones. Acabo de encontrar esta entre mis archivos y creo que tiene algo de originalidad como para merecer ser publicada:

¿Cuál es la suma de los dígitos del número 2^(1000)?

>>> 2**1000
107150860718626732094842504906000[algunos números fueron intencionalmente borrados]
>>> a = 2**1000
>>> sum((int(x) for x in list(str(a))))
1366

¿A alguien se le ocurre otra forma?

Euler 8 (Python)

Julio 2

Enunciado 8

Encontrar el mayor producto de cinco dígitos consecutivos en este número de 100 dígitos:

73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450

Solución

>>> b = 7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450
>>> s = str(b)
>>> s
'7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450'
>>> l = list(s)
>>> l
['7', '3', '1', '6', '7', '1', '7', '6', '5', '3', '1', '3', '3', '0', '6', '2', '4', '9', '1', '9', '2', '2', '5', '1', '1', '9', '6', '7', '4', '4', '2', '6', '5', '7', '4', '7', '4', '2', '3', '5', '5', '3', '4', '9', '1', '9', '4', '9', '3', '4', '9', '6', '9', '8', '3', '5', '2', '0', '3', '1', '2', '7', '7', '4', '5', '0', '6', '3', '2', '6', '2', '3', '9', '5', '7', '8', '3', '1', '8', '0', '1', '6', '9', '8', '4', '8', '0', '1', '8', '6', '9', '4', '7', '8', '8', '5', '1', '8', '4', '3', '8', '5', '8', '6', '1', '5', '6', '0', '7', '8', '9', '1', '1', '2', '9', '4', '9', '4', '9', '5', '4', '5', '9', '5', '0', '1', '7', '3', '7', '9', '5', '8', '3', '3', '1', '9', '5', '2', '8', '5', '3', '2', '0', '8', '8', '0', '5', '5', '1', '1', '1', '2', '5', '4', '0', '6', '9', '8', '7', '4', '7', '1', '5', '8', '5', '2', '3', '8', '6', '3', '0', '5', '0', '7', '1', '5', '6', '9', '3', '2', '9', '0', '9', '6', '3', '2', '9', '5', '2', '2', '7', '4', '4', '3', '0', '4', '3', '5', '5', '7', '6', '6', '8', '9', '6', '6', '4', '8', '9', '5', '0', '4', '4', '5', '2', '4', '4', '5', '2', '3', '1', '6', '1', '7', '3', '1', '8', '5', '6', '4', '0', '3', '0', '9', '8', '7', '1', '1', '1', '2', '1', '7', '2', '2', '3', '8', '3', '1', '1', '3', '6', '2', '2', '2', '9', '8', '9', '3', '4', '2', '3', '3', '8', '0', '3', '0', '8', '1', '3', '5', '3', '3', '6', '2', '7', '6', '6', '1', '4', '2', '8', '2', '8', '0', '6', '4', '4', '4', '4', '8', '6', '6', '4', '5', '2', '3', '8', '7', '4', '9', '3', '0', '3', '5', '8', '9', '0', '7', '2', '9', '6', '2', '9', '0', '4', '9', '1', '5', '6', '0', '4', '4', '0', '7', '7', '2', '3', '9', '0', '7', '1', '3', '8', '1', '0', '5', '1', '5', '8', '5', '9', '3', '0', '7', '9', '6', '0', '8', '6', '6', '7', '0', '1', '7', '2', '4', '2', '7', '1', '2', '1', '8', '8', '3', '9', '9', '8', '7', '9', '7', '9', '0', '8', '7', '9', '2', '2', '7', '4', '9', '2', '1', '9', '0', '1', '6', '9', '9', '7', '2', '0', '8', '8', '8', '0', '9', '3', '7', '7', '6', '6', '5', '7', '2', '7', '3', '3', '3', '0', '0', '1', '0', '5', '3', '3', '6', '7', '8', '8', '1', '2', '2', '0', '2', '3', '5', '4', '2', '1', '8', '0', '9', '7', '5', '1', '2', '5', '4', '5', '4', '0', '5', '9', '4', '7', '5', '2', '2', '4', '3', '5', '2', '5', '8', '4', '9', '0', '7', '7', '1', '1', '6', '7', '0', '5', '5', '6', '0', '1', '3', '6', '0', '4', '8', '3', '9', '5', '8', '6', '4', '4', '6', '7', '0', '6', '3', '2', '4', '4', '1', '5', '7', '2', '2', '1', '5', '5', '3', '9', '7', '5', '3', '6', '9', '7', '8', '1', '7', '9', '7', '7', '8', '4', '6', '1', '7', '4', '0', '6', '4', '9', '5', '5', '1', '4', '9', '2', '9', '0', '8', '6', '2', '5', '6', '9', '3', '2', '1', '9', '7', '8', '4', '6', '8', '6', '2', '2', '4', '8', '2', '8', '3', '9', '7', '2', '2', '4', '1', '3', '7', '5', '6', '5', '7', '0', '5', '6', '0', '5', '7', '4', '9', '0', '2', '6', '1', '4', '0', '7', '9', '7', '2', '9', '6', '8', '6', '5', '2', '4', '1', '4', '5', '3', '5', '1', '0', '0', '4', '7', '4', '8', '2', '1', '6', '6', '3', '7', '0', '4', '8', '4', '4', '0', '3', '1', '9', '9', '8', '9', '0', '0', '0', '8', '8', '9', '5', '2', '4', '3', '4', '5', '0', '6', '5', '8', '5', '4', '1', '2', '2', '7', '5', '8', '8', '6', '6', '6', '8', '8', '1', '1', '6', '4', '2', '7', '1', '7', '1', '4', '7', '9', '9', '2', '4', '4', '4', '2', '9', '2', '8', '2', '3', '0', '8', '6', '3', '4', '6', '5', '6', '7', '4', '8', '1', '3', '9', '1', '9', '1', '2', '3', '1', '6', '2', '8', '2', '4', '5', '8', '6', '1', '7', '8', '6', '6', '4', '5', '8', '3', '5', '9', '1', '2', '4', '5', '6', '6', '5', '2', '9', '4', '7', '6', '5', '4', '5', '6', '8', '2', '8', '4', '8', '9', '1', '2', '8', '8', '3', '1', '4', '2', '6', '0', '7', '6', '9', '0', '0', '4', '2', '2', '4', '2', '1', '9', '0', '2', '2', '6', '7', '1', '0', '5', '5', '6', '2', '6', '3', '2', '1', '1', '1', '1', '1', '0', '9', '3', '7', '0', '5', '4', '4', '2', '1', '7', '5', '0', '6', '9', '4', '1', '6', '5', '8', '9', '6', '0', '4', '0', '8', '0', '7', '1', '9', '8', '4', '0', '3', '8', '5', '0', '9', '6', '2', '4', '5', '5', '4', '4', '4', '3', '6', '2', '9', '8', '1', '2', '3', '0', '9', '8', '7', '8', '7', '9', '9', '2', '7', '2', '4', '4', '2', '8', '4', '9', '0', '9', '1', '8', '8', '8', '4', '5', '8', '0', '1', '5', '6', '1', '6', '6', '0', '9', '7', '9', '1', '9', '1', '3', '3', '8', '7', '5', '4', '9', '9', '2', '0', '0', '5', '2', '4', '0', '6', '3', '6', '8', '9', '9', '1', '2', '5', '6', '0', '7', '1', '7', '6', '0', '6', '0', '5', '8', '8', '6', '1', '1', '6', '4', '6', '7', '1', '0', '9', '4', '0', '5', '0', '7', '7', '5', '4', '1', '0', '0', '2', '2', '5', '6', '9', '8', '3', '1', '5', '5', '2', '0', '0', '0', '5', '5', '9', '3', '5', '7', '2', '9', '7', '2', '5', '7', '1', '6', '3', '6', '2', '6', '9', '5', '6', '1', '8', '8', '2', '6', '7', '0', '4', '2', '8', '2', '5', '2', '4', '8', '3', '6', '0', '0', '8', '2', '3', '2', '5', '7', '5', '3', '0', '4', '2', '0', '7', '5', '2', '9', '6', '3', '4', '5', '0']
>>> i = [int(x) for x in l]
>>> i
[7, 3, 1, 6, 7, 1, 7, 6, 5, 3, 1, 3, 3, 0, 6, 2, 4, 9, 1, 9, 2, 2, 5, 1, 1, 9, 6, 7, 4, 4, 2, 6, 5, 7, 4, 7, 4, 2, 3, 5, 5, 3, 4, 9, 1, 9, 4, 9, 3, 4, 9, 6, 9, 8, 3, 5, 2, 0, 3, 1, 2, 7, 7, 4, 5, 0, 6, 3, 2, 6, 2, 3, 9, 5, 7, 8, 3, 1, 8, 0, 1, 6, 9, 8, 4, 8, 0, 1, 8, 6, 9, 4, 7, 8, 8, 5, 1, 8, 4, 3, 8, 5, 8, 6, 1, 5, 6, 0, 7, 8, 9, 1, 1, 2, 9, 4, 9, 4, 9, 5, 4, 5, 9, 5, 0, 1, 7, 3, 7, 9, 5, 8, 3, 3, 1, 9, 5, 2, 8, 5, 3, 2, 0, 8, 8, 0, 5, 5, 1, 1, 1, 2, 5, 4, 0, 6, 9, 8, 7, 4, 7, 1, 5, 8, 5, 2, 3, 8, 6, 3, 0, 5, 0, 7, 1, 5, 6, 9, 3, 2, 9, 0, 9, 6, 3, 2, 9, 5, 2, 2, 7, 4, 4, 3, 0, 4, 3, 5, 5, 7, 6, 6, 8, 9, 6, 6, 4, 8, 9, 5, 0, 4, 4, 5, 2, 4, 4, 5, 2, 3, 1, 6, 1, 7, 3, 1, 8, 5, 6, 4, 0, 3, 0, 9, 8, 7, 1, 1, 1, 2, 1, 7, 2, 2, 3, 8, 3, 1, 1, 3, 6, 2, 2, 2, 9, 8, 9, 3, 4, 2, 3, 3, 8, 0, 3, 0, 8, 1, 3, 5, 3, 3, 6, 2, 7, 6, 6, 1, 4, 2, 8, 2, 8, 0, 6, 4, 4, 4, 4, 8, 6, 6, 4, 5, 2, 3, 8, 7, 4, 9, 3, 0, 3, 5, 8, 9, 0, 7, 2, 9, 6, 2, 9, 0, 4, 9, 1, 5, 6, 0, 4, 4, 0, 7, 7, 2, 3, 9, 0, 7, 1, 3, 8, 1, 0, 5, 1, 5, 8, 5, 9, 3, 0, 7, 9, 6, 0, 8, 6, 6, 7, 0, 1, 7, 2, 4, 2, 7, 1, 2, 1, 8, 8, 3, 9, 9, 8, 7, 9, 7, 9, 0, 8, 7, 9, 2, 2, 7, 4, 9, 2, 1, 9, 0, 1, 6, 9, 9, 7, 2, 0, 8, 8, 8, 0, 9, 3, 7, 7, 6, 6, 5, 7, 2, 7, 3, 3, 3, 0, 0, 1, 0, 5, 3, 3, 6, 7, 8, 8, 1, 2, 2, 0, 2, 3, 5, 4, 2, 1, 8, 0, 9, 7, 5, 1, 2, 5, 4, 5, 4, 0, 5, 9, 4, 7, 5, 2, 2, 4, 3, 5, 2, 5, 8, 4, 9, 0, 7, 7, 1, 1, 6, 7, 0, 5, 5, 6, 0, 1, 3, 6, 0, 4, 8, 3, 9, 5, 8, 6, 4, 4, 6, 7, 0, 6, 3, 2, 4, 4, 1, 5, 7, 2, 2, 1, 5, 5, 3, 9, 7, 5, 3, 6, 9, 7, 8, 1, 7, 9, 7, 7, 8, 4, 6, 1, 7, 4, 0, 6, 4, 9, 5, 5, 1, 4, 9, 2, 9, 0, 8, 6, 2, 5, 6, 9, 3, 2, 1, 9, 7, 8, 4, 6, 8, 6, 2, 2, 4, 8, 2, 8, 3, 9, 7, 2, 2, 4, 1, 3, 7, 5, 6, 5, 7, 0, 5, 6, 0, 5, 7, 4, 9, 0, 2, 6, 1, 4, 0, 7, 9, 7, 2, 9, 6, 8, 6, 5, 2, 4, 1, 4, 5, 3, 5, 1, 0, 0, 4, 7, 4, 8, 2, 1, 6, 6, 3, 7, 0, 4, 8, 4, 4, 0, 3, 1, 9, 9, 8, 9, 0, 0, 0, 8, 8, 9, 5, 2, 4, 3, 4, 5, 0, 6, 5, 8, 5, 4, 1, 2, 2, 7, 5, 8, 8, 6, 6, 6, 8, 8, 1, 1, 6, 4, 2, 7, 1, 7, 1, 4, 7, 9, 9, 2, 4, 4, 4, 2, 9, 2, 8, 2, 3, 0, 8, 6, 3, 4, 6, 5, 6, 7, 4, 8, 1, 3, 9, 1, 9, 1, 2, 3, 1, 6, 2, 8, 2, 4, 5, 8, 6, 1, 7, 8, 6, 6, 4, 5, 8, 3, 5, 9, 1, 2, 4, 5, 6, 6, 5, 2, 9, 4, 7, 6, 5, 4, 5, 6, 8, 2, 8, 4, 8, 9, 1, 2, 8, 8, 3, 1, 4, 2, 6, 0, 7, 6, 9, 0, 0, 4, 2, 2, 4, 2, 1, 9, 0, 2, 2, 6, 7, 1, 0, 5, 5, 6, 2, 6, 3, 2, 1, 1, 1, 1, 1, 0, 9, 3, 7, 0, 5, 4, 4, 2, 1, 7, 5, 0, 6, 9, 4, 1, 6, 5, 8, 9, 6, 0, 4, 0, 8, 0, 7, 1, 9, 8, 4, 0, 3, 8, 5, 0, 9, 6, 2, 4, 5, 5, 4, 4, 4, 3, 6, 2, 9, 8, 1, 2, 3, 0, 9, 8, 7, 8, 7, 9, 9, 2, 7, 2, 4, 4, 2, 8, 4, 9, 0, 9, 1, 8, 8, 8, 4, 5, 8, 0, 1, 5, 6, 1, 6, 6, 0, 9, 7, 9, 1, 9, 1, 3, 3, 8, 7, 5, 4, 9, 9, 2, 0, 0, 5, 2, 4, 0, 6, 3, 6, 8, 9, 9, 1, 2, 5, 6, 0, 7, 1, 7, 6, 0, 6, 0, 5, 8, 8, 6, 1, 1, 6, 4, 6, 7, 1, 0, 9, 4, 0, 5, 0, 7, 7, 5, 4, 1, 0, 0, 2, 2, 5, 6, 9, 8, 3, 1, 5, 5, 2, 0, 0, 0, 5, 5, 9, 3, 5, 7, 2, 9, 7, 2, 5, 7, 1, 6, 3, 6, 2, 6, 9, 5, 6, 1, 8, 8, 2, 6, 7, 0, 4, 2, 8, 2, 5, 2, 4, 8, 3, 6, 0, 0, 8, 2, 3, 2, 5, 7, 5, 3, 0, 4, 2, 0, 7, 5, 2, 9, 6, 3, 4, 5, 0]
>>> def mult(lista):
...     return reduce(mul, lista, 1)
...
>>> mult([])
1
>>> mult([1,2,3])
6
>>> for x in range(1001-5):
...     m = mult(i[x:x+5])
...     if m > maxmult:
...             maxmult = m
...
>>> maxmult
40824

Euler 7 (Python)

Junio 18

Enunciado 7

Listando los primeros seis números primos: 2, 3, 5, 7, 11,y 13, podemos ver que el 6° primo es el 13.

¿Cuál es el 10001° primo?

Solución

La solución fue obtenida en el intérprete interactivo de Python 2.5.2:

>>> from math import sqrt
>>> def primo(n):
...     for i in xrange(2,int(sqrt(n))+1):
...         if n % i == 0:
...             return False
...     return True
>>> while i < 10002:
...     if primo(a):
...             i +=1
...     a += 1
...
>>> i
10002
>>> a
104744
>>> a-1
104743

Euler 6 (Python)

Junio 16

Enunciado 6

La suma de los cuadrados de los primeros diez números naturales es:

12 + 22 + … + 102 = 385

El cuadrado de la suma de los primeros diez números naturales es:

(1 + 2 + … + 10)2 = 552 = 3025

Así que la diferencia entre la suma de los cuadrados de los diez primeros números naturales y el cuadrado de la suma es 3025 − 385 = 2640.

Encontrar la diferencia entre la suma de los cuadrados de los primeros cien números naturales y el cuadrado de la suma.

Solución

La solución fue obtenida utilizando el intérprete interactivo de Python 2.5.2:

>>> def a(n):
...     s = sum(xrange(1,n+1))
...     a1 = s ** 2
...     a2 = sum([x**2 for x in xrange(1,n+1)])
...     return a1, a2, a1-a2
...
>>> a(10)
(3025, 385, 2640)
>>> a(100)
(25502500, 338350, 25164150)

Python tips

  • Con ** podemos elevar un número a cualquier potencia sin necesidad de importar ningún módulo.
  • Para denotar una tupla solo hacen falta las comas (,), no los paréntesis al principio y al final.

Euler 5 (Python)

Junio 15

Enunciado 5

2520 es el menor número que puede ser dividido sin resto por todos los números de 1 a 10.

¿Cuál es el menor número que que puede dividirse sin resto por todos los números de 1 a 20?

Solución

La solución fue obtenida ejecutando el siguiente programa Python 2.5.2:

from math import sqrt
from operator import mul, add

def primo(n):
    for i in xrange(2,int(sqrt(n))+1):
        if n % i == 0:
            return False
    return True

def factorizar(n):
    primos = [x for x in xrange(2,n+1) if primo(x)]
    factores = []
    if n == 1:
        return [1]
    for p in primos:
        if n == p:
                factores.append(p)
                return factores
        if n % p == 0:
                n /= p
                factores.append(p)
                while n % p == 0:
                    n /= p
                    factores.append(p)
    return factores

def mcm(l):
    '''Maximo comun multiplo'''
    ff = [factorizar(i) for i in l]
    singles = list(set(reduce(add,ff)))
    temp = []
    for s in singles:
        temp.extend([s] * max([f.count(s) for f in ff]))
    return reduce(mul,temp,1)

if __name__ == '__main__':
    #print mcm(range(1,11))
    print mcm(range(1,21))

Python tips

  • El módulo operator tiene varias funciones útiles equivalentes a operadores como * y + que pueden utilizarse con funciones como reduce, cuyo primer parámetro es una función.
  • reduce toma una función f de dos argumentos y una lista l. Aplica f a los dos primeros elementos de la lista y obtiene un resultado, luego aplica la función f al resultado con el tercer elemento de la lista, y así sucesivamente hasta consumir toda la lista y retornar el resultado final. Opcionalmente se le puede pasar un tercer parámetro para que la primer llamada a la función f sea aplicada sobre este y el primer elemento de la lista.

Euler 4 (Python)

Junio 12

Enunciado 4

Un número palíndromo se lee igual en ambos sentidos. El mayor palíndromo construido a partir del producto de dos números de dos dígitos es 9009 = 91 × 99.

Encontrar el mayor palíndromo que se puede construir como el producto de dos números de tres dígitos.

Solución

La solución fue obtenida en el intérprete interactivo de Python 3.0rc1+. Necesitaba Python 3 para utilizar itertools.combinations:

juanjo@fenix:~$ python3
Python 3.0rc1+ (py3k, Oct 28 2008, 09:23:29)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from itertools import combinations
>>> tri = range(999, 99, -1)
>>> mults = []
>>> for a,b in combinations(tri, 2):
...     s = str(a*b)
...     if s == s[::-1]:
...             mults.append(int(s))
...
>>> max(mults)
906609

Python tips

  • combinations genera la combinación con los elementos de la lista argumento tomados de a n, si se especifica el parámetro n.
  • En Python 3 print deja de ser una sentencia para convertirse en una función, por lo que siempre debe ser llamado con parámetros.
  • unString[::-1] es un idiom usado para invertir una cadena de texto (en el ejemplo, unString). Se lee: los elementos de unString, desde el principio al final, con paso -1.

Euler 3 (Python)

Junio 7

Enunciado 3

Los factores primos de 13195 son 5, 7, 13 y 29.

¿Cual es el mayor factor primo del número 600851475143?

Solución

La solución fue obtenida en el intérprete interactivo de Python 2.5.2:

>>> from math import sqrt
>>> the_number = 600851475143
>>> my_number = sqrt(the_number)
>>> my_number
775146.09922452678
>>> my_number = int(my_number)
>>> my_number
775146
>>> def esprimo(n):
...     for i in xrange(2,int(sqrt(n))+1):
...             if n % i == 0:
...                     return False
...     return True
...
>>> esprimo(8)
False
>>> esprimo(3)
True
>>> esprimo(6823)
True
>>> esprimo(100109)
True
>>> esprimo(100110)
False
>>> for i in xrange(1, my_number+1):
...      if the_number % i == 0 and esprimo(i):
...             print i
...
1
71
839
1471
6857

Python tips

  • xrange, en lugar de crear una lista entera de números como hace range devuelve un generador que va entregando números a medida que los necesitamos.
  • La clase int se instancia para obtener enteros. Si la llamamos con un float como parámetro, podemos usarla para forzar un entero.

Euler 2 (Python)

Junio 4

Enunciado 2

Cada nuevo item en la secuencia de Fibonacci es generado sumando los dos términos previos. Empezando con 1 y 2, los primeros 10 términos serían:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, …

Encontrar la suma de todos los términos pares en la secuencia que no supera los 4 millones.

Solución

La solución fue obtenida en el intérprete interactivo de Python 2.5.2:

>>> MAX = 4000000
>>> def evsum(n):
...     s = 0
...     a,b = 1,2
...     while True:
...         if a >= n:
...             break
...         if a % 2 ==0:
...             print a, " ",
...             s += a
...         a,b = b,a+b
...     return s
...
>>> evsum(MAX)
2   8   34   144   610   2584   10946   46368   196418   832040   3524578
4613732

Python tips

  • La asignación múltiple es un idom muy cómodo: a,b = 1,2
  • Si agregamos una coma final a la enumeración de objetos a ser impresos con print, se logra el efecto de que no se imprima el salto de línea (\n) final.

Euler 1 (Python)

Mayo 28

Project Euler es un sitio web que reta a los programadores a resolver problemas matemáticos mediante código. Me parece entretenido. Voy a ir resolviendo problemas y posteando mi solución en Python acompañada de comentarios sobre el código que puedan servirles a quienes están empezando a aprender el lenguaje.

Enunciado 1

Si listamos todos los números menores a 10 que son múltiplos de 3 o 5, obtenemos 3, 5, 6 y 9. La suma de esos múltiplos es 23.

Encontrar la suma de todos los múltiplos de 3 o 5 menores a 1000.

Solución

La solución fue obtenida en el intérprete interactivo de Python 2.5.2:

>>> def mults(n=10):
...     r = []
...     for i in range(1, n):
...             if i % 3 == 0:
...                     r.append(i)
...             elif i % 5 == 0:
...                     r.append(i)
...     return r
...
>>> mults()
[3, 5, 6, 9]
>>> sum(mults())
23
>>> sum(mults(n=1000))
233168

Python tips

  • En la definición de la función mults se incluye un argumento por defecto n con valor 10. Cuando más adelante se llama a esta función sin parámetros, n toma el valor por defecto.
  • La función range, incluida en el lenguaje devuelve una lista de números sobre la que se puede iterar. Muy útil para usar con la estructura for. Más información haciendo help(range) en el intérprete interactivo.

Intercambio de valores rápido en Python

Mayo 4

Cuando empecé a cursar Ingeniería en Sistemas en el año 2003, tuvimos una materia llamada Algoritmos y Estructuras de Datos. La semana del curso estaba compuesta por una clase teórica, una clase práctica y una clase “especial” dictada por un docente de apellido Marina que tenía como objetivo hacernos pensar resolviendo problemas; en las primeras clases ni siquiera programábamos.
El lenguaje de programación de la materia era C y en una de las clases, este docente recordaba risueño que un alumno había querido intercambiar el valor de dos variables
int a = 1;
int b = 2;
haciendo:
a = b;
b = a;
El error es evidente; en a se copia el valor contenido en b (2) pisando el valor original (1) y al ejecutarse la segunda sentencia, el nuevo valor de a (2) es copiado en b.

La siguiente tabla muestra los valores que van tomando las variables a y b:

La forma correcta de intercambiar los valores habría sido utilizando una variable auxiliar en la cual mantener uno de los valores:
int aux;
int a = 1;
int b = 2;
aux = a;
a = b;
b = aux;
La siguiente tabla muestra los valores que van tomando las variables aux, a y b:

Lo gracioso del asunto es que unos años más tarde conocí otro lenguaje de programación, Python.

Read the rest of this entry »

Los chicos malos

Enero 3

“Esto es lo que ocurre con la gente que piensa que odia las computadoras. Lo que realmente odia es a los malditos programadores”
— Larry Niven

Por suerte muchos mortales aún no saben de nuestra existencia :-) .

Larry Niven, nacido en la ciudad de Los Angeles (EE. UU.) en 1938, es un escritor de ciencia ficción estadounidense. Conocido sobre todo como el autor de la serie Mundo Anillo y también por el universo creado bajo el nombre de Espacio Conocido (Known Space), el éxito de su carrera como escritor de ciencia ficción lo acreditan sus varios premios Hugo y Nébula. Se ha dedicado a la escritura profesionalmente desde 1963.

La mayoría de las historias de Niven tienen lugar en un universo de ficción denominado “Espacio conocido”, que presenta un escenario futuro en el que la una humanidad ultratecnificada comparte los mundos de diversos sistemas cercanos al Sol con más de una docena de razas alienígenas entre las que se incluyen especies como los agresivos kzin o los cobardes titerotes de Pierson, los subyugados kdatlyno o los pulpoides Jotoki. Muchos alienígenas son encarnados en personajes que, con frecuencia, acompañan a los protagonistas o son los propios protagonistas de las novelas de Niven.

Fuente: Wikipedia

Fans club del autor: http://www.larryniven.org

Este post es parte de Citas sobre programación.

Nosotros, los programadores

Enero 2

“La mayoría de ustedes están familiarizados con las virtudes del programador. Son tres, por supuesto: pereza, impaciencia y orgullo desmedido”
— Larry Wall

De las tres, la pereza es la más importante. Nos impulsa a resolver problemas. Muchas veces me encuentro escribiendo programas con el objetivo de evitar hacer tareas repetitivas, difíciles de hacer “a mano” o aburridas.

Larry Wall (nacido el 27 de septiembre de 1954) es un programador, lingüista y autor, más conocido por haber creado el lenguaje de programación Perl en 1987.

Wall es el autor del programa rn (lector de artículos de Usenet) y del casi universal patch. Ha ganado el IOCCC (concurso internacional de código C ofuscado) dos veces y recibió el primer premio de la Free Software Foundation para el avance del software libre en 1998.

Más allá de sus habilidades técnicas, Wall es conocido por su irónico sentido del humor, que manifiesta en sus comentarios en el código fuente o en Usenet. Por ejemplo (traducción libre): “No me gusta hacer cosas estúpidas, excepto si son a propósito”.

Fuente: Wikipedia

Este post es parte de Citas sobre programación.

Citas sobre programación

Enero 1

A partir de hoy, 1º de enero, van a ir apareciendo durante siete días seguidos en este blogs citas, principalmente relacionadas con el acto de programar, que en muy pocas palabras encierran conceptos muy importantes: a veces superficialmente divertidos y otras más profundos. Además de la cita, voy a completar los posts que aparezcan con información del autor, links, fotos o alguna que otra anécdota para ilustrarla.

La primera es de Alan Kay.

“La mayoría del software actual es muy parecido a una pirámide egipcia, con millones de ladrillos puestos unos encima de otros sin una estructura integral, simplemente realizada a base de fuerza bruta y miles de esclavos”
– Alan Kay

Querido programador, espero que nunca te encuentres bajo el látigo construyendo una pirámide :) .

Alan Kay, es un informático estadounidense, conocido por su trabajos pioneros en la programación orientada a objetos y el diseño de sistemas de interfaz gráfica de usuario. Kay colaboró en la creación de Squeak, un entorno para la creación y experimentación multimedia en 1995 mientras trabajaba en Apple y todavía sigue colaborando con el proyecto.

Fuente: Wikipedia