or1ko's diary

日々を書きます

295

久しぶりに見かけたのでチャレンジ

一昔前は、すごい勢いで投稿されていたけど、
最近は寂しい限りみたいだ。
パスワードとかが分からなくてログインできず...再発行も面倒で...orz

import Data.Char (isDigit)
import Data.List (find, groupBy, sortBy)
import Data.Maybe (maybe, fromJust)

main = print $ sortBy oCmp objs

objs = ["A10B1","A10B10","A10B2","A1B1","A1B10","A1B2","A2B1","A2B10","A2B2"]

-- 中間に含まれる文字列も考慮して比較
oCmp :: String -> String -> Ordering
oCmp sa sb = maybe EQ id (find (EQ /=) $ zipWith estrCmp (str2s sa) (str2s sb))
  where
    str2s = groupBy (\x y -> isDigit x == isDigit y)

-- 整数として扱えるなら整数として比較
-- そうでないなら、文字列として比較
estrCmp :: String -> String -> Ordering
estrCmp sa sb
  | and [isDigitStr sa, isDigitStr sb] = compare (readInteger sa) (readInteger sb)
  | otherwise = compare sa sb
  where
    readInteger = (read :: String -> Integer)
    isDigitStr = all isDigit