깨끗한 비트 확인


28

에서 의 정수 두 개를 취하는 프로그램 / 함수를 작성 하고 숫자의 이진 형식이 정확히 1 비트가 아닌지 여부를 반환합니다.0255

예를 들어, 과 은 이진 형식 과를 가지며 1 비트 떨어져 있습니다. 마찬가지로 와 는 and 이므로 true를 반환합니다.10000000010000000015224010011000000011000

그러나 프로그램의 한 비트가 뒤집어지면 오류가 발생하도록 코드는 깨끗 해야합니다. 예를 들어, 프로그램이 단일 바이트a(01100001) 인 경우 8 개의 가능한 모든 수정 된 프로그램 :

á ! A q i e c `

오류를 던져야합니다. 바이트 단위 로 수정하고 있는지 확인하십시오 (예 : 실제 2 바이트 문자가 아니라 á실제로 바이트 나타냅니다 ).225á

테스트 사례 :

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

규칙 :

  • 가능한 많은 프로그램 (바이트 수 * 8) 또는 완전한 원시 증명이 있으므로 프로그램이 제대로 원시 상태인지 확인할 수있는 테스트 프레임 워크를 제공하십시오.
    • 제발 당신이 그것을 게시하기 전에 프로그램이 유효한지 확인하십시오.
  • 출력은 진실 / 거짓 (어느 쪽이든 괜찮음)이거나 다른 두 가지 오류가 아닌 값이어야합니다.
  • 오류는 런타임, 컴파일러, 인터프리터 등일 수 있습니다.

7
솔루션의 모든 가능한 변형을 생성하는 방법을 찾는 사람이 있다면이 Japt 프로그램 작업을 수행해야합니다. petershaggynoble.github.io/Japt-Interpreter/…
Shaggy

4
다음은 Python에도 있습니다. 온라인으로 사용해보십시오!
TFeld

프로그램을 언급 했으므로 기능이 허용되지 않습니까?
Kevin Cruijssen

5
@KevinCruijssen 함수 제출이 정상임을 지정했습니다
Jo King

4
그 의견은 +1최근 솔루션의 대부분보다 더 많은 것을 가지고 있습니다! : \
Shaggy

답변:


16

파이썬 2 , 35 바이트

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

온라인으로 사용해보십시오!

2의 거듭 제곱 검사 n&-n==n를 사용하여 n==0오 탐지를 제거합니다 .

참고로, 이들은 1 비트 떨어져있는 한 문자 이진 연산자 쌍이므로 사용하기가 어렵습니다.

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

다행히, &그리고 ^이들 사이에 없습니다.

또한 점에 유의 ==될 수 있습니다 <=+주석 문자가 될 수 있습니다 #.


파이썬 2 , 41 바이트

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

온라인으로 사용해보십시오!

촬영 TFeld의를 lambda a,b:bin(a^b).count('1')==1 하고에 하나의을 변경하여 자연 그대로의 제작 +True==is. 1 바이트 동안 King King에게 감사합니다.


9

파이썬 2 , 72 67 50 바이트

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

온라인으로 사용해보십시오!

Jo King 덕분에 -5 바이트


진실 / 거짓을 위해 True/ False를 반환합니다 .

이 프로그램은 기본적으로와 동일 lambda a,b:bin(a^b).count('1')==1하지만 비트 플립시 작동하는 숫자 및 기타 문자는 없습니다.

거의 모든 것이 이름이 지정된 함수인지 확인하여 작동합니다 (모두 깨끗합니다).

마지막에있는 원시 테스트는 단일 비트 (모든 비트에 대해)를 뒤집고 입력에서 함수를 시도합니다. 그것이 작동하는 경우 (정확하거나 그렇지 않은 경우) 해당 변형이 인쇄됩니다. 인쇄 된 프로그램이 없습니다 = 깨끗한 기능.


8

자바 8, 68 61 56 45 바이트

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

-11 덕분 바이트 @EmbodimentOfIgnorance을 교체, 상수를 java.awt.Font.BOLD 함께 -~(a^a).

온라인으로 사용해보십시오.

설명:

가장 짧은 기본 기능은 다음과 같습니다.

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

온라인으로 사용해보십시오.

숫자 계산을 위해 숫자 =또는 +/*피연산자 중 하나도 없도록 수정되었습니다 (따라서 +문자열 연결에 적합 함).

+"".equals의해 비교할 수 있습니다 String.equals(String)대신 int==int.
참고 : Integer.equals(int)여기에서 사용할 수는 있지만 더 많은 바이트가 될 것입니다. 왜냐하면 .bitCountand 대신 객체 와 java.awt.Font.BOLD원시 모두 이므로 기본을 int사용 하기 전에 둘 중 하나를 Integer객체 new Integer(...)로 변환해야 Integer합니다 .equals.


(int) Math.log (Math.E)는 21 바이트
만기 된 데이터


@ExpiredData 감사합니다. 실제로로 더 짧은 상수를 찾았 java.awt.Font.BOLD지만 귀하 Objects.equals는 훌륭한 골프입니다. 감사합니다!
Kevin Cruijssen

@ExpiredData 실제로 Objectsjava.util.가져 오기의 일부 이므로이를 바이트 수에 추가하여 69 바이트로 만들어야합니다. : :
Kevin Cruijssen

3
시겠습니까 -~(a^a)1 일?
무지의 실시

7

C (gcc) , 56 바이트

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

온라인으로 사용해보십시오!

반환 0쌍 (1)에 의해 다른 경우, 비는 달리 제로. EXIT_SUCCESS쌍이 1 씩 다르면 다른 값을 반환 하는 것을 고려하지 않는 한 C에서는 약간 특이합니다 .

함수 이름을 깨끗하게 유지하면서 원래대로 sizeof((char)d))상수를 생성하는 데 사용 합니다 1.

그런 다음 인수의 XOR의 팝 수로 1을 XOR합니다. 운 좋게도이 ^심볼은 매우 긴 식별자와 같이 깨끗하게 유지하기 쉽습니다 __builtin_popcount.

한편 솔루션을 테스트하는 데 사용되는 스크립트는 다음과 같습니다.

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

./flipbit내가 작성한 도구를 사용하는 도구는 다음과 같습니다.

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

까다로운 비트는 다음과 같습니다.

  • 공백 : 모든 공백 (줄 바꿈 포함)에는 유사하게 작동하는 깨끗한 쌍둥이가 있습니다.
  • 비교 : =그것은 모든 경우에 비교 될 수 있기 때문에 잘 작동하지 않습니다. 마찬가지로 -잘 작동하지 않습니다. 따라서 ^1과 동등성을 주장하는 데 사용됩니다.
  • 변수 이름 : f는 b와 충돌하므로 d를 대신 함수 이름으로 사용해야했습니다.

^운영자를 어떻게 깨끗하게 유지 합니까? 그 비트가 변경된 경우 다른 연산자가되는 것을 막아야합니까? 이것은 여전히 ​​컴파일되지만 잘못된 대답을 줄 것입니다. 나는 여기서 "원초적"이라는 단어의 의미에 대해 오해하고 있는가?
코디 그레이

4
하나의 비트 뒤집 으면 코드 포인트 30에서 ^하나 _\ZVN~Þ또는 인쇄 할 수없는 문자 로만 변경할 수 있습니다 . ~연산자는 단 하나의 연산자이지만 단항 연산자입니다.
관련이없는 문자열

1
또는 __LINE__대신에 사용하십시오 sizeof(char). 함수가 .c 파일의 1 행에 있다고 가정하는 것이 좋습니다. 또는 unixTIO 및 대부분의 다른 Linux에서는 1로 정의됩니다.
Digital Trauma

2
char-casted sizeof의 주된 이유는 d가능한 적은 바이트로 소스에 구워 지기 때문 입니다. 그렇지 않으면 d(또는 함수 이름)을 변경하면 코드가 계속 작동합니다. 심지어 (__LINE__)으로 d();늘 일 때문에는 d();다른 문자로 변경 될 수 있고, 함수가 호출되어야 적이 있기 때문에 여전히 따라서 연결되지 컴파일합니다.
LambdaBeta

1
@LambdaBeta 함수 이름이 변경되면 d가 자체 참조가 아닌 경우에도 링크 오류가 발생합니다. 나는 이것이 개인적으로 충분하다고 생각합니다.
디지털 외상

7

R , 38 37 바이트

Nick Kennedy 덕분에 -1 바이트.

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

온라인으로 사용해보십시오! (TIO를 올바르게 설정 한 Giuseppe에게 감사합니다.)

닉 케네디의 체커를 사용하여 깨끗하다는 증거 .

R은 이것을 False와 True로 해석하기 때문에 허위 에 대해서는 0을 출력하고, 진실에 대해서는 양의 값을 허용 합니다.

설명 : 와 bitwXor(a,b)사이에 비트 XOR을 (정수로) 제공합니다 . 2의 거듭 제곱인지 확인하려면 밑이 2 인 로그가 정수인지 확인하십시오. 이 함수 는 푸 아송 분포의 확률 밀도 함수를 제공합니다.이 값은 정수가 아닌 값의 경우 0이고 음이 아닌 정수의 경우 양수입니다. 이 있기 때문에이 두 번째 인수가 필요합니다 (모든 양의 실수 일을하고 1로 해석됩니다).abdpoisTdpoisT

고유 한 값으로 출력해야하는 경우 다음 버전은 42 바이트로 FALSE 또는 TRUE를 출력합니다 (-8 바이트의 경우 주세페 덕분).

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

그리고 또한 깨끗 합니다. 온라인으로 사용해보십시오!


2
내 것보다 훨씬 작은 것을 얻는 것이 좋습니다! 당신은 대체 할 수있는 piT(자연 그대로 계속) 바이트를 저장합니다. 또한 TIO가 현재 답변과 일치하지 않습니다.
Nick Kennedy

@NickKennedy 감사합니다! (그리고 코드를 작성해 주셔서 감사합니다!). 연결된 TIO는 모든 테스트 사례를 확인하는 수정 된 버전입니다. 실제 코드에 TIO를 추가 하겠지만 두 번의 호출로 TIO를 올바르게 실행하는 방법을 알 수 없습니다 scan(). 당신은 아이디어가 있습니까? (코드는 컴퓨터에서 잘 작동합니다.)
Robin Ryder

2
@NickKennedy 아마도 이런 식으로 뭔가 ? TIO와 코드를 일치시키기 위해?
주세페

@ 주세페 원더풀, 감사합니다!
로빈 라이더

1
두 번째 버전은 Nick 's :-)Fexp(-Inf)T
Giuseppe

6

R , 83 바이트

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

온라인으로 사용해보십시오!

이것이 깨끗하다는 증거

사실 주위 근무 as.integer, as.double단지 조금 떨어져있는 등 is.integer, is.double등은 어려운 비트이었다. 결국, sum(T^el(.[-T])하나를 생성하고 as.double길이가 1보다 큰 벡터를 반환 하는지 확인하는 방법으로 사용 하는 것이 최선이었습니다. 포장 t은 그렇지 않으면 identical될 수 있는 사실을 처리하는 것 ide~tical입니다.


5

줄리아 0.7 , 20 바이트

(a,b)->ispow2(ab)

온라인으로 사용해보십시오!

Here is a pristine validator that tries running each modified anonymous function against some input, and neither passes successfully. Note that the code has a multi-byte unicode character, and some possible outputs from bit flipping are not even included, as those produce invalid UTF-8 strings.


x and y are one bit apart, so I believe this is a counter example. y and x are also 1 bit off 9 and 6 respectively.
Expired Data

젠장, 복잡한 것들을 생각하면서, 나는 가장 간단한 것을 절대 놓쳤다. 변수를 변경하면 문제가 해결되기를 바랍니다.
Kirill L.


4

C 번호 (카메라 C 번호 인터랙티브 컴파일러) , 128 (101) 77 70 61 74 바이트

Ascii-Only 덕분에 -27 바이트

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

온라인으로 사용해보십시오!

리터럴을 사용하지 않고 C #에서 숫자를 얻으려면 매우 창의적이어야합니다. ^ 연산자 만 사용하십시오. 변수 a, b는 서로 1 비트 이상 떨어져 있으며 다른 모든 것은 키워드 / 이름입니다.


비트 수를 세지 않아도됩니다. 1에서 128 사이의 2의 거듭 제곱이 충분한 지 점검하십시오.
ASCII 전용

@ ASCII-only 정수를 사용할 수 없거나 +/*=수학 또는 유효성 검사 작업을 할 수없는 경우 적절한 바이트 수로 확인하십시오. ;)
Kevin Cruijssen

@KevinCruijssen C #은 :( 너무 열거 있습니다. 젠장
ASCII 전용


1
O_o 다른 -24. btw 더 이상 사용하지 않음+
ASCII 전용

3

JavaScript (엄격 모드의 ES6), 61 바이트

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

온라인으로 사용해보십시오! 또는 수정 된 모든 프로그램이 잘못되었는지 확인하십시오


오 세상에 나는 코드 골프 링크를 클릭 하고이 답변을 컨텍스트에서 보았고 거의 심장 마비가 있음을 알지 못했습니다. OMG NO
Marie

4
@ 마리주의! 인증 된 골프 글래스로만이 코드를 응시할 수 있습니다. 그렇지 않으면 망막에 화상을 입을 수 있습니다. : p
Arnauld


1

MATLAB, 37 바이트

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

테스트 스위트를 Octave에서 작동시킬 수 없으므로 TIO 링크가 없습니다. 유용한 의견에 대해 @ExpiredData에 감사드립니다.

테스트 스위트 :

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 제안 해 주셔서 감사합니다. numel테스트 스위트가 Octave에서 작동하지 않는 것 같아서 MATLAB을 대신 사용했습니다.
Sanchises

아마 38 바이트 .. matlab 라이센스를 얻지 못했지만 작동해야 함
만료 된 데이터

1
@ExpiredData 감사합니다. 실제로 1 바이트를 더 잘 수행 할 수 있습니다 eye!
Sanchises

1
@ExpiredData 나는 옥타브에서도 매우 화가났다. 그러나 OP 주석에서 Python 프로그램을 사용하면 문제없이 새로운 캐릭터를 소개 할 수 있는지 알 수 있습니다.
Sanchises

1

펄 6 , 77 43 바이트

-33 바이트의 Jo King에게 감사합니다.

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

이것은

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

1로 다시 작성되었습니다 elems([""]). 2로 다시 작성 sum(elems([""]),elems([""])); elems(["",""])작동하는 것처럼 보이지만 elems([""-""])유효하며 테스터를 정지시키는 것 같습니다.

온라인으로 사용해보십시오!


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.