パリティビットを生成する


18

パリティビットは、チェックサムの最も単純な形態の一つです。まず、偶数または奇数のパリティを選択する必要があります。偶数を選択するとしましょう。次に、送信するメッセージが必要です。メッセージが「Foo」だとしましょう。これは次のようにバイナリで書かれています。

01000110 01101111 01101111

ここで、115の合計数をカウントします。15は奇数であるため、メッセージの最後に1ビットを追加する必要があり、偶数の「オン」ビットがあります。 。この最後に追加されたビットは、「パリティビット」と呼ばれます。チェックサムに奇数パリティを選択した場合、オンビットの数が奇数のままになるように、余分な「0」を追加する必要があります。

チャレンジ:

文字列の正しいパリティビットを決定するプログラムまたは関数を作成する必要があります。プログラムには2つの入力が必要です。

  • 文字列s。これは、チェックサムが計算されるメッセージです。これは、95個の印刷可能なASCII文字に制限されます。

  • 文字または単一の文字列pのいずれかになります、e偶数パリティのために、またはo奇数パリティのために。

正しいパリティビットを表す真偽値を生成します。aの場合は真実1、aの場合は偽です0

文字列または文字の「オン」ビットの数をカウントする組み込み関数は許可されていません。たとえば、これを行う機能ff('a') == 3またはf('foo') == 16禁止されています。基本変換など、その他はすべて公平なゲームです。

テストIO:

(without the quotes)
s: "0"
p: 'e'
output: 0

s: "Foo"
p: 'e'
output: 1

s: "Hello World!"
p: 'o'
output: 0

s: "Alex is right"
p: 'e'
output: 1

s: "Programming Puzzles and Code-Golf" 
p: 'e'
output: 0

s: "Programming Puzzles and Code-Golf" 
p: 'o'
output: 1

これはcodegolfであるため、標準の抜け穴が適用され、バイト単位の最短回答が優先されます。

リーダーボード


10
むしろ迷惑なことに、o同等のものさえあります。
ニール

あなたは明確にすることができます上「の数を数える組み込み関数『』文字列または文字のビットが許可されていませんが。」少し良く?組み込みのベース変換はどうですか?など
-orlp

Stackサイトに関する@DrGreenEg​​gsandHamDJコメントは揮発性であり、有能なユーザーの気まぐれで、理由もなく警告なしに消える可能性があります。そのため、コメントセクションではなく、投稿自体にチャレンジに不可欠な仕様を含めることを強くお勧めします。

1
@catたとえば、Pythonの場合:str(int(s, 2)).count('1')?いいえ、それはそのルールに違反する単一の組み込み関数であるとは考えません。私の編集はそれをより明確にしますか?
DJMcMayhem

1
@cat私に関する限りchar == single_char_string。それをポストに編集しました。
DJMcMayhem

回答:


9

MATL8 7バイト

8\hBz2\

オンラインでお試しください!または、すべてのテストケースを一度に検証します

8\    % Implicitly take first input ('e' or 'o'), and compute modulo 8. Inputs 'e' and 'o' 
      % give 5 or 7 respectively, which have an even or odd number of `1` bits resp.
h     % Implicitly take second input, and concatenate
B     % Convert to binary. Gives 2D array, with one row for each original entry 
z     % Number of nonzero values in that 2D array
2\    % Modulo 2, i.e. compute parity

9

Java、97バイト

なぜなら、Javaを知っているからです。

(s,c)->{boolean e=1>0;for(int i:s.getBytes())while(i>0){if(i%2==1)e=!e;i/=2;}return c=='o'?e:!e;}

これはaのラムダですBiFunction<String, Character, Boolean>

eそしてoどうやら私のロジックが後方だったので、return文で反転されているように見えます。


5

Python 2、51バイト

lambda s,p:`map(bin,map(ord,p+s))`[9:].count('1')%2

これは、Sp3000のアイデアに基づいており、文字ごとに合計するのではなく、バイナリの文字コードのリストの文字列表現で1をカウントします。

新しいトリックはハンドルにあるeo、この中にも。e奇数と偶数の場合o、カウントを実行する前に文字列にパリティビットを追加するだけで済みます(「1」がTruthyであるため、それらを反転します)。残念ながら、そうではありません。しかし、最後の2ビットを除くすべてを削除すると、事実になります。

e 0b11001|01
o 0b11011|11 

これは9、文字列表現の最初の文字を削除することにより行われます。

['0b11001|01', 

うわー、それは本当にすてきな処理方法ですeo
Sp3000

4

ゼリー、9 8バイト

OBFSḂ⁼V}

オンラインでお試しください!

