Vérification des bits vierges


28

Écrivez un programme / fonction qui prend deux entiers compris entre 0 et 255 inclus, et retourne si les formes binaires des nombres sont exactement un bit différentes.

Par exemple, 1 et 0 ont des formes binaires 00000001et 00000000, qui sont séparées d'un bit. De même, 152 et 24 sont 010011000et 000011000, donc ils retournent vrai.

Cependant , votre code doit être vierge , de sorte que si un bit de votre programme est retourné, il devrait générer une erreur. Par exemple, si votre programme était le seul octeta(01100001), alors les 8 programmes modifiés possibles:

á ! A q i e c `

doit lancer une erreur. Assurez-vous que vous modifiez par octets (par exemple, le áhaut représente réellement l'octet 225 , pas le caractère réel sur deux octets á).

Cas de test:

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

Règles:

  • Fournissez un cadre de test qui peut vérifier que votre programme est correctement vierge, car il y aura beaucoup de programmes possibles (nombre d'octets * 8), ou bien une preuve complète de pureté.
    • Veuillez vous assurer que votre programme est valide avant de le publier.
  • La sortie doit être véridique / falsey (dans tous les cas, c'est bien), ou bien deux valeurs distinctes sans erreur
  • Les erreurs peuvent être l'exécution, le compilateur, l'interpréteur, etc.

7
Si quelqu'un cherche un moyen de générer toutes les variantes possibles de sa solution, ce programme Japt devrait (quelqu'un s'il vous plaît vérifier) ​​faire le travail: petershaggynoble.github.io/Japt-Interpreter/…
Shaggy

4
En voici un en Python également: Essayez-le en ligne!
TFeld le

Les fonctions ne sont pas autorisées, puisque vous avez mentionné le programme?
Kevin Cruijssen

5
@KevinCruijssen J'ai spécifié que les soumissions de fonctions sont correctes
Jo King

4
Ce commentaire a plus de +1s que la majorité de mes solutions récentes! : \
Shaggy

Réponses:


16

Python 2 , 35 octets

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

Essayez-le en ligne!

Utilise le contrôle de puissance de deux n&-n==n, éliminant les n==0faux positifs.

Pour référence, ce sont les paires d'opérateurs binaires à un caractère qui sont séparées d'un bit, ce qui les rend difficiles à utiliser:

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

Heureusement, &et ^n'en font pas partie.

Notez également que cela ==peut devenir <=et +peut devenir le caractère de commentaire #.


Python 2 , 41 octets

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

Essayez-le en ligne!

Prendre TFeld lambda a,b:bin(a^b).count('1')==1 et le rendre vierge en changeant les 1 en +Trueet ==vers is. Merci à Jo King pour 1 octet.


9

Python 2 , 72 67 50 octets

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

Essayez-le en ligne!

-5 octets, merci à Jo King


Renvoie True/ Falsepour pour vérité / falsey.

Le programme est fondamentalement le même que lambda a,b:bin(a^b).count('1')==1, mais sans chiffres et autres caractères qui fonctionnent lorsqu'ils sont inversés.

Fonctionne en s'assurant que presque tout est une fonction nommée (qui sont toutes assez vierges)

Le test vierge à la fin retourne un seul bit (pour chaque bit) et essaie la fonction sur une entrée. Si cela fonctionne (correct ou non), cette variation est imprimée. Aucun programme imprimé = fonction vierge.


8

Java 8, 68 61 56 45 octets

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

-11 octets grâce à @EmbodimentOfIgnorance , en remplaçant constant java.awt.Font.BOLD par -~(a^a).

Essayez-le en ligne.

Explication:

La fonction de base la plus courte serait:

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

Essayez-le en ligne.

Ceci est modifié afin qu'il n'y ait pas de chiffre,, =ni l'un des +/*opérandes qu'il contient pour les calculs numériques (donc la +concaténation de chaîne est correcte):

Le +""et .equalssont à comparer au String.equals(String)lieu de int==int.
REMARQUE: Integer.equals(int)pourrait être utilisé ici, mais serait plus d'octets, car les deux .bitCountet java.awt.Font.BOLDsont primitifs intau lieu de Integer-objets, donc un supplément new Integer(...)serait nécessaire pour transformer l'un des deux en un Integer-objet, avant de pouvoir utiliser le .equals.


(int) Math.log (Math.E) est de 21 octets
Données expirées le


@ExpiredData Merci, en fait vient de trouver une constante plus courte avec java.awt.Font.BOLD, mais Objects.equalsc'est un bon golf, merci!
Kevin Cruijssen

@ExpiredData En fait, Objectsfait partie de l' java.util.importation, donc je dois ajouter cela au nombre d'octets, j'ai peur, ce qui en fait 69 octets .. :(
Kevin Cruijssen

3
Fonctionnerait -~(a^a)pour 1?
Incarnation de l'ignorance

7

C (gcc) , 56 octets

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

Essayez-le en ligne!

Renvoie 0si la paire diffère de 1, non nul sinon. Un peu inhabituel pour C, à moins que vous ne pensiez qu'il revienne EXIT_SUCCESSsi la paire diffère de 1, toute autre valeur sinon.

Utilise sizeof((char)d))pour produire la constante 1d'une manière vierge tout en forçant également le nom de la fonction à être vierge.

Il XORs ensuite que 1 avec le popcount du XOR des arguments. Heureusement, le ^symbole est facile à garder vierge, tout comme l'identifiant très long __builtin_popcount.

En attendant, voici le script utilisé pour tester la solution:

#!/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

Qui utilise l' ./flipbitoutil que j'ai écrit dont la source est simplement:

#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;
}

Les morceaux difficiles étaient:

  • Espaces: tous les espaces (y compris les sauts de ligne) ont des jumeaux immaculés qui fonctionneront de la même manière
  • Comparaison: =ne fonctionne pas bien, car elle peut être une comparaison dans tous les cas où elle peut apparaître. De même -ne fonctionne pas bien. Ainsi ^est utilisé pour affirmer l'égalité avec 1.
  • Noms de variables: f se heurterait à b, donc devait utiliser d comme nom de fonction à la place.

Comment gardez-vous l' ^opérateur immaculé? Si les bits ont été modifiés, qu'est-ce qui l'empêche de devenir un opérateur différent? Cela compilerait toujours, mais vous donnerait juste la mauvaise réponse. Suis-je en train de mal comprendre la signification du mot "vierge" ici?
Cody Gray

4
En retournant un seul bit, ^il ne peut être changé qu'en l'un quelconque _\ZVN~Þou le caractère non imprimable au point de code 30. ~est le seul de ceux qui est un opérateur, mais ce n'est qu'un opérateur unaire.
Chaîne sans rapport le

1
Ou même utiliser à la __LINE__place de sizeof(char). Je pense que c'est bien de supposer que votre fonction sera sur la ligne 1 de votre fichier .c. Ou même unixest défini à 1 sur TIO, et probablement la plupart des autres Linux.
Digital Trauma

2
La principale raison de la taille de castof est de se dcuire dans la source dans le moins d'octets possible. Sinon d(ou quel que soit le nom de la fonction), vous pouvez simplement le modifier et le code fonctionnera toujours. Même (__LINE__)avec d();ne fonctionnera pas car d();peut être changé en n'importe quelle autre lettre et il sera toujours compilé puisque la fonction n'a jamais à être appelée, donc n'est pas liée.
LambdaBeta

1
@LambdaBeta Si le nom de la fonction change, alors il y aura une erreur de lien, même si d n'est pas auto-référentiel. Je pense que cela suffit, personnellement.
Digital Trauma

7

R , 38 37 octets

-1 octet grâce à Nick Kennedy.

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

Essayez-le en ligne! (Merci à Giuseppe d'avoir correctement configuré le TIO.)

Preuve qu'il est vierge (en utilisant le vérificateur de Nick Kennedy ).

Sorties 0 pour falsey, et une valeur positive pour véridique, ce que je comprends est acceptable car R interprétera ces derniers comme faux et vrai.

Explication: bitwXor(a,b)donne (sous forme d'entier) le XOR au niveau du bit entre aet b. Pour vérifier s'il s'agit d'une puissance de 2, vérifiez si sa base de connexion 2 est un entier. La fonction dpoisdonne la fonction de densité de probabilité de la distribution de Poisson: sa valeur est 0 pour les valeurs non entières, et quelque chose de positif pour les entiers non négatifs. Le Test là car dpoisnécessite un deuxième argument (tout travail réel positif, etT est interprété comme 1).

Si nous insistons pour produire des valeurs distinctes, la version suivante génère FALSE ou TRUE en 42 octets (merci à Giuseppe pour -8 octets):

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

et est également vierge . Essayez-le en ligne!


2
Bravo d'avoir obtenu quelque chose de beaucoup plus petit que le mien! Vous pouvez remplacer pipar Tpour enregistrer un octet (toujours vierge). Votre TIO ne correspond pas non plus à votre réponse pour le moment.
Nick Kennedy

@NickKennedy Merci! (Et merci d'avoir écrit le code pour vérifier qu'il est vierge!). Le TIO auquel je suis lié est une version modifiée qui vérifie tous les cas de test. J'ajouterai un TIO au code réel, mais je ne sais pas comment faire fonctionner TIO correctement avec deux appels à scan(); Avez-vous une idée? (Le code fonctionne bien sur un ordinateur.)
Robin Ryder

2
@NickKennedy Peut-être quelque chose comme ça? pour obtenir le TIO et le code pour correspondre?
Giuseppe

@Giuseppe Magnifique, merci!
Robin Ryder

1
votre deuxième version pourrait utiliser Fau lieu de exp(-Inf), dans le même sens que Nick T:-)
Giuseppe

6

R , 83 octets

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

Essayez-le en ligne!

Preuve que c'est vierge

Contourner le fait que as.integer, as.doubleetc. ne sont que légèrement éloignés is.integer, is.doubleetc. était le plus difficile. En fin de compte, le mieux que je pouvais faire était d' utiliser sum(T^el(.[-T])à la fois la génération d'un et la vérification qui as.doubleavait renvoyé un vecteur de longueur> 1. L'emballage test de gérer le fait que, autrement, identicalpeut devenir ide~tical.


5

Julia 0,7 , 20 octets

(a,b)->ispow2(ab)

Essayez-le en ligne!

Voici un validateur vierge qui essaie d'exécuter chaque fonction anonyme modifiée sur une entrée, et aucun ne réussit. Notez que le code a un caractère unicode multi-octets et que certaines sorties possibles du retournement de bits ne sont même pas incluses, car celles-ci produisent des chaînes UTF-8 invalides.


xet ysont un peu séparés, donc je pense que c'est un contre-exemple. yet xsont également à 1 bit 9et 6respectivement.
Données expirées le

Merde, en pensant à des choses complexes, j'ai absolument manqué la plus simple. Espérons que le changement des variables le corrigera.
Kirill L.


4

C # (Visual C # Interactive Compiler) , 128 101 77 70 61 74 octets

-27 octets grâce à Ascii-Only

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

Essayez-le en ligne!

Vous devez être assez créatif pour obtenir des nombres en C # sans utiliser de littéraux. Utilise uniquement l'opérateur ^. Les variables a, b sont toutes à plus d'un bit l'une de l'autre et tout le reste est un mot-clé / nom.


vous n'avez pas besoin de compter les bits - vérifier si c'est une puissance de 2 entre 1 et 128 inclus suffit
uniquement en ASCII

@ ASCII uniquement Bonne chance pour avoir vérifié cela dans un nombre raisonnable d'octets lorsque nous ne pouvons pas utiliser d'entiers ni +/*=pour des opérations mathématiques ou de validation. ;)
Kevin Cruijssen

@KevinCruijssen C # a aussi des énumérations
ASCII uniquement le


1
O_o un autre -24. btw vous n'utilisez plus+
ASCII uniquement le

3

JavaScript (ES6 en mode strict), 61 octets

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

Essayez-le en ligne! ou Assurez-vous que tous les programmes modifiés sont incorrects


Oh mon Dieu, je ne savais pas que j'avais cliqué sur un lien de golf de code et vu cette réponse hors de son contexte et j'ai presque eu une crise cardiaque. Comme, OMG NO
Marie

4
@Marie Attention! Vous ne pouvez regarder ce code qu'avec des lunettes de golf certifiées. Sinon, cela pourrait brûler votre rétine. : p
Arnauld


1

MATLAB, 37 octets

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

Désolé, pas de lien TIO, car je ne peux pas faire fonctionner la suite de tests sous Octave. Merci @ExpiredData pour quelques commentaires utiles.

Suite de tests:

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 Merci pour la suggestion. J'ai opté pour un MATLAB à la numelplace, car ma suite de tests ne semble pas fonctionner dans Octave.
Sanchises

38 octets peut-être .. pas de licence matlab mais ça devrait marcher
Données expirées

1
@ExpiredData Merci, on peut en fait faire un octet de mieux avec eye!
Sanchises

1
@ExpiredData Je sais, je suis aussi très ennuyé à Octave. Mais l'utilisation du programme Python dans les commentaires OP est pratique pour voir si vous pouvez introduire un nouveau personnage sans problème.
Sanchises

1

Perl 6 , 77 43 octets

Merci à Jo King pour -33 octets.

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

Cela équivaut à

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

1a été réécrit comme elems([""]). 2a été réécrit comme sum(elems([""]),elems([""])); elems(["",""])peut sembler fonctionner mais elems([""-""])est également valide et semble bloquer le testeur.

Essayez-le en ligne!


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.