2の2のべき乗の和または差


27

あなたの挑戦であり、整数与えられた、あなたはそれを受け入れることを選択する必要がありK >= 1、負でない整数を見つけるAB 、その結果ホールド以下の2つの条件のうち少なくとも1:

  1. K = 2^A + 2^B
  2. K = 2^A - 2^B

そこに、このような存在しない場合AB、あなたのプログラムは、任意の方法で動作をする場合があります。(明確にするために、AおよびB同等であってもよいです。)

テストケース

多くの場合、複数の解決策がありますが、ここにいくつか例を示します。

K => A, B
1 => 1, 0
15 => 4, 0                      ; 16 - 1 = 15
16 => 5, 4                      ; 32 - 16 = 16; also 3, 3: 8 + 8 = 16
40 => 5, 3                      ; 2^5 + 2^3 = 40
264 => 8, 3
17179867136 => 34, 11           ; 17179869184 - 2048 = 17179867136 

最後のテストケースは17179867136、比較的新しいマシンで10秒未満で実行する必要があります。これはコードゴルフであるため、バイト単位の最短プログラムが勝ちます。完全なプログラムまたは機能を使用できます。


5
AをBに等しくすることはできますか?
デニス

2
@Dennisなぜそうなのかわかりません。
コナーオブライエン

...とのために16、両方5,43,3有効です。
タイタス

実際に私はそれについて考えると、否定的ABなることができますか?(例:-1, -11)
Sp3000

@ Sp3000いいえ、良い点です。
コナーオブライエン

回答:


3

ゼリー11 10 バイト

;0+N&$BL€’

@xnorによるPythonの回答から少しいじるトリックを適用する

TryItOnlineでテストする
すべてのテストケースはTryItOnlineにもあります

どうやって?

;0+N&$BL€’ - main link takes an argument, k, e.g 15
;0         - concatenate k with 0, e.g. [15, 0]
     $     - last two links as a monad
   N       - negate, e.g. -15
    &      - bitwise and, e.g. -15&15=1 since these two are called as a monad (one input)
  +        - add, vectorises, e.g. [16,1]
      B    - convert to binary, vectorises, e.g. [[1,0,0,0,0],[1]]
       L€  - length for each, e.g. [5,1]
         ’ - decrement, vectorises, e.g. [4,0]

15

Python 2、43バイト

lambda n:[len(bin((n&-n)+k))-3for k in n,0]

言うことn==2^a ± 2^ba>b。そして、の最大の2のべき乗の係数n2^bであり、ビットトリックを使用して見つけることができます2^b = n&-n。これにより2^b + n、どちらか2^a + 2 * 2^bまたはちょうどに等しい計算ができます2^a。どちらもa* と同じ長さのビット長です。したがって、バイナリ表現の長さから計算されたn&-nおよびのビット長を出力します(n&-n)+n。Python 3は、の括弧では1バイト長くなりfor k in(n,0)]ます。

* 2^a + 2^bwithにa==b+1は1つの長いビット長がありますが、それをとして解釈できるので問題ありません2^(a+1)-2^b


素晴らしい-ちょっとしたフィドルを探しましたが、うまくいかず、Jellyに移植しただけです。
ジョナサンアラン

試してみてくださいn=4または8または16してください。
タイタス

@Titus f(2**n)リターン(n+1,n)2**(n+1)-2**n=2**nそれほど問題はありません。
ジョナサンアラン

ああ... Pythonのフォーマットはbin()何ですか?
タイタス

@Titusこれは、先頭0bに文字列があり、したがってになり-3ます。
ジョナサンアラン

8

JavaScript(ES6)、73バイト

(n,[s,f,z]=/^1+(.*1)?(0*)$/.exec(n.toString(2)))=>[s.length-!!f,z.length]

減算の場合、最初の数値はバイナリ表現の桁数で、2番目の数値は末尾のゼロの数です。加算の場合、最初の数値から1を引きます。バイナリ表現がすべて1であり、その後に0が続く場合、加算の場合が想定され、そうでない場合は減算の場合が想定されます。JavaScriptのB≤30でのみ動作する@xnorのバージョンの36バイトポート:

n=>[(l=Math.log2)(n+(n&=-n))|0,l(n)]

2
@ETHproductions確かに、私は36までゴルフをしました。–
ニール

残念なことに、36バイトバージョンは170億のテストケースでは機能しないと考えました。
ETHproductions

@ETHproductionsそうではありませんが、ビット単位の操作を使用していたため、ポートも削除しました(削除してからのコメント、ため息)。
ニール

申し訳ありませんが、ここにもまたあります。n=>[n,0].map(k=>((n&-n)+k).toString(2).length-1)両方のバージョン[34,11]が最後のテストケースに戻ります(FF 48を使用しています)。
ETHproductions

