私は最近Mastermindソルバーを構築するためにhomework assignment of some UPenn Haskell Courseを完了しました(自習用)。列挙型の操作:ヒストグラムのリスト表示、比較、およびビルド
割り当ては
data Color = Red | Green | Blue | Yellow | Orange | Purple deriving (Eq, Show)
type Code = [Color]
の定義から始まりと列挙型の様々な操作を必要とします。
長のnのすべてのコードを列挙するために(すなわち、長さのすべてのデカルトの組み合わせ:私はcomplete the assignmentに管理してきましたが、私は自分のコードが不必要に反復的または非効率的だと感じたいくつかの部分がありました
Color
値のN)、私はそれだけでColor
のあらゆる可能だとしてこれは、反復的に脆いようでallColors = [Red, Green, Blue, Yellow, Orange, Purple]
を使用しました。列挙型を単独で定義し、それらからリストを作成する方法はありますか?概念的には、
allColors = listAll(Color)
(質問はlistAll
となります)のようにしたいと思います。表現の多くは(
l
、r
はColor
秒である)(if l == r then 1 else 0)
が含まれていますので、私はboolToInt
機能を書いてしまってきました。確かに2つの列挙型を比較し、その結果をより簡単に整数にキャストするいくつかの方法がありますか?つまり、私は解決策の一部は、私はこれは両方思わcountColor :: Color -> Code -> Int countColor _ [] = 0 countColor c (r:rs) = (boolToInt (c == r)) + countColor c rs countColors :: Code -> [Int] countColors code = [countColor c code | c <- allColors]
を使用しなかったこれ、
Code
からヒストグラムを構築する必要が0に評価する
Red == Red
1に評価するため、およびRed == Blue
が欲しいです非効率かつ冗長です。これを行うためのより短い+より効率的な方法がありますか?我々は、我々は> [minBound .. maxBound] :: [Color] [Red,Green,Blue,Yellow,Orange,Purple]
2)整数にブール値に変換するために使用できる
data Color = Red | Green | Blue | Yellow | Orange | Purple deriving (Eq, Show, Enum, Bounded, Ord)
を定義する場合
多くのおかげでそれを実装します。私は本当に1 + 2が好きです。あなたの3も短いですが、対数時間ですか、いいえ?しかし、おそらくそれはHaskell(または一般的な関数型言語)の性質です。 –
@Amiはい、私が書いたとおりです。 O(n log n)時間の代わりにO(n)時間が必要な場合は、配列と左折を使用する必要があります。あなたのコードのこの部分のパフォーマンスが重要であることが分かっていない限り、あまり心配する必要はありません。 – chi
ああ、はい、それを逃した。再び、多くのありがとう! –