この数字は悪ですか?


34

前書き

数論では、そのバイナリ表現に1の偶数がある場合、数は悪と見なされます。今日の課題では、特定の数が悪かどうかを特定します。

チャレンジ

あなたの仕事は、その数字が悪かどうかに関係なく、入力および出力として単一の非負整数を受け入れる(または返す)完全なプログラムまたは関数を書くことです。

  • 数値が悪けれ真理値を出力し、数値が悪でなければ値を出力できます。
  • 受け入れ可能な形式で入力および出力できます
  • 標準の抜け穴は許可されていません。
  • OEISシーケンスA001969は、すべての悪の番号を含むシーケンスです。
  • ここでは最初の10000の悪番号のリストは、参考のために、である(そしてより多くのテストケース!)
  • この質問はなので、短いほど良いです。
  • ゴルフ言語の極端に短い答えに惑わされないでください。好きな言語で送信することをお勧めします。
  • 以下にテストケースを示します。

    3 => True
    11 => False
    777 => True
    43 => True
    55 => False
    666 => False
    

リーダーボード

ページの下部には、この質問のリーダーボードを含むスタックスニペットがあります。(ありがとう、@ MartinEnder)

回答が表示されるようにするには、次のマークダウンテンプレートを使用して、見出しから回答を開始してください。

# Language Name, N bytes

N提出物のサイズはどこですか。スコアを改善する場合、古いスコアを打つことで見出しに残すことができます。例えば:

# Ruby, <s>104</s> <s>101</s> 96 bytes

ヘッダーに複数の数字を含める場合(たとえば、スコアが2つのファイルの合計であるか、インタープリターフラグペナルティーを個別にリストする場合)、実際のスコアがヘッダーの最後の数字であることを確認します。

# Perl, 43 + 2 (-p flag) = 45 bytes

言語名をリンクにして、リーダーボードスニペットに表示することもできます。

# [><>](http://esolangs.org/wiki/Fish), 121 bytes

編集:私はこの質問が重複しないのであると信じて、この、その質問はものの数をカウントするように求めているのに対しので、この質問はものの数が偶数であるかどうかを尋ねています。ビットを数えるだけでこの質問達成できます他のアプローチもあります。


2
関連(すべての2進数をXORすることは、モジュロ2の合計を取ることと同じです)。
ケビンクルーッセン


2
@BetaDecayしかし、それは逆には機能しません。つまり、これらすべての答えを取り、MOD 2を削除することはできません。したがって、このチャレンジはいくつかの新しい方法を誘います。
Amphibological

13
私はそれ666 => Falseがテストケースであるべきだと信じています。
user2390246

3
リーダーボードが壊れている
ジョーキング

回答:


35

Z80アセンブリ(8ビット)、2バイト

次のコードは、255までの値でのみ機能します。

; Input is given in register A.
; P flag is set if A is evil.
B7     or A
C9     ret


16ビットバージョン(すべてのテストケースで動作)、3バイト

これは、65535までの値で機能します。

; Input is given in BC.
; Output is the same as above.
78     ld A,B
A9     xor C
C9     ret

あなたが冒険を感じているなら、入力をAそのCように保存することで1バイトを削ることができます

      ld BC, 777
C5    push BC
F1    pop AF

そして、実行中

A9    xor C
C9    ret

ただし、これは呼び出し元に負担をかけるため、2バイト(push BCおよびpop AF)もカウントする必要がある場合があります。


私はこれが好きですが、これはどのように機能しますか?アセンブリ(6502 +アーム)の記憶は、orsが2つのオペランドを持つビット単位である
北ブラッド

2
@北部・ブラドリーZ80で、それが第二オペランドことを暗示していますorニーモニックは、この場合、アキュムレータAである、コマンドはそれが唯一のステータスレジスタ(特に、パリティフラグを)リフレッシュするA.を変更しないとAの内容を反映しています。
cschultz2048

1
Pあたりとして許さcodegolf.meta.stackexchange.com/a/8509/29560F(フラグ)レジスタ内のシングルビットで、影響を受ける命令のペアは3つのみです。また、この回答でAは、8ビットのレジスタであるため、8 ビット値のみを競合していることに言及していません。この手段、のために答えを与えることができない777、または255以上の任意の他の符号なしの値
CJデニス

