Me he tomado la libertad de cambiar el orden de los parámetros magic
bajo el supuesto de que la base 10 es más común y opcional:
def magic(digits,base=10)
raise "Max magic base of 36" unless base <= 36
(base**digits).times do |i|
str = "%#{digits}s" % i.to_s(base)
parts = str.scan(/./).map{ |n| n.to_i(base)+1 }
yield *parts
end
end
magic(3,2){ |a,b,c| p [a,b,c] }
#=> [1, 1, 1]
#=> [1, 1, 2]
#=> [1, 2, 1]
#=> [1, 2, 2]
#=> [2, 1, 1]
#=> [2, 1, 2]
#=> [2, 2, 1]
#=> [2, 2, 2]
magic(2,16){ |a,b| p [a,b] }
#=> [1, 1]
#=> [1, 2]
#=> [1, 3]
#=> ...
#=> [16, 15]
#=> [16, 16]
Explicación:
Al traducir el problema original de 1..10
a 0..9
y concatenando los dígitos vemos que la salida solo está contando, con acceso a cada dígito.
0000
0001
0002
...
0010
0011
0012
...
9997
9998
9999
Así que eso es lo que hace mi código anterior.Cuenta de 0 hasta el número máximo (basado en el número de dígitos y los valores por dígito permitido), y para cada número que:
Convierte el número en la 'base' apropiado:
i.to_s(base) # e.g. 9.to_s(8) => "11", 11.to_s(16) => "b"
Usos String#%
para rellenar la cadena con el número correcto de caracteres:
"%#{digits}s" % ... # e.g. "%4s" % "5" => " 5"
convierte a esta sola cadena en una matriz de cadena de un solo carácter s:
str.scan(/./) # e.g. " 31".scan(/./) => [" ","3","1"]
Tenga en cuenta que en Ruby 1.9 esto se realiza mejor con str.chars
Convierte cada una de estas cadenas de un solo carácter de nuevo en un número:
n.to_i(base) # e.g. "b".to_i(16) => 11, " ".to_i(3) => 0
añade 1 a cada de estos números, ya que el deseo era comenzar en 1 en lugar de 0
Splat this new array of numbers as arguments t o el bloque, un número por bloque param:
yield *parts
lo que la salida se puede esperar? ¿es algo así como '1 2 3 4 \ n 5 6 7 8 \ n 9 10' o' 0 0 0 1 \ n 0 0 0 2 ... '? –
@nash No; el primer código se ejecuta solo. Si ajustaras todo '(1..10)' a '(0..9)', obtendrías ''0 0 0 0 '', '0 0 0 1', ... '9 9 9 8', '9 9 9 9''. – Phrogz
Este es un duplicado de http://stackoverflow.com/questions/5226895/combine-array-of-array-into-all-possible-combinations-forward-only-in-ruby/5227021#5227021, pero me gusta esto las respuestas de la pregunta mejor. –