ไบต์คู่เท่านั้น


64

สถานการณ์

เมื่อเร็ว ๆ นี้คุณสังเกตเห็นพฤติกรรมแปลก ๆ บางอย่างกับโปรแกรมแก้ไขข้อความที่คุณโปรดปราน ตอนแรกดูเหมือนว่ามันจะไม่สนใจตัวอักษรแบบสุ่มในรหัสของคุณเมื่อเขียนลงดิสก์ หลังจากที่ในขณะที่คุณสังเกตเห็นรูปแบบ; อักขระที่มีค่า ASCII แปลก ๆ กำลังถูกละเว้น ภายใต้การตรวจสอบเพิ่มเติมคุณพบว่าคุณสามารถเขียนไปยังไฟล์ได้อย่างถูกต้องหากทุกๆแปดบิตเป็นศูนย์ ตอนนี้คุณต้องรู้ว่าไฟล์ที่มีค่าของคุณได้รับผลกระทบจากข้อผิดพลาดแปลก ๆ นี้หรือไม่

งาน

คุณต้องเขียนโปรแกรมที่สมบูรณ์ที่กำหนดว่าไฟล์มีไบต์คี่ใด ๆ (แสดงให้เห็นว่าไม่มีการขัดจังหวะ) แต่เนื่องจากโปรแกรมแก้ไขข้อความของคุณคุณไม่สามารถเขียนไบต์แปลก ๆ ในซอร์สโค้ดของคุณได้ คุณอาจสันนิษฐานว่ามีการเข้ารหัสที่มีอยู่ล่วงหน้าสำหรับการป้อนข้อมูลอย่างไรก็ตามคุณยังต้องตรวจสอบทุกไบต์แต่ละตัวไม่ใช่เฉพาะอักขระ

อินพุต

โปรแกรมของคุณจะนำเนื้อหาหรือพา ธ ไปยังไฟล์จาก stdin หรือบรรทัดคำสั่ง

เอาท์พุต

โปรแกรมของคุณจะส่งออกไปยัง stdout เป็นค่าจริงหากไฟล์ที่กำหนดมีไบต์คี่หรือเท็จถ้าทุก ๆ แปดแปดเป็นศูนย์

เกณฑ์

นี่คือรหัสกอล์ฟโปรแกรมที่สั้นที่สุดที่จะทำให้งานสำเร็จลุล่วง หากต้องการส่งที่ถูกต้องทุก ๆ แปดบิตในซอร์สโค้ดไฟล์จะต้องเป็นศูนย์ ฉันอยากจะแนะนำรวมถึงสำเนาของไบนารีซอร์สโค้ดของคุณในการส่งของคุณ

ช่องโหว่มาตรฐานใช้

กรณีทดสอบ

(ในการเข้ารหัส ASCII) อินพุต:

"$&(*,.02468:<>@BDFHJLNPRTVXZ\^`bdfhjlnprtvxz|~

Output:
falsy

Input:
!#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}

Output:
truthy

Input:
LOREMIPSVMDOLORSITAMETCONSECTETVRADIPISCINGELITSEDDOEIVSMODTEMPORINCIDIDVNTVTLABOREETDOLOREMAGNAALIQVA
VTENIMADMINIMVENIAMQVISNOSTRVDEXERCITATIONVLLAMCOLABORISNISIVTALIQVIPEXEACOMMODOCONSEQVAT
DVISAVTEIRVREDOLORINREPREHENDERITINVOLVPTATEVELITESSECILLVMDOLOREEVFVGIATNVLLAPARIATVR
EXCEPTEVRSINTOCCAECATCVPIDATATNONPROIDENTSVNTINCVLPAQVIOFFICIADESERVNTMOLLITANIMIDESTLABORVM

Output:
truthy