2
くそー組み込み:P
ジョーキング

1
@ cschultz2048をAと対になっているF私は受け入れないように、ABまたはBA16ビット値として。BCは16ビットですが、もう1つをAXOR する前に1つをロードする追加の命令が必要です。Z80の回答は、質問に応じて255または65535まで完全に機能することを常に述べてきました。16ビットバージョンも追加するのでしょうか?したがって、8ビット値の場合は2バイト、16ビット値の場合は3バイトです。
CJデニス

25

JavaScript(ES6)、18バイト

f=n=>n?!f(n&~-n):1

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

説明

ビット単位のロジックは次のようになります。

  • 整数の場合、はと~-n同等-(-n)-1であるため、のもう1つの方法ですn-1。その特定のケースでは、実際にを使用できましたn-1
  • n & (n-1)最下位ビットのセット削除1におけるNをデクリメントするのでnはすべての後続オン0「にSを1 S」とクリア1変わらない他のすべてを残してすぐに、(キャリー伝搬により)以下。

    n = 24(バイナリで11000)の例:

      11000 (24)                  11000 (24)
    -     1                   AND 10111 (23)
    -------                   ---------
    = 10111 (23)              =   10000 (16)
       ^                           ^
       |                           |
       +--- this bit is cleared ---+
    

したがって、nのバイナリ表現に1がある限り、再帰呼び出しを処理し、毎回結果を反転します。最後の呼び出しは常に1を返します。!

例:

f(24) = !f(16) = !!f(0) = !!1 = true
f(7) = !f(6) = !!f(4) = !!!f(0) = !!!1 = false

こんにちは、私はコードが何をするのか理解していますが、ビットごとの操作に関するいくつかの記事を読んだり、数字が2のべき乗かどうかをチェックしたりするにもかかわらず、その背後にあるロジック/理由を理解することはできません。再帰関数とは何かを知っています。なぜこのように使われたのか、なぜこれがパズル、つまり再帰と!f(2のべき乗)<==>悪の数字とのリンクに答えるのかがわかりません。時間があれば、説明を歓迎します:)ありがとう!
-supafly

1
@supafly説明を追加しました。ところで、PPCGへようこそ!
アーナルド

処理は非常に明確になりました。それでも、アイデア/推論は本当に魔法です!ご説明ありがとうございます!
補足として

13

Python 2、25バイト

lambda n:int(bin(n),13)%2

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

bin(n)のような結果が得られ'0b10101'ます。これを基数13の整数として読み取ると、

モジュロ2まで減少 1 1 5 + 1 1 4 + 0 1 3 + 1 1 2 + 0

11135+1134+0133+1132+0131+1130
1 + 1 + 0 + 1
115+114+013+112+011+110(mod2)
1+1+0+1+0+1(mod2).

したがって、int(bin(n),13)%21 +(の1の数bin(n))モジュロ2に等しくなります。

n悪の場合、結果は1です。それ以外の場合は0です。

Noodle9からこのトリックを選びました


これはPython 2であるため、非推奨のrepr backtick構文を使用してコードをさらに短縮できますlambda n:int(`n`,13)%2オンラインでお試しください!
GarethPW

ええ、そこには少し頭がおならがあり、intの基本引数の目的を忘れていました。おっと!
GarethPW

11

Japt -h!5 4 3バイト

¤å^

それを試してみてください


説明

¤       :Convert to base-2 string
 å^     :Cumulatively reduce by XORing
        :Implicitly output the last element negated

Kevinの05AB1Eソリューションを移植する@LuisfelipeDejesusMunozも、試してみたい場合は5バイトで動作します。
シャギー

¤¬x vこれはケビンの答えです
ルイスフェリペデジェススムニョス

@LuisfelipeDejesusMunoz、うん、それだけです。
シャギー

8

C#(Visual C#Interactive Compiler)43 38バイト


ゴルフ オンラインで試しください!

i=>Convert.ToString(i,2).Sum(c=>c)%2<1

非ゴルフ

