Только четные байты


64

Сценарий

В последнее время вы замечали странное поведение в вашем любимом текстовом редакторе. Сначала казалось, что он игнорирует случайные символы в вашем коде при записи на диск. Через некоторое время вы заметили шаблон; символы с нечетными значениями ASCII игнорировались. При дальнейшей проверке вы обнаружили, что вы можете правильно записывать файлы, только если каждый восьмой бит равен нулю. Теперь вам нужно знать, была ли эта ценная ошибка затронута на ваших ценных файлах.

Задание

Вы должны написать полную программу, которая определяет, содержит ли файл какие-либо нечетные байты (демонстрируя, что он не поврежден). Но из-за вашего текстового редактора вы не можете писать какие-либо нечетные байты в вашем исходном коде. Вы можете принять любую существующую кодировку для ввода, однако вы все равно должны проверять каждый отдельный байт, а не только символы.

вход

Ваша программа будет извлекать содержимое или путь к файлу из стандартного ввода или командной строки.

Выход

Ваша программа выведет на стандартный вывод либо истинное значение, если данный файл содержит нечетный байт, либо ложное значение, если каждый восьмой бит равен нулю.

критерии

Это код гольф, самая короткая программа, которая завершает задачу, побеждает. Чтобы быть верным представлением, каждый восьмой бит в исходном коде файла должен быть нулем. Я бы порекомендовал включить копию ваших двоичных файлов исходного кода в ваше представление.

Применяются стандартные лазейки .

Тестовые случаи

(В кодировке 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
Ну что ж, у БФ есть шанс в этом вызове.
TLW

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

Ответы:


26

GS2 , 4 байта

dΦ("

Попробуйте онлайн!

HexDump

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если все в порядке.

объяснение

Проблема заключается в том, как определить нечетные байты, не имея доступа к командам /(split) или %(modulo). Решением было умножить значение на 128 (последовательность 28*8**), а затем записать этот результат в игровое поле. В строго стандартном интерпретаторе ячейки игрового поля имеют 8-битные значения со знаком, поэтому нечетное число, умноженное на 128, усекается до -1, а четное число становится 0.

Другой трюк заключался в чтении -1 или 0 обратно с игрового поля без доступа к команде g(get). Обходным путем для этого было записать значение в середину существующей строковой последовательности ( " "), а затем выполнить эту последовательность, чтобы поместить вложенное значение в стек. В этот момент определение нечетности байта является простым тестом с нулевым значением.

Последний аспект, который стоит обсудить, - это результат. В ложном случае мы достигаем >$.последовательности с одним значением в стеке, поэтому $очищаем стек, делая .вывод равным нулю. В истинном случае мы идем по пути 20`:>$.. Так как два больше нуля, сравнение помещает единицу в стек и :создает дублирующую копию, поэтому $не удаляет ее, пока не получит вывод.


1
Это может быть поздно и ново, но это уже мой любимый ответ.
Wheat Wizard

@WheatWizard Я только сейчас понял, почему этот ответ так привлек к себе внимание. Спасибо за щедрость!
Джеймс Холдернесс

12

CJam (11 байт)

"r2":(~f&2b

Онлайн демо

Убирая уловки, чтобы избежать лишних байтов, это сводится к

q1f&2b

который считывает входные данные, отображает побитовое И с 1, а затем выполняет базовое преобразование, давая ноль, если все И были равны нулю.


3
Этот код грустный:(
betseg

Потому что он может иметь только половину символов @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 (примечание: коды операций, влияющие на слова, обычно бывают нечетными, бит W - это символ некоторых кодов операций), он создает фрагмент кода в 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

Входными данными является имя файла, взятое как строка, заключенная в одинарные кавычки. Выходные данные - это число нечетных байтов в файле, которое действительно, если не равно нулю.

объяснение

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

Полученное целое число является истинным (ненулевым), если любой из байтов был нечетным.


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¬Ạ¬.
Эрик Outgolfer

4

Сетчатка , 106 байт

Удаляет все разрешенные символы, затем сопоставляет любые оставшиеся символы. Истинными значениями будут количество найденных символов. Ложные значения будут 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ничего не делает с переводами строки. Он только определяет, как разделить ввод, но не удаляет символы.
Орджан Йохансен

Ой, это очень плохо.
Орджан Йохансен

@ ØrjanJohansen Да, вы правы -0, я хотел сделать весь блок в виде комка, но это не должно иметь значения, но я не могу обойти это ... Жаль! Я уберу эти комментарии. Спасибо за головы, хотя!
Дом Гастингс

Так это работает сейчас? Думаю, мне следует удалить некоторые комментарии. Из различий в редактировании я вижу, что теперь вы включаете каждый четный байт в программу. Я думаю, что вы могли бы сказать это явно, поскольку не все эти персонажи появляются (по крайней мере, для меня).
Орджан Йохансен

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

0

Japt , 10 байт

ø0ôH² ®dZÄ

Попробуйте онлайн!

Кодовая страница Джапта - 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(преобразовать число в символ).

Оказывается, что Джапт выигрывает у 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.