O         convert each character in argument 1 (left arg) to its codepoint (ord)
 B        convert to binary (list of 0s and 1s)
  F       flatten
   S      sum the entire list, giving the number of 1s in the entire string
    Ḃ     mod 2 (take the last bit)
       }  now, with the second (right) argument...
      V   eval with no arguments. This returns...
            1 for e because it expands to 0e0 (i.e., does 0 exist in [0])
            0 for o because it expands to 0o0 (0 OR 0, false OR false, false)
     ⁼    test equality between the two results

デニスのバイトに感謝します!


1
私自身はゼリーの答えを考え出そうとしていましたが、それらの連鎖ルールは私を除外します:
ルイスメンドー

2
@LuisMendo私は同じ船に乗っています。これは、それを学習しようとした後の私の最初のゼリーの答えです...あまりにも長い:P
Doorknob

あのV}...あれは本当にかっこよかった!!! (デニスは本物のゴルファーです)+1あらゆる試みを打ち負かしました。
エリックアウトゴルファー

4

C、62バイト

  • @LevelRiverStと@TonHospelのおかげで12バイト節約されました。

XORには、パリティを維持しながら文字列を1文字に減らすために使用できるという優れたプロパティがあります。

f(s,p)char*s;{for(p/=8;*s;)p^=*s>>4^*s++;p^=p/4;return p%4%3;}

イデオン。


1
27030>>((p^p>>4)&15)&1 pのパリティを計算する必要があり、さらに1バイト短くなります
トンホスペル

1
のスペースchar *sは不要です
トンホスペル

2
62バイト:常に0 0が返され、これは規則の下で許容される1の1又は2を返すことができる:f(s,p)char*s;{for(p/=8;*s;)p^=*s>>4^*s++;p^=p/4;return p%4%3;}%3truthy if it's a 1
レベル・リバーセント

1
27030>>((p^p>>4)&15)&1。まあ、間違いなく、明らかに。;-)
デジタル外傷

@LevelRiverStブリリアント!ありがとう!
デジタル外傷

4

Python、58 57バイト

lambda s,p:sum(bin(ord(c)).count("1")for c in s)&1!=p>'e'

1
53(Python 2のみ):lambda s,p:`map(bin,map(ord,s))`.count('1')%2^(p>'e')
Sp3000

でバイトを保存できます!=p>'e'
-xnor

Pythonがそれを連鎖不平等として扱うため、バイトセーブは実際には機能しません。
-xnor

lambda s,p:`map(bin,map(ord,p+s))`[8:].count('1')%2
-xnor

@xnor自分の答えを投稿するだけです。
orlp

3

Pyth、12バイト

q@"oe"sjCz2w

テストスイート。

         z    take a line of input
        C     convert to int
       j  2   convert to base 2, array-wise (so, array of 0s and 1s)
      s       sum (count the number of ones)
 @"oe"        modular index into the string to get either "o" or "e"
q          w  test equality to second line of input

3

JavaScript(ES6)、84 72バイト

(s,p)=>(t=p>'e',[...s].map(c=>t^=c.charCodeAt()),t^=t/16,t^=t/4,t^t/2)&1

ビット調整は、基数2に変換して1s をカウントするよりも短いことが判明しました。


2

Perl、29バイト

+2を含む -p

STDINの入力をパリティ文字スペース文字列として実行します。たとえば

parity.pl <<< "p Programming Puzzles and Code-Golf"

parity.pl

#!/usr/bin/perl -p
$_=unpack"B*",$_|b;$_=1&y;1;

2

J、27バイト