i => Convert.ToString( i, 2 ).Sum( c => c ) % 2 < 1

テスト付きの完全なコード

Func<Int32, Boolean> f = i => Convert.ToString( i, 2 ).Sum( c => c ) % 2 < 1;

Int32[] testCases = { 3, 11, 777, 43, 55 };

foreach( Int32 testCase in testCases ) {
    Console.Write( $" Input: {testCase}\nOutput: {f(testCase)}" );
    Console.WriteLine("\n");
}

Console.ReadLine();

リリース

  • V1.1 - -5 bytes-置き換えCountSum
  • v1.0の - 43 bytes-初期ソリューション。

ノート

  • なし

2
あなたの「権利のない」バージョンが私に与えた笑いに賛成。
ジャックブラウンスタイン

8

Bash(外部ユーティリティなし)、56 44バイト

while(($1));do set $(($1/2)) $(($2+$1%2));done;!(($2%2))

(($1))&&exec $0 $[$1/2] $[$2+$1%2];!(($2%2))

これは$1、最初のコマンドライン引数として渡された番号がにあることを前提としています。また、これがシェルスクリプトであると想定しています(それexec自体ができるように)。

ファッションの後に、を使用してexec $0$1)の数がゼロになるまで再帰を繰り返し、各反復で2で除算します。また$2、奇数の数値を取得した回数も(で)合計します。最後に、合計が$2奇数でない場合、元の数は「悪」でした。

呼び出しの例:

$ ./script 3 && echo evil
evil

$ ./script 11 && echo evil

$ ./script 777 && echo evil
evil

$ ./script 43 && echo evil
evil

$ ./script 55 && echo evil

のために0

$ ./script 0 && echo evil
./script: line 1: ((: %2: syntax error: operand expected (error token is "%2")
evil

正しい結果が得られますが、少し余分にあります。


7

R37 26バイト

!sum(scan()%/%2^(0:31))%%2

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

Robert S.の答えの代替案で、これは組み込みのビット分割を回避しますが、最終的にはゴルフが少なくなりますを回避しますが、最終的にはゴルファーが、JayCeとdigEmAllのおかげでわずかにゴルファーが増えます。

2311


log2の代わりに31をハードコーディングしないのはなぜですか?オンラインでお試しください!
-digEmAll


@digEmAllありがとう!精度の問題については確信がありませんでしたが、過去のでは、おそらく(おそらく)and 演算子の精度が失われているので、それは議論の余地があるでしょう。2311%/%%%
ジュゼッペ

また、intToBitsは2 ^ 31-1までの整数値のみをサポートします;)
digEmAll



5

R99 98 44 34 28バイト

-1 Kevin Cruijssenに感謝します!-54 ngmに感謝!-10ジュゼッペに感謝!-6 JayCeに感謝します!

!sum(intToBits(scan())>0)%%2

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


または、binaryLogicパッケージを使用して(39バイト):

!sum(binaryLogic::as.binary(scan()))%%2

2
私はRをあまりよく知らないが、私は==0そうなることができると確信している<1:)
ケビンCruijssen



1
これもうまくいくと思います:32バイトですが、少し説明が必要です:)
digEmAll


5

C(gcc)、36バイト

c;f(n){for(c=0;n;c++)n&=n-1;n=~c&1;}

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

K&R https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighanのメソッド

最適化レベル0でコンパイルする必要があります


gcc 5.4.0でコンパイルしません:(関数名のerror: expected constructor, destructor, or type conversion before '(' token矢印が指すf)。どのコンパイラフラグが必要ですか?
villapx

1
では機能しません-O
nwellnhof

2
「真実の場合は0、偽の場合は1を返します」これは合法ですか?あなたの答えを信用しようとせず、ただ好奇心が強い。注:質問の「真実」という言葉は、この回答にリンクしています。そして、このコメントは真実性にも言及しています。
Borka223

@nwellnhof @villapx 7.3.0では問題なくコンパイルできます-O0。コンパイラフラグが欠落していないことを確認してください。

@ Borka223このサイトを何ヶ月も熟読した後、あなたのソリューション内で一貫している限り、真実と偽りは何でもあり得るという印象を受けました。しかし、あなたがリンクした答えは確かにそれと矛盾するようです。私は先に行き、バイトを追加しました。ありがとう
-vazt


