Kiểm tra bit nguyên sơ


28

Viết chương trình / hàm có hai số nguyên trong phạm vi từ 0 đến 255 , và trả về việc dạng nhị phân của các số có khác nhau một bit hay không.

Ví dụ, 10 có dạng nhị phân 0000000100000000cách nhau một bit. Tương tự, 15224010011000000011000, vì vậy chúng trả về đúng.

Tuy nhiên , mã của bạn phải còn nguyên sơ , sao cho nếu bất kỳ một bit nào trong chương trình của bạn bị lật, nó sẽ gây ra lỗi. Ví dụ: nếu chương trình của bạn là byte đơna(01100001), thì tất cả 8 chương trình được sửa đổi có thể:

á ! A q i e c `

phải ném một lỗi. Hãy chắc chắn rằng bạn đang sửa đổi theo byte (ví dụ: trên áthực tế có đại diện cho byte 225 , không phải là ký tự hai byte thực tế á).

Các trường hợp thử nghiệm:

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

Quy tắc:

  • Cung cấp một khung kiểm tra có thể xác minh rằng chương trình của bạn còn nguyên sơ, vì sẽ có rất nhiều chương trình có thể (số byte * 8), hoặc bằng chứng hoàn toàn khác về tính nguyên sơ.
    • Hãy chắc chắn rằng chương trình của bạn là hợp lệ trước khi bạn đăng nó.
  • Đầu ra cần phải là sự thật / falsey (dù cách nào cũng tốt) hoặc nếu không thì hai giá trị không lỗi khác biệt
  • Lỗi có thể là thời gian chạy, trình biên dịch, trình thông dịch, vv

7
Nếu bất cứ ai đang tìm cách tạo ra tất cả các biến thể có thể có của giải pháp của họ, chương trình Japt này sẽ (ai đó vui lòng kiểm tra lại) thực hiện công việc: petershaggynoble.github.io/Japt-Interpreter/,
Shaggy

4
Đây cũng là một trong Python: Hãy thử trực tuyến!
TFeld

Chức năng không được phép, vì bạn đã đề cập đến chương trình?
Kevin Cruijssen

5
@KevinCruijssen Tôi đã chỉ định rằng việc gửi chức năng là ổn
Jo King

4
Nhận xét đó có nhiều +1s hơn phần lớn các giải pháp gần đây của tôi! : \
Shaggy

Câu trả lời:


16

Python 2 , 35 byte

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

Hãy thử trực tuyến!

Sử dụng kiểm tra sức mạnh của hai n&-n==n, loại bỏ n==0dương tính giả.

Để tham khảo, đây là các cặp toán tử nhị phân một char cách nhau một bit, khiến chúng khó sử dụng:

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

May mắn thay, &^không nằm trong số này.

Cũng lưu ý rằng ==có thể trở thành <=, và +có thể trở thành nhân vật bình luận #.


Python 2 , 41 byte

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

Hãy thử trực tuyến!

Lấy TFeld lambda a,b:bin(a^b).count('1')==1 và làm cho nó trở nên nguyên sơ bằng cách thay đổi 1 +True==thành is. Cảm ơn Jo King cho 1 byte.


9

Python 2 , 72 67 50 byte

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

Hãy thử trực tuyến!

-5 byte, nhờ Jo King


Trả về True/ Falsecho sự thật / falsey.

Chương trình về cơ bản giống như lambda a,b:bin(a^b).count('1')==1, nhưng không có số và ký tự khác hoạt động khi lật bit.

Hoạt động bằng cách đảm bảo rằng hầu hết mọi thứ là một hàm được đặt tên (tất cả đều khá nguyên sơ)

Kiểm tra nguyên sơ ở cuối lật một bit (cho mỗi bit) và thử chức năng trên một đầu vào. Nếu điều đó hoạt động (chính xác hay không), biến thể đó được in. Không có chương trình in = chức năng nguyên sơ.


8

Java 8, 68 61 56 45 byte

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

-11 byte nhờ @EmbodimentOfIgnorance , thay thế hằng số java.awt.Font.BOLD bằng -~(a^a).

Hãy thử trực tuyến.

Giải trình:

Hàm cơ sở ngắn nhất sẽ là:

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

Hãy thử trực tuyến.

Điều này đã được sửa đổi để không có một chữ số, =cũng không phải là một trong các +/*toán hạng trong nó để tính toán số (vì vậy, +việc ghép chuỗi là tốt):

Các +"".equalslà để so sánh bởi String.equals(String)thay vì int==int.
LƯU Ý: Integer.equals(int)có thể được sử dụng ở đây, nhưng sẽ có nhiều byte hơn, vì cả hai .bitCountjava.awt.Font.BOLDnguyên thủy intthay vì Integer-objects, do đó, new Integer(...)cần phải bổ sung để chuyển đổi một trong hai thành một Integer-object, trước khi chúng ta có thể sử dụng .equals.


(int) Math.log (Math.E) là 21 byte
Dữ liệu hết hạn


@ExpiredData Cảm ơn, thực sự chỉ tìm thấy một hằng số ngắn hơn với java.awt.Font.BOLD, nhưng bạn Objects.equalslà một golf tốt, cảm ơn!
Kevin Cruijssen

@ExpiredData Trên thực tế, Objectslà một phần của quá trình java.util.nhập, vì vậy tôi phải thêm số đó vào số byte tôi sợ, làm cho nó 69 byte .. :(
Kevin Cruijssen

3
Sẽ -~(a^a)làm việc cho 1?
Hiện thân của sự thiếu hiểu biết

7

C (gcc) , 56 byte

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

Hãy thử trực tuyến!

Trả về 0nếu cặp khác nhau 1, khác không. Hơi bất thường đối với C, trừ khi bạn xem xét nó trở lại EXIT_SUCCESSnếu cặp khác 1, bất kỳ giá trị nào khác.

Sử dụng sizeof((char)d))để tạo ra hằng số 1một cách nguyên sơ đồng thời buộc tên hàm phải còn nguyên sơ.

Sau đó, XOR cho rằng 1 với số lượng XOR của các đối số. May mắn là ^biểu tượng dễ dàng để giữ nguyên sơ, như là định danh rất dài __builtin_popcount.

Trong khi đó, đây là kịch bản được sử dụng để kiểm tra giải pháp:

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

Sử dụng ./flipbitcông cụ tôi đã viết có nguồn chỉ đơn giản là:

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

Các bit khó khăn là:

  • Khoảng trắng: Tất cả các khoảng trắng (bao gồm cả dòng mới) có cặp song sinh nguyên sơ sẽ hoạt động tương tự
  • So sánh: =không hoạt động tốt, vì nó có thể là so sánh trong mọi trường hợp nó có thể xuất hiện. Tương tự như vậy -không hoạt động tốt. Do đó ^được sử dụng để khẳng định sự bình đẳng với 1.
  • Tên biến: f sẽ đụng độ với b, vì vậy phải sử dụng d làm tên hàm thay thế.

Làm thế nào để bạn giữ cho các ^nhà điều hành nguyên sơ? Nếu các bit trên đó được thay đổi, điều gì ngăn nó trở thành một toán tử khác? Điều này vẫn sẽ biên dịch, nhưng sẽ chỉ cung cấp cho bạn câu trả lời sai. Tôi có hiểu nhầm gì đó về ý nghĩa của từ "nguyên sơ" ở đây không?
Cody Grey

4
Bằng cách chỉ lật một bit, ^chỉ có thể thay đổi thành bất kỳ một _\ZVN~Þhoặc một ký tự không thể in được tại mã 30. ~là người duy nhất là một toán tử, nhưng đó chỉ là một toán tử đơn nguyên.
Chuỗi không liên quan

1
Hoặc thậm chí sử dụng __LINE__thay vì sizeof(char). Tôi nghĩ thật tốt khi cho rằng chức năng của bạn sẽ nằm trên dòng 1 của tệp .c của bạn. Hoặc thậm chí unixđược định nghĩa là 1 trên TIO và có lẽ là hầu hết các Linux khác.
Chấn thương kỹ thuật số

2
Lý do chính cho kích thước được đúc bằng char là để được dđưa vào nguồn theo ít byte nhất có thể. Mặt khác d(hoặc bất cứ điều gì bạn đặt tên hàm) chỉ có thể được thay đổi và mã sẽ vẫn hoạt động. Ngay cả (__LINE__)khi d();không hoạt động vì d();có thể thay đổi thành bất kỳ chữ cái nào khác và nó vẫn sẽ biên dịch vì hàm không bao giờ phải gọi, do đó không được liên kết.
LambdaBeta

1
@LambdaBeta Nếu tên của hàm thay đổi, thì sẽ có lỗi liên kết, ngay cả khi d không tự tham chiếu. Tôi nghĩ rằng điều này là đủ, cá nhân.
Chấn thương kỹ thuật số

7

R , 38 37 byte

-1 byte nhờ Nick Kennedy.

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

Hãy thử trực tuyến! (Cảm ơn Giuseppe đã thiết lập TIO đúng cách.)

Bằng chứng là nó còn nguyên sơ (sử dụng công cụ kiểm tra của Nick Kennedy ).

Kết quả 0 cho falsey và giá trị dương cho sự thật, điều mà tôi hiểu là có thể chấp nhận được vì R sẽ diễn giải những điều này là Sai và Đúng.

Giải thích: bitwXor(a,b)cung cấp (dưới dạng một số nguyên) XOR bitwise giữa ab. Để kiểm tra xem nó có phải là lũy thừa 2 hay không, kiểm tra xem nhật ký của nó trong cơ sở 2 có phải là số nguyên hay không. Hàm dpoiscung cấp hàm mật độ xác suất của phân phối Poisson: giá trị của nó là 0 đối với các giá trị không nguyên và một số dương cho các số nguyên không âm. Có Tbởi vì dpoisđòi hỏi một đối số thứ hai (bất kỳ tác phẩm thực sự tích cực nào, và Tđược hiểu là 1).

Nếu chúng tôi nhấn mạnh vào việc xuất ra các giá trị riêng biệt, phiên bản sau sẽ xuất FALSE hoặc TRUE thành 42 byte (nhờ Giuseppe cho -8 byte):

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

cũng còn nguyên sơ . Hãy thử trực tuyến!


2
Làm tốt lắm khi nhận được một cái gì đó nhỏ hơn nhiều so với của tôi! Bạn có thể thay thế pibằng Tđể lưu một byte (vẫn còn nguyên sơ). Ngoài ra TIO của bạn không tương ứng với câu trả lời của bạn tại thời điểm này.
Nick Kennedy

@NickKennedy Cảm ơn! (Và cảm ơn vì đã viết mã để kiểm tra xem nó còn nguyên sơ!). TIO tôi liên kết đến là một phiên bản sửa đổi để kiểm tra tất cả các trường hợp thử nghiệm. Tôi sẽ thêm TIO vào mã thực tế, nhưng tôi không thể tìm ra cách để TIO chạy đúng với hai cuộc gọi đến scan(); Bạn có một ý tưởng? (Mã này hoạt động tốt trên máy tính.)
Robin Ryder

2
@NickKennedy Có lẽ một cái gì đó như thế này? để có được TIO và mã phù hợp?
Giuseppe

@Giuseppe Tuyệt vời, cảm ơn!
Robin Ryder

1
phiên bản thứ hai của bạn có thể sử dụng Fthay vì exp(-Inf), cùng dòng với Nick T:-)
Giuseppe

6

R , 83 byte

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

Hãy thử trực tuyến!

Bằng chứng là điều này còn nguyên sơ

Làm việc xung quanh thực tế là as.integer, as.doublevv chỉ là một chút từ is.integer, is.doublevv là khó khăn nhất. Cuối cùng, sử dụng sum(T^el(.[-T])như một cách vừa tạo một cái và kiểm tra as.doubleđã trả về một vectơ có độ dài> 1 là cách tốt nhất tôi có thể làm. Gói tlà để xử lý thực tế rằng nếu không identicalcó thể trở thành ide~tical.


5

Julia 0,7 , 20 byte

(a,b)->ispow2(ab)

Hãy thử trực tuyến!

Dưới đây là trình xác nhận nguyên sơ thử chạy từng hàm ẩn danh đã sửa đổi đối với một số đầu vào và không vượt qua thành công. Lưu ý rằng mã có ký tự unicode nhiều byte và một số đầu ra có thể có từ việc lật bit thậm chí không được bao gồm, vì chúng tạo ra các chuỗi UTF-8 không hợp lệ.


xycách nhau một chút, vì vậy tôi tin rằng đây là một ví dụ ngược lại. yxcũng được tắt 1 bit 96tương ứng.
Dữ liệu hết hạn

Chết tiệt, trong khi suy nghĩ về những điều phức tạp, tôi hoàn toàn bỏ lỡ điều đơn giản nhất. Hy vọng, thay đổi các biến sẽ khắc phục nó.
Kirill L.


4

C # (Trình biên dịch tương tác Visual C #) , 128 101 77 70 61 74 byte

-27 byte chỉ nhờ vào Ascii

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

Hãy thử trực tuyến!

Bạn phải khá sáng tạo để có được số trong C # mà không cần sử dụng chữ. Chỉ sử dụng toán tử ^. Các biến a, b cách nhau hơn 1 bit và mọi thứ khác là từ khóa / tên.


bạn không cần phải đếm bit - kiểm tra xem sức mạnh của 2 trong khoảng từ 1 đến 128 đã đủ chưa
ASCII chỉ có

Chỉ có ASCII Chúc may mắn kiểm tra rằng trong một số byte hợp lý khi chúng tôi không thể sử dụng số nguyên cũng như +/*=cho các hoạt động toán học hoặc xác nhận. ;)
Kevin Cruijssen

@KevinCruijssen C # cũng có enums :(. Damnit
ASCII-only


1
O_o khác -24. btw bạn không còn sử dụng+
ASCII-chỉ

3

JavaScript (ES6 ở chế độ nghiêm ngặt), 61 byte

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

Hãy thử trực tuyến! hoặc Đảm bảo rằng tất cả các chương trình sửa đổi là sai


Ôi trời ơi, tôi không nhận ra mình đã nhấp vào một liên kết golf mã và thấy câu trả lời này ngoài ngữ cảnh và gần như bị đau tim. Giống như, OMG NO
Marie

4
@Marie Thận trọng! Bạn chỉ có thể nhìn chằm chằm vào mã này với kính golf được chứng nhận. Nếu không, nó có thể đốt cháy võng mạc của bạn. : p
Arnauld


1

MATLAB, 37 byte

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

Xin lỗi, không có liên kết TIO, vì tôi không thể khiến bộ thử nghiệm hoạt động theo Octave. Cảm ơn @ExpiredData cho một số ý kiến ​​hữu ích.

Bộ kiểm tra:

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 Cảm ơn bạn đã gợi ý. Tôi đã đi tìm MATLAB numelthay vì bộ thử nghiệm của tôi dường như không hoạt động ở Octave.
Sanchise

38 byte có thể .. không có giấy phép MATLAB nhưng sẽ hoạt động
Dữ liệu hết hạn

1
@ExpiredData Cảm ơn, người ta thực sự có thể làm tốt hơn một byte với eye!
Sanchise

1
@ExpiredData Tôi biết, tôi cũng rất bực mình ở Octave. Nhưng sử dụng chương trình Python trong các bình luận OP rất hữu ích để xem bạn có thể giới thiệu một nhân vật mới mà không gặp vấn đề gì không.
Sanchise

1

Perl 6 , 77 43 byte

Cảm ơn Jo King cho -33 byte.

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

Điều này tương đương với

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

1được viết lại như elems([""]). 2được viết lại như sum(elems([""]),elems([""])); elems(["",""])có vẻ như hoạt động nhưng elems([""-""])cũng hợp lệ và dường như treo máy kiểm tra.

Hãy thử trực tuyến!


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.