Tylko parzyste bajty

64

Scenariusz

Ostatnio zauważyłeś dziwne zachowanie w swoim ulubionym edytorze tekstu. Na początku wydawało się, że ignoruje losowe znaki w kodzie podczas zapisywania na dysku. Po chwili zauważyłeś wzór; znaki o nieparzystych wartościach ASCII były ignorowane. Podczas dalszej kontroli odkryłeś, że możesz poprawnie zapisywać do plików tylko wtedy, gdy co ósmy bit jest równy zero. Teraz musisz wiedzieć, czy ten cenny plik został dotknięty tym dziwnym błędem.

Zadanie

Musisz napisać kompletny program, który określa, czy plik zawiera jakieś nieparzyste bajty (pokazując, że nie jest uszkodzony). Ale z powodu edytora tekstu nie można pisać żadnych nieparzystych bajtów w kodzie źródłowym. Możesz założyć wcześniej istniejące kodowanie dla danych wejściowych, jednak nadal musisz sprawdzać każdy pojedynczy bajt, nie tylko znaki.

Wejście

Twój program pobierze zawartość lub ścieżkę do pliku ze standardowego wejścia lub wiersza poleceń.

Wynik

Twój program wyświetli stdout albo prawdziwą wartość, jeśli dany plik zawiera nieparzysty bajt, albo fałsz, jeśli co ósmy bit jest równy zero.

Kryteria

To jest golf golf, najkrótszy program, który wykonuje zadanie, wygrywa. Aby zgłoszenie było prawidłowe, co ósmy bit w kodzie źródłowym plików musi wynosić zero. Polecam dołączenie kopii plików binarnych kodu źródłowego do twojego zgłoszenia.

Obowiązują standardowe luki .

Przypadki testowe

(W kodowaniu ASCII) Wejście:

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

Output:
falsy

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

Output:
truthy

Input:
LOREMIPSVMDOLORSITAMETCONSECTETVRADIPISCINGELITSEDDOEIVSMODTEMPORINCIDIDVNTVTLABOREETDOLOREMAGNAALIQVA
VTENIMADMINIMVENIAMQVISNOSTRVDEXERCITATIONVLLAMCOLABORISNISIVTALIQVIPEXEACOMMODOCONSEQVAT
DVISAVTEIRVREDOLORINREPREHENDERITINVOLVPTATEVELITESSECILLVMDOLOREEVFVGIATNVLLAPARIATVR
EXCEPTEVRSINTOCCAECATCVPIDATATNONPROIDENTSVNTINCVLPAQVIOFFICIADESERVNTMOLLITANIMIDESTLABORVM

Output:
truthy

Napiwki

  • Wybierz język mądrze. To wyzwanie może nie być możliwe w każdym języku

  • Polecenie Unix xxd -b <file name>wydrukuje pliki binarne pliku na konsoli (wraz z dodatkowymi funkcjami formatowania)

  • Możesz używać innych kodowań innych niż ASCII, takich jak UTF-8, o ile wszystkie inne reguły są przestrzegane

Kreator pszenicy
źródło
2
Niektóre języki mają trudności z odczytem danych wieloliniowych, ale to nie tak, że to wyzwanie ma być łatwe, więc prawdopodobnie jest OK. : P Czy wejście może być puste?
Dennis
9
!#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}są zakazanymi drukowalnymi znakami ASCII dla każdego, kogo to obchodzi. Dozwolone znaki do wydruku ASCII to" $&(*,.02468:<>@BDFHJLNPRTVXZ\^`bdfhjlnprtvxz|~
Patrick Roberts
9
Całkiem przydatne, że wszystkie samogłoski są zakazane ... ;-)
owacoder
4
Welp, tyle dla BF mają szansę w tym wyzwaniu.
TLW,
2
Zauważ też, że jeśli w pliku DOS / Windows występują jakieś podziały linii, [CR]ma on dziwny bit. Miałem nadzieję, że WhiteSpace jest bezpieczny, ale niestety [TAB]. Jeśli chcesz iść do starej szkoły, EBCDIC daje ci trzy samogłoski.
GuitarPicker

Odpowiedzi:

26

GS2 , 4 bajty

