สร้างบิตพาริตี


18

บิตพาริตีเป็นหนึ่งในรูปแบบที่ง่ายที่สุดของการตรวจสอบ ขั้นแรกคุณต้องเลือกพาริตี้แม้กระทั่งหรือคี่ สมมติว่าเราเลือกได้ ตอนนี้เราต้องการข้อความที่จะส่ง สมมติว่าข้อความของเราคือ "Foo" สิ่งนี้เขียนในรูปแบบไบนารี่เป็น:

01000110 01101111 01101111

ตอนนี้เรานับจำนวนทั้งหมดของ1ที่นั่นนั่นคือ 15 เนื่องจาก 15 เป็นเลขคี่เราจะต้องบวกหนึ่งบิตเพิ่มเข้าไปที่ส่วนท้ายของข้อความของเราและตอนนี้เราจะมีจำนวนบิต 'บน' . บิตที่เพิ่มล่าสุดนี้เรียกว่า "บิตพาริตี" หากเราเลือกพาริตี้คี่สำหรับเช็คซัมของเราเราจะต้องเพิ่มพิเศษ '0' เพื่อให้จำนวนบิตบนยังคงแปลก

ความท้าทาย:

คุณต้องเขียนโปรแกรมหรือฟังก์ชั่นที่กำหนดบิตพาริตี้ที่ถูกต้องสำหรับสตริง โปรแกรมของคุณจะต้องมีสองอินพุต:

  • sสตริง, นี่คือข้อความที่จะทำการคำนวณการตรวจสอบ สิ่งนี้จะถูก จำกัด ไว้ที่ 95 อักขระ ASCII ที่พิมพ์ได้

  • อักขระหรือสตริงอักขระเดี่ยวpที่จะเป็นแบบeพาริตีคู่หรือoสำหรับพาริตีคี่

และสร้างค่าความจริงที่เป็นเท็จซึ่งแสดงถึงบิตพาริตีที่ถูกต้อง Truthy ถ้าเป็น1และ falsey 0ถ้ามันเป็น

ไม่อนุญาตให้ใช้บิวด์อินที่นับจำนวนบิต "บน" ในสตริงหรืออักขระ ตัวอย่างเช่นฟังก์ชั่นfที่ทำสิ่งนี้: f('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มีความเท่าเทียมกัน
Neil

คุณช่วยอธิบาย"Builtins ที่นับจำนวนบิต" กับ "ในสตริงหรืออักขระไม่ได้หรือไม่ ดีกว่านี้ไหม? สิ่งที่เกี่ยวกับการแปลงฐานในตัว? อื่น ๆ ..
orlp

@DrGreenEggsandHamDJ ความคิดเห็นเกี่ยวกับไซต์สแต็กมีความผันผวนและอาจหายไปโดยไม่มีการเตือนล่วงหน้าโดยไม่มีเหตุผล เป็นผลให้มีการสนับสนุนอย่างมากว่ารายละเอียดสำคัญที่รวมอยู่ในความท้าทายนั้นไม่ได้อยู่ในส่วนความคิดเห็น
แมว

1
@cat ตัวอย่างเช่นในหลาม: str(int(s, 2)).count('1')? ไม่ฉันจะไม่พิจารณาว่าจะเป็นซิงเกิ้ลฟังก์ชั่นในตัวที่ละเมิดกฎที่ การแก้ไขของฉันทำให้ชัดเจนยิ่งขึ้นหรือไม่
DJMcMayhem

1
@cat char == single_char_stringเท่าที่ฉันกังวล ฉันยังแก้ไขที่โพสต์
DJMcMayhem

คำตอบ:


9

MATL , 8 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 ไบต์

เพราะคุณรู้ชวา

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

BiFunction<String, Character, Boolean>นี่คือแลมบ์ดาสำหรับเป็น

eและoดูเหมือนจะกลับรายการในคำสั่งส่งคืนเนื่องจากเห็นได้ชัดว่าตรรกะของฉันย้อนหลัง


5

Python 2, 51 ไบต์

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

นี่ขึ้นอยู่กับแนวคิดของ Sp3000 ที่จะนับ 1 ในการแสดงสตริงของรายการของรหัสตัวละครในรูปแบบไบนารีแทนที่จะรวมสำหรับตัวละครแต่ละตัว

เคล็ดลับใหม่คือการจัดการeและoในเรื่องนี้เช่นกัน หากeเป็นเลขคี่และoแม้กระทั่งเราสามารถเติมบิตพาริตีลงในสตริงก่อนทำการนับ (พลิกพวกเขาเพราะ '1' เป็นความจริง) น่าเสียดายที่พวกเขาไม่ได้ แต่ถ้าเราลบทั้งหมดยกเว้นบิตสุดท้ายของพวกเขาตอนนี้ก็จริง

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
ฉันเป็นตัวฉันเองพยายามหาคำตอบของ Jelly แต่กฎการผูกมัดเหล่านั้นทำให้ฉัน :-)
Luis Mendo

2
@ LuisMendo ฉันอยู่ในเรือลำเดียวกัน นี่เป็นคำตอบแรกของฉันหลังจากที่พยายามที่จะเรียนรู้มันนาน ... นานเกินไป: P
Doorknob

นั่นV}... อันนั้นเจ๋งจริงๆ !!! (เดนนิสเป็นนักกอล์ฟตัวจริง) +1 มันเอาชนะทุกความพยายามของฉัน
Erik the Outgolfer

4

C, 62 ไบต์

  • บันทึก 12 ไบต์ด้วย @LevelRiverSt และ @TonHospel

แฮคเกอร์มีคุณสมบัติที่ดีที่สามารถใช้เพื่อลดสตริงลงไปที่หนึ่งอักขระในขณะที่รักษาความเท่าเทียมกัน

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

