Wziąłem wolność zmieniając kolejność parametrów magic
przy założeniu, że podstawy 10 jest bardziej powszechne i opcjonalnie:
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]
Wyjaśnienie:
Przekładając pierwotnego problemu od 1..10
do 0..9
i łączenie cyfr widzimy, że dane wyjściowe właśnie się liczy, z dostępem do każdej cyfry.
0000
0001
0002
...
0010
0011
0012
...
9997
9998
9999
Tak właśnie robi mój powyższy kod.Liczy od 0 do liczby maksymalnej (na podstawie liczby cyfr i dopuszczalne wartości za cyfra), a dla każdego numeru IT:
Konwertuje liczbę do odpowiedniej „bazy”:
i.to_s(base) # e.g. 9.to_s(8) => "11", 11.to_s(16) => "b"
Używa String#%
pad ciąg do prawidłowego liczba znaków:
"%#{digits}s" % ... # e.g. "%4s" % "5" => " 5"
zamienia ten pojedynczy łańcuch na tablicę pojedynczy ciąg znaków s:
str.scan(/./) # e.g. " 31".scan(/./) => [" ","3","1"]
Należy zauważyć, że w Ruby 1.9 to lepiej zrobić z str.chars
Przekształca każde z tych ciągów pojedynczych znaków z powrotem na numer:
n.to_i(base) # e.g. "b".to_i(16) => 11, " ".to_i(3) => 0
dodaje 1 do siebie tych liczb, ponieważ pożądane było rozpoczęcie od 1 zamiast 0
Ułożenie nowej tablicy liczb jako argumentów t O bloku, numer jeden na blok param:
yield *parts
co wyjście można się spodziewać? czy jest to coś w rodzaju '1 2 3 4 \ n 5 6 7 8 \ n 9 10' lub' 0 0 0 1 \ n 0 0 0 2 ... '? –
@nash Nie; pierwszy kod działa samodzielnie. Jeśli dopasowałeś wszystkie '(1..10)' do '(0..9)', wtedy otrzymasz '0 0 0 0 ',' 0 0 0 1 ', ...' 9 9 9 8 ', "9 9 9 9". – Phrogz
To jest duplikat http://stackoverflow.com/questions/5226895/combine-array-of-array-into-all-possible-combinations-forward-only-in-ruby/5227021#5227021, ale lubię to odpowiedzi na pytania lepiej. –