dΦ("

Wypróbuj online!

Hexdump

0000000: 64 e8 28 22                                      d.("

Jak to działa

      (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.
Dennis
źródło
21

Befunge, 36 bajtów

Wiem, że to stare pytanie, ale chciałem spróbować, bo myślałem, że będzie to interesujące wyzwanie w Befunge.

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

Wypróbuj online!

Wyprowadza, 1jeśli dane wejściowe są uszkodzone (tzn. Zawierają nieparzysty bajt) i 0jeśli jest w porządku.

Wyjaśnienie

Problem polega na tym, jak określić nieparzyste bajty bez dostępu do poleceń /(dzielenia) lub %(modulo). Rozwiązaniem było pomnożenie wartości przez 128 (sekwencja 28*8**), a następnie zapisanie tego wyniku na polu gry. W ściśle standardowym interpretatorze komórki pola gry mają 8-bitowe wartości, więc liczba nieparzysta pomnożona przez 128 zostaje obcięta do -1, a liczba parzysta staje się 0.

Inną sztuczką było odczytywanie wartości -1 lub 0 z pola gry bez dostępu do polecenia g(get). Obejściem tego problemu było zapisanie wartości na środku istniejącej sekwencji ciągów ( " "), a następnie wykonanie tej sekwencji w celu wypchnięcia zamkniętej wartości na stos. W tym momencie określenie dziwności bajtu jest prostym testem mniejszym od zera.

Ostatnim aspektem wartym omówienia jest wynik. W fałszywym przypadku dochodzimy do >$.sekwencji z tylko jedną wartością na stosie, więc $czyści stos, co powoduje, że .wynik jest zerowy. W prawdziwym przypadku podążamy ścieżką 20`:>$.. Ponieważ dwa są większe od zera, porównanie wypycha jeden na stos, a następnie :tworzy duplikat, aby $nie upuścił go, zanim zostanie wydrukowany.

James Holderness
źródło
1
To może być spóźnione i nowe, ale to już moja ulubiona odpowiedź.
Wheat Wizard
@WheatWizard Dopiero teraz zdałem sobie sprawę, dlaczego ta odpowiedź cieszy się tak dużym zainteresowaniem. Dziękuję za nagrodę!
James Holderness,
12

CJam (11 bajtów)

"r2":(~f&2b

Demo online

Usuwając sztuczki, aby uniknąć nieparzystych bajtów, zmniejsza się do

q1f&2b

który odczytuje dane wejściowe, mapuje bitowo AND za pomocą 1, a następnie wykonuje konwersję podstawową, dając zero, gdy wszystkie AND były zerowe.

Peter Taylor
źródło
3
Ten kod jest smutny:(
betseg
Ponieważ może mieć tylko połowę znaków @betseg
Roman Gräf
9

Plik .COM do wydruku, 100 bajtów

^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

Używanie bardzo luźnej definicji źródła jako czegoś, co może być rozsądnie wpisane przez człowieka i zainspirowane standardowym plikiem testowym antywirusa EICAR Standard (więcej informacji na temat „Bawmy się z plikiem testowym EICAR” w Bugtraq).

Używając tylko drukowalnych nieparzystych bajtów ASCII (uwaga: kody wpływające na słowa bywają nieparzyste, bit W jest lsb niektórych opcodów), tworzy fragment kodu w SP (który wygodnie ustawiamy tuż za naszym kodem generującym) , a wykonanie kończy się na wygenerowanym kodzie.

Wykorzystuje fakt, że stos początkowo zawiera wskaźnik zbliżony do początku PSP i że początek PSP zawiera INT 20hinstrukcję (więcej informacji na ten temat na https://stackoverflow.com/questions/12591673/ ).

Prawdziwe źródło:

; 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
ninjalj
źródło
9

MATL , 7 bajtów

l$Z$2\z

Kod źródłowy wykorzystuje kodowanie UTF-8. Więc bajty źródłowe są (dziesiętnie)

108    36    90    36    50    92   122

Dane wejściowe to nazwa pliku, traktowana jako ciąg ujęty w pojedyncze cudzysłowy. Dane wyjściowe to liczba nieparzystych bajtów w pliku, co jest prawdą, jeśli nie jest zero.

Wyjaśnienie

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
Luis Mendo
źródło
8

CJam, 18 17 15 bajtów

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

Zakłada, że ​​ustawienia regionalne są ustawione na Latin-1. Wypróbuj online!

Jak to działa

Proste rozwiązanie wygląda następująco.

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.

Niestety znaki qi inie mogą pojawić się w kodzie źródłowym. Aby obejść ten problem, będziemy dynamicznie tworzyć część powyższego kodu źródłowego, a następnie oceniać ciąg.

"<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.
Dennis
źródło
7

Pyth, 20 13 bajtów

vj0>LhZ.BRj.z

Lub binarnie:

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

Wypróbuj online

Jak to działa

           .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

Wynikowa liczba całkowita jest prawdziwa (niezerowa), jeśli dowolny z bajtów był nieparzysty.

Anders Kaseorg
źródło
4

Galaretka , 13 bajtów

24‘ịØBvF|\ṪBṪ

Oczekuje danych wejściowych jako cytowanego argumentu wiersza polecenia. Wypróbuj online!

Hexdump

0000000: 32 34 fc d8 12 42 76 46 7c 5c ce 42 ce           24...BvF|\.B.
Dennis
źródło
Gdyby to nie było dla nieparzystych ograniczeń bajtów, to byłoby równie pracować w 6 bajtów: O%2¬Ạ¬.
Erik the Outgolfer,
4

Siatkówka , 106 bajtów

Usuwa każdą dozwoloną postać, a następnie dopasowuje pozostałe postacie. Prawdziwe wartości to liczba znalezionych znaków. Wartości Falsey będą 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|\||~

.

Wypróbuj online

Ponieważ .domyślnie nie pasuje do nowych linii, nie muszę ich usuwać.

mbomb007
źródło
1

Perl 5 + -p0136 bajtów

Podobnie do innych odpowiedzi, usuwa wszystkie parzyste bajty i pozostawia wszelkie nieparzyste bajty (co jest prawdą).

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

Wypróbuj online!

Dom Hastings
źródło
-0nie robi nic nowego. Określa tylko sposób podziału danych wejściowych, nie usuwa żadnych znaków.
Ørjan Johansen
Och, to źle.
Ørjan Johansen
@ ØrjanJohansen Tak, masz rację -0, chciałem zrobić cały blok jako bryłę, ale to nie powinno mieć znaczenia, ale nie mogę tego obejść ... Szkoda! Wyczyszczę te komentarze. Dzięki za heads-up!
Dom Hastings,
Więc to działa teraz? Chyba powinienem usunąć niektóre komentarze. Z diff edycji, widzę, że teraz włączasz każdy parzysty bajt do programu. Myślę, że możesz powiedzieć to wprost, ponieważ nie wszystkie te postacie pojawiają się (przynajmniej dla mnie).
Ørjan Johansen
@ ØrjanJohansen tak! Chyba już to mam. Nie sądzę, żeby wszystkie inne odpowiedzi obejmowały wszystkie parzyste bajty, myślę, że kilka działa tylko na drukowalnym ASCII. Jestem przekonany, że teraz robi to, co chciałem. Mam nadzieję, że tak!
Dom Hastings,
0

Japt , 10 bajtów

ø0ôH² ®dZÄ

Wypróbuj online!

Strona kodowa Japt to ISO-8859-1. Kod podaje, falsegdy sam jest wprowadzony jako ciąg, a zatem prawidłowe przesłanie.

Rozpakowane i jak to działa

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

Nie posiadanie String.c(pobierz kod znaków lub mapa nad kodami znaków) było uciążliwe, ale na szczęście jest Number.d(konwersja numeru na znak).

Okazuje się, że Japt wygrywa z CJam, Pyth i Jelly :)


Bez ograniczenia istnieje kilka sposobów, aby to zrobić w 6 bajtach (znów na poziomie CJam i 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"jest konwertowany na liczbę 0 (fałsz) niezależnie od tego, jak długo to trwa. Z drugiej strony wszystko, co zawiera 1, jest konwertowane na wartość niezerową doublelub Infinityjeśli jest zbyt duża (obie są prawdą).

¬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

Bardziej proste podejście, które bezpośrednio daje truelub false.

Lub rozwiązanie 5 bajtów jest nawet możliwe przy pomocy -dflagi:

¨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
Bubbler
źródło