Haskell, 48
f=(!!)(sequence=<<(tail$iterate(['A'..'Z']:)[]))
Daha az golf:
f n = (concatMap sequence $ tail $ iterate (['A'..'Z'] :) []) !! n
açıklama
Haskell'in sequence
birleştiricisi, eylemlerin bir listesini alır ve bunları gerçekleştirir ve listedeki her eylemin sonucunu döndürür. Örneğin:
sequence [getChar, getChar, getChar]
şuna eşittir:
do
a <- getChar
b <- getChar
c <- getChar
return [a,b,c]
Haskell'de eylemler değerler gibi ele alınır ve >>=
(bind) ve return
ilkeller kullanılarak birbirine yapıştırılır . Herhangi bir tür, bir Monad örneğine sahip olarak bu işleçleri uygularsa "eylem" olabilir .
Bu arada, liste türünün bir monad örneği vardır. Örneğin:
do
a <- [1,2,3]
b <- [4,5,6]
return (a,b)
Bu eşittir [(1,4),(1,5),(1,6),(2,4),(2,5),(2,6),(3,4),(3,5),(3,6)]
. Liste kavrayışının çarpıcı şekilde benzer olduğuna dikkat edin:
[(a,b) | a <- [1,2,3], b <- [4,5,6]]
Listeler bir tür "eylem" olduğundan, sequence
listelerle birlikte kullanabiliriz . Yukarıdakiler şu şekilde ifade edilebilir:
sequence [[1,2,3],[4,5,6]]
Böylece, sequence
bize ücretsiz kombinasyonlar verir!
Böylece, listeyi oluşturmak için:
["A","B"..."Z","AA","AB"]
Sadece geçmek için listeler yapmam lazım sequence
[['A'..'Z'],['A'..'Z','A'..'Z'],...]
Ardından concatMap
, hem sequence
listelere uygulamak hem de sonuçta oluşan listeleri birleştirmek için düğmelerini kullanın . Tesadüfen, concatMap
bir =<<
liste monad benim de burada birkaç karakter tıraş sağlar, böylece listeleri için fonksiyon.