เคล็ดลับ

  • เลือกภาษาอย่างฉลาดความท้าทายนี้อาจเป็นไปไม่ได้ในทุกภาษา

  • คำสั่ง Unix xxd -b <file name>จะพิมพ์ไบนารีของไฟล์ไปยังคอนโซล (พร้อมกับการจัดรูปแบบบางอย่างเพิ่มเติม)

  • คุณสามารถใช้การเข้ารหัสอื่นที่ไม่ใช่ ASCII เช่น UTF-8 ตราบใดที่ปฏิบัติตามกฎอื่น ๆ


2
บางภาษามีการอ่านอินพุตหลายบรรทัดได้ยาก แต่ไม่ใช่ความท้าทายนี้หมายถึงเป็นเรื่องง่ายดังนั้นจึงอาจใช้ได้ : P อินพุตว่างเปล่าได้ไหม
เดนนิส

9
!#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}เป็นอักขระ ASCII ที่พิมพ์ได้ซึ่งถูกแบนสำหรับทุกคนที่ใส่ใจ อักขระ ASCII ที่พิมพ์ได้ที่อนุญาตคือ" $&(*,.02468:<>@BDFHJLNPRTVXZ\^`bdfhjlnprtvxz|~
Patrick Roberts

9
ค่อนข้างมีประโยชน์ที่สระทั้งหมดถูกแบน ... ;-)
owacoder

4
ยินดีมากที่ BF มีโอกาสในการท้าทายนี้
TLW

2
โปรดทราบด้วยว่าหากคุณมีตัวแบ่งบรรทัดใด ๆ ในไฟล์ DOS / Windows แสดง[CR]ว่าบิตนั้นแปลก ผมหวังว่าช่องว่างความปลอดภัย [TAB]แต่อนิจจา หากคุณต้องการไปโรงเรียนเก่า EBCDIC ให้เสียงสระสามเสียง
GuitarPicker

คำตอบ:



21

Befunge ขนาด 36 ไบต์

ฉันรู้ว่านี่เป็นคำถามเก่า แต่ฉันต้องการที่จะลองเพราะฉันคิดว่ามันจะเป็นความท้าทายที่น่าสนใจใน Befunge

>~:0`|
>20`:>$.@
|` " "<
*8*82<^p24*

ลองออนไลน์!

มันจะส่งผล1ถ้าอินพุตเสียหาย (เช่นมีไบต์คี่) และ0ถ้ามันตกลง

คำอธิบาย

ปัญหาคือวิธีการกำหนดไบต์คี่โดยไม่ต้องเข้าถึงคำสั่ง/(หาร) หรือ%(modulo) วิธีแก้คือการคูณค่าด้วย 128 (ลำดับ28*8**) จากนั้นเขียนผลลัพธ์นั้นลงในสนามแข่งขัน สำหรับล่ามมาตรฐานอย่างเคร่งครัดเซลล์ playfield จะได้รับการลงนามค่า 8 บิตดังนั้นเลขคี่คูณด้วย 128 จะถูกปัดเศษเป็น -1 ในขณะที่เลขคู่จะกลายเป็น 0

เคล็ดลับอื่น ๆ ในการอ่าน -1 หรือ 0 กลับมาจาก playfield โดยไม่ต้องเข้าถึงgคำสั่ง (get) วิธีแก้ปัญหาสำหรับสิ่งนี้คือการเขียนค่าลงในกึ่งกลางของลำดับสตริงที่มีอยู่ ( " ") จากนั้นดำเนินการลำดับนั้นเพื่อผลักดันค่าที่ล้อมรอบไปยังสแต็ก ณ จุดนั้นการพิจารณาความผิดปกติของไบต์คือการทดสอบที่น้อยกว่าศูนย์อย่างง่าย

ประเด็นสุดท้ายที่ควรพูดถึงคือผลลัพธ์ ในกรณีที่ผิดเราไปถึง>$.ลำดับที่มีเพียงหนึ่งค่าบนสแต็กดังนั้น$ล้างสแต็กที่ทำให้.เอาต์พุตเป็นศูนย์ 20`:>$.ในกรณีที่จริงเราปฏิบัติตามเส้นทาง เนื่องจากสองมีค่ามากกว่าศูนย์การเปรียบเทียบจึงส่งหนึ่งรายการไปยังสแต็กและ:ทำให้สำเนาที่ซ้ำกันดังนั้น$จะไม่ลดลงก่อนที่จะได้รับผลลัพธ์


