元のビットチェック


28

範囲内の2つの整数取るプログラム/機能書くに包括的に、数字のバイナリ形式かどうかを返しますが、正確に一つは、異なるビットされています。0255

たとえば、とはバイナリ形式とがあり、これらは1ビット離れています。同様に、とはand であるため、trueを返します。10000000010000000015224010011000000011000

ただし、コードは初期状態でなければならず、プログラムのいずれかのビットが反転した場合、エラーがスローされます。たとえば、プログラムがシングルバイトa01100001)の場合、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)が多数あるため、プログラムが適切に初期状態であることを検証できるテストフレームワークを提供するか、または初期状態の完全な証拠を提供します。
    • 投稿する前に、プログラムが有効であることを確認してください
  • 出力は、真実/偽(どちらの方法でも問題ありません)であるか、2つの異なる非エラー値である必要があります
  • エラーには、ランタイム、コンパイラ、インタプリタなどがあります。

7
ソリューションのあらゆるバリエーションを生成する方法を探している人がいる場合、このJaptプログラムpetershaggynoble.github.io/Japt-Interpreter
Shaggy


あなたはプログラムに言及したので、機能は許可されていませんか?
ケビンクルーッセン

5
@KevinCruijssen関数の送信は問題ないことを指定しました
Jo King

4
このコメントには+1、私の最近のソリューションの大半よりも多くのコメントが付いています!:\
シャギー

回答:


16

Python 2、35バイト

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

オンラインでお試しください!

2のべき乗チェックを使用してn&-n==nn==0誤検知を排除します。

参考までに、これらは1文字のバイナリ演算子のペアであり、1ビット離れているため、使用が難しくなります。

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

幸い、&および^これらの中ではありません。

また、コメント文字になったり、コメント文字になったりする可能性がある==ことに注意してください。<=+#


Python 2、41バイト

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

オンラインでお試しください!

撮影TFeldのを lambda a,b:bin(a^b).count('1')==1し、それが1つのを変更することで、自然のまま作る+True==しますis。1バイトのJo Kingに感謝します。


9

Pythonの272の 67 50バイト

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

オンラインでお試しください!

-5バイト、Jo Kingのおかげ


True/ Falseをtrue / falseyで返します。

プログラムは基本的にと同じですがlambda a,b:bin(a^b).count('1')==1、ビット反転時に機能する数字やその他の文字はありません。

ほとんどすべてが名前付き関数であることを確認することにより機能します(これらはすべて非常に自然です)

最後の初期テストでは、1ビットを(すべてのビットに対して)反転させ、入力に対して関数を試行します。それが機能する場合(正しいかどうか)、そのバリエーションが印刷されます。印刷されたプログラムはありません=元の機能。


8

Java 8、68 61 56 45バイト

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

@EmbodimentOfIgnoranceのおかげで-11バイト、定数 java.awt.Font.BOLDをに置き換えました-~(a^a)

オンラインでお試しください。

説明:

最も短い基本関数は次のとおりです。

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

オンラインでお試しください。

