Solo byte pari


64

Lo scenario

Ultimamente hai notato strani comportamenti con il tuo editor di testo preferito. Inizialmente sembrava che ignorasse i caratteri casuali nel codice quando si scriveva sul disco. Dopo un po 'hai notato uno schema; i caratteri con valori ASCII dispari venivano ignorati. Sotto ulteriore controllo hai scoperto che puoi scrivere correttamente sui file solo se ogni ottavo bit è zero. Ora devi sapere se i tuoi file importanti sono stati interessati da questo strano bug.

L'obiettivo

È necessario scrivere un programma completo che determini se un file contiene byte dispari (dimostrando che non è corrotto). Ma a causa del tuo editor di testo non puoi scrivere byte dispari nel tuo codice sorgente. Puoi assumere qualsiasi codifica preesistente per l'input, tuttavia devi comunque controllare ogni singolo byte, non solo i caratteri.

Ingresso

Il programma prenderà il contenuto o il percorso di un file da stdin o dalla riga di comando.

Produzione

Il programma emetterà su stdout un valore di verità se il file dato contiene un byte dispari o un falso se ogni ottavo bit è zero.

criteri

Si tratta di code golf, il programma più breve che completa l'attività vince. Per essere un invio valido ogni ottavo bit nel codice sorgente dei file deve essere zero. Raccomanderei di includere una copia dei file binari del codice sorgente nella richiesta.

Si applicano scappatoie standard .

Casi test

(Nella codifica ASCII) Ingresso:

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

Output:
falsy

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

Output:
truthy

Input:
LOREMIPSVMDOLORSITAMETCONSECTETVRADIPISCINGELITSEDDOEIVSMODTEMPORINCIDIDVNTVTLABOREETDOLOREMAGNAALIQVA
VTENIMADMINIMVENIAMQVISNOSTRVDEXERCITATIONVLLAMCOLABORISNISIVTALIQVIPEXEACOMMODOCONSEQVAT
DVISAVTEIRVREDOLORINREPREHENDERITINVOLVPTATEVELITESSECILLVMDOLOREEVFVGIATNVLLAPARIATVR
EXCEPTEVRSINTOCCAECATCVPIDATATNONPROIDENTSVNTINCVLPAQVIOFFICIADESERVNTMOLLITANIMIDESTLABORVM

Output:
truthy

Suggerimenti

  • Scegli saggiamente la lingua questa sfida potrebbe non essere possibile in tutte le lingue

  • Il comando Unix xxd -b <file name>stamperà i file binari di un file sulla console (insieme ad alcuni elementi di formattazione extra)

  • È possibile utilizzare altre codifiche diverse da ASCII come UTF-8 purché vengano seguite tutte le altre regole


2
Alcune lingue hanno difficoltà a leggere input multilinea, ma non è come se questa sfida fosse facile, quindi probabilmente va bene. : P L'ingresso può essere vuoto?
Dennis,

9
!#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}sono i caratteri ASCII stampabili vietati, per chiunque si preoccupi. I caratteri ASCII stampabili consentiti sono" $&(*,.02468:<>@BDFHJLNPRTVXZ\^`bdfhjlnprtvxz|~
Patrick Roberts,

9
Abbastanza utile che tutte le vocali siano bandite ... ;-)
owacoder il

4
Welp, tanto per BF che ha una possibilità in questa sfida.
TLW

2
Si noti inoltre che se si dispone di interruzioni di riga in un file DOS / Windows, [CR]ha il bit dispari. Speravo che WhiteSpace fosse al sicuro, ma purtroppo [TAB]. Se vuoi andare alla vecchia scuola, EBCDIC ti dà tre vocali.
GuitarPicker

Risposte:


26

GS2 , 4 byte

