ダブル、XOR、もう一度やり直してください


20

任意の整数n> 0に対して、関数gg(n)= n XOR(n * 2)として定義します。

所与のx> 0、最小の整数を見つける> 0、YようグラムK(Y)= X一部について> 0 kは

x = 549

549 = 483 XOR (483 * 2)     (as binary: 1000100101 = 111100011 XOR 1111000110)
483 = 161 XOR (161 * 2)     (as binary:  111100011 =  10100001 XOR  101000010)

つまり、g 2(161)= 549です。g(n)= 161のようなnは存在しないため、これ以上先に進むことはできません。したがって、x = 549の期待される出力はy = 161です。

ルール

  • 無効なエントリをサポートすることは想定されていません。入力値xに対してペア(y、k)が存在することが保証されています。
  • これはなので、バイト単位の最短回答が勝ちです!

テストケース

     3 -->     1
     5 -->     1
     6 -->     2
     9 -->     7
    10 -->     2
    23 -->    13
    85 -->     1
   549 -->   161
   960 -->    64
  1023 -->   341
  1155 -->   213
  1542 -->     2
  9999 -->  2819
 57308 --> 19124
 57311 -->   223
983055 -->     1

3
関連OEIS:A048274シーケンスa(n) = g(n)
ジュゼッペ

回答:


5

Java 8、68 57 53 52バイト

n->{for(int i=0;i<n;)i-=(i*2^i)==n?n=i:-1;return n;}

@OlivierGrégoireのおかげで-5バイト。

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

説明:

n->{                 // Method with integer as both parameter and return-type
  for(int i=0;i<n;)  //  Loop `i` in the range (1,n)
    i-=(i*2^i)==n?   //   If `i*2` XOR-ed with `i` equals `n`
        n=i          //    Set `n` to `i`, and set `i` to 0 to reset the loop
       :             //   Else:
        -1;          //    Increase `i` by 1 to go to the next iteration
  return n;}         //  Return `n` after the entire loop

1
n->{for(int i=0;i<n;)i-=(i*2^i)==n?n=i:-1;return n;}(52バイト)。ごめんなさい^^ '
オリビエグレゴワール

@OlivierGrégoireさらに賢く、ありがとう!
ケビンクルーッセン

for(int i=0;n>i-=i+i^i^n?-1:n=i;);
タイタス

@Titus Javaで動作しないのではないかと心配しています(ただし、JavaScriptの反復的な回答でそのアプローチを使用していますが)。Javaではi+i^i^n?ブール値ではないため、コンパイルすらされません。さらに、n>i-=...括弧(n>(i-=...))が必要になりn=i、三項ifのelse節では、if節でのみ許可されません(この最後の節では理由はわかりませんが、残念ながらJavaでそれはそうなっています) )。
ケビンCruijssen

1
@KevinCruijssen「そしてn=i、三項ifのelse節では許可されていません」Javaはそれを(i-=(i*2^i)!=n?-1:n)=i違法として解析するためです。
オリビエグレゴワール


3

JavaScript、53バイト

f=x=>(i=0,y=(G=x=>x&&(i^=x&1)+2*G(x>>1))(x),i?x:f(y))

Gg^-1、どのセットi0成功した場合、設定i1失敗した場合。


1
これは、私が使用しようとしたアプローチでしたが、50バイトのバージョンを思いつきましたf=n=>(g=n=>n<2?0/!n:n%2+2*g(n/2^n%2))(n)?f(g(n)):n。悲しいことに、退屈なアプローチは12バイト短くなります。
ニール

3

Pyth13 12 10バイト

@MrXcoderのおかげで1バイト節約し、提案に従ってさらに2バイト節約しました

fqQ.W<HQxy

オンラインで試す

説明:

fqQ.W<HQxyZZT   Implicit: Q=eval(input()), trailing ZZT inferred

f               Return the first T in [1,2,3...] where the following is truthy
   .W       T     Functional while - loop until condition is true, starting value T
     <HQ            Condition: continue while iteration value (H) less than input
        xyZZ        Body: xor iteration value (Z) with double (y) iteration value (Z)
 qQ               Is the result of the above equal to input?

1
T12バイトの末尾を削除できます。
Mr Xcoder

3

R73 65バイト

f=function(x){for(i in 1:x)if(x==bitwXor(i,i*2)){i=f(i);break};i}

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

調整のおかげで、ジュゼッペ(-8)に感謝します。とてもシンプルでありながら非常に効果的です


