2016-05-27 6 views
-2

ı質問があります。 ıバイナリリストを生成したいのですが、リストのメンバ間では1ビットだけ変更されます。すべてのメンバー間でバイナリ1ビットの変更を生成

oneBitAll ::積分A => A - > [[文字列]

nに対する= 2

出力:

[ "00"、 "01"、 "11"、 "10"] [ "00"、 "10"、 "11"、 "01"] VEの

N = 3

oneBitAll 3
[[ "000"、 "001"、 "011" 「001」、「011」、「111」、「101」、「101」、「101」、「101」、 「100」、「110」、「010」、「000」、「001」、「101」、「100」、「110」、「111」、「011」、「010」、 「001」、「101」、「011」、「011」、「010」、「110」、「100」、「000」、「010」、「011」、「001」、「101」、 、 "111"、 "110"、 "100"]、.....]

メンバー間で1ビットだけが変更されます。

助けてください。 this.but私はすべての組み合わせを見つけたいため、これが唯一の

g 0 = [""] 
g n = (map ('0':)) (g (n-1)) ++ (map ('1':)) (reverse (g (n-1))) 

グレイコードを与える

はtrueです。

どのように特定のn個の番号に対してすべてのグレーコードを生成できますか?

permute [] = [[]] 
permute xs = concatMap (\x -> map (x:) $ permute $ delete x xs) xs 
g 0 = [""] 
g n = (map ('0':)) (g (n-1)) ++ (map ('1':)) (reverse (g (n-1))) 
oneBitAll n = (map transpose . permute . transpose $ g n) 

このコードは、可能性の半分を生成します。このコードを追加することはできますか? 012 [001] [011] [010] [110] [111] [101] [100] [000] [010] [011] 「001」、「101」、「111」、「110」、「100」、「000」、「001」、「101」、「100」、「110」、「111」、「011」 「001」、「001」、「000」、「100」、「100」、「100」、「100」、「101」、 「001」、「011」、「111」、「110」、「010」、「000」、「100」、「110」、「010」、「011」、「111」、 "101"、 "001"]]

12人のメンバーを生成する必要があります。

+0

難しいですか?どのようにできますか? – rooney

+0

google "グレーコード" – ErikR

+0

ありがとうございますが、これはすべての可能性を与えるでしょうか? – rooney

答えて

0

グレーコードの構造の多くを利用する、これを行うよりスマートな方法があります。この方法はすばやく汚れていますが、かなりうまくいくようです。

基本的な考え方は、ビットストリングのすべてのシーケンスを生成し、グレーコードでないものを除外することです。ただし、各シーケンスの接頭辞をチェックして、グレイコードに拡張できる可能性があることを確認し、接頭辞を整理することはできないという点で、少し巧妙になります。

  • 連続したビット列の各ペアは、正確に一つの場所に異なります。私たちの目的のために

    は、グレイコードは、5つのプロパティを持つことになります。

  • シーケンスはサイクリックです。最初と最後のビットストリングもちょうど1か所で異なります。
  • シーケンス内の2つのビットストリングは等しくありません。
  • ビットストリング長nのコードは2^n個の要素を持っています。
  • 循環対称性を破るために、すべてのコードはすべてゼロのビット列で開始します。これらの特性の

3つのコードプレフィックスに表すことができる環状の条件のみ終了コードに適用され、のように書くことができる

import Control.Monad 
import Data.List 

validCodePrefix xss = nearbyPairs && unique && endsWithZeros where 
    nearbyPairs = all (uncurry nearby) (zip xss (tail xss)) 
    unique = all ((1==) . length) . group . sort $ xss 
    endsWithZeros = all (all (=='0')) (take 1 (reverse xss)) 

nearby xs xs' = length [() | (x, x') <- zip xs xs', x /= x'] == 1 

cyclic xss = nearby (head xss) (last xss) 

我々は実現することができます適切な長さのビットストリングから繰り返し選択し、有効なものだけを保持することによって、同じ時間に長さ条件を検索して実施します。

codes n = go (2^n) [] where 
    go 0 code = [reverse code | cyclic code] 
    go i code = do 
     continuation <- replicateM n "01" 
     guard (validCodePrefix (continuation:code)) 
     go (i-1) (continuation:code) 
+0

おかげで多くの良い答え – rooney

関連する問題