dΦ("

Provalo online!

hexdump

0000000: 64 e8 28 22                                      d.("

Come funziona

      (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 byte

So che questa è una vecchia domanda, ma volevo provarlo perché pensavo che sarebbe stata una sfida interessante in Befunge.

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

Provalo online!

Emette 1se l'input è danneggiato (cioè contiene un byte dispari) e 0se è OK.

Spiegazione

Il problema è come determinare i byte dispari senza avere accesso ai comandi /(divide) o %(modulo). La soluzione era moltiplicare il valore per 128 (la sequenza 28*8**), quindi scrivere quel risultato nel campo di gioco. Su un interprete rigorosamente standard, le celle del campo di gioco sono contrassegnate da valori a 8 bit, quindi un numero dispari moltiplicato per 128 viene troncato a -1 mentre un numero pari diventa 0.

L'altro trucco stava nel leggere -1 o 0 dal campo di gioco senza avere accesso al gcomando (get). La soluzione per questo era scrivere il valore nel mezzo di una sequenza di stringhe esistente ( " "), quindi eseguire quella sequenza per spingere il valore racchiuso nello stack. A quel punto, determinare la stranezza del byte è un semplice test diverso da zero.

Un aspetto finale degno di discussione è l'output. Nel caso falso, raggiungiamo la >$.sequenza con un solo valore nello stack, quindi $cancella lo stack rendendo l' .output pari a zero. Nel vero caso, seguiamo il percorso 20`:>$.. Poiché due è maggiore di zero, il confronto ne inserisce uno nello stack e :crea una copia duplicata in modo $che non la rilasci prima che venga emessa.


1
Potrebbe essere tardi e nuovo, ma è già la mia risposta preferita.
Wheat Wizard

@WheatWizard Mi sono appena reso conto ora perché questa risposta ha ricevuto così tanta attenzione. Grazie per la generosità!
James Holderness,

12

CJam (11 byte)

"r2":(~f&2b

Demo online

Eliminando i trucchi per evitare byte dispari, questo si riduce a

q1f&2b

che legge l'input, mappa un AND bit a bit con 1e quindi esegue una conversione di base, dando zero se tutti gli AND erano zero.


3
Questo codice è triste:(
betseg

Perché può contenere solo la metà dei caratteri @betseg
Roman Gräf

9

File .COM stampabile, 100 byte

^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

Utilizzando una definizione molto generica di sorgente come qualcosa che può essere ragionevolmente digitato da un essere umano e ispirato al file di test antivirus standard EICAR (maggiori informazioni su "Divertiamoci con il file di test EICAR" su Bugtraq).

Utilizzando solo byte ASCII non dispari stampabili (nota a margine: i codici operativi che influenzano le parole tendono ad essere dispari, il bit W è lsb di alcuni codici operativi), costruisce un frammento di codice su SP (che convenientemente impostiamo appena oltre il nostro codice di generazione) e l'esecuzione finisce col passare al codice generato.

Utilizza il fatto che lo stack inizialmente contiene un puntatore vicino all'inizio della PSP e che l'inizio della PSP contiene l' INT 20histruzione (maggiori informazioni al riguardo su https://stackoverflow.com/questions/12591673/ ).

Vera fonte:

; 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 byte

l$Z$2\z

Il codice sorgente utilizza la codifica UTF-8. Quindi i byte di origine sono (in decimali)

108    36    90    36    50    92   122

L'input è un nome file, preso come una stringa racchiusa tra virgolette singole. L'output è il numero di byte dispari nel file, che è vero se non diverso da zero.

Spiegazione

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 byte

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

Presuppone che l'impostazione internazionale sia impostata su Latin-1. Provalo online!

Come funziona

La soluzione semplice è la seguente.

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.

Sfortunatamente, i caratteri qe inon possono apparire nel codice sorgente. Per ovviare a questo problema, creeremo in modo dinamico parte del codice sorgente sopra riportato, quindi valuteremo la stringa.

"<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 byte

vj0>LhZ.BRj.z

O in binario:

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

Provalo online

Come funziona

           .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

Il numero intero risultante è true (diverso da zero) se uno qualsiasi dei byte fosse dispari.


4

Gelatina , 13 byte

24‘ịØBvF|\ṪBṪ

Si aspetta l'input come argomento della riga di comando citato. Provalo online!

hexdump

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

Se non fosse per la restrizione byte dispari, questo sarebbe ugualmente funzionare a 6 byte: O%2¬Ạ¬.
Erik the Outgolfer,

4

Retina , 106 byte

Rimuove tutti i caratteri consentiti, quindi corrisponde a tutti i caratteri rimanenti. I valori veritieri saranno il numero di caratteri trovati. I valori di Falsey saranno 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|\||~

.

Provalo online

Poiché .non corrisponde alle nuove righe per impostazione predefinita, non è necessario rimuoverle.


1

Perl 5 + -p0, 136 byte

Simile ad altre risposte, questo rimuove tutti i byte pari e lascia tutti i byte dispari (il che è vero).

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

Provalo online!


-0non fa nulla a newline. Determina solo come suddividere l'input, non rimuove alcun carattere.
Ørjan Johansen,

Troppo male.
Ørjan Johansen,

@ ØrjanJohansen Sì, hai ragione -0, volevo fare l'intero blocco come un nodulo, ma non dovrebbe importare, ma non posso aggirare questo ... Peccato! Pulirò questi commenti. Grazie per l'attenzione però!
Dom Hastings,

Quindi funziona ora? Immagino che dovrei eliminare alcuni dei commenti. Dalla modifica modifica, vedo che ora stai includendo ogni byte pari nel programma. Penso che potresti volerlo dire esplicitamente, dal momento che non tutti questi personaggi si presentano (almeno per me).
Ørjan Johansen,

@ ØrjanJohansen sì! Penso di averlo ora. Non penso che tutte le altre risposte coprano neanche tutti i byte, penso che alcuni lavori solo su ASCII stampabile. Sono abbastanza fiducioso che questo faccia quello che volevo ora. Lo spero comunque!
Dom Hastings,

0

Japt , 10 byte

ø0ôH² ®dZÄ

Provalo online!

La tabella codici di Japt è ISO-8859-1. Il codice indica falsequando viene inserito come stringa, quindi un invio valido.

Disimballato e come funziona

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

Non avere String.c(ottenere charcode o mappare su charcodes) è stata una seccatura, ma per fortuna c'è Number.d(convertire il numero in char).

Si scopre che Japt vince su CJam, Pyth e Jelly :)


Senza la restrizione, ci sono un paio di modi per farlo in 6 byte (andando di nuovo alla pari con CJam e 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"viene convertito nel numero 0 (falsy) indipendentemente da quanto tempo è. D'altra parte, tutto ciò che contiene 1 viene convertito in un valore diverso da zero doubleo Infinityse è troppo grande (entrambi veritieri).

¬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

Approccio più diretto che produce direttamente trueo false.

Oppure, la soluzione a 5 byte è persino possibile con l'aiuto di -dflag:

¨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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.