产生奇偶校验位


18

奇偶校验位,是的校验的最简单的形式之一。首先,您必须选择奇偶校验。假设我们选择了偶数。现在,我们需要一条消息来传输。假设我们的信息是“ Foo”。用二进制形式写成:

01000110 01101111 01101111

现在,我们计算其中1的s 的总数为15。由于15是一个奇数,因此我们必须在消息末尾添加一个额外的位,而现在我们将获得偶数个“ on”位。最后添加的位称为“奇偶校验位”。如果我们为校验和选择了奇数奇偶校验,则必须添加一个额外的“ 0”,以便打开位数保持为奇数。

挑战:

您必须编写一个程序或函数来确定字符串的正确奇偶校验位是多少。您的程序必须接受两个输入:

  • 字符串,s。这是将计算校验和的消息。这将仅限于95个可打印的ASCII字符。

  • 一个字符或单个字符串p,将e用于偶校验或o奇校验。

并产生代表正确奇偶校验位的真假值。如果是1,则为True,如果为,则为false 0

不允许对字符串或字符中的“ on”位数进行计数的内建函数。例如,执行以下操作的函数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

这是代码高尔夫球,因此存在标准漏洞,并且以字节为单位的最短答案为胜。

排行榜


10
相当烦人,o甚至具有同等价值。
尼尔

您是否可以澄清“不允许对字符串或字符中的“ on”位数进行计数的构建程序”。好一点?内置基本转换如何?等等
orlp 2016年

@DrGreenEg​​gsandHamDJ在Stack网站上的注释易变,并且会以任何有能力的用户心血来潮而无故消失而无故警告。因此,强烈建议将挑战所必需的规范放在帖子本身,而不是评论部分。

1
@cat例如,在蟒蛇:str(int(s, 2)).count('1')?不,我不认为这是一个单一的内置函数有违反规则。我的编辑内容是否更清楚?
DJMcMayhem

1
@cat就我而言char == single_char_string。我也将其编辑到帖子中。
DJMcMayhem

Answers:


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;}

这是一个lambda 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)。不幸的是,事实并非如此。但是,如果我们除去除它们的最后两位以外的所有位,那么现在是正确的。

e 0b11001|01
o 0b11011|11 

这是通过删除第一个 9字符串表示形式字符来完成的。

['0b11001|01', 

哇,这是一种非常整洁的处理方式eo
Sp3000 '16

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
门把手

那个V}...真的很棒!!!(丹尼斯是一名真正的高尔夫球手)+1它击败了我的每一次尝试。
暴民埃里克(Erik the Outgolfer)'16年

4

C,62字节

  • @LevelRiverSt和@TonHospel节省了12个字节。

XOR具有不错的属性,它可用于将字符串缩减为一个字符,同时保留奇偶校验。

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个字节
Ton Hospel

1
里面的空间char *s没有装饰-Ton Hospel
'16

2
62字节:f(s,p)char*s;{for(p/=8;*s;)p^=*s>>4^*s++;p^=p/4;return p%4%3;}所述%3将始终为0返回0,但也可以返回1或2所述的1。这是根据规则可接受的:truthy if it's a 1
等级河圣

1
27030>>((p^p>>4)&15)&1。好吧,很明显。;-)
Digital Trauma 2016年

@LevelRiverSt辉煌!谢谢!
Digital Trauma'Apr

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 2016年

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字节

/我在角落哭

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

是的...因此,基本转换不适用于PowerShell。从输入字符串到二进制表示的转换$a|%{[convert]::toString(+$_,2)}本身是32个字节...

在过程中将input $a$b显式转换$a为char数组。然后,我们检查是否$b-equal o以及-xor该程序的另一半相同。对于这一部分,我们采用输入字符串$a,将其通过循环传递给每个字母,将其转换为二进制,将所有字母-join组合成一个实心字符串,而-replace所有0s都没有任何内容。然后.length,我们计算该字符串的,并将其作为mod-2来确定它是偶数还是奇数,这很方便0 or来说1非常理想的-xor

将返回TrueFalse相应地。请参阅下面的测试用例:

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 ]

?就像一个三元运算符:它测试第三个堆栈项的真实性,然后选择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个字节

十六进制转储:

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第二个参数(字符)dl。它返回中的结果eax,因此与兼容fastcall调用约定。

此代码在使用setpo指令时会弯曲规则:

不允许对字符串或字符中的“ on”位数进行计数的内建函数

该指令设置al为上一条指令计算的奇偶校验位-因此,我在规则上有以下两个技巧:

  • 它不计算“ on”位的数量-它直接计算奇偶校验位!
  • 从技术上讲,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,因为我希望在寄存器中拥有数字0(ah在这种情况下),以便能够以正确的顺序(0, [ecx]而不是[ecx], 0)进行比较。


1

朱莉娅58 47 45 40字节

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

这是一个接受字符串和字符并返回整数的函数。

要获取二进制表示形式中的位数,我们首先应用 bin函数应用于字符串中的每个字符,从而为我们提供了二进制字符串数组。然后将它们简化为一个prod(因为*在Julia中是字符串连接),并采用该字符串与的字符代码的交集1,从而得到一串字符串。该字符串的最后一个索引是个数。如果提供的字符为o,则将其与1进行异或,否则将其与0进行异或,然后使用按位与1获得奇偶校验。

在线尝试!(包括所有测试用例)

感谢Dennis,节省了18个字节!


1

05AB1E 15,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 È

感谢Adnan节省2个字节。


哇,很棒!您可以使用以下²命令打高尔夫球两个字节。这会自动将第二个输入推入堆栈顶部。另外,可以使用来缩短两个字符的字符串。所以"oe"等于。对于13个字节:€ÇbSOÈ„oe²k<^:)
Adnan

05AB1E也使用CP-1252编码,因此此处的每个字符均为1个字节:)。
阿德南

@Adnan:谢谢!使用notepad ++进行字节计数,并假设它已计算chars:P
Emigna '16

0

Ruby,57个字节

如果0在Ruby中是假的,则==可能会将其切换为just -,或者可能会有其他优化,但事实并非如此。

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

0

视网膜,102字节

在第一行获取字符串,在第二行获取字母。使用ISO 8859-1编码。

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

在线尝试

第一行中的字符类与二进制表示形式中具有奇数个字符的任何字符匹配。

此处介绍使用regex进行偶数/奇数检测的工作方式。


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

 常见的Lisp,87

(lambda(s p)(=(mod(reduce'+(mapcar'logcount(map'list'char-code s)))2)(position p"oe")))
  • 总计的字符数的对数计数s
  • 将其其余部分除以2,将其p与字符串中奇偶校验参数的位置"oe"(0或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而不是boolean来去除一些字符。

这是一个lambda BiFunction<String, Character, Boolean>


0

Matlab,49个字节

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

哪里:

  • x是输入字符串;
  • 对于偶数校验,p是“ e”,对于奇数校验,p是“ 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第二个参数除外。幸运的是,o和的后3位e分别具有奇偶校验。

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是偶数,因此这不是问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.