Hoy necesitaba generar números hexadecimales de largo 24, de forma aleatoria, así que me hice un programita...
Hay seguramente muchas formas de hacerlo, yo elegí esta:
Seudocódigo:
24 veces:Código Ruby:
elegir un dígito aleatorio entre 0 y F (hexadecimal)
imprimirlo
hexaDigit = ('0'..'9').to_a + ('A'..'F').to_aSimple, ¿no? Se puede escribir más corto, pero no mucho más claro que esto...
24.times do
print hexaDigit[rand(16)]
end
Muy bueno Marcos! va una sugerencia (nuevito en Ruby, no tengo ni unas pocas horas de mirar un par de tutoriales y ya estoy opinando sobre Ruby)
ResponderBorrar24.times do print rand(16).to_s(16)end
:)
David: está bueno el tip de .to_s(16), no lo tenía.
ResponderBorrarIgual lo que decía, es más corto de escribir, pero no necesariamente más claro. Tenés que saber que significa ese to_s(16) para entender el programa...
Lo podés hacer incluso más corto (como 3 caracteres menos!), si cambiás el do-end por { }. Así:
24.times { print rand(16).to_s(16) }
si, el to_s también puede ser más claro si se hace to_s(base=16) lo del {} buen dato :)
ResponderBorrarDejo el código equivalente en Python, no de pesado, sino en honor al Python Day a celebrarse mañana :)
ResponderBorrarfrom random import random
print [("%X" % int(random()*15)) for x in xrange(24)]
Ah, perdón, faltó unirlos!
ResponderBorrarprint "".join([("%X" % int(random()*15)) for x in xrange(24)])
David: Bueno, creo que entonces tenemos un ganador... Con el to_s(base=16) sí queda bien claro.
ResponderBorrarVarrojo: Python es un lenguaje muy interesante, y en muchos aspectos comparable a Ruby. Pero en este caso, creo que el "24.times do..." supera ampliamente la solución en Python.
ResponderBorrarHola,
ResponderBorrarInteresante como se escribe en Ruby y lo fácil de leer que queda. Me di cuenta lo que hacia más rápido en Ruby que en Python. En Smalltalk es así:
hexaDigit := ('0' completeTo: '9'), ('A' completeTo: 'F').
random := RandomLinearCongruential newParkMiller.
1 to: 24 do: [:index |
Transcript show: (hexaDigit at: ((random next * 16) asInteger + 1)).
].
Es bastante similar a Ruby.
Saludos,
Bruno
PD: para hacerlo mas parecido a Ruby podemos implementar el siguiente método en la clase Number.
ResponderBorrarNumber
timesRepeat: aBlock
"Evaluate the argument receiver object (self) times"
^(1 to: self do: aBlock)
Al tener el nuevo método #timesRepeat:, que tiene como argumento un bloque de código (BlockClosure) el ejemplo queda:
hexaDigit := ('0' completeTo: '9'), ('A' completeTo: 'F').
random := RandomLinearCongruential newParkMiller.
24 timesRepeat: [
Transcript show: (hexaDigit at: ((random next * 16) asInteger + 1)).
].
Perdon por la 3ra entrada pero ...
ResponderBorrarPD2:
El método #completeTo: tampoco lo tenia disponible así que lo agregue a la clase String.
Para poder enviar el mensaje '0' completeTo: '9' etc. Crear los métodos me tomo un par de minutos.
Con este método también queda parecido a Ruby.
String
completeTo: aString
"Answer a new concatenated collection with the reciver to argument following the Ascii Table.
Both string must have size = 1 otherwise answer an empty string"
| newString |
newString := ''.
((self size = 1) and: [aString size = 1]) ifFalse: [^newString].
self first asciiValue to: aString first asciiValue do: [:index | newString := newString, (Character value: index) asString].
^newString
Smalltalk: Creo que tus comentarios refuerzan mi punto. Estamos hablando que en Ruby se escribe el programa (y se lee casi como en inglés) usando menos de 50 caracteres.
ResponderBorrarEn tu solución usaste más de 500... sin contar las descripciones de los métodos.
No conozco la filosofía de Ruby, pero en Smalltalk es la legibilidad del código, y no la cantidad de caracteres lo que importa. La cantidad de caracteres se ve atenuada por el "autocompletation", habrá 500 caracteres pero habré digitado 40.
ResponderBorrarY la descripción de los métodos es fundamental, más cuando se muestra el código a personas que no conocen el lenguaje (ya sea Ruby/C##/Smalltalk/etc).
Veo que en Ruby se intenta escribir igual que en ingles, este es una de las ventajas de Smalltalk debido al uso de "keyword arguments" y "keyword messages".
Otro punto importante es poder modificar las clases base como String e Integer, no se si se podrá hacer esto en Python o Ruby (pero es para otro post no este). No es una desventaja poder o tener que agregar métodos a las clases fundamentales, sino que es una ventaja INMENSA.
Pero los mas importante es la legibilidad no la cantidad de caracteres escritos.
Ruby
hexaDigit = ('0'..'9').to_a + ('A'..'F').to_a
24.times do
print hexaDigit[rand(16)]
end
Smalltalk
hexaDigit := ('0' completeTo: '9'), ('A' completeTo: 'F').
random := RandomLinearCongruential newParkMiller.
24 timesRepeat: [Transcript show: (hexaDigit at: ((random next * 16) asInteger + 1)).].
No veo mucha diferencia, te acepto en este caso que la version de Ruby es un poco mas legible en "hexaDigit at:", pero en el caso de Ruby no estas especificando que función randomica que se esta usando.
Saludos,
Bruno
Bruno:
ResponderBorrar>Otro punto importante es poder modificar las
>clases base como String e Integer, no se si se
>podrá hacer esto en Python o Ruby
En Python no se. En Ruby sí se puede, igual que se puede en otros lenguajes "modernos" como Objective-C (modernos dije, no?...) o más recientemente en C# 3.0
>No veo mucha diferencia, te acepto en este caso
>que la version de Ruby es un poco mas legible en
>"hexaDigit at:"
La versión final en Ruby, gracias al aporte de David, quedó así:
24.times do print rand(16).to_s(base=16) end
que no usa el array hexaDigit para nada.
Y sí, en Smalltalk se puede hacer lo mismo, definiendo una extensión de Number para implementar el to_s(base=16) :)
Esto es mucho más que genial!!:)!!!
ResponderBorrarEste comentario ha sido eliminado por el autor.
ResponderBorrar