4

PHP、37 36バイト

<?=1&~substr_count(decbin($argn),1);

実行するには:

echo '<input>' | php -nF <filename>

または 、オンラインでお試しください!

プリント 1trueおよび0falseでします。

-1バイト、Benoit Esnardに感謝!


1
モジュロ演算を削除することで1バイト節約できると思います:<?=1&~substr_count(decbin($argn),1);。これはfalseの場合も0を出力します。
ブノワエズナード

ありがとう@BenoitEsnard!それは非常に賢いです、私は私の答えを更新しました:)あなたは毎日新しいことを学びます!
ダヴィッド

4

Brachylog、4バイト

ḃo-0

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

複数のテストケースの場合(😈は悪であり、👼はそうではありません。)

-述語について最近発見したものを使用します。そのドキュメントは「[入力]の要素の違い」と述べていますが、実際に行うのは「入力の偶数インデックス要素(0番目から)の合計から奇数の合計を引いたもの」入力のインデックス付き要素」。

ここに、

数値を2進数の配列に変換し、

o それらをソートして、すべての1をまとめます。

ここで、1の数が偶数である場合、偶数のインデックスと奇数のインデックスには同じ数の1があります。だから-その後は0になります。ただし、1の数が奇数の場合、余分な1が突き出て、差は-1または1になります。

したがって、最後に、差が0であると断言し、それに応じて真または偽の結果を取得します。より柔軟な出力要件、これは両方のfalsey出力としてtruthy出力と-1と1と0と、3バイトの応答のために除去することができます。


4

INTERCAL90 65 63バイト

DOWRITEIN:1
DO:2<-'#0$#65535'~?':1~:1'
DOREADOUT:2
PLEASEGIVEUP

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

Cスタイルのコメントを使用して、(それが価値あるものであるために)ゴルフを解いて拡張しました。

DO WRITE IN :1 //Store user input in 1
DO :2<-:1~:1 //Select just the ones. So will convert binary 10101 to 111
DO :3<-:?2 //Run the unary xor over the result. Essentially, xor with the right bitshifted
           //(with wraparound) value).
DO :9<-#0$#65535 //Intermingle the 16 bit values of all 0's and all 1's, to create a
                 //32 bit number with 1's in the odd positions.
DO :4<-:9~:3 //It turns out that at this point, evil numbers will have no bits in odd
             //positions, and non-evil numbers will have precisely one bit in an odd
             //position. Therefore, the ~ will return 0 or 1 as appropriate.
PLEASE READ OUT :4 //Politely output
PLEASE GIVE UP //Polite and self explanatory

INTERCALでこれを実現するには、いくつかの譲歩をしなければなりませんでした。1つ目は、すべてのINTERCALプログラムと同様に、数値入力を書き出す必要があります。したがって、入力707する場合は、を提供しますSEVEN OH SEVEN

2つ目は、INTERCALには適切な真実または偽の価値がないということです。代わりに、I数字が悪ではない場合はローマ数字(1)を出力し、0(通常は-ローマ数字は0を表すことができないため)を出力します。

これらを反転させて、悪の数が1を返し、悪の数が0を返すようにしたい場合は、3バイトを追加しますが、次のように4行目と5行目を変更しないでください。

DO:9<-#65535$#0
DO:4<-#1~:9~3


3

dc18 16バイト

[2~rd1<M+]dsMx2%

(スタックに)悪の場合は0、悪でない場合は1を返します

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

かなり簡単です- ~商と剰余の結合演算子を新しい商に再帰的に適用し、すべての剰余を加算し、2をmodします(2バイトを費やして標準の真実/偽になります)

特にif(boolean)構造のない言語では、0が真実で1が偽であるというコンセンサスを反映するように編集されました。


3

Python 2、29バイト

lambda n:~bin(n).count('1')&1

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

Trueの場合は1、それ以外の場合は0を返します。

