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(ab)

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.