Verificação Pristine de Bit


28

Escreva um programa / função que use dois números inteiros no intervalo de 0 a , inclusive, e retorne se as formas binárias dos números são exatamente um pouco diferentes.255

Por exemplo, e têm formas binárias e , que são um pouco separadas. Da mesma forma, e são e , portanto, eles retornam verdadeiros.10000000010000000015224010011000000011000

No entanto , seu código deve ser primitivo , de modo que, se algum bit no seu programa for invertido, ocorrerá um erro. Por exemplo, se o seu programa era o byte únicoa(01100001), todos os 8 possíveis programas modificados:

á ! A q i e c `

deve lançar um erro. Verifique se você está modificando por bytes (por exemplo, o álá em cima realmente representa o byte , não o caractere real de dois bytes ).225á

Casos de teste:

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

Regras:

  • Forneça uma estrutura de teste que possa verificar se o seu programa está funcionando corretamente, pois haverá muitos programas possíveis (número de bytes * 8), ou então uma prova completa da manutenção.
    • Verifique se o seu programa é válido antes de publicá-lo.
  • A saída precisa ser verdade / falsey (de qualquer maneira é bom), ou então dois valores distintos de não erro
  • Os erros podem ser tempo de execução, compilador, intérprete etc.

7
Se alguém está procurando uma maneira de gerar todas as variações possíveis de sua solução, este programa em Japt deve (alguém, por favor, verifique): petershaggynoble.github.io/Japt-Interpreter/…
— Shaggy

4
Aqui também está um em Python: Experimente online!
— TFeld 8/04

As funções não são permitidas, pois você mencionou o programa?
— Kevin Cruijssen 8/04

5
@KevinCruijssen Especifiquei que as submissões de funções são aceitáveis
— Jo King

4
Esse comentário tem mais +1do que a maioria das minhas soluções recentes! : \
— Shaggy

Respostas:


16

Python 2 , 35 bytes

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

Experimente online!

Usa a verificação de potência de dois n&-n==n, eliminando o n==0falso positivo.

Para referência, estes são os pares de operadores binários de um caractere que estão um pouco separados, tornando-os difíceis de usar:

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

Felizmente, &e ^não estão entre estes.

Observe também que ==pode se tornar <=e +pode se tornar o caractere de comentário #.


Python 2 , 41 bytes

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

Experimente online!

Tomando TFeld lambda a,b:bin(a^b).count('1')==1 e tornando-o primitivo, alterando os 1s para +Truee== para is. Agradecimentos a Jo King por 1 byte.


9

Python 2 , 72 67 50 bytes

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

Experimente online!

-5 bytes, graças a Jo King


Devoluções True / Falsepara truthy / falsey.

O programa é basicamente o mesmo que lambda a,b:bin(a^b).count('1')==1, mas sem números e outros caracteres que funcionam quando os bits são invertidos.

Funciona certificando-se de que quase tudo seja uma função nomeada (que é bastante primitiva)

O teste primitivo no final inverte um único bit (para cada bit) e tenta a função em uma entrada. Se isso funcionar (correto ou não), essa variação será impressa. Nenhum programa impresso = função intocada.


8

Java 8, 68 61 56 45 bytes

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

-11 bytes graças a @EmbodimentOfIgnorance , substituindo constante java.awt.Font.BOLD por -~(a^a).

Experimente online.

Explicação:

A função base mais curta seria:

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

Experimente online.

Isso é modificado para não haver um dígito, =nem um dos +/*operandos para cálculos numéricos (portanto, o+ concatenação de String está correta):

O +""e .equalsdeve ser comparado em String.equals(String)vez de int==int.
NOTA: Integer.equals(int)pode ser usado aqui, mas seria mais bytes, uma vez que tanto o .bitCounte java.awt.Font.BOLDsão primitivos intem vez de Integer-objects, então um adicional new Integer(...)seria necessário para transformar um dos dois a uma Integer-object, antes que pudéssemos usar o .equals.


(int) Math.log (Math.E) é 21 bytes
— Dados expirados


@ExpiredData Obrigado, na verdade, apenas encontrei uma constante mais curta com java.awt.Font.BOLD, mas o seu Objects.equalsé um bom golfe, obrigado!
— Kevin Cruijssen em

@ExpiredData Na verdade, Objectsfaz parte da java.util.importação, então eu tenho que adicionar isso à contagem de bytes, receio, tornando-o 69 bytes. :(
— Kevin Cruijssen em

3
Iria -~(a^a)trabalhar para 1?
— Modalidade de ignorância

7

C (gcc) , 56 bytes

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

Experimente online!

Retorna 0se o par diferir em 1, diferente de zero. Um pouco incomum para C, a menos que você considere retornar EXIT_SUCCESSse o par diferir em 1, qualquer outro valor caso contrário.

Usa sizeof((char)d))para produzir a constante de 1maneira primitiva, enquanto também força o nome da função a ser primitiva.

Em seguida, XORs 1 com o popcount do XOR dos argumentos. Felizmente, ^é fácil manter o símbolo intacto, assim como o identificador muito longo __builtin_popcount.

Enquanto isso, aqui está o script usado para testar a solução:

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

Que usa a ./flipbitferramenta que escrevi cuja fonte é simplesmente:

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

Os bits complicados foram:

  • Espaço em branco: todos os espaços em branco (incluindo novas linhas) têm gêmeos primitivos que funcionarão de maneira semelhante
  • Comparação: =não funciona bem, pois pode ser uma comparação em todos os casos em que pode aparecer. Da mesma forma -não funciona bem. Assim, ^é usado para afirmar a igualdade com 1.
  • Nomes de variáveis: f colidiriam com b, portanto, tinha que usar d como o nome da função.

Como você mantém o ^operador intocado? Se os bits alterados, o que impede que ele se torne um operador diferente? Isso ainda seria compilado, mas apenas forneceria a resposta errada. Estou entendendo mal algo sobre o significado da palavra "intocada" aqui?
— Cody Gray

4
Ao virar apenas um bit, ^só pode ser alterado para qualquer um dos _\ZVN~Þcaracteres ou não imprimíveis no ponto de código 30. ~é o único daqueles que é um operador, mas é apenas um operador unário.
— String não relacionada

1
Ou até mesmo use em __LINE__vez de sizeof(char). Eu acho que é bom supor que sua função estará na linha 1 do seu arquivo .c. Ou ainda, unixé definido como 1 no TIO, e provavelmente na maioria dos outros Linux.
— Digital Trauma

2
A principal razão para o tamanho de char-casted é entrar dna fonte no menor número de bytes possível. Caso contrário d(ou qualquer que seja o nome da função), poderá ser alterado e o código ainda funcionará. Mesmo (__LINE__)com d();não vai funcionar porque d();pode ser alterado para qualquer outra letra e ainda irá compilar uma vez que a função nunca tem que ser chamado, portanto, não está ligada.
— LambdaBeta 9/04

1
@LambdaBeta Se o nome da função mudar, haverá um erro de link, mesmo que d não seja auto-referencial. Eu acho que isso é suficiente, pessoalmente.
— Digital Trauma

7

R , 38 bytes 37

-1 byte graças a Nick Kennedy.

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

Experimente online! (Obrigado a Giuseppe por configurar o TIO corretamente.)

Prova de que é intocada (usando o verificador de Nick Kennedy ).

Saídas 0 para falsey e um valor positivo para verdade, que eu entendo é aceitável, já que R as interpretará como False e True.

Explicação: bitwXor(a,b)fornece (como um inteiro) o XOR bit a bit entre ae b. Para verificar se é uma potência de 2, verifique se o logon na base 2 é um número inteiro. A função dpoisfornece a função de densidade de probabilidade da distribuição de Poisson: seu valor é 0 para valores não inteiros e algo positivo para números inteiros não negativos. O Texiste porque dpoisrequer um segundo argumento (qualquer real positivo funciona e Té interpretado como 1).

Se insistirmos em gerar valores distintos, a versão a seguir gera FALSE ou TRUE em 42 bytes (graças a Giuseppe por -8 bytes):

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

e também é intocada . Experimente online!


2
Bem feito em conseguir algo muito menor que o meu! Você pode substituir pipor Tpara salvar um byte (ainda intocado). Além disso, seu TIO não corresponde à sua resposta no momento.
— Nick Kennedy

@NickKennedy Thanks! (E obrigado por escrever o código para verificar se está impecável!). O TIO ao qual vinculei é uma versão modificada que verifica todos os casos de teste. Vou adicionar um TIO ao código real, mas não consigo descobrir como fazer o TIO funcionar corretamente com duas chamadas para scan(); Você tem alguma ideia? (O código funciona bem em um computador.)
— Robin Ryder

2
@NickKennedy Talvez algo assim? para obter o TIO e o código correspondentes?
— Giuseppe

@ Giuseppe Wonderful, obrigado!
— Robin Ryder

1
sua segunda versão poderia usar em Fvez de exp(-Inf), da mesma maneira que a de Nick T:-)
— Giuseppe

6

R , 83 bytes

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

Experimente online!

Prova de que isso é intocado

Trabalhando em torno do fato de que as.integer, as.doubleetc. são apenas um pouco longe is.integer, is.doubleetc. foi a parte mais difícil. No final, usar sum(T^el(.[-T])como meio de gerar um e verificar as.doublese retornou um vetor de comprimento> 1 foi o melhor que pude fazer. A embalagem té para lidar com o fato de que de outra forma identicalpode se tornar ide~tical.


5

Julia 0,7 , 20 bytes

(a,b)->ispow2(a⊻b)

Experimente online!

Aqui está um validador primitivo que tenta executar cada função anônima modificada em relação a alguma entrada e nenhuma passa com êxito. Observe que o código possui um caractere unicode de vários bytes e algumas saídas possíveis de inversão de bits nem são incluídas, pois elas produzem seqüências UTF-8 inválidas.


xe yestão um pouco separados, então acredito que este é um exemplo contrário. ye xtambém estão 1 bit desligados 9e 6respectivamente.
— Dados expirados

Porra, enquanto pensava em coisas complexas, eu absolutamente sentia falta da mais simples. Felizmente, alterar as variáveis ​​irá corrigi-lo.
— Kirill L.


4

C # (compilador interativo do Visual C #) , 128 101 77 70 61 74 bytes

-27 bytes graças ao Ascii-Only

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

Experimente online!

Você precisa ser bastante criativo para obter números em C # sem usar literais. Usa apenas o operador ^. As variáveis ​​a, b estão todas a mais de um bit de distância uma da outra e todo o resto é uma palavra-chave / nome.


você não precisa contar bits - verificar se é uma potência de 2 entre 1 e 128 inclusive é suficiente
— apenas ASCII

@ Somente ASCII Boa sorte verificando isso em um número razoável de bytes quando não podemos usar números inteiros nem +/*=para operações matemáticas ou de validação. ;)
— Kevin Cruijssen em

@KevinCruijssen C # também tem enums :(. Damnit
— somente ASCII


1
O_o outro -24. btw você não usa mais+
— ASCII-only

3

JavaScript (ES6 no modo estrito), 61 bytes

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

Experimente online! ou Verifique se todos os programas modificados estão incorretos


Oh meu Deus, eu não percebi que cliquei em um link de código de golfe e vi essa resposta fora de contexto e quase tive um ataque cardíaco. Como, OMG NO
— Marie

4
@Marie Cuidado! Você só pode olhar para este código com copos de golfe certificados. Caso contrário, pode queimar sua retina. : p
— Arnauld


1

MATLAB, 37 bytes

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

Desculpe, não há link TIO, porque não consigo fazer com que o conjunto de testes funcione no Octave. Obrigado @ExpiredData por alguns comentários úteis.

Suíte de teste:

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 Obrigado pela sugestão. Fui para um MATLAB numel, porque minha suíte de testes não parece estar funcionando no Octave.
— Sanchises

38 bytes talvez .. não tem uma licença Matlab, mas deve funcionar
— Expirado dados

1
@ExpiredData Obrigado, pode-se realmente fazer um byte melhor com eye!
— Sanchises

1
@ExpiredData Eu sei, também estou muito irritado com a Octave. Mas usar o programa Python nos comentários do OP é útil para ver se você pode introduzir um novo personagem sem problemas.
— Sanchises

1

Perl 6 , 77 43 bytes

Agradecimentos a Jo King por -33 bytes.

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

Isso é equivalente a

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

1foi reescrito como elems([""]). 2foi reescrito como sum(elems([""]),elems([""])); elems(["",""])pode parecer funcionar, mas elems([""-""])também é válido e parece travar o testador.

Experimente online!


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.