Pemeriksaan Bit Pristine

28

Tulis program / fungsi yang mengambil dua bilangan bulat dalam kisaran hingga inklusif, dan mengembalikan apakah bentuk biner dari angka-angka itu persis berbeda satu bit.0255

Sebagai contoh, dan memiliki bentuk biner dan , yang terpisah satu bit. Demikian pula, dan adalah dan , jadi mereka mengembalikan true.10000000010000000015224010011000000011000

Namun , kode Anda harus asli , sehingga jika ada satu bit dalam program Anda dibalik, itu akan menimbulkan kesalahan. Misalnya, jika program Anda adalah byte tunggala(01100001), maka semua 8 program yang mungkin dimodifikasi:

á ! A q i e c `

harus melempar kesalahan. Pastikan Anda memodifikasi dengan byte (misalnya di ásana sebenarnya mewakili byte , bukan karakter dua byte yang sebenarnya ).225á

Kasus uji:

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

Aturan:

  • Berikan kerangka pengujian yang dapat memverifikasi bahwa program Anda benar-benar murni, karena akan ada banyak program yang mungkin (jumlah byte * 8), atau bukti lengkap tentang keaslian.
    • Harap pastikan program Anda berlaku sebelum Anda posting.
  • Output harus benar-benar benar / salah (baik jalan baik-baik saja), atau dua nilai non-error yang berbeda
  • Kesalahan dapat berupa runtime, compiler, interpreter dll.
Jo King
sumber
7
Jika ada yang mencari cara untuk menghasilkan semua kemungkinan variasi dari solusi mereka, program Japt ini harus (seseorang tolong periksa ulang) melakukan pekerjaan: petershaggynoble.github.io/Japt-Interpreter/…
Shaggy
4
Ini salah satu di Python juga: Cobalah online!
TFeld
Fungsi tidak diizinkan, karena Anda menyebutkan program?
Kevin Cruijssen
5
@KevinCruijssen Saya telah menetapkan bahwa pengiriman fungsi tidak masalah
Jo King
4
Komentar itu memiliki lebih +1dari sebagian besar solusi terbaru saya! : \
Shaggy

Jawaban:

16

Python 2 , 35 byte

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

Cobalah online!

Menggunakan kekuatan dari dua cek n&-n==n, menghilangkan n==0false positive.

Sebagai referensi, ini adalah pasangan dari operator biner satu char yang terpisah satu sama lain, sehingga sulit digunakan:

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

Untungnya, &dan ^tidak ada di antara ini.

Perhatikan juga yang ==bisa menjadi <=, dan +bisa menjadi karakter komentar #.


Python 2 , 41 byte

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

Cobalah online!

Mengambil TFeld's lambda a,b:bin(a^b).count('1')==1 dan menjadikannya asli dengan mengubah 1's ke +Truedan ==ke is. Terima kasih kepada Jo King untuk 1 byte.

Tidak
sumber
9

Python 2 , 72 67 50 byte

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

Cobalah online!

-5 byte, terima kasih kepada Jo King


Pengembalian True/ Falseuntuk untuk kebenaran / falsey.

Program ini pada dasarnya sama dengan lambda a,b:bin(a^b).count('1')==1, tetapi tanpa angka dan karakter lain yang berfungsi saat dibalik.

Bekerja dengan memastikan bahwa hampir semuanya adalah fungsi bernama (yang semuanya cukup murni)

Tes murni pada akhirnya membalik bit tunggal (untuk setiap bit), dan mencoba fungsi pada input. Jika itu berhasil (benar atau tidak), variasi itu dicetak. Tidak ada program yang dicetak = fungsi asli.

TFeld
sumber
8

Java 8, 68 61 56 45 byte

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

-11 byte terima kasih kepada @EmbodimentOfIgnorance , ganti dengan konstan .java.awt.Font.BOLD-~(a^a)

Cobalah online.

Penjelasan:

Fungsi basis terpendek adalah:

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

Cobalah online.

Ini dimodifikasi sehingga tidak ada digit,, =atau salah satu +/*operan di dalamnya untuk perhitungan numerik (jadi +untuk rangkaian-string baik-baik saja):

The +""dan .equalsyang untuk membandingkan dengan String.equals(String)bukan int==int.
CATATAN: Integer.equals(int)bisa digunakan di sini, tapi akan lebih byte, karena kedua .bitCountdan java.awt.Font.BOLDprimitif intbukan Integer-objects, sehingga tambahan new Integer(...)akan diperlukan untuk mengubah salah satu dari dua ke Integer-object, sebelum kita bisa menggunakan .equals.

Kevin Cruijssen
sumber
(int) Math.log (Math.E) adalah 21 byte
Data Kedaluwarsa
1
59 bytes
Expired Data
@ExpiredData Terima kasih, sebenarnya baru saja menemukan konstanta yang lebih pendek java.awt.Font.BOLD, tetapi Objects.equalsgolf Anda bagus, terima kasih!
Kevin Cruijssen
@ExpiredData Sebenarnya, Objectsadalah bagian dari java.util.impor, jadi saya harus menambahkan itu ke byte-count aku takut, membuatnya menjadi 69 byte .. :(
Kevin Cruijssen
3
Akan -~(a^a)bekerja untuk 1?
Perwujudan Ketidaktahuan
7

C (gcc) , 56 byte

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

Cobalah online!

Mengembalikan 0jika pasangan berbeda dengan 1, bukan nol sebaliknya. Agak tidak biasa untuk C, kecuali jika Anda menganggapnya kembali EXIT_SUCCESSjika pasangan berbeda dengan 1, nilai lainnya sebaliknya.

Menggunakan sizeof((char)d))untuk menghasilkan konstanta 1dengan cara yang murni sementara juga memaksa nama fungsi menjadi murni.

Kemudian XOR 1 dengan popcount XOR dari argumen. Untungnya ^simbolnya mudah disimpan, seperti pengenal yang sangat panjang __builtin_popcount.

Sementara itu, berikut ini skrip yang digunakan untuk menguji solusinya:

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

Yang menggunakan ./flipbitalat yang saya tulis sumbernya adalah:

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

Bit yang rumit adalah:

  • Ruang putih: Semua ruang putih (termasuk baris baru) memiliki kembar asli yang akan bekerja sama
  • Perbandingan: =tidak berfungsi dengan baik, karena bisa menjadi perbandingan dalam setiap kasus itu bisa muncul. Demikian pula -tidak bekerja dengan baik. Dengan demikian ^digunakan untuk menegaskan kesetaraan dengan 1.
  • Nama variabel: f akan berbenturan dengan b, jadi harus menggunakan d sebagai nama fungsi.
LambdaBeta
sumber
Bagaimana Anda menjaga ^operator tetap asli? Jika bit pada itu diubah, apa yang menghentikannya dari menjadi operator yang berbeda? Ini masih akan dikompilasi, tetapi hanya akan memberi Anda jawaban yang salah. Apakah saya salah paham tentang arti kata "murni" di sini?
Cody Grey
4
Dengan membalik hanya satu bit, ^hanya dapat diubah menjadi salah satu dari _\ZVN~Þatau karakter yang tidak diinginkan pada codepoint 30. ~adalah satu-satunya dari mereka yang merupakan operator, tetapi itu hanya operator unary.
String Tidak Terkait
1
Atau bahkan digunakan __LINE__sebagai gantinya sizeof(char). Saya pikir tidak apa-apa untuk menganggap bahwa fungsi Anda akan ada pada baris 1 dari file .c Anda. Atau bahkan unixdidefinisikan sebagai 1 pada TIO, dan mungkin sebagian besar Linux lainnya.
Digital Trauma
2
Alasan utama untuk sizeof char-casted adalah untuk ddimasukkan ke dalam sumber dalam byte sesedikit mungkin. Kalau tidak d(atau apa pun nama Anda fungsinya) hanya dapat diubah dan kode masih akan berfungsi. Bahkan (__LINE__)dengan d();tidak berfungsi karena d();dapat diubah ke huruf lain dan masih akan dikompilasi karena fungsi tidak pernah harus dipanggil, dengan demikian tidak ditautkan.
LambdaBeta
1
@LambdaBeta Jika nama fungsi berubah, maka akan ada kesalahan tautan, bahkan jika d bukan referensi diri. Saya pikir ini sudah cukup, secara pribadi.
Digital Trauma
7

R , 38 37 byte

-1 byte terima kasih kepada Nick Kennedy.

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

Cobalah online! (Terima kasih kepada Giuseppe karena mengatur TIO dengan benar.)

Bukti bahwa itu asli (menggunakan checker Nick Kennedy ).

Keluaran 0 untuk falsey, dan nilai positif untuk kebenaran, yang saya mengerti dapat diterima karena R akan menafsirkan ini sebagai False dan True.

Penjelasan: bitwXor(a,b)memberikan (sebagai bilangan bulat) XOR bitwise antara adan b. Untuk memeriksa apakah kekuatan 2, periksa apakah basis 2 masuknya adalah bilangan bulat. Fungsi ini dpoismemberikan fungsi kerapatan probabilitas dari distribusi Poisson: nilainya 0 untuk nilai non-integer, dan sesuatu yang positif untuk integer non-negatif. Itu Tada karena dpoismemerlukan argumen kedua (setiap karya nyata positif, dan Tditafsirkan sebagai 1).

Jika kami bersikeras untuk menghasilkan nilai yang berbeda, versi berikut ini menghasilkan SALAH atau BENAR dalam 42 byte (terima kasih kepada Giuseppe untuk -8 byte):

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

dan juga murni . Cobalah online!

Robin Ryder
sumber
2
Bagus untuk mendapatkan sesuatu yang jauh lebih kecil dari milikku! Anda dapat mengganti pidengan Tuntuk menyimpan byte (masih asli). TIO Anda juga tidak sesuai dengan jawaban Anda saat ini.
Nick Kennedy
@NickKennedy Terima kasih! (Dan terima kasih telah menulis kode untuk memeriksa apakah ini asli!). TIO yang saya tautkan adalah versi modifikasi yang memeriksa semua kasus uji. Saya akan menambahkan TIO ke kode aktual, tetapi saya tidak tahu bagaimana caranya agar TIO dapat berjalan dengan baik dengan dua panggilan scan(); apakah kamu punya ide? (Kode berfungsi baik di komputer.)
Robin Ryder
2
@NickKennedy Mungkin kira - kira seperti ini? untuk mendapatkan TIO dan kode yang cocok?
Giuseppe
@Giuseppe Hebat, terima kasih!
Robin Ryder
1
versi kedua Anda bisa digunakan Fsebagai ganti exp(-Inf), di sepanjang baris yang sama dengan Nick T:-)
Giuseppe
6

R , 83 byte

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

Cobalah online!

Bukti bahwa ini asli

Mengatasi kenyataan bahwa as.integer, as.doubledll. Hanya berjarak sedikit dari is.integer, is.doubledll. Adalah bagian yang paling sulit. Pada akhirnya, menggunakan sum(T^el(.[-T])sebagai cara menghasilkan satu dan memeriksa yang as.doubletelah mengembalikan vektor> 1 panjang adalah yang terbaik yang bisa saya lakukan. Bungkusnya tadalah untuk menangani fakta bahwa kalau tidak identicalbisa jadi ide~tical.

Nick Kennedy
sumber
5

Julia 0.7 , 20 byte

(a,b)->ispow2(ab)

Cobalah online!

Berikut ini adalah validator murni yang mencoba menjalankan setiap fungsi anonim yang dimodifikasi terhadap beberapa input, dan keduanya tidak berhasil. Perhatikan bahwa kode tersebut memiliki karakter unicode multi-byte, dan beberapa kemungkinan keluaran dari bit flipping bahkan tidak disertakan, karena kode tersebut menghasilkan string UTF-8 yang tidak valid.

Kirill L.
sumber
xdan yagak terpisah, jadi saya percaya ini adalah contoh balasan. ydan xjuga 1 bit off 9dan 6masing - masing.
Data Kedaluwarsa
Sial, sambil memikirkan hal-hal rumit, aku benar-benar merindukan yang paling sederhana. Semoga, mengubah variabel akan memperbaikinya.
Kirill L.
5

C # (Visual C # Interactive Compiler) , 37 byte

a=>b=>a!=b&((a^b)&-(a^b)).Equals(a^b)

Bagian a=>b=>tidak dapat diubah, atau fungsi tersebut tidak valid.

Di a!=b, =tidak dapat diubah karena inttidak dapat dikonversi ke bool.

Cobalah online!

Perwujudan Ketidaktahuan
sumber
4

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

-27 byte berkat Ascii-Only

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

Cobalah online!

Anda harus cukup kreatif untuk mendapatkan angka dalam C # tanpa menggunakan literal. Hanya menggunakan operator ^. Variabel a, b semuanya lebih dari 1 bit dari satu sama lain dan yang lainnya adalah kata kunci / nama.

Data Kedaluwarsa
sumber
Anda tidak perlu menghitung bit - memeriksa apakah kekuatan 2 antara 1 dan 128 inklusif sudah cukup
ASCII
@ Hanya ASCII Selamat mencoba memeriksa bahwa dalam jumlah byte yang wajar ketika kita tidak dapat menggunakan integer atau +/*=untuk operasi matematika atau memvalidasi. ;)
Kevin Cruijssen
@KevinCruijssen C # memiliki enum juga :(. Damnit
ASCII-only
1
101?
ASCII
1
O_o lagi -24. btw Anda tidak lagi menggunakan+
ASCII-satunya
3

JavaScript (ES6 dalam mode ketat), 61 byte

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

Cobalah online! atau Pastikan semua program yang diubah salah

Arnauld
sumber
Ya ampun, saya tidak menyadari bahwa saya mengklik tautan kode golf dan melihat jawaban ini di luar konteks dan hampir mengalami serangan jantung. Seperti, OMG TIDAK
Marie
4
@Marie Caution! Anda hanya dapat menatap kode ini dengan kacamata golf bersertifikat. Jika tidak, itu dapat membakar retina Anda. : p
Arnauld
1

MATLAB, 37 byte

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

Maaf, tidak ada tautan TIO, karena saya tidak bisa menjalankan test suite di bawah Octave. Terima kasih @ExpiredData untuk beberapa komentar bermanfaat.

Test suite:

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)
Sanchises
sumber
41 byte
Expired Data
@ExpiredData Terima kasih atas sarannya. Saya memilih MATLAB numel, karena test suite saya sepertinya tidak berfungsi di Octave.
Sanchises
38 byte mungkin .. tidak mendapat lisensi matlab tetapi harus berfungsi
Expired Data
1
@ExpiredData Terima kasih, satu sebenarnya dapat melakukan satu byte lebih baik dengan eye!
Sanchises
1
@ExpiredData Saya tahu, saya juga sangat kesal pada Octave. Tetapi menggunakan program Python di komentar OP berguna untuk melihat apakah Anda dapat memperkenalkan karakter baru tanpa masalah.
Sanchises
1

Perl 6 , 77 43 byte

Terima kasih kepada Jo King untuk -33 byte.

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

Ini setara dengan

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

1ditulis ulang sebagai elems([""]). 2ditulis ulang sebagai sum(elems([""]),elems([""])); elems(["",""])mungkin tampak berfungsi tetapi elems([""-""])juga valid dan tampaknya menggantung tester.

Cobalah online!

bb94
sumber