Problem:
ヒストグラム

テンアイスクリームという名前のアイスクリーム屋さんがあります。このお店では常に 10 種類のアイスクリームが店頭に並ぶようにしています。お店の店長は商品開発の参考にするために、アイスクリームの売れ具合を表すグラフを毎日作成しています。

そんな店長のために、あなたは各アイスクリームの販売数をグラフで表示するプログラムを作成することになりました。

一日に販売されるアイスクリームの総数と売れたアイスクリームの番号を入力とし、アイスクリームの種類ごとに販売した数だけ * (半角アスタリスク) を出力するプログラムを作成してください。ただし、アイスクリームの種類を 0 から 9 までの整数で表わします。また、販売個数がゼロのアイスクリームは、- (半角ハイフン) をひとつ出力します。

Input

複数のデータセットの並びが入力として与えられます。入力の終わりはゼロひとつの行で示されます。
各データセットは以下の形式で与えられます。

n
c1
c2
:
cn

1 行目に一日に販売されるアイスクリームの総数 n (1 ≤ n ≤ 10000) が与えられます。続く n 行に第 i のアイスクリームの種類 ci (0 ≤ ci≤ 9) が与えられます。

データセットの数は 20 を超えません。

Output

入力データセットごとに、各アイスクリームの種類の番号順に販売数を出力します。

Sample Input

15
2
6
7
0
1
9
8
7
3
8
9
4
8
2
2
3
9
1
5
0

Output for the Sample Input

*
*
***
*
*
-
*
**
***
**
-
*
-
-
-
*
-
-
-
*

Solution in Haskell (judge verdict: Accepted)

import Control.Applicative
import Control.Monad
import Control.Monad.ST
import qualified Data.ByteString as BS
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 qualified Data.Sequence as Sequence
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.IArray
import Data.Array.MArray
import Data.Array.IO
import Data.Array.ST
import Data.IORef
import Data.STRef
import GHC.ST
-- import System.IO.Unsafe

-- templete
readInt = read :: String -> Int
readInteger = read :: String -> Integer
readDouble = read :: String -> Double
getInt = readLn :: IO Int
getInts = map readInt . words <$> getLine
getInteger = readLn :: IO Integer
getIntegers = map readInteger . words <$> getLine
getDouble = readLn :: IO Double
getDoubles = map readDouble . words <$> getLine
sjoin :: (Show a) => [a] -> String
sjoin = unwords . map show
tjoin :: (Show a, Show b) => (a, b) -> String
tjoin (x, y) = show x ++ (' ' : show y)
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
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)
binMap :: (a -> a -> b) -> [a] -> [b]
binMap f (x:xs@(y:_)) = f x y : binMap f xs
binMap _ _ = []
splitRec :: Int -> [a] -> [[a]]
splitRec _ [] = []
splitRec n xs = let (y,ys) = splitAt n xs in y : splitRec n ys
infixl 7 `divCeil`
divCeil :: Integral a => a -> a -> a
x `divCeil` y = (x+y-1) `div` y
coverC :: Ord a => (a, a) -> a -> Bool
coverC (l,r) x = l<=x && x<=r
coverH :: Ord a => (a, a) -> a -> Bool
coverH (l,r) x = l<=x && x<r
ibsearch :: (Int -> Bool) -> (Int,Int) -> Int
ibsearch f (ok,ng) = if abs (ok-ng) <= 1 then ok else let mid = (ok + ng) `div` 2 in ibsearch f (if f mid then (mid,ng) else (ok,mid))
-- templete

f cs = [let s = replicate (arr!i) '*' in cond "-" s $ null s | i <- [0..9]]
  where
    arr = array (0,9) $ [(i,0) | i <- [0..9]] ++ (map (fnTuple (head, length)) . group . sort $ cs)


main = do
    n <- getInt
    unless (n==0) $ replicateM n getInt >>= mapM_ putStrLn . f >> main