@ETHproductions Aha、2番目の結果が30以下の場合、より正確に機能します。
ニール

6

Perl、52 49 32バイト

古いソリューション(49バイト)

+1を含む -p

STDINに入力を与えます。

pow2.pl <<< 17179867136

pow2.pl

#!/usr/bin/perl -p
$_=reverse sprintf"%b",$_;/()1(?:1+|0*)/;$_="@+"

ただし、xnorのアルゴリズムを使用してツイストを追加すると、32バイトになります。

perl -nE 'say 13/9*log|0for$;=$_&-$_,$_+$'

コードだけ:

say 13/9*log|0for$;=$_&-$_,$_+$

これは、13/9 = 1.444...かなり上にあるため、重大な丸め誤差に悩まされます1/log 2 = 1.44269...logそれ自体にも丸め誤差がありますが、13/9の分析でまとめることができるほど小さいです)。しかし、いずれかがあるため2**big - 2** smallに修正されます2** big、これがない母校ないログとするための計算の前に2**big + 2 * 2**smallその下に切り捨てられますも安心です。..そして範囲の反対側の2**n+2**(n-1)範囲で十分に増加されません。[0,64]私は正常に(することはできませんとにかく整数の範囲以上をサポート&して、間違った結果をもたらすために)を使用します(1.5ただし、乗数は大きな数に対しては遠すぎます)。


5

Brachylog、23バイト

,A:B#+.:2rz:^a{+|-}?,.=

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

これは必要以上に高速です。たとえば、これはTIOでまだ10秒未満です。

説明

これは基本的に、最適化されていない式の直接の転写です。

,A:B     The list [A, B]
#+       Both A and B are greater than or equal to 0
.        Output = [A, B]
:2rz     The list [[2, A], [2, B]]
:^a      The list [2^A, 2^B]
{+|-}?   2^A + 2^B = Input OR 2^A - 2^B = Input
,.=      Assign a value to A and B which satisfy those constraints

2
この挑戦は言語のためになされたようです:D
コナーオブライエン

4

Python、69バイト

def f(k):b=bin(k)[::-1];return len(b)-2-(b.count('1')==2),b.find('1')

テストはideoneで行われています

非有効な入力は何でもできるので、入力に正確に2ビットが設定されている場合は2の2の累乗の合計であり、そうでない場合(有効な場合)は、いくつかのビットの実行( 1ビットだけの可能性)であり、MSBとLSBセットより次に大きい2のべき乗の差になります。


4

JAVA 7、142140、134バイト

これはPPCGの私の最初の投稿です!私は本当にヒントにゴルフにフィードバックを感謝
のおかげで、凍結を 2つのバイトを保存します

void f(long n){for(int i=-1,j;i++<31;)for(j=0;j++<34;){long a=1,x=a<<i,y=a<<j;if(x+y==n|y-x==n){System.out.println(j+" "+i);return;}}}

ウンゴルフ

void f(long n){
    for(int i=-1,j;i++<31;)
         for(j=0;j++<34;){
          long a=1,x=a<<i,y=a<<j;
            if(x+y==n|y-x==n){
            System.out.println(j+" "+i);
        return;
        }
            }
    }

イデオン


1
こんにちは 不可解な別の放浪者もいます。40=2**3+2**5たとえば、には機能しないようです。、多分私はない、なぜそれを見て、私は見ることができないの転写エラーをした ...
ジョナサン・アラン

1
@JonathanAllan正常に動作するようになりました。実際、この行には括弧がありませんでしたif((a << i)+(a << j)== n |(a << j)-(a << i)== n ) ありがとう。
ナンバーノット

1変数を宣言する代わりにリテラルを使用できませんか?
タイタス

1
@TItusリテラル1を使用する場合、このテストケース(17179867136)は使用できません。リテラル1を使用すると、Javaが自動的にINTメモリスペースを割り当てるためです。
ナンバーノット

