n 番目の文字列

解答(修正版)

  • a. "!!!!!!!;6'uVO%_e"
  • b. "!\"#$%&'fosI;t`Hg"
  • c. "\"%'[03569FfLoUXy"

追記

['!'..'z']ではありませんでした。ついでに書き直したもの。

import Control.Monad.Fix (fix)

solveall = [solve g t characters 16 largenum 
      | (g, t) <- [(gen_a, tostr_a), (gen_b, tostr_b), (gen_c, tostr_c)]]
  where
    characters = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"
    largenum = 99999999999999999

solve gen tostr str nc nth 
    = tostr str $ fix 
        $ \pos -> search (gen (fromIntegral $ length str) nc pos) nth

search :: [[Integer]] -> Integer -> [Int]
search [] 0 = []
search (ps:pss) x = m : search pss (x - b)
  where (m, b) = last $ takeWhile ((<= x).snd) $ zip [0..] ps

-- a.
gen_a ncs nc _ = [[k * ncs^n | k <- [0..ncs - 1]] | n <- [nc - 1, nc - 2..0]] 
tostr_a str = map (str !!)

-- b.
gen_b ncs nc _ = [[k * product [ncs - n - (nc - n - 1)..(ncs - n - 1)] | k <- [0..ncs - n - 1]]
          | n <- [0..nc - 1]]
tostr_b str [] = []
tostr_b str (n:ns) = (str !! n): tostr_b (deleteNth n str) ns

-- c.
gen_c ncs nc = gen nc 0
  where gen 0 m _ = []
        gen n m ~(p:ps) 
          = scanl (+) 0 [comb (ncs - k) (n - 1) | k <- [fromIntegral m + 1..ncs - (n - 1) - 1]] : gen (n - 1) (m + p + 1) ps
tostr_c str [] = []
tostr_c str (x:xs) = (str !! x):tostr_c (drop (x + 1) str) xs

comb n m = product [(m + 1)..n] `div` product [1..(n - m)]
-- deleteNth _ [] = []
deleteNth 0 (x:xs) = xs
deleteNth n (x:xs) = x:deleteNth (n - 1) xs