Ideone


1
27030>>((p^p>>4)&15)&1 ควรคำนวณความเท่าเทียมกันของ p และสั้นกว่า 1 ไบต์
Ton Hospel

1
พื้นที่ในchar *sนั้นถูก จำกัด
Ton Hospel

2
62 ไบต์: มักจะกลับ 0 0 แต่อาจจะกลับมา 1 หรือ 2 สำหรับ 1 นี้เป็นที่ยอมรับภายใต้กฎ: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. เห็นได้ชัดว่า ;-)
Digital Trauma

@ LevelRiverSt ยอดเยี่ยม! ขอบคุณ!
Digital Trauma

4

Python 58 58ไบต์

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

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

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 ไบต์ในตัวมันเอง ...

รับอินพุต$aและการแคส$bต์อย่างชัดเจน$aเป็นอักขระอาเรย์ในกระบวนการ จากนั้นเราจะตรวจสอบว่า$bเป็น-eqUAL ไปoและ-xorกับอีกครึ่งหนึ่งของโปรแกรม สำหรับส่วนที่เราใช้สายป้อน$aท่อมันผ่านห่วงการแปลงจดหมายถึงไบนารีแต่ละ-joinทั้งหมดเข้าด้วยกันเหล่านั้นในรูปแบบสตริงของแข็งหนึ่งและ-replaceทุก0วินาทีกับอะไร จากนั้นเรานับ.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 ]

?เป็นเหมือนผู้ประกอบการที่ประกอบไปด้วย: มันทดสอบความจริงของรายการสแต็กที่สามและเลือกtrueค่าหรือfalseค่า

มันประมาณคร่าวๆกับ pseduocode แบบ C ต่อไปนี้:

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และอาร์กิวเมนต์ที่สอง (ถ่าน) dlใน มันส่งคืนผลลัพธ์eaxดังนั้นจึงเข้ากันได้กับfastcallแบบแผนการโทร

รหัสนี้โค้งกฎเมื่อใช้setpoคำสั่ง:

ไม่อนุญาตให้ใช้บิวด์อินที่นับจำนวนบิต "บน" ในสตริงหรืออักขระ

คำสั่งนี้ตั้งค่าalเป็นบิตพาริตีที่คำนวณโดยคำสั่งก่อนหน้า - ดังนั้นฉันจึงมี nitpicks สองตัวนี้ในกฎ:

  • มันไม่นับจำนวนบิต "กับ" - คำนวณบิตพาริตีโดยตรง!
  • ในทางเทคนิคมันเป็นคำสั่งก่อนหน้า ( 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ซึ่งทำให้เรามีสตริงของ ดัชนีสุดท้ายของสตริงนั้นคือจำนวนของดัชนี เราใช้ XOR นี้ด้วย 1 ถ้าอักขระที่ให้ไว้คือoและ 0 มิฉะนั้นรับพาริตีโดยใช้ bitwise และ 1

ลองออนไลน์! (รวมถึงกรณีทดสอบทั้งหมด)

บันทึกไปแล้ว 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 ไบต์


ว้าวดีมาก! คุณสามารถตีสองไบต์ได้โดยใช้²คำสั่ง สิ่งนี้จะผลักดันอินพุตที่สองที่ด้านบนของสแต็กโดยอัตโนมัติ นอกจากนี้สายสองถ่านสามารถ shortend ใช้ ดังนั้นจะเทียบเท่ากับ"oe" สำหรับ 13 ไบต์: €ÇbSOÈ„oe²k<^:)
Adnan

05AB1E ใช้การเข้ารหัสCP-1252ดังนั้นอักขระแต่ละตัวที่นี่คือ 1 ไบต์ :)
Adnan

@Adnan: ขอบคุณ! ใช้ notepad ++ สำหรับ bytecount และเพิ่งคิดว่ามันนับตัวอักษร: P
Emigna

0

Ruby, 57 ไบต์

หาก0เป็นเท็จในทับทิม==อาจจะเปลี่ยนเป็นเพียง-หรืออาจมีการเพิ่มประสิทธิภาพอื่น ๆ แต่ก็ไม่ได้

->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 กลับพวกเขาในการสั่งซื้อน้อย endian ดังนั้นโดยการวางธงแพริตีที่ส่วนท้ายของสตริงของเราแกะสิ่งทั้งหมดและวางบิตสุดท้าย 5 บิตจากนั้นเราสามารถสรุปสิ่งทั้งหมด mod 2 สำหรับคำตอบที่ดีที่สุดของเรา

การใช้งาน:

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

0

 เสียงกระเพื่อมสามัญ, 87

(lambda(s p)(=(mod(reduce'+(mapcar'logcount(map'list'char-code s)))2)(position p"oe")))
  • รวม logcount ของรหัสถ่านของ sของถ่านรหัสของ
  • ส่วนที่เหลือของสิ่งนี้เมื่อหารด้วย 2 จะถูกเปรียบเทียบกับตำแหน่งของอาร์กิวเมนต์ parity pในสตริง"oe"(ทั้ง 0 หรือ 1) ตัวอย่างเช่นหากมี 4 รายการส่วนที่เหลือเป็นศูนย์ ถ้า p คือoดังนั้นไม่ควรเพิ่มบิตเพิ่มเติมและการทดสอบกลับเท็จ

พริตตี้พิมพ์

(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 แทนบูลีน

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

เครื่องมือทุบตีและยูนิกซ์ (72 ไบต์)

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

ยกเว้นsเป็นpอาร์กิวเมนต์แรกและอาร์กิวเมนต์ที่สอง โชคดีที่ 3 บิตสุดท้ายoและ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เป็นคู่ดังนั้นจึงไม่ใช่ปัญหา

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.