Problem:
カード並べ

問題

花子さんは n 枚（4 ≤ n ≤ 10）のカードを並べて遊んでいる．
それぞれのカードには 1 以上 99 以下の整数が 1 つずつ書かれている．
花子さんは，これらのカードの中から k 枚（2 ≤ k ≤ 4）を選び，
横一列に並べて整数を作ることにした．
花子さんは全部で何種類の整数を作ることができるだろうか．

例えば，1, 2, 3, 13, 21 の 5 枚のカードが与えられ，そこから 3 枚を選び整数を作ることを考える．
2, 1, 13 をこの順に並べると，整数 2113 を作ることができる．
また，21, 1, 3 をこの順に並べても，同じ整数 2113 を作ることができる．
このように，異なるカードの組み合わせから同じ整数が作られることもある．

n 枚のカードに書かれた整数が与えられたとき，
その中から k 枚を選び，横一列に並べることで作ることができる整数の個数を求めるプログラムを作成せよ．

入力

入力は複数のデータセットからなる．各データセットは以下の形式で与えられる．

各データセットは 2+n 行からなる．
1 行目にはカードの枚数 n （4 ≤ n ≤ 10）が，
2 行目にはカードを選ぶ枚数 k （2 ≤ k ≤ 4）が書かれている．
2+i 行目（1 ≤ i ≤ n）には i 枚目のカードに書かれている 1 以上 99 以下の整数が書かれている．

n, k がともに 0 のとき入力の終了を示す.データセットの数は 5 を超えない．

出力

データセットごとに，花子さんが作ることができる整数の個数を1 行に出力する．

入出力例

入力例

4
2
1
2
12
1
6
3
72
2
12
7
2
1
0
0

出力例

7
68

1つ目の入力例 において，
1, 2, 12, 1 の 4 枚のカードの中から 2 枚を選び，横一列に並べて作ることができる整数は，
11, 12, 21, 112, 121, 122, 212 の 7 個である．

上記問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。

Solution in Haskell (judge verdict: Accepted)

import Control.Applicative
import Control.Monad
import Control.Monad.ST
import Data.Functor
import Data.Function
import Data.Monoid
import Data.Maybe
import Data.List
import qualified Data.Foldable as Foldable
import qualified Data.Set as Set
import Data.List.Split
import Data.Bits
import Data.Char
import Data.Ix
import Data.Ratio
import Data.Ord
import Data.Tuple
import Data.Array
--import Data.Array.Unboxed
import Data.Array.IO
import Data.Array.ST
import Data.IORef
import Data.STRef
-- import System.IO.Unsafe
 
readInt = read :: String -> Int
readDouble = read :: String -> Double
getInt = readLn :: IO Int
getInts = map readInt . words <$> getLine
getDouble = readLn :: IO Double
sjoin :: (Show a) => [a] -> String
sjoin = unwords . map show
cond :: a -> a -> Bool -> a
cond t f c = if c then t else f
apply2 :: (a -> a -> b) -> [a] -> b
apply2 f [x,y] = f x y
apply3 :: (a -> a -> a -> b) -> [a] -> b
apply3 f [x,y,z] = f x y z
apply4 :: (a -> a -> a -> a -> b) -> [a] -> b
apply4 f [x,y,z,w] = f x y z w
fnBin :: (b -> c -> d) -> (a -> b) -> (a -> c) -> a -> d
fnBin op f g x = op (f x) $ g x
fnTuple :: (a -> b, a -> c) -> a -> (b, c)
fnTuple (f,g) a = (f a, g a)
replace :: (Eq a) => a -> a -> [a] -> [a]
replace x y = map (\z -> if z==x then y else z)
modifyArray :: (Ix i, MArray a e m) => a i e -> i -> (e -> e) -> m ()
modifyArray arr ix f = readArray arr ix >>= writeArray arr ix . f
-- end of templete

toSet = map head . group . sort

f _ 1 s = s
f n k s = concat [map (x++) $ f (n-1) (k-1) (a++b) | t <- [0..n-1], let (a,(x:b)) = splitAt t s]

main = do
    n <- getInt
    k <- getInt
    when (n/=0 || k/=0) $ do
        d <- replicateM n getLine
        print $ length $ toSet $ f n k d
        main