1
iとともにjを宣言できますfor(int i=-1,j;[...]
。– Frozn

4

Mathematica、57 54バイト

LegionMammal978のおかげで3バイト節約されました!

Do[Abs[2^a-#]==2^b&&Print@{a,b},{a,2Log@#+1},{b,0,a}]&

実際には、1つの適切なペア{a、b}をすべて印刷します。入力を表すときに表示される可能性の2Log@#+1ある最大値の上限です(厳密な上限はLog [2#] / Log [2] = 1.44 ... Log [#] + 1です)。テスト入力でほぼ瞬時に実行され、100桁の入力で4分の1秒未満で(新しいが市販のコンピューターで)実行されます。a#

1つのまかせa1の代わりに0のデフォルト値で開始は、2つのバイトを保存します。入力が2の場合、出力{0,0}が失われますが、その場合は出力{2,1}が見つかります。これで十分です。


すべて*適切なペア?(3バイトを節約するためにIf[Abs[2^a-#]==2^b,Print@{a,b}]置き換えることもできAbs[2^a-#]==2^b&&Print@{a,b}ます。)
LegionMammal978

いい観察、わかりました!「すべて*」は脚注でしたが、より明確になりました。
グレッグマーティン

3

MATL23 22バイト

BnQ:qWtG-|ym)1)tG-|hZl

オンラインでお試しください!または、すべてのテストケースを確認します

説明

B      % Implicit input. Convert to binary. Gives n digits
nQ:q   % Range [1 ... n+1]
W      % 2 raised to that, element-wise: gives [1 2 4 ... 2^(n+1)] (*)
tG-|   % Duplicate. Absolute difference with input, element-wise (**)
y      % Push a copy of (*)
m      % True for elements of (**) that are members of (*)
)      % Use as logical index to select elements from (*)
1)     % Take the first element. Gives power of the first result
tG-|   % Duplicate. Absolute difference with input. Gives power of the second result
hZl    % Concatenate. Take binary logarithm. Implicit display

3

Perl 6バイト

{.base(2).flip~~/1[1+|0*]/;$/.to,$/.from}

Perl 5の回答から恥知らずにコピーされアルゴリズム)

説明:

# bare block lambda with implicit parameter 「$_」
{
  # turn into binary
  # ( implicit method call on 「$_」 )
  .base(2)

  # flip the binary representation
  .flip

  ~~ # smartmatch that against:

  /
    1      # a 「1」
    [
      | 1+ # at least one 「1」
      | 0* # or any number of 「0」
    ]
  /;

  # returns a list comprised of

  # the position of the end of the match (larger of the two)
  $/.to,
  # the position of the beginning of the match
  $/.from
}

使用法:

# give it a lexical name for clarity
my &bin-sum-diff = {.base(2).flip~~/1[1+|0*]/;$/.to,$/.from}

say bin-sum-diff 15; # (4 0)
say bin-sum-diff 16; # (5 4)

say bin-sum-diff 20; # (4 2)
# 2**4==16, 2**2==4; 16+4 == 20

say bin-sum-diff 40; # (5 3)
say bin-sum-diff 264; # (8 3)
say bin-sum-diff 17179867136; # (34 11)

1

PHP、73バイト

ジョナサンのPyhton 2ソリューションを54バイト(+13オーバーヘッド)でコピーできたかもしれませんが、
別の何かを思いつきました。

ファイルに保存してから、phpまたはで実行しphp-cgiます。

<?=strlen($n=decbin($argv[1]))-!!strpos($n,'01')._.strpos(strrev($n),49);

アンダースコアで区切って印刷abますが、解決策はありません。

特徴的なソリューション、96バイト

<?=preg_match('#^(10*1|(1+))(0*)$#',decbin($argv[1]),$m)?strlen($m[0])-!$m[2]._.strlen($m[3]):_;

プリントabアンダースコアで区切ってます。解決策がない唯一のアンダースコア。

さらに11バイトの操作を示します。
コードの最初のアンダースコアをに置き換えてください'-+'[!$m[2]]


echo strlen($ n = decbin($ argv [1]))-!! strpos($ n、'01 ').'- +' [!$ n [2]]。strpos(strrev( $ n)、49); それが65であるバック6 + 0私を与える
イェルクHülsermann

@JörgHülsermann:67には解決策がありません。解決策がない場合の動作は未定義です。したがって、67で何を印刷するかは重要ではありません
タイタス

0

PHP、117バイト

if(preg_match("#^(1+|(10*1))0*$#",$b=decbin($k=$argv[1]),$t))echo($l=strlen($b))-($t[2]?1:0).",",$l+~strrpos($b,"1");

拡張バージョン4のケース

$l=strlen($b=decbin($k=$argv[1]));
// Case 1: n=2(n-1)=n+n or n=n*(2-1)=2n-n 
if(preg_match('#^100*$#',$b))echo($l-2).'a+'.($l-2).':'.$l.'a-'.($l-1);
// Case 2: n-m
elseif(preg_match('#^1+0*$#',$b)){echo $l.'b-',strpos($b,"0")?$l-strpos($b,"0"):0;}
// Case 3: n+m 
elseif(preg_match('#^10*10*$#',$b))echo ($l-1).'c+',$l-strrpos($b,"1")-1;
else echo "Nothing";

ショートバージョンのユニオンケース1と3は、ケース3との違いを生み、両方のバージョンでケース4は出力を提供しません。

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