Controllo bit incontaminato


28

Scrivi un programma / funzione che accetta due numeri interi compresi tra 0 e 255 inclusi e restituisce se le forme binarie dei numeri sono esattamente un bit differenti.

Ad esempio, e hanno forme binarie e , che sono un po 'distanti. Allo stesso modo, e sono e , quindi, ritornano veri.1 240000000010000000015224010011000000011000

Tuttavia , il codice deve essere incontaminato , in modo tale che se un bit nel programma viene invertito, dovrebbe generare un errore. Ad esempio, se il tuo programma era il singolo bytea(01100001), tutti gli 8 possibili programmi modificati:

á ! A q i e c `

deve generare un errore. Assicurati di modificare i byte (ad es. Il punto in áalto rappresenta effettivamente il byte 225 , non il carattere a due byte effettivo á).

Casi test:

0,1     => Truthy
1,0     => Truthy
152,24  => Truthy
10,10   => Falsey
10,11   => Truthy
11,12   => Falsey
255,0   => Falsey

Regole:

  • Fornire un framework di test in grado di verificare che il programma sia correttamente integro, poiché ci saranno molti programmi possibili (numero di byte * 8), oppure una prova completa di originalità.
    • Si prega di assicurarsi che il programma è valido prima di postare esso.
  • L'output deve essere true / false (in entrambi i casi va bene), oppure due distinti valori non di errore
  • Gli errori possono essere runtime, compilatore, interprete ecc.

7
Se qualcuno è alla ricerca di un modo per generare tutte le possibili varianti della propria soluzione, questo programma Japt dovrebbe (qualcuno per favore ricontrolla) fare il lavoro: petershaggynoble.github.io/Japt-Interpreter/…
Shaggy

4
Eccone uno anche in Python: provalo online!
TFeld

Le funzioni non sono consentite, dal momento che hai menzionato il programma?
Kevin Cruijssen,

5
@KevinCruijssen Ho specificato che l'invio delle funzioni è ok
Jo King l'

4
Quel commento ha più messaggi +1della maggior parte delle mie recenti soluzioni! : \
Shaggy l'

Risposte:


16

Python 2 , 35 byte

lambda a,b:(a^b)&-(a^b)in[a^b or[]]

Provalo online!

Utilizza il controllo della potenza di due n&-n==n, eliminando il n==0falso positivo.

Per riferimento, queste sono le coppie di operatori binari a un carattere che sono un po 'distanti, rendendoli difficili da usare:

+ /
- /
* +
% -
< |
< >

Fortunatamente, &e ^non sono tra questi.

Si noti inoltre che ==può diventare <=e +diventare il personaggio del commento #.


Python 2 , 41 byte

lambda a,b:bin(a^b).count(`+True`)is+True

Provalo online!

Prendere TFeld lambda a,b:bin(a^b).count('1')==1 e renderlo incontaminato cambiando gli 1 in +Truee ==in is. Grazie a Jo King per 1 byte.


9

Python 2 , 72 67 50 byte

lambda a,b:sum(map(int,'{:b}'.format(a^b)))is+True

Provalo online!

-5 byte, grazie a Jo King


Resi True/False per verità / falsità.

Il programma è sostanzialmente lo stesso di lambda a,b:bin(a^b).count('1')==1 , ma senza numeri e altri caratteri che funzionano se capovolti.

Funziona assicurandosi che quasi tutto sia una funzione con nome (che sono tutti abbastanza incontaminati)

Il test incontaminato alla fine lancia un singolo bit (per ogni bit) e prova la funzione su un input. Se funziona (corretto o no), quella variazione viene stampata. Nessun programma stampato = funzione incontaminata.


8

Java 8, 68 61 56 45 byte

a->b->(a.bitCount(a^b)+"").equals(-~(a^a)+"")

-11 byte grazie a @EmbodimentOfIgnorance , sostituendo la costante java.awt.Font.BOLD con -~(a^a).

Provalo online.

Spiegazione:

La funzione di base più breve sarebbe:

a->b->a.bitCount(a^b)==1

Provalo online.

Questo viene modificato in modo che non ci sia una cifra, =né uno degli +/*operandi al suo interno per i calcoli numerici (quindi +per la concatenazione di stringhe va bene):

I +""e .equalssono da confrontare String.equals(String)invece di int==int.
NOTA: Integer.equals(int)potrebbe essere usato qui, ma sarebbe più byte, dal momento che sia gli oggetti .bitCounte java.awt.Font.BOLDsono primitivi intanziché Integer-oggetto, quindi new Integer(...)sarebbe necessario un ulteriore per trasformare uno dei due in un oggetto Integer, prima che potessimo usare il .equals.


(int) Math.log (Math.E) è 21 byte
Dati scaduti


@ExpiredData Grazie, in realtà ho appena trovato una costante più breve con java.awt.Font.BOLD, ma il tuo Objects.equalsè un bel golf, grazie!
Kevin Cruijssen

@ExpiredData In realtà, Objectsfa parte dijava.util. dell'importazione, quindi devo aggiungerlo al conteggio dei byte, temo, rendendolo 69 byte .. :(
Kevin Cruijssen

3
Funzionerebbe -~(a^a)per 1?
Incarnazione dell'ignoranza l'

7

C (gcc) , 56 byte

d(a,b){return(sizeof((char)d))^__builtin_popcount(a^b);}

Provalo online!

Restituisce 0se la coppia differisce di 1, altrimenti diverso da zero. Leggermente inusuale per C, a meno che non lo consideri tornare EXIT_SUCCESSse la coppia differisce di 1, altrimenti qualsiasi altro valore.

Utilizza sizeof((char)d))per produrre la costante 1in modo incontaminato forzando allo stesso tempo il nome della funzione.

Quindi XORs che 1 con il popcount di XOR degli argomenti. Fortunatamente il ^simbolo è facile da mantenere intatto, così come l'identificatore molto lungo __builtin_popcount.

Nel frattempo, ecco lo script utilizzato per testare la soluzione:

#!/bin/bash

SOURCE_FILE=$1
FOOT_FILE=$2
TMP_SRC=temp.c

LENGTH="$(wc -c <"$SOURCE_FILE")"
BITS=$((LENGTH*8))

cat "$SOURCE_FILE" >"$TMP_SRC"
cat "$FOOT_FILE" >>"$TMP_SRC"
if gcc -w $TMP_SRC -o t.out >/dev/null 2>&1; then
    if ./t.out; then
        echo "Candidate solution..."
    else
        echo "Doesn't even work normally..."
        exit
    fi
else
    echo "Doesn't even compile..."
    exit
fi

for i in $(seq 1 $BITS); do
    ./flipbit "$i" <"$SOURCE_FILE" >"$TMP_SRC"
    cat "$FOOT_FILE" >>"$TMP_SRC"
    if gcc -w $TMP_SRC -o t.out >/dev/null 2>&1; then
        echo "Testing flipped bit $i:"
        cat "$TMP_SRC"

        ./t.out >/dev/null 2>&1
        STATUS=$?
        if [ "$STATUS" -eq 0 ]; then
            echo "It works!"
            exit
        elif [ "$STATUS" -eq 1 ]; then
            echo "It doesn't work..."
            exit
        else
            echo "It crashes"
        fi
    fi
done

Che utilizza lo ./flipbitstrumento che ho scritto la cui fonte è semplicemente:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
    int bittoflip = atoi(argv[1]) - 1;
    int ch;

    while ((ch = fgetc(stdin)) != EOF) {
        if (bittoflip < 8 && bittoflip >= 0) {
            putchar(ch ^ (1 << bittoflip));
        } else {
            putchar(ch);
        }

        bittoflip -= 8;
    }

    return 0;
}

I pezzi difficili sono stati:

  • Spazio bianco: tutti gli spazi bianchi (comprese le nuove righe) hanno gemelli incontaminati che funzioneranno in modo simile
  • Confronto: =non funziona bene, dal momento che può essere un confronto in ogni caso potrebbe apparire. Allo stesso modo -non funziona bene. così^ viene usato per affermare l'uguaglianza con 1.
  • Nomi delle variabili: f si scontrerebbe con b, quindi doveva usare d come nome della funzione.

Come si mantiene l' ^operatore incontaminato? Se i bit su quello sono stati cambiati, che cosa impedisce che diventi un operatore diverso? Questo sarebbe ancora compilare, ma ti darebbe solo la risposta sbagliata. Sto fraintendendo qualcosa sul significato della parola "incontaminata" qui?
Cody Grey,

4
Lanciando solo un bit, ^può essere modificato solo in uno _\ZVN~Þo in uno dei caratteri non stampabili al punto di codice 30. ~è l'unico di quelli che è un operatore, ma è solo un operatore unario.
Stringa non correlata

1
O addirittura usare al __LINE__posto di sizeof(char). Penso che vada bene supporre che la tua funzione sarà sulla linea 1 del tuo file .c. O addirittura unixè definito a 1 su TIO, e probabilmente la maggior parte degli altri Linux.
Trauma digitale il

2
Il motivo principale per la dimensione di cast cast è di essere dinserito nella fonte nel minor numero di byte possibile. Altrimenti d(o qualunque sia il nome della funzione) può essere semplicemente modificato e il codice continuerà a funzionare. Anche (__LINE__)con d();non funzionerà perché d();può essere modificato in qualsiasi altra lettera e verrà comunque compilato poiché la funzione non deve mai essere chiamata, quindi non è collegata.
LambdaBeta,

1
@LambdaBeta Se il nome della funzione cambia, si verificherà un errore di collegamento, anche se d non è autoreferenziale. Penso che questo sia sufficiente, personalmente.
Trauma digitale il

7

R , 38 37 byte

-1 byte grazie a Nick Kennedy.

dpois(log2(bitwXor(scan(),scan())),T)

Provalo online! (Grazie a Giuseppe per aver impostato correttamente il TIO.)

Prova che è incontaminata (usando la pedina di Nick Kennedy ).

Produce 0 per falso e un valore positivo per verità, che capisco è accettabile poiché R interpreterà questi come Falso e Vero.

Spiegazione: bitwXor(a,b)fornisce (come numero intero) lo XOR bit a bit tra ae b. Per verificare se è una potenza di 2, controlla se il suo log in base 2 è un numero intero. La funzione dpoisfornisce la funzione di densità di probabilità della distribuzione di Poisson: il suo valore è 0 per valori non interi e qualcosa di positivo per numeri interi non negativi. L' Tè lì perché dpoisrichiede un secondo argomento (eventuali opere reali positivi, eT viene interpretato come 1).

Se insistiamo nel fornire valori distinti, la seguente versione restituisce FALSE o TRUE in 42 byte (grazie a Giuseppe per -8 byte):

dpois(log2(bitwXor(scan(),scan())),T)%in%F

ed è anche incontaminato . Provalo online!


2
Ben fatto per ottenere qualcosa di molto più piccolo del mio! È possibile sostituire picon Tper salvare un byte (ancora incontaminato). Anche il tuo TIO al momento non corrisponde alla tua risposta.
Nick Kennedy,

@NickKennedy Grazie! (E grazie per aver scritto il codice per verificare che sia incontaminato!). Il TIO a cui sono collegato è una versione modificata che controlla tutti i casi di test. Aggiungerò un TIO al codice effettivo, ma non riesco a capire come far funzionare correttamente TIO con due chiamate a scan(); Hai un'idea? (Il codice funziona bene su un computer.)
Robin Ryder

2
@NickKennedy Forse qualcosa del genere? per far corrispondere il TIO e il codice?
Giuseppe,

@Giuseppe Meraviglioso, grazie!
Robin Ryder,

1
la tua seconda versione potrebbe usare al Fposto di exp(-Inf), sulla stessa linea di quella di Nick T:-)
Giuseppe,

6

R , 83 byte

t(identical(sum(.<-as.double(intToBits(Reduce(bitwXor,scan())))),sum(T^el(.[-T]))))

Provalo online!

Prova che questo è incontaminato

Risolvere il fatto che as.integer, as.doubleecc. Sono solo un po 'distanti da is.integer, is.doubleecc. È stato il momento più difficile. Alla fine, usare sum(T^el(.[-T])sia un modo per generare uno sia per verificare che as.doubleabbia restituito un vettore di lunghezza> 1 è stato il massimo che potevo fare. Il wrapping tè gestire il fatto che altrimenti identicalpotrebbe diventare ide~tical.


5

Julia 0,7 , 20 byte

(a,b)->ispow2(ab)

Provalo online!

Ecco un validatore incontaminato che prova a eseguire ciascuna funzione anonima modificata con un input e nessuno dei due passa con successo. Si noti che il codice ha un carattere unicode multibyte e che alcuni possibili output derivanti dall'inversione di bit non sono nemmeno inclusi, poiché producono stringhe UTF-8 non valide.


xe ysono un po 'separati, quindi credo che questo sia un contro esempio. ye xsono anche 1 bit off 9e 6rispettivamente.
Dati scaduti

Dannazione, mentre pensavo a cose complesse, mi mancava assolutamente la più semplice. Si spera che cambiando le variabili si risolverà.
Kirill L.


4

C # (compilatore interattivo Visual C #) , 128 101 77 70 61 74 byte

-27 byte grazie a Ascii-Only

a=>b=>{var d=Math.Log(a^b,(int)Math.E);return d.Equals((int)Math.Abs(d));}

Provalo online!

Devi essere abbastanza creativo per ottenere numeri in C # senza usare valori letterali. Utilizza solo ^ operatore. Le variabili a, b sono tutte a più di 1 bit di distanza l'una dall'altra e tutto il resto è una parola chiave / nome.


non è necessario contare i bit - è sufficiente verificare se è compresa una potenza compresa tra 1 e 128 compreso
solo ASCII l'

@ Solo ASCII Buona fortuna controllandolo in un numero ragionevole di byte quando non possiamo usare numeri interi né +/*=per operazioni matematiche o di validazione. ;)
Kevin Cruijssen

@KevinCruijssen Anche C # ha enumerazioni :(. Dannazione
ASCII


1
O_o un altro -24. tra l'altro non si usa più+
solo ASCII l'

3

JavaScript (ES6 in modalità rigorosa), 61 byte

(y,z,e)=>eval(`(y${(e='^=z)*!(y&~-y)')!='^=z)*!(y&~-y)'||e}`)

Provalo online! oppure Assicurarsi che tutti i programmi modificati siano errati


Oh mio Dio, non mi rendevo conto di aver cliccato su un link di codice golf e ho visto questa risposta fuori contesto e ho quasi avuto un infarto. Ad esempio, OMG NO
Marie,

4
@Marie Attenzione! Puoi fissare questo codice solo con occhiali da golf certificati. Altrimenti, potrebbe bruciare la retina. : p
Arnauld


1

MATLAB, 37 byte

@(c,e)eq(nnz(de2bi(bitxor(c,e))),eye)

Spiacente, nessun collegamento TIO, perché non riesco a far funzionare la suite di test in Octave. Grazie @ExpiredData per alcuni commenti utili.

Suite di test:

program = '@(c,e)eq(nnz(de2bi(bitxor(c,e))),eye)';
number_of_characters = nnz(program);
success = [];
for character_counter = 0 : number_of_characters
    for bit_no = 1:8
        prog_temp = program;
        if(character_counter > 0)
            prog_temp(character_counter) = bitxor(double(prog_temp(character_counter)),2^(bit_no-1));
        elseif(bit_no<8) % Test the unmodified program once
            continue
        end
        try
            eval(prog_temp);
            eval('ans(2,3)');
            disp(prog_temp)
            success(end+1)=1;   
        catch
            success(end+1)=0;
        end 
    end
end
assert(nnz(success)==1)


@ExpiredData Grazie per il suggerimento. Ho optato per un MATLAB numelinvece, perché la mia suite di test non sembra funzionare in Octave.
Sanchises

38 byte forse .. non ha una licenza matlab ma dovrebbe funzionare
Dati scaduti

1
@ExpiredData Grazie, si può effettivamente fare un byte meglio con eye!
Sanchises

1
@ExpiredData Lo so, sono anche molto seccato con Octave. Ma usare il programma Python nei commenti OP è utile per vedere se è possibile introdurre un nuovo personaggio senza problemi.
Sanchises

1

Perl 6 , 77 43 byte

Grazie a Jo King per -33 byte.

{elems(i)eq(sum [+^](@_).polymod(+@_ xx*))}

Questo equivale a

{1 eq(sum [+^](@_).polymod(2 xx*))}

1è stato riscritto come elems([""]). 2è stato riscritto come sum(elems([""]),elems([""])); elems(["",""])potrebbe sembrare che funzioni ma elems([""-""])è anche valido e sembra appendere il tester.

Provalo online!


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.