Тільки навіть байти


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|~
Патрік Робертс

9
Досить зручно, що всі голосні заборонені ... ;-)
owacoder

4
Welp, стільки, що BF має шанс у цьому виклику.
TLW

2
Також зауважте, що якщо у файлі DOS / Windows є будь-які розриви рядків, цей [CR]біт має непарний біт. Я сподівався, що WhiteSpace в безпеці, але на жаль [TAB]. Якщо ви хочете пройти стару школу, EBCDIC дає три голосні.
GuitarPicker

Відповіді:


26

GS2 , 4 байти

dΦ("

Спробуйте в Інтернеті!

Гексдумп

0000000: 64 e8 28 22                                      d.("

Як це працює

      (implicit) Read all input and push it on the stack.
 Φ    Map the previous token over all characters in the string:
d       Even; push 1 for even characters, 0 for odd ones.
  (   Take the minimum of the resulting list of Booleans.
   "  Negate the minimum.

21

Befunge, 36 байт

Я знаю, що це давнє питання, але я хотів спробувати його, тому що думав, що це буде цікавим викликом у Befunge.

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

Спробуйте в Інтернеті!

Він видає, 1якщо вхід пошкоджений (тобто містить непарний байт), і 0якщо це нормально.

Пояснення

Проблема полягає в тому, як визначити непарні байти, не маючи доступу до команд /(ділити) або %(модуль). Рішення полягало в тому, щоб помножити значення на 128 (послідовність 28*8**), а потім записати цей результат у поле гри. На строго стандартному інтерпретаторі осередки ігрового поля підписують 8 бітових значень, тому непарне число, помножене на 128, стає усіченим на -1, а парне число стає 0.

Інша хитрість полягала в тому, щоб прочитати -1 або 0 назад з ігрового поля, не маючи доступу до команди g(get). Вирішення цього завдання полягало в тому, щоб записати значення в середину існуючої послідовності рядків ( " "), а потім виконати цю послідовність, щоб натиснути додане значення на стек. Тоді визначення дивацтва байта - це простий тест, менший від нуля.

Одним із заключних аспектів, які варто обговорити, є результат. У хибному випадку ми досягаємо >$.послідовності лише з одним значенням на стеку, тому $очищає стек, роблячи .висновок нулем. У справжньому випадку ми йдемо шляхом 20`:>$.. Оскільки два більше нуля, порівняння виштовхує один на стек, і :робить копію, що $не повторює її, перш ніж вона отримає вихід.


1
Це може бути пізно і новим, але це вже моя улюблена відповідь.
Пшеничний майстер

@WheatWizard Я лише зараз зрозумів, чому ця відповідь привертає таку велику увагу. Дякую за щедрість!
Джеймс Холдернес

12

CJam (11 байт)

"r2":(~f&2b

Демонстрація в Інтернеті

Видаляючи трюки, щоб уникнути непарних байтів, це зводиться до

q1f&2b

який зчитує введення, відображає біт І з 1, а потім виконує базове перетворення, даючи нуль iff, якщо всі AND були нульовими.


3
Цей код сумний:(
betseg

Тому що це може бути лише половина знаків @betseg
Роман

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 для друку (бічна примітка: опкоди, що впливають на слова, як правило, непарні, W біт - lsb деяких опкодів), він створює фрагмент коду в 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

Вхід - це ім'я файлу, взятого як рядок, укладений в окремі лапки. Вихід - кількість непарних байтів у файлі, який є truthy iff nonzero.

Пояснення

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&

Припускає, що локальний параметр встановлений на Latino-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

Отримане ціле число є truthy (ненульовим), якщо будь-який з байтів був непарним.


4

Желе , 13 байт

24‘ịØBvF|\ṪBṪ

Очікує введення як аргументований аргумент командного рядка. Спробуйте в Інтернеті!

Гексдумп

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

Якби не було для непарних байтів обмеження, це в рівній мірі буде працювати на 6 байт: O%2¬Ạ¬.
Ерік Аутгольфер

4

Сітківка , 106 байт

Видаляє кожен дозволений символ, а потім відповідає будь-яким іншим символам. Значення Truthy - це кількість знайдених символів. Значення Фальсі будуть 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, я хотів зробити цілий блок як грудочку, але це не має значення, але я не можу обійти це ... Шкода! Я приберу ці коментарі. Дякую за голову вгору!
Дом Гастінгс

Так це працює зараз? Гадаю, я повинен видалити деякі коментарі. З точки зору редагування, я бачу, що ви зараз включаєте кожен парний байт у програму. Я думаю, ви можете сказати це прямо, оскільки не всі ці персонажі відображаються (принаймні для мене).
Ørjan Johansen

@ ØrjanJohansen так! Я думаю, я зараз це отримав. Я не думаю, що всі інші відповіді не охоплюють навіть навіть байтів, я думаю, що деякі з них працюють лише на друкованому ASCII. Я майже впевнений, що це робить те, що я хотів зараз. Я все одно сподіваюся!
Дом Гастінгс

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(отримати charcode або карту над charcodes) було болем, але, на щастя, є Number.d(перетворити номер у char).

Виявляється, 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

Простіший підхід , який дає безпосередньо trueабо false.

Або рішення 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.