1
この関数は再帰的であるので、あなたの前の回答とは反対に、あなたはない必要なf=機能がにバインドする必要があるためf、適切な作業に。そうは言っても、すてきな仕事、そして私から+1を取ります!
ジュゼッペ

2
ロジックの再調整を行い、これを65バイトに
ジュゼッペ



2

C(gcc)57 56 55 51バイト

X(O,R){for(R=1;R;O=R?R:O)for(R=O;--R&&(R^2*R)-O;);}

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


1
+1X(O,R)
JayCe

@ceilingcat良い提案、ありがとう。
ジョナサンフレッチ

for(R=1;R;O=R?R:O)バイトを保存します。

R=O;最後に不要なようで、さらに4バイト節約できます。

@Rogemのようです、ありがとう。
ジョナサンフレッチ

2

Z80Golf、22バイト

00000000: 1600 1803 4216 007a b830 097a 82aa b828  ....B..z.0.z...(
00000010: f314 18f3 78c9                           ....x.

@KevinCruijssenのJava回答のポート

9-Try it onlineの入力の例!

85-Tit it onlineの入力の例!

アセンブリ:

;d=loop counter
;b=input and output
f:
	ld d,0
	jr loop
	begin:
	ld b,d
	ld d,0
	loop:
		ld a,d
		cp b
		jr nc,end	; if d==b end
		ld a,d
		add d		; mul by 2
		xor d
		cp b
		jr z,begin	; if (d*2)^d==b set b to d
		inc d
		jr loop
	end:
	ld a,b
	ret

関数を呼び出して結果を出力するためのアセンブリ例:

ld b,9 ; input to the function, in this case 9
call f
add 30h ; ASCII char '0'
call 8000h ; putchar
halt

a代わりにループカウンターを作成するとdld d,0命令をxor a両方の時間で置き換えることができ、2バイトを節約できます。
ミシャラヴロフ


1

JavaScript(Node.js)、48 45 38バイト

f=(n,i=0)=>i<n?i*2^i^n?f(n,i+1):f(i):n

-7バイトは、@ Neilが以下の反復バージョンの再帰バージョンを作成してくれたおかげです。大規模なテストケースでは機能しません。

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


すべてのテストケースで機能する反復45バイトバージョン:

n=>{for(i=0;i<n;)i-=i*2^i^n?-1:n=i;return n;}

Java回答のポート。@Arnauldの
おかげで-3バイト。

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


1
できますi-=i*2^i^n?-1:n=i(ただし、残念ながらJavaではできません)。
アーナルド

@Arnauldは、Javaのブール値1がJS だけで可能なことを考え出しました。ありがとう!
ケビンCruijssen

1
再帰的に書き込まれた38バイト(より大きな入力では機能しません):f=(n,i=0)=>i<n?i*2^i^n?f(n,i+1):f(i):n
ニール


1

ゼリー11 9バイト

BÄḂṛḄß$Ṫ?

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

ヒント:ループの代わりに再帰関数を使用します。


非常に高速で、残念ながらブルートフォースアプローチを失います。

ご了承ください:

  • X> 0f(x)が> X
  • popcount(f(x))は偶数です。popcount(n)nに設定されたビット数です。
  • 場合、nが偶数POPCOUNTを有し、そこに存在するXように F(X)= N
  • LET B(X)のバイナリ表現であり、X、およびP(L)がリストであるLを除去最後の要素を有します。その場合、B(x)Ṗ(B(f(x)))の累積XORです。

だから、繰り返し:

  • バイナリ表現を計算します(B
  • 次に、累積XORを使用します(^\またはを使用しますÄḂ。これらは同じ効果があります)。
  • ?累積XOR の末尾(最後の要素)()がゼロでない(奇数ポップカウント) かどうかを確認します
    • その場合、バイナリリストを10進数に変換し、再帰します。
    • そうでない場合は、入力()を返します。

9バイト:B^\⁸Ḅß$Ṫ?
Leaky Nun

1

Forth(gforth)、71バイト

: f 0 begin 2dup dup 2* xor = if nip 0 else 1+ then 2dup < until drop ;

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

説明

0                 \ add an index variable to the top of the stack
begin             \ start an indefinite loop
  2dup            \ duplicate the top two stack items (n and i)
  dup 2* xor =    \ calculate i xor 2i and check if equal to n
  if nip 0        \ if equal, drop n (making i the new n) and use 0 as the new i
  else 1+         \ otherwise just increment i by 1
  then            \ end the if-statement
  2dup <          \ duplicate the top two stack items and check if n < i
until             \ if previous statement is true, end the loop
drop              \ drop i, leaving n on top of the stack

1

Perl 6、44バイト

{({first {($^a+^2*$a)==$_},^$_}...^!*).tail}

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

拡張:

{  # bare block lambda with implicit parameter $_

  (
    # generate a sequence

    # no need to seed the sequence with $_, as the following block will
    # default to using the outer $_
    # $_, 

    { # parameter $_

      first
        {  # block with placeholder parameter $a

          ( $^a +^ 2 * $a ) # double (numeric) xor
          == $_             # is it equal to the previous value
        },

        ^$_  # Range up to and excluding the previous value ( 0..^$_ )
    }

    ...^  # keep doing that until: (and throw away last value)

    !*    # it doesn't return a trueish value

  ).tail  # return the last generated value
}



1

F#、92バイト

let rec o i=
 let r=Seq.tryFind(fun x->x^^^x*2=i){1..i-1}
 if r.IsNone then i else o r.Value

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

1からの数字を再帰的にチェックしi-1ます。一致する場合は、その数値の小さい方を確認します。一致するものがない場合は、入力番号を返します。


1

JavaScript(Node.js)、40バイト

f=n=>g(n)%2?n:f(g(n)/2)
g=x=>x&&x^g(x/2)

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

-1バイトをありがとう。

私のゼリーのポート答え

最後に、このアプローチが短い言語があります(おっと)。(PythonとJavaを試しましたが、動作しません)

誰かが私が/2代わりに使用できる理由を説明できます>>1か?


1
x/2算術アンダーフローが原因で機能します。IEEE 754番号は、2で十分な回数で割ると、最終的に0として評価されます。(そして、小数部はXORされたときに単に無視されるので、これは結果に影響しません。)
Arnauld


@Shaggyは機能することに驚いた。PythonやLuaなどで機能することは知っていますが、Javascriptでは機能しません。
user202729

false最後の繰り返しに戻っは暗黙的にキャストされた0ビット単位のXOR演算子で。
シャギー

実際、@ Shaggy は関係ありませんfalse。JS &&はPython / Luaとほぼ同じように動作しandます。
user202729

1

K(ngn / k)32 26バイト

{$[*|a:2!+\2\x;x;2/-1_a]}/

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

{ } 引数付きの関数です x

/ 収束するまで適用します

$[ ; ; ] if-then-else

2\xx(これはngn / kに固有です)の2進数

+\ 部分和

2! mod 2

a: 割りあてる a

*|最後-逆(|)で最初に取得(*

上記が1の場合、x返されます

さもないと:

-1_a の最後の要素をドロップ a

2/ バイナリをデコード


0

C、62バイト

Kevin CruijssenのJavaに基づく:

int n(int j){for(int i=0;i<j;)i-=(i*2^i)==j?j=i:-1;return j;}

テストする:

#include <stdio.h>
int n(int j);
#define p(i) printf("%6d --> %5d\n", i, n(i))
int main(void)
{
    p(3);
    p(5);
    p(6);
    p(9);
    p(10);
    p(23);
    p(85);
    p(549);
    p(960);
    p(1023);
    p(1155);
    p(1542);
    p(9999);
    p(57308);
    p(57311);
    p(983055);
}

実行すると、テストプログラムは以下を出力します。

     3 -->     1
     5 -->     1
     6 -->     2
     9 -->     7
    10 -->     2
    23 -->    13
    85 -->     1
   549 -->   161
   960 -->    64
  1023 -->   341
  1155 -->   213
  1542 -->     2
  9999 -->  2819
 57308 --> 19124
 57311 -->   223
983055 -->     1

C、54バイト

C89またはK&R Cでのみ動作します:

n(j){for(i=0;i<j;)i-=(i*2^i)==j?j=i:-1;return j;}


int n(int j){for(int i=0;j>i-=i*2^i^j?-1:j=i;);return j;}これらの57バイトは機能しますか?
タイタス

0

Wolfram言語(Mathematica)、58バイト

Min[{#}//.x_:>Select[Range@#,MemberQ[x,#|BitXor[#,2#]]&]]&

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

入力のみを含むリストで始まります。リストを既にリストにあるすべての整数で繰り返し置き換えるか、double-and-xor操作でリストにマップします。その後//.、固定点に達するまでこれを行うように言います。答えは結果の最小要素です。

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