'oe'&i.@[=[:~:/^:2@#:3&u:@]

使用法

   f =: 'oe'&i.@[=[:~:/^:2@#:3&u:@]
   'e' f '0'
0
   'e' f 'Foo'
1
   'o' f 'Hello World!'
0
   'e' f 'Alex is right'
1
   'e' f 'Programming Puzzles and Code-Golf'
0
   'o' f 'Programming Puzzles and Code-Golf'
1

1

JavaScript(ES6)、69バイト

(s,p)=>[...s].map(c=>{for(n=c.charCodeAt();n;n>>=1)r^=n&1},r=p>"e")|r

1

PowerShell v2 +、91バイト

/ meコーナーで叫ぶ

param([char[]]$a,$b)$b-eq'o'-xor(-join($a|%{[convert]::toString(+$_,2)})-replace0).length%2

ええ...だから、ベース変換はPowerShellの強力なスーツではありません。入力文字列からバイナリ表現への変換$a|%{[convert]::toString(+$_,2)}は、それ自体で32バイトです...

入力$aとを受け取り、プロセス$bで明示的に$achar配列としてキャストします。私たちは、その後、かどうかをチェックし$bている-eqにUALをo、および-xorプログラムの残りの半分とのこと。その部分については、入力文字列を取得$aし、ループを介して各文字をバイナリに変換し、-joinそれらをすべて一緒に1つの固体文字列に変換し、-replaceすべての0sに何も付けません。次に.length、その文字列のをカウントし、mod-2を使用して、偶数か奇数かを判断します。これは、0または1に最適です-xor

TrueまたはFalseそれに応じて返されます。以下のテストケースを参照してください。

PS C:\Tools\Scripts\golfing> .\generate-parity-bit.ps1 "0" e
False

PS C:\Tools\Scripts\golfing> .\generate-parity-bit.ps1 "Foo" e
True

PS C:\Tools\Scripts\golfing> .\generate-parity-bit.ps1 "Hello World!" o
False

PS C:\Tools\Scripts\golfing> .\generate-parity-bit.ps1 "Alex is right" e
True

PS C:\Tools\Scripts\golfing> .\generate-parity-bit.ps1 "Programming Puzzles and Code-Golf" e
False

PS C:\Tools\Scripts\golfing> .\generate-parity-bit.ps1 "Programming Puzzles and Code-Golf" o
True

1

ファクター、85バイト

なんらかの理由で、数分前にコードを単純化した(そして短縮したのかもしれない)まで、この問題に頭を包むことができませんでした。

[ "e" = [ even? ] [ odd? ] ? [ [ >bin ] { } map-as concat [ 49 = ] count ] dip call ]

?三項演算子のようなものです。3番目のスタック項目の真実性をテストし、true値または値を選択しfalseます。

これは、次のCのようなpseduocodeとほぼ同等です。

void* parity_tester_function = strcmp(p, "e") ? (void *) even?  // it's a function pointer (I think)
                                              : (void *) odd? ;

残りのコードは非常に簡単です。

[                       ! to count a string's set bits:
    [ >bin ] { } map-as ! get the binary of each character, and map as an array, because you can't have stringy data nested in another string (that's called a type error)
    concat              ! { "a" "B" } concat -> "aB"
    [ 49 = ] count      ! count items in the resulting string which match this condition (in this case, the condition we're testing is whether the character has the same code point as "1")
] dip                   ! take the above function pointer off the stack, apply this anonymous function to the now-top of the stack, then restore the value after the quotation finishes.
                        ! in other words, apply this quotation to the second-to-top item on the stack
call                    ! remember that conditionally chosen function pointer? it's on the top of the stack, and the number of sets bits is second.
                        ! we're gonna call either odd? or even? on the number of set bits, and return the same thing it does.

1

IA-32マシンコード、15バイト

Hexdump:

0f b6 c2 40 32 01 0f 9b c0 3a 21 41 72 f6 c3

アセンブリコード:

    movzx eax, dl;
    inc eax;
repeat:
    xor al, [ecx];
    setpo al;
    cmp ah, [ecx];
    inc ecx;
    jb repeat;
    ret;

これは、最初の引数(文字列)をecx、2番目の引数(文字)を受け取る関数ですdl。結果をで返すeaxため、fastcall呼び出し規約と互換性があります。

このコードは、setpo命令を使用するときにルールを曲げます:

文字列または文字の「オン」ビットの数をカウントするビルトインは許可されません

この命令はal、前の命令で計算されたパリティビットに設定されます。そのため、ルールには次の2つの点があります。

  • 「オン」ビットの数はカウントしません-パリティビットを直接計算します!
  • 技術的にはxor、パリティビットを計算するのは前の命令()です。setpo命令はのみに移動しalレジスタ。

邪魔にならないこれらのセマンティックの詳細は、ここでコードが何をするかの説明です。

文字の表現は次のとおりです。

'e' = 01100101
'o' = 01101111

それらに1を追加すると、たまたま正しいパリティを持っています。

'e' + 1 = 01100110 (odd parity)
'o' + 1 = 01110000 (even parity)

そのXORため、文字列のすべての文字alをこれらの値に初期化して、答えを出します。


最初の命令はmovzx eax, dl、より明白な(そしてより短い)の代わりですmov al, dl。なぜなら、(ahこの場合)レジスタに数値0を入れて、正しい順序(0, [ecx]ではなく[ecx], 0)で比較できるようにするためです。


1

ジュリア、58 47 45 40バイト

f(s,p)=(p>'e')$endof(prod(bin,s)∩49)&1

これは、文字列と文字を受け取り、整数を返す関数です。

バイナリ表現の1の数を取得するには、まずbin文字列の各文字に関数を適用します。これにより、バイナリ文字列の配列が得られます。次にprod*Juliaの文字列連結であるため)を使用してそれらを1つに減らし、その文字列との文字コードの集合交差を取得し1、1の文字列を取得します。その文字列の最後のインデックスは1の数です。指定された文字がoの場合は1でXORを行い、それ以外の場合はビット単位のAND 1を使用してパリティを取得します。

オンラインでお試しください!(すべてのテストケースを含む)

デニスのおかげで18バイト節約できました!


1

05AB1E15、13のバイト

コード:

€ÇbSOÈ„oe²k<^

入力例:

Programming Puzzles and Code-Golf
o

出力例:

1

説明:

€                 # for each char in string
 Ç                # get ascii value
  b               # convert to binary
   S              # split to single chars (ex: '1101' to '1','1','0','1')
    O             # sum
     È            # check if even
      „oe         # push string "oe"
         ²        # push 2nd input (p)
          k       # get 1-based index of p in "oe"
           <      # decrease (to get either 0-based index)
            ^     # xor with result of È

2バイトを節約してくれたAdnanに感謝します。


わあ、とてもいい!この²コマンドを使用して、2バイトをゴルフで飛ばすことができます。これにより、スタックの2番目の入力が自動的にプッシュされます。また、を使用して2文字の文字列を短縮できます。はと"oe"同等です。13バイトの場合:€ÇbSOÈ„oe²k<^:)
Adnan

05AB1EはCP-1252エンコードも使用するため、ここの各文字は1バイトです:)。
アドナン

@アドナン:ありがとう!バイトカウントにnotepad ++を使用し、charsをカウントしていると仮定しました:P
Emigna

0

ルビー、57バイト

0Rubyでfalseだった場合、==おそらくjust -に切り替えることができます。または、他の最適化があるかもしれませんが、そうではありません。

->s,b{s.gsub(/./){$&.ord.to_s 2}.count(?1)%2==(b>?i?0:1)}

0

網膜、102バイト

1行目に文字列を、2行目に文字を取得します。ISO 8859-1エンコードを使用します。

[12478abdghkmnpsuvyzCEFIJLOQRTWX#%&)*,/;=>@[\]^| ](?=.*¶)
1
[^1](?=.*¶)
0
^(0|10*1)*¶o|^0*1(0|10*1)*¶e

オンラインで試す

最初の行の文字クラスは、バイナリ表現で奇数の1の文字と一致します。

正規表現を使用した偶数/奇数検出の仕組みの説明はこちら


0

オクターブ、56バイト

f=@(s,p) mod(sum((i=bitunpack([s p]))(1:length(i)-5)),2)

bitunpackこの関数は、ASCII文字のために、リトルエンディアンの順序でそれらを返します。したがって、文字列の最後にパリティフラグを置き、すべてをアンパックし、最後の5ビットをドロップすることにより、最終的な答えとしてmod 2全体を合計できます。

使用法:

octave:137> f('Hello World!', 'o')
ans = 0
octave:138> f('Hello World!', 'e')
ans =  1

0

 Common Lisp、87

(lambda(s p)(=(mod(reduce'+(mapcar'logcount(map'list'char-code s)))2)(position p"oe")))
  • の文字コードのログカウントを合計しますs
  • この残りの部分は、2で除算するpと、ストリング内のパリティ引数の位置"oe"(0または1)と比較されます。たとえば、1が4つある場合、残りはゼロです。pがの場合o、追加のビットは追加されず、テストはfalseを返します。

プリティプリント

(lambda (s p)
  (= (mod (reduce '+ (mapcar 'logcount (map 'list 'char-code s))) 2)
     (position p "oe")))