これは修正されているため、数値計算のために数字=+/*オペランドもありません(したがって、+文字列連結の場合は問題ありません):

比較することがあるの代わりに。 注:はここで使用できますが、とは両方とも-objectsの代わりにプリミティブであるため、より多くのバイトになるため、2つのうちの1つを-object に変換する前に追加が必要になります。+"".equalsString.equals(String)int==int
Integer.equals(int).bitCountjava.awt.Font.BOLDintIntegernew Integer(...)Integer.equals


(int)Math.log(Math.E)は21バイト
期限切れデータ


@ExpiredDataおかげで、実際にはでより短い定数を見つけましたjava.awt.Font.BOLDが、あなたObjects.equalsは素晴らしいゴルフです、ありがとう!
ケビンクルーッセン

@ExpiredData実際にObjectsは、java.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の場合は0、それ以外の場合は0を返します。EXIT_SUCCESSペアが1だけ異なる場合に戻ることを考慮しない限り、Cの場合は少し異常です。

を使用sizeof((char)d))して、1関数名を初期化すると同時に、初期化された方法で定数を生成します。

次に、その1を引数のXORのポップカウントと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
1ビットのみを反転することにより、コードポイント30の^いずれか1つ_\ZVN~Þまたは印刷不可能な文字にのみ変更できます。~演算子であるのは1つだけですが、それは単項演算子です。
無関係な文字列

1
またはの__LINE__代わりに使用することもできますsizeof(char)。関数が.cファイルの1行目にあると仮定するのは問題ないと思います。またはunix、TIO、およびおそらく他のほとんどのLinuxで1に定義されます。
デジタル外傷

2
文字キャストされたsizeofの主な理由は、d可能な限り少ないバイト数でソースに焼き付けられることです。それ以外の場合d(または関数に名前を付けたもの)を変更するだけで、コードは引き続き機能します。でも、(__LINE__)d();文句を言わない仕事ためにはd();、他の文字に変更することができ、関数が呼び出される必要がありませんので、それはまだので、リンクされていない、コンパイルされます。
LambdaBeta

1
@LambdaBeta関数の名前が変更されると、dが自己参照ではない場合でもリンクエラーが発生します。個人的にはこれで十分だと思います。
デジタル外傷

7

R38 37バイト

ニック・ケネディのおかげで-1バイト。

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

オンラインでお試しください!(TIOを適切に設定してくれたGiuseppeに感謝します。)

Nick Kennedyのチェッカーを使用して)純粋であることの証明

falseの場合は0、trueの場合は正の値を出力しますが、RはこれらをFalseおよびTrueとして解釈するため、許容範囲内であると理解しています。

説明:とのbitwXor(a,b)間のビットごとのXORを(整数として)与えます。2のべき乗かどうかを確認するには、2を底とする対数が整数かどうかを確認します。この関数は、ポアソン分布の確率密度関数を提供します。その値は、非整数値の場合は0、非負整数の場合は正の値です。これは、2番目の引数が必要なためです(肯定的な実際の動作であり、1と解釈されます)。abdpoisTdpoisT

個別の値への出力を要求する場合、次のバージョンは42バイトでFALSEまたはTRUEを出力します(-8バイトのGiuseppeに感謝)。

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

そしてまた、自然のままですオンラインでお試しください!


2
私のものよりもはるかに小さいものを手に入れることでうまくやった!を置き換えpiTバイトを保存することもできます(まだ元のままです)。また、あなたのTIOは現時点ではあなたの答えに対応していません。
ニックケネディ

@NickKennedyありがとう!(そしてそれをチェックするコードを書いてくれてありがとう!)私がリンクしたTIOは、すべてのテストケースをチェックする修正バージョンです。実際のコードにTIOを追加しますが、TIOを2回呼び出して適切に実行する方法がわかりませんscan()。アイデアはありますか?(コードはコンピューター上で正常に動作します。)
ロビンライダー

2
@NickKennedyたぶんこんな感じ?TIOとコードを一致させるために?
ジュゼッペ

@ジュゼッペワンダフル、ありがとう!
ロビンライダー

1
2番目のバージョンでは、Nickの同じ行に沿ってのF代わりにを使用できます:-)exp(-Inf)T
ジュゼッペ

6

R、83バイト

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

オンラインでお試しください!

これが純粋であることの証拠

as.integeras.doubleなどがis.integeris.doubleなどから少し離れているという事実を回避することは最も困難なことでした。最終sum(T^el(.[-T])的には、1を生成する方法と、1をas.double超える長さのベクトルを返すチェックを行う方法の両方を使用するのが最善でした。ラッピングtはそうでなければなりidenticalうる事実を扱うことですide~tical


5

ジュリア0.7、20バイト

(a,b)->ispow2(ab)

オンラインでお試しください!

これは、一部の入力に対して変更された各匿名関数を実行しようとし、どちらも正常にパスしない初期バリデーターです。コードにはマルチバイトのユニコード文字が含まれており、無効なUTF-8文字列が生成されるため、ビットフリッピングから出力される可能性のあるものも含まれていないことに注意してください。


xそしてyそう、1ビット離れている私は、これは反例であると考えています。 yまた、それぞれx1ビットオフです。96
期限切れのデータ

くそー、複雑なことを考えながら、私は絶対に最も単純なものを見逃した。うまくいけば、変数を変更することで修正されるでしょう。
キリルL.


4

C#(Visual C#Interactive Compiler)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ビット以上離れており、それ以外はすべてキーワード/名前です。


あなたはビットをカウントする必要はありません-それは2包括的に1〜128のパワーが十分にされていた場合にチェック
ASCIIのみ

@ASCIIのみ整数を使用できない場合や+/*=、数学的操作や検証操作に使用できない場合に、妥当なバイト数でチェックするようにしてください。;)
Kevin Cruijssen

@KevinCruijssen C#にも列挙型があります:(。damnit
ASCIIのみ


1
O_oもう-24。ところで、あなたはもう使用しない+
ASCIIのみ

3

JavaScript(厳格モードのES6)、61バイト

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

オンラインでお試しください!または、変更されたすべてのプログラムが間違っていることを確認します


ああ、コードゴルフリンクをクリックして、この答えが文脈から外れているのに気づかず、心臓発作を起こしそうになりました。OMG NO
マリー

4
@マリー注意!認定されたゴルフグラスでのみこのコードをじっと見ることができます。そうしないと、網膜が焼ける可能性があります。:p
Arnauld


1

MATLAB、37バイト

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

申し訳ありませんが、TIOリンクはありません。テストスイートをOctaveで動作させることができないためです。役に立つコメントをありがとう@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

Perl 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.