1
นี่อาจจะช้าและใหม่ แต่ก็เป็นคำตอบที่ฉันชอบอยู่แล้ว
ข้าวสาลีตัวช่วยสร้าง

@WeatWizard ฉันเพิ่งรู้ตอนนี้ว่าทำไมคำตอบนี้ได้รับความสนใจมาก ขอบคุณสำหรับความโปรดปราน!
James Holderness

12

CJam (11 ไบต์)

"r2":(~f&2b

การสาธิตออนไลน์

การเลาะเทคนิคเพื่อหลีกเลี่ยงไบต์คี่ซึ่งจะลดลง

q1f&2b

ซึ่งอ่านอินพุตแม็พ bitwise และด้วย1จากนั้นทำการแปลงฐานทำให้ iff ทั้งหมดเป็นศูนย์


3
รหัสนี้เป็นที่น่าเศร้า:(
เดิมพัน

เพราะสามารถมีได้เพียงครึ่งเดียวของตัวอักษร @betseg
Roman Gräf

9

ไฟล์. COM ขนาด 100 ไบต์

^FZjfDXVL\,LPXD$$4"PXD,lHPXDjJXDRDX@PXDjtXDH,nPXDj@XD4`@PXD,ZHPXD4,@PXD4:4"PXDH,\PXD4"PXD,hPXDRDX@P\

hexdump:

00000000  5e 46 5a 6a 66 44 58 56  4c 5c 2c 4c 50 58 44 24  |^FZjfDXVL\,LPXD$|
00000010  24 34 22 50 58 44 2c 6c  48 50 58 44 6a 4a 58 44  |$4"PXD,lHPXDjJXD|
00000020  52 44 58 40 50 58 44 6a  74 58 44 48 2c 6e 50 58  |RDX@PXDjtXDH,nPX|
00000030  44 6a 40 58 44 34 60 40  50 58 44 2c 5a 48 50 58  |Dj@XD4`@PXD,ZHPX|
00000040  44 34 2c 40 50 58 44 34  3a 34 22 50 58 44 48 2c  |D4,@PXD4:4"PXDH,|
00000050  5c 50 58 44 34 22 50 58  44 2c 68 50 58 44 52 44  |\PXD4"PXD,hPXDRD|
00000060  58 40 50 5c                                       |X@P\|
00000064

การใช้คำจำกัดความของแหล่งข้อมูลที่หลวมมากเป็นสิ่งที่มนุษย์สามารถพิมพ์ได้อย่างสมเหตุสมผลและได้รับแรงบันดาลใจจากไฟล์ทดสอบไวรัสมาตรฐาน EICAR (ข้อมูลเพิ่มเติมที่"มาสนุกกับไฟล์ทดสอบ EICAR"ที่ Bugtraq)

ใช้เฉพาะ ASCII แบบไม่พิมพ์ที่ไม่ใช่คี่ (หมายเหตุด้านข้าง: opcode ที่มีผลต่อคำต่าง ๆ มีแนวโน้มที่จะเป็นเลขคี่บิต W คือ lsb ของบางส่วนของ opcodes) มันสร้างส่วนของรหัสที่ SP (ซึ่งเราตั้งค่าไว้อย่างสะดวก และการดำเนินการจะจบลงด้วยการสร้างรหัส

มันใช้ข้อเท็จจริงที่ว่าสแต็กในตอนแรกมีตัวชี้ใกล้ถึงจุดเริ่มต้นของ PSP และจุดเริ่มต้นของ PSP นั้นมีINT 20hคำสั่ง (ข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้ที่https://stackoverflow.com/questions/12591673/ )

แหล่งที่มาจริง:

; we want to generate the following fragment of code

;  5E                pop si             ; zero SI (pop near pointer to start of PSP)
;  46                inc si             ; set SI to 1
; loop:
;  B406              mov ah,0x6         ; \
;  99                cwd                ; >
;  4A                dec dx             ; > D-2106--DLFF
;  CD21              int 0x21           ; > DIRECT CONSOLE INPUT
;  7405              jz end             ; > jump if no more input
;  40                inc ax             ; > lsb 0/1 odd/even
;  21C6              and si,ax          ; > zero SI on first odd byte
;  EBF3              jmp short loop     ; /
; end:
;  96                xchg ax,si         ; return code
;  B44C              mov ah,0x4c        ; D-214C
;  CD21              int 0x21           ; TERMINATE WITH RETURN CODE

 pop si             ; this two opcodes don't need to be encoded
 inc si

 pop dx             ; DX = 20CD (int 0x20 at start of PSP)
 push byte +0x66
 inc sp
 pop ax
 push si
 dec sp
 pop sp             ; SP = 0x0166
 sub al,0x4c        ; B4
 push ax
 pop ax
 inc sp
 and al,0x24
 xor al,0x22        ; 06
 push ax
 pop ax
 inc sp
 sub al,0x6c
 dec ax             ; 99
 push ax
 pop ax
 inc sp
 push byte +0x4a    ; 4A
 pop ax
 inc sp
 push dx            ; [20]CD
 inc sp
 pop ax
 inc ax             ; 21
 push ax
 pop ax
 inc sp
 push byte +0x74    ; 74
 pop ax
 inc sp
 dec ax
 sub al,0x6e        ; 05
 push ax
 pop ax
 inc sp
 push byte +0x40    ; 40
 pop ax
 inc sp
 xor al,0x60
 inc ax             ; 21
 push ax
 pop ax
 inc sp
 sub al,0x5a
 dec ax             ; C6
 push ax
 pop ax
 inc sp
 xor al,0x2c
 inc ax             ; EB
 push ax
 pop ax
 inc sp
 xor al,0x3a
 xor al,0x22        ; F3
 push ax
 pop ax
 inc sp
 dec ax
 sub al,0x5c        ; 96
 push ax
 pop ax
 inc sp
 xor al,0x22        ; B4
 push ax
 pop ax
 inc sp
 sub al,0x68        ; 4C
 push ax
 pop ax
 inc sp
 push dx            ; [20]CD
 inc sp
 pop ax
 inc ax
 push ax            ; 21
 pop sp             ; now get the stack out of the way

9

MATL , 7 ไบต์

l$Z$2\z

ซอร์สโค้ดใช้การเข้ารหัส UTF-8 ดังนั้นแหล่งที่มาของไบต์จึงเป็นทศนิยม

108    36    90    36    50    92   122

อินพุตเป็นชื่อไฟล์ซึ่งถูกใช้เป็นสตริงที่อยู่ในเครื่องหมายคำพูดเดี่ยว เอาต์พุตคือจำนวนไบต์คี่ในไฟล์ซึ่งเป็นจริง iff ที่ไม่ใช่ศูนย์

คำอธิบาย

l    % Push a 1. We use `l` instead of `1` to have an even value
$    % Input specificication. This indicates that the next function takes 1 input
Z$   % Input file name implicitly, read its raw bytes and push them as an array of chars
2\   % Modulo 2
z    % Number of nonzero values. This gives the number of odd bytes. Implicitly display

8

CJam, 18 17 15 ไบต์

"<rj":(((*~:|X&

สมมติว่าโลแคลถูกตั้งค่าเป็น Latin-1 ลองออนไลน์!

มันทำงานอย่างไร

ทางออกที่ตรงไปตรงมาจะเป็นดังนี้

q       e# Read all input from STDIN and push it as a string on the stack.
 :i     e# Cast each character to its code point.
   :|   e# Take the bitwise OR of all code points.
     X  e# Push 1.
      & e# Take the bitwise AND of the logical OR and 1.

น่าเสียดายที่ตัวอักษรqและiไม่สามารถปรากฏในซอร์สโค้ด เมื่อต้องการแก้ไขปัญหานี้เราจะสร้างส่วนหนึ่งของซอร์สโค้ดด้านบนแบบไดนามิกจากนั้นประเมินสตริง

"<rj"         e# Push that string on the stack.
     :(       e# Decrement all characters, pushing ";qi".
       (      e# Shift out the first character, pushing "qi" and ';'.
        (     e# Decrement ';' to push ':'.
         *    e# Join "qi" with separator ':', pushing "q:i". 
          ~   e# Evaluate the string "q:i", which behaves as explained before.

7

Pyth, 20 13 ไบต์

vj0>LhZ.BRj.z

หรือในไบนารี:

00000000: 01110110 01101010 00110000 00111110 01001100 01101000  vj0>Lh
00000006: 01011010 00101110 01000010 01010010 01101010 00101110  Z.BRj.
0000000c: 01111010                                               z

ลองออนไลน์

มันทำงานอย่างไร

           .z   all lines of input
          j     join on newline
       .BR      convert each character to binary
   >LhZ         take the last (0 + 1) characters of each binary string
 j0             join on 0
v               evaluate as an integer

จำนวนเต็มผลลัพธ์เป็นจริง (ไม่ใช่ศูนย์) iff ใด ๆ ของไบต์เป็นเลขคี่


4

เยลลี่ขนาด 13 ไบต์

24‘ịØBvF|\ṪBṪ

คาดว่าอินพุตเป็นอาร์กิวเมนต์บรรทัดคำสั่งที่ยกมา ลองออนไลน์!

hexdump

0000000: 32 34 fc d8 12 42 76 46 7c 5c ce 42 ce           24...BvF|\.B.

ถ้ามันไม่ได้สำหรับข้อ จำกัด ไบต์แปลกนี้อย่างเท่าเทียมกันจะทำงานที่ 6 O%2¬Ạ¬ไบต์:
Erik the Outgolfer

4

เรติน่า 106 ไบต์

ลบทุกตัวละครที่ได้รับอนุญาตจากนั้นตรงกับตัวละครที่เหลืออยู่ ค่าความจริงจะเป็นจำนวนอักขระที่พบ ค่า Falsey 0จะ

`"| |\$|&|\(|\*|,|\.|0|2|4|6|8|:|<|>|@|B|D|F|H|J|L|N|P|R|T|V|X|Z|\\|\^|`|b|d|f|h|j|l|n|p|r|t|v|x|z|\||~

.

ลองออนไลน์

เนื่องจาก.ไม่ตรงกับบรรทัดใหม่ตามค่าเริ่มต้นฉันจึงไม่ต้องลบออก


1

Perl 5 + -p0, 136 ไบต์

เช่นเดียวกับคำตอบอื่น ๆ ซึ่งจะลบไบต์คู่ทั้งหมดและปล่อยไบต์คี่ใด ๆ (ซึ่งเป็นความจริง)

tr<�
 "$&(*,.02468:<>@BDFHJLNPRTVXZ\\^`bdfhjlnprtvxz|~€‚„†ˆŠŒŽ’”–˜šœž ¢¤¦¨ª¬®°²´¶¸º¼¾ÀÂÄÆÈÊÌÎÐÒÔÖØÚÜÞàâäæèêìîðòôöøúüþ><>d

ลองออนไลน์!


-0ไม่ทำอะไรเลยเพื่อขึ้นบรรทัดใหม่ มันเป็นตัวกำหนดวิธีแยกอินพุตเท่านั้นโดยจะไม่ลบอักขระใด ๆ
Ørjan Johansen

อุ๊ยนั่นแย่เกินไป
Ørjan Johansen

@ ØrjanJohansenใช่คุณพูดถูก-0ฉันอยากจะทำทั้งก้อนเหมือนก้อน แต่นั่นไม่ควรทำอะไร แต่ฉันไม่สามารถหลีกเลี่ยงสิ่งนี้ได้ ... แย่มาก! ฉันจะล้างความคิดเห็นเหล่านี้ ขอบคุณสำหรับหัวขึ้นแม้ว่า!
Dom Hastings

ดังนั้นตอนนี้ทำงานอย่างไร เดาฉันควรลบความคิดเห็นบางส่วน จากการแก้ไขต่างฉันเห็นว่าตอนนี้คุณรวมไบต์ทุกคู่ในโปรแกรมแล้ว ฉันคิดว่าคุณอาจต้องการที่จะพูดอย่างชัดเจนเนื่องจากตัวละครเหล่านั้นไม่ปรากฏทั้งหมด (สำหรับฉันอย่างน้อย)
Ørjan Johansen

@ ØrjanJohansenใช่! ฉันคิดว่าฉันได้รับแล้ว ฉันไม่คิดว่าคำตอบอื่น ๆ ทั้งหมดจะครอบคลุมไบต์ทั้งหมดเช่นกันฉันคิดว่าใช้งาน ASCII ที่พิมพ์ได้ ฉันค่อนข้างมั่นใจว่านี่เป็นสิ่งที่ฉันต้องการในตอนนี้ ฉันหวังว่าอย่างนั้น!
Dom Hastings

0

Japt , 10 ไบต์

ø0ôH² ®dZÄ

ลองออนไลน์!

เพจรหัสของ Japt คือ ISO-8859-1 รหัสจะให้falseเมื่อตัวเองถูกป้อนเป็นสตริงดังนั้นการส่งที่ถูกต้อง

เอาออกแล้วมันทำงานอย่างไร

Uø0ôHp2  mZ{ZdZ+1

Uø      Does input string contain any element in the following array...?
0ôHp2     Range of 0 to 32**2, inclusive
mZ{       Map...
ZdZ+1       Convert the number Z to a char having charcode 2*Z+1

ไม่มีString.c(ได้รับรหัสหรือแผนที่มากกว่าตัวอักษร) เป็นความเจ็บปวด แต่โชคดีที่มีNumber.d(แปลงหมายเลขเป็นตัวอักษร)

ปรากฎว่า Japt ชนะเหนือ CJam, Pyth และ Jelly :)


ไม่มีข้อ จำกัด มีสองวิธีใน6 ไบต์ (ไปกับ CJam และ Jelly อีกครั้ง):

®c uÃn

Unpacked: UmZ{Zc u} n

UmZ{   Map on each char...
Zc u     Convert to charcode modulo 2
}
n      Convert the resulting string to number

"000..000"จะถูกแปลงเป็นตัวเลข 0 (เท็จ) ไม่ว่าจะนานเท่าใด ในทางตรงกันข้ามสิ่งใดก็ตามที่มี 1 จะถูกแปลงเป็นค่าที่ไม่ใช่ศูนย์doubleหรือInfinityถ้ามันใหญ่เกินไป

¬d_c u

Unpacked: q dZ{Zc u

q    Convert to array of chars
dZ{  Is something true when mapped with...
Zc u   Convert each char to charcode modulo 2

วิธีการตรงไปตรงมามากขึ้นที่อัตราผลตอบแทนโดยตรงหรือtruefalse

หรือวิธีแก้ปัญหา5 ไบต์สามารถทำได้ด้วยความช่วยเหลือของการ-dตั้งค่าสถานะ:

¨c u

Unpacked: q mZ{Zc u

q     Convert to array of chars
mZ{   Map...
Zc u    Convert to charcode modulo 2

      Result is array of zeros and ones
-d    Apply .some() on the resulting array
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.