0

Java、91バイト

(s,c)->{s+=c%8;int e=1;for(int i:s.getBytes())while(i>0){if(i%2==1)e^=1;i/=2;}return e==0;}

@ CAT97と同じことをしましたが、モジュロ8と@Luis Mendoの連結を使用していくつかの文字を削除し、ブール値の代わりにintを使用しました。

これはaのラムダですBiFunction<String, Character, Boolean>


0

Matlab、49バイト

f=@(x,p)mod(sum(sum(dec2bin(x)-'0'))+(p-'e'>0),2)

どこ:

  • xは入力文字列です。
  • pは、偶数パリティの場合は「e」、奇数パリティの場合は「o」です。

例えば:

>> f('Programming Puzzles and Code-Golf','e')

ans =

     0

0

BashおよびUnixツール(72バイト)

f(){ bc<<<"$(xxd -b<<<"$2$1"|cut -b9-64|tail -c +7|tr -dc 1|wc -c)%2" }

s最初のp引数および2番目の引数を除きます。幸い最後の3ビットoe、それぞれ奇数と偶数パリティを持っています。

xxd -b        print the concatenation of `p` and `s` in binary
cut -b9-64    parse xxd output
tail -c +7    keep only the last 3 bits of `p`
tr -dc 1      keep only the `1`s
wc -c         count them
bc ...%2      modulo two

入力を介して入力<<<すると改行文字が追加されますが、のパリティ\nは偶数であるため、問題はありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.