Bozulmamış bit kontrol


28

- aralığında iki tam sayı alan ve bir sayıların ikili formlarının birbirinden tamamen farklı olup olmadığını döndüren bir program / işlev yazın .0255

Örneğin, ve ikili formlara sahiptir ve bunlar birbirlerinden biraz ayrıdır. Benzer şekilde, ve de öyle ve bu yüzden de gerçek oluyorlar.10000000010000000015224010011000000011000

Bununla birlikte , kodunuz bozulmamış olmalıdır, öyle ki programınızdaki herhangi bir bit ters çevrilmişse bir hata yapmalıdır. Örneğin, programınız tek bayta(01100001) ise, 8 olası tüm değiştirilmiş programlar:

á ! A q i e c `

bir hata yapmalı. Bayt tarafından değişiklik yaptığınızdan emin olun (örneğin, áyukarıdaki iki gerçek bayt karakterini değil, bayt temsil eder ).225á

Test durumları:

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

Kurallar:

  • Birçok olası program (bayt sayısı * 8) veya başka bir bütünlük kanıtı olacağından, programınızın uygun şekilde bozulmamış olduğunu doğrulayabilen bir test çerçevesi sağlayın.
    • Lütfen göndermeden önce programınızın geçerli olduğundan emin olun.
  • Çıktının ya truthy / falsey (ya da yolunda iyidir) ya da iki farklı hata dışı değer olması gerekir.
  • Hatalar çalışma zamanı, derleyici, tercüman vb. Olabilir.

7
Herkes en onların çözümün olası tüm varyasyonları oluşturmak için bir yol arıyoruz, bu Japt programı olmalıdır (birisi çift çek memnun) iş yapmak: petershaggynoble.github.io/Japt-Interpreter/...
Shaggy

4
İşte Python'da bir tane: Çevrimiçi deneyin!
TF

Programdan bahsettiğinizden beri fonksiyonlara izin verilmez.
Kevin Cruijssen

5
@KevinCruijssen İşlev bildirimlerinin tamam olduğunu belirttim
Jo King

4
Bu yorum +1benim son çözümlerimin çoğundan daha fazla! : \
Shaggy

Yanıtlar:


16

Python 2,35 bayt

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

Çevrimiçi deneyin!

Sahte pozitifi n&-n==nortadan kaldırarak, ikisinin gücünü kullanır n==0.

Başvuru için, bunlar, birbirlerinden biraz ayrılmış olan tek char ikili operatörlerinin çiftleridir;

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

Neyse ki, &ve ^bunların arasında değildir.

Ayrıca unutmayınız ==olabilir <=ve +açıklama karakterini haline gelebilir #.


Python 2,41 bayt

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

Çevrimiçi deneyin!

Alarak TFeld en lambda a,b:bin(a^b).count('1')==1 ve hiç 1'ler değiştirerek değmemiş yapım +Trueve ==için is. Jo King'e 1 bayt için teşekkürler.


9

Python 2 , 72 67 50 bayt

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

Çevrimiçi deneyin!

-5 bayt, Jo King sayesinde


İade True/ Falsetruthy / Falsey için için.

Program temelde aynıdır lambda a,b:bin(a^b).count('1')==1, fakat sayısız ve bit saygısız olduğunda çalışan diğer karakterleri içermez.

Neredeyse her şeyin adlandırılmış bir işlev olduğundan emin olarak çalışır (hepsi oldukça bozulmamış)

Sonundaki bozulmamış testi tek bir bit çevirir (her bit için) ve bir girişteki işlevi dener. Bu işe yararsa (doğru ya da değil), bu varyasyon yazdırılır. Basılı program yok = bozulmamış fonksiyon.


8

Java 8, 68 61 56 45 bayt

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

@EmbodimentOfIgnorance sayesinde -11 bayt , sabit java.awt.Font.BOLD ile değiştirilir -~(a^a).

Çevrimiçi deneyin.

Açıklama:

En kısa temel fonksiyon şöyle olacaktır:

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

Çevrimiçi deneyin.

Bu, sayısal hesaplamalar için rakam =, ne de içindeki +/*işlemcilerden biri olmadığı için değiştirilir ( +dize bitiştirme işlemi için iyidir):

+""Ve .equalskarşılaştırma yapmak üzere olan String.equals(String)yerine int==int.
NOT: Integer.equals(int)Her iki yana burada kullanılabilir, ancak daha fazla bayt olacağını .bitCountve java.awt.Font.BOLDilkel intyerine Integer-Nesneleri ek böylece, new Integer(...)bir bunlardan birini dönüştürmek için gerekli olacak Integer-Nesne kullandığımız edemeden, .equals.


(int) Math.log (Math.E) 21 bayttır
Süresi dolmuş veriler


@ExpiredData Teşekkürler, aslında sadece daha kısa bir sabit buldum java.awt.Font.BOLD, ancak Objects.equalsgüzel bir golf, teşekkürler!
Kevin Cruijssen

@ExpiredData Aslında, içe aktarma Objectsişleminin bir parçası java.util., bu yüzden korktuğum bayt sayısına eklemeliyim, bunu 69 bayt yapar .. :(
Kevin Cruijssen

3
-~(a^a)1 için çalışacak mıydı ?
Cehalet

7

C (gcc) , 56 bayt

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

Çevrimiçi deneyin!

İade 0çifti 1 farklı ise, aksi olmayan sıfır. EXIT_SUCCESSParite 1, eğer başka bir değerden farklı olursa, geri dönmeyi düşünmüyorsanız, C için sıra dışı bir şey

Kullanımları sizeof((char)d))sabit üretmek için 1de bozulmamış olması fonksiyon adı zorlayarak ederken bozulmamış bir şekilde.

Daha sonra XOR, argümanların XOR popcount'uyla 1 olur. Neyse ki, ^sembol çok uzun tanımlayıcı olduğu gibi, bozulmamış tutmak kolaydır __builtin_popcount.

Bu arada, işte çözümü test etmek için kullanılan senaryo:

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

Hangi ./flipbitkaynak basit olan yazdığım aracı kullanıyor :

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

Zor kısımlar şunlardı:

  • Boşluk: Bütün boşluklarda (yeni satırlar dahil), benzer şekilde çalışacak bozulmamış ikizler bulunur
  • Karşılaştırma: iyi =çalışmaz, çünkü ortaya çıkabileceği her durumda bir karşılaştırma olabilir. Benzer şekilde iyi -çalışmıyor. Böylece ^1 ile eşitlik iddia etmek için kullanılır.
  • Değişken isimleri: f b ile çakışır, bunun yerine d işlev ismi olarak kullanılmalıdır.

^Operatörü bozulmamış halde nasıl tutarsınız ? Eğer bunun bitleri değişmişse, farklı bir operatör olmasını engelleyen nedir? Bu hala derlenirdi, ama sadece yanlış cevabı verirdi. Burada "bozulmamış" kelimesinin anlamı hakkında bir yanlış anlama mı yapıyorum?
Cody Gray,

4
Saygısız By tek bit, ^sadece herhangi birine değiştirilebilir _\ZVN~Þveya kod noktasıyla 30. en basılamaz karakteri ~bir operatöre olan kişiler sadece bir tanesidir, ama sadece tekli operatörü.
İlişkisiz Dize

1
Ya da __LINE__yerine kullanın sizeof(char). İşlevinizin .c dosyanızın 1. satırında olacağını varsaymanın uygun olduğunu düşünüyorum. Hatta unixTIO'da 1, hatta çoğu diğer Linux'ta bile tanımlanmıştır.
Dijital Travma

2
Char-chared büyüklüğünün asıl nedeni dkaynağa mümkün olan en az baytta pişirilmesidir. Aksi taktirde d(veya işlevi ne adlandırırsanız) sadece değiştirilebilir ve kod çalışmaya devam eder. İstenmeyen işlerde bile (__LINE__), başka bir harfle değiştirilebildiğinden ve işlev asla çağrılmaması gerektiğinden derlenecektir, bu nedenle bağlantılı değildir. d();d();
LambdaBeta

1
@LambdaBeta Eğer fonksiyonun ismi değişirse, d kendini referans göstermese bile bir bağlantı hatası olacaktır. Kişisel olarak bunun yeterli olduğunu düşünüyorum.
Dijital Travma

7

R , 38 37 bayt

Nick Kennedy sayesinde -1 bayt.

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

Çevrimiçi deneyin! (TIO'yu doğru bir şekilde ayarlamak için Giuseppe'ye teşekkürler.)

El değmemiş bir kanıt ( Nick Kennedy'nin denetleyicisini kullanarak ).

Falsey için 0 çıktısı ve R'nin bunları Yanlış ve Doğru olarak yorumlayacağı için anladığım kadarıyla gerçeğin pozitif bir değeri kabul edilebilir .

Açıklama: bitwXor(a,b)(bir tam sayı olarak) arasında bit tabanlı bir XOR verir ave b. Gücünün 2 olup olmadığını kontrol etmek için, ana 2'deki girişinin bir tamsayı olup olmadığını kontrol edin. İşlev dpois, Poisson dağılımının olasılık yoğunluğu işlevini verir: değeri, tamsayı olmayan değerler için 0'dır ve negatif olmayan tamsayılar için pozitif bir şeydir. Var T, çünkü dpoisikinci bir argüman gerektirir (pozitif gerçek işler ve T1 olarak yorumlanır).

Farklı değerlerde çıktı almakta ısrar edersek, aşağıdaki sürüm 42 baytta FALSE veya TRUE (-8 bayt için Giuseppe sayesinde) çıktı verir:

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

ve ayrıca bozulmamış . Çevrimiçi deneyin!


2
Benimkinden çok daha küçük bir şey almak için aferin! Bir bayt (hala bozulmamış) kaydetmek için piile değiştirebilirsiniz T. Ayrıca, TIO'nuz şu anda cevabınıza uymuyor.
Nick Kennedy

@NickKennedy Teşekkürler! (Ve kontrol etmek için kod yazdığınız için teşekkürler bozulmamış!). Bağlandığım TIO, tüm test durumlarını kontrol eden değiştirilmiş bir versiyondur. Gerçek koda bir TIO ekleyeceğim, ancak iki çağrı ile TIO'nun düzgün çalışmasını nasıl sağlayacağımı bulamıyorum scan(); bir fikrin var mı (Kod bir bilgisayarda iyi çalışıyor.)
Robin Ryder

2
@NickKennedy Belki böyle bir şey ? TIO'yu ve kodun uyuşması için mi?
Giuseppe

@Giuseppe Harika, teşekkürler!
Robin Ryder

1
ikinci versiyonunuz Fyerine exp(-Inf)Nick's T:-) ile aynı satırlar boyunca kullanabilirsiniz
Giuseppe

6

R , 83 bayt

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

Çevrimiçi deneyin!

Bunun bozulmamış olduğunun kanıtı

Gerçeği etrafında çalışarak as.integer, as.doublesadece biraz uzak vb is.integer, is.doublevb zor biraz. Sonunda, sum(T^el(.[-T])hem bir tane üretmenin hem de as.double> 1 uzunluklu bir vektör verdiğini kontrol etmenin yapabileceğim en iyisiydi. Ambalaj t, aksi takdirde identicalolabileceği gerçeğini ele almaktır ide~tical.


5

Julia 0.7 , 20 bayt

(a,b)->ispow2(ab)

Çevrimiçi deneyin!

Burada bir Her değiştirilen adsız işlevi bazı girdilere karşı çalıştırmayı deneyen ve hiçbiri başarılı geçemeyen bozulmamış bir onaylayıcı . Kodun bir baytlık unicode karaktere sahip olduğunu ve geçersiz sayma işleminden kaynaklanan bazı olası çıktıların geçersiz UTF-8 dizeleri ürettiği için dahil edilmediğini unutmayın.


xve ybir parça ayrı, bu yüzden bunun bir karşı örnek olduğuna inanıyorum. yve xayrıca 1 bit 9ve 6sırasıyla.
Süresi dolmuş veriler

Kahretsin, karmaşık şeyler hakkında düşünürken, en basitini kesinlikle özledim. Umarım, değişkenleri değiştirmek onu düzeltecektir.
Kirill L.


4

C # (Visual C # Etkileşimli Derleyici) , 128 101 77 70 61 74 bayt

-27 Ascii sayesinde sadece bayt

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

Çevrimiçi deneyin!

Harfleri kullanmadan C # ile sayı elde etmek için oldukça yaratıcı olmalısınız. Sadece ^ operatörünü kullanır. A, b değişkenleri birbirinden 1 bit ötededir ve diğer her şey bir anahtar kelime / addır.


bit saymanız gerekmez - 1 ile 128 arasında 2 arasında bir güç yeterli olup olmadığını kontrol edin
ASCII-yalnızca

@ Bayt sayısını makul biz ne de tamsayılar kullanamadığı zaman olmadığını kontrol ASCII sadece iyi şanslar +/*=matematiksel ya doğrulayarak işlemleri için. ;)
Kevin Cruijssen

@KevinCruijssen C # 'nın da numaralandırması var :(. Damnit
ASCII


1
O_o başka -24. artık kullanmadığınızda btw+
ASCII sadece



1

MATLAB, 37 bayt

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

Üzgünüz, TIO bağlantısı yok, çünkü test odasının Octave altında çalışmasını sağlayamıyorum. Bazı yararlı yorumlar için @ExpiredData teşekkürler.

Test odası:

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 Öneri için teşekkürler. Bunun numelyerine bir MATLAB'a gittim , çünkü test takımım Octave'da çalışmıyor gibi görünüyor.
Sanchises

38 byte belki .. bir matlab lisansı yok ama çalışması gerekiyor
Süresi dolmuş veriler

1
@ExpiredData Teşekkürler, biri aslında bir bayt ile daha iyi yapabilir eye!
Sanchises

1
@ExpiredData Biliyorum, ben de Octave'de çok kızgınım. Ancak OP yorumlarında Python programını kullanmak, sorunsuz bir şekilde yeni bir karakter sunup sunamayacağınızı görmek için kullanışlıdır.
Sanchises

1

Perl 6 , 77 43 bayt

-33 bayt için Jo King'e teşekkürler.

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

Bu eşdeğerdir

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

1olarak yeniden yazıldı elems([""]). 2olarak yeniden yazıldı sum(elems([""]),elems([""]));elems(["",""])İşe yarayabilir, ancak elems([""-""])aynı zamanda geçerlidir ve test cihazını asmak gibi görünüyor.

Çevrimiçi deneyin!


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.