数値を「0b11」などのバイナリ文字列に変換し、1の数をカウントし、結果の補数を取得し、補数の最後のビットを返します(ありがとう、 https://codegolf.stackexchange.com/users/53560/cdlane!) (1 if the original number was even, 0 if it was odd).


1
No fewer bytes but lambda n:~bin(n).count('1')&1 replaces the modular division with something potentially less expensive.
cdlane

3

x86-16, 3 bytes

NASM listing:

 1                                  parity16:
 2 00000000 30E0                        xor al,ah
 3 00000002 C3                          ret

16-bit integer function arg in AX (which is destroyed), return value in PF.

The hardware calculates the parity of the result for us, in x86's Parity Flag. The caller can use jp / jnp to branch, or whatever they like.

Works exactly like @cschultz's Z80 / 8080 answer; in fact 8086 was designed to make mechanical source-porting from 8080 easy.

Note that PF is only set from the low byte of wider results, so test edi,edi wouldn't work for an x86-64 version. You'd have to horizontal-xor down to 16 bits, or popcnt eax, edi / and al,1 (where 0 is truthy).


3

C++ (gcc) (-O0),  36  31 bytes

int f(int i){i=!i||i%2-f(i/2);}

Try it online!


C++ (clang), 35 bytes

int f(int i){return!i||i%2-f(i/2);}

Try it online!


Here is my first attempt at code golfing, hope I didn't break any rule I might have missed.

Edit:
- Saved 5 bytes thanks to @Jonathan Frech : replaced != by - and return by i= (the last replacement does not seem to work with clang though)
- Since there seems to be a debate whether I should use gcc -O0 abuse, I thought I could just give both versions


Welcome to PPCG! You may be able to save a byte by golfing != to - and another four by golfing return to i=.
Jonathan Frech

@JonathanFrech It's been a long time since I did C++, does it implicitly return the last assigned expression in a function if there's no return statement? I'm guessing it's a gcc thing?
sundar - Reinstate Monica

1
It is a gcc specific undefined behaviour abuse on optimization level O0.
Jonathan Frech

By switching to K&R C, you can get it down to 23 bytes (very impressive!) Try it online!
ErikF

@JonathanFrech: why do people insist on using that stupid gcc -O0 hack? It's not like the length of a language's total boilerplate matters much when comparing implementations. Also, it makes it more interesting to choose between return vs. call-by-reference (updating *i in place). I'd rather write C or C++ answers, not un-optimized-gcc-only answers, because un-optimized-gcc isn't a very useful language.
Peter Cordes

3

SML, 32 Bytes

fun%0=1| %n=(n+ %(n div 2))mod 2

Explaination:

  • % is function name
  • takes in input in repl and returns 1 if evil, 0 otherwise
  • n is input, returns (n + %(n//2)) % 2

Made by 2 bored Carnegie Mellon Students


Welcome to PPCG, and good first answer!
mbomb007

2

Forth (gforth), 53 bytes

: f 1 swap begin 2 /mod -rot xor swap ?dup 0= until ;

Try it online!

Explanation

Takes the xor-sum of the digits of the binary form of the number. (repeatedly divides by 2 and xors the remainder with the "sum" value)

Code Explanation

: f              \ begin a new word definition
  1 swap         \ place 1 on the stack below the input (n)
  begin          \ start an indefinite loop
    2 /mod       \ get the quotient and remainder of dividing n by 2
    -rot         \ move the sum and remainder to the top of the stack
    xor          \ xor the sum and remainder
    swap         \ move the quotient back to the top of the stack
    ?dup         \ duplicate if > 0
    0=           \ get "boolean" indicating if quotient is 0
  until          \ end the loop if it is, otherwise go back to the beginning
;                \ end the word definition

2

Java 8, 40 36 bytes

n->n.toString(n,2).chars().sum()%2<1

-4 bytes thanks to @Okx for something I shouldn't have forgotten myself..

Try it online.

Explanation:

n->                // Method with Integer parameter and boolean return-type
  n.toString(n,2)  //  Convert the integer to a binary String
   .chars()        //  Convert that to an IntStream of character-encodings
   .sum()          //  Sum everything together
    %2<1           //  And check if it's even

Note that the character encoding for 0 and 1 are 48 and 49, but summing them and taking modulo-2 still holds the correct results because 48%2 = 0 and 49%2 = 1.


1
n.toString(n,2) saves 4 bytes.
Okx

@Okx Not sure how I forgot about that one, lol.. Thanks! ;)
Kevin Cruijssen

If you're allowed to use 1 and 0 instead of true and false (not sure for Java), you can change to: ~n.toString(n,2).chars().sum()%2 to save one byte.
Mario Ishac

1
@MarDev Unfortunately 0 and 1 aren't truthy/falsey in Java, only booleans/Booleans are. If a challenge would state two distinct outputs are allowed the <1 could have been removed to save 2 bytes indeed. :)
Kevin Cruijssen


2

Retina 0.8.2, 28 bytes

.+
$*
+`(1+)\1
$+0
0

11

^$

Try it online! Link includes test cases. Explanation:

.+
$*

Convert to unary.

+`(1+)\1
$+0

Partial binary conversion (leaves extra zeroes).

0

Delete all the zeros.

11

Modulo the ones by two.

^$

Test whether the result is zero.


2

x86 Assembly, 12 11 bytes

F3 0F B8 44 24 04  popcnt      eax,dword ptr [esp+4] ; Load EAX with the number of ones in arg
F7 D0              not         eax ; One's complement negation of EAX
24 01              and         al,1 ; Isolate bottom bit of EAX
C3                 ret             

-1 byte thanks to @ceilingcat's suggestion


@ceilingcat Good catch!
Govind Parmar

1
Suggest inc eax instead of not eax. Also may want to mention that this requires a processor with support for the popcnt instruction.
ceilingcat

1
also you do not have to take arg from stack. see allowed calling conventions codegolf.stackexchange.com/a/161497/17360 (Peter Cordes's more in-depth answer codegolf.stackexchange.com/a/165020/17360)
qwr

1
Note that you may return a boolean in FLAGS stackoverflow.com/a/48382679/3163618
qwr

Shouldn't 666 be a test case?
Arcanist Lupus

2

Bash + GNU utilities, 33

dc -e2o?p|tr -d 0|wc -c|dc -e?2%p

Try it online!

Reads input from STDIN. Outputs 1 for True and 0 for False.

  • dc converts input to a binary string
  • tr removes zeros
  • wc counts remaining ones (and trailing newline, which corrects sense of logic
  • dc calculates count mod 2 and outputs the answer

2

Python 2, 28 27 bytes

f=lambda n:n<1or n&1^f(n/2)

Try it online!

Returns a truthy value if exactly one of the ones-bit is a 1 and the result of calling this function on n/2 is truthy is true (or n==0). It works because n/2 is equivalent to a right bitshift with floor division (so Python 2 only).

Alternate version, also 28 27 bytes

g=lambda n:n<1or g(n&n-1)^1

Try it online!

Based on the K&R method of counting set bits referenced by vazt.

Both of these could be two bytes shorter if the output allowed falsey to mean evil.

Edit: Thanks to Amphibological for saving a byte!


You can remove the spaces between the 1 and the or to save +1 byte. Nice solution!
Amphibological

Man, I thought I tried that. Good catch!
Jack Brounstein

2

APL (Dyalog Unicode), 10 bytesSBCS

Anonymous tacit function. Can take any array of integers as argument.

≠⌿12∘⊥⍣¯1

Try it online!

2∘⊥⍣¯1 convert to binary, using as many digits as needed by the largest number, separate digits along primary axis

1⍪ prepend ones along the primary axis

≠⌿ XOR reduction along the primary axis


2

J, 9 bytes

Anonymous tacit function. Can take any integer array as argument.

1-2|1#.#:

Try it online!

1- one minus (i.e. logical negation of)

2| the mod-2 of

1#. the sum (lit. the base-1 evaluation) of

#: the binary representation


Nice one! the boring approach is 9 bytes: 2|1+1#.#:
Conor O'Brien

This only seems to work because 777 in the input makes every number be represented in 10 bits. Replace it with e.g. 480 and the output flips.
FrownyFrog

@ConorO'Brien Boring trumps incorrect.
Adám

@FrownyFrog Fixed.
Adám
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.