binarrayを見つけてください!


24

binarrayは、次のプロパティを満たす配列として定義します。

  • 空ではない
  • 最初の値は 1
  • 最後の値は 1
  • 他のすべての値は、0または1

たとえば、配列[ 1, 1, 0, 1 ]は有効なbinarrayです。

タスク

非空の配列の指定されたA非負整数の整数正N、ジョブを見つけることであるbinarray Bの長さNを生成することを可能にするAをのコピー制限のない数合計することによってBを、無制限の数だけシフトポジション。

A = [ 1, 1, 2, 4, 1, 2, 2, 1, 0, 1, 0, 1, 1, 0, 1 ]
N = 4

この入力では、binarray B = [ 1, 1, 0, 1 ]が有効な答えになります。

  [ 1, 1, 0, 1 ]
+       [ 1, 1, 0, 1 ]
+       [ 1, 1, 0, 1 ]
+          [ 1, 1, 0, 1 ]
+                   [ 1, 1, 0, 1 ]
+                                  [ 1, 1, 0, 1 ]
  -----------------------------------------------
= [ 1, 1, 2, 4, 1, 2, 2, 1, 0, 1, 0, 1, 1, 0, 1 ]

ルール

  • 入力は、合理的な形式で取得できます。
  • 出力は、ネイティブ配列(例[1, 1, 0, 1])またはセパレータ付きまたはなしのバイナリ文字列(例:"1,1,0,1"または"1101"
  • 有効なbinarrayを 1つだけ出力または返す必要があります。または、複数の解決策が存在する場合、それらすべてを印刷するか返すかを選択できます。
  • 解決策につながらない入力をサポートする必要はありません。
  • 合計には、Bのコピーと重複しない暗黙的なゼロが含まれる場合があります。上記の合計の2番目のゼロは、このような暗黙のゼロです。
  • Aの最大サイズが100で、Bの最大サイズが30であると仮定できます。
  • これはコードゴルフなので、バイト単位の最短回答が勝ちです。標準的な抜け穴は禁止されています。

テストケース

Input : N = 1 / A = [ 1, 2, 3, 4, 5 ]
Output: [ 1 ]

Input : N = 2 / A = [ 1, 2, 100, 99 ]
Output: [ 1, 1 ]

Input : N = 3 / A = [ 1, 1, 1 ]
Output: [ 1, 1, 1 ]

Input : N = 3 / A = [ 1, 1, 3, 2, 2 ]
Output: [ 1, 1, 1 ]

Input : N = 3 / A = [ 1, 0, 2, 1, 1, 1, 0, 0, 1, 0, 1 ]
Output: [ 1, 0, 1 ]

Input : N = 4 / A = [ 1, 2, 2, 2, 1 ]
Output: [ 1, 1, 1, 1 ]

Input : N = 4 / A = [ 1, 1, 2, 4, 1, 2, 2, 1, 0, 1, 0, 1, 1, 0, 1 ]
Output: [ 1, 1, 0, 1 ]

Input : N = 4 / A = [ 1, 1, 0, 2, 1, 0, 1 ]
Output: [ 1, 0, 0, 1 ] or [ 1, 1, 0, 1 ]

Input : N = 5 / A = [ 1, 3, 6, 9, 8, 6, 3, 4 ]
Output: [ 1, 1, 1, 0, 1 ]

Input : N = 8 / A = [ 2, 1, 0, 2, 3, 3, 1, 2, 1 ]
Output: [ 1, 0, 0, 1, 1, 1, 0, 1 ]

Input : N = 10 / A = [ 1, 2, 1, 2, 2, 1, 3, 3, 3, 2, 3, 0, 2, 1, 1, 0, 1 ]
Output: [ 1, 1, 0, 1, 0, 1, 1, 1, 0, 1 ]

Input : N = 13 / A = [ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 ]
Output: [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 ]

Input : N = 5 / A = [ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 ]
Output: [ 1, 1, 1, 1, 1 ]

Input : N = 6 / A = [ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 ]
Output: [ 1, 0, 0, 0, 0, 1 ]

Input : N = 7 / A = [ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 ]
Output: [ 1, 1, 0, 0, 0, 1, 1 ]

Input : N = 9 / A = [ 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 ]
Output: [ 1, 0, 1, 0, 1, 0, 1, 0, 1 ]

N合理的にサポートされるべき最大の価値は何ですか?
ニール

Iは、AとBの両方にサイズ制限を追加した@Neil
アルノー

1
@fənɛtɪk多分、しかしためN=4, A = [ 1, 1, 2, 4, 1, 2, 2, 2, 1, 2, 2, 1, 2, 0, 1 ]、あなたは両方の11とまだ13だけで割り切れる30459を取得[ 1, 1, 0, 1 ]し、[ 1, 0, 1, 1 ]有効な回答です。
ニール

1
@ fəˈnɛtɪkこれらの数値は基数2で記述されていないため、算術の規則は適用されません。たとえば、追加するときに明示的に持ち運ぶことはできません。
BallpointBen

2
これらのテストケースを追加してください。これらのテストケースは、投稿された回答のほぼすべてに違反しているようです。N= 3、A = [1、0、2、0、2、0、1]、output = [1、0、1]; N = 3、A = [1、1、1、0、0、0、1、1、1]、出力= [1、1、1]。
アンデルスカセオルグ

回答:


8

PHP、105 92 90 86バイト

ヨルグのソリューションが修正され、ゴルフが行われました。

for($b=1+2**$argv[1];;)--$argc>1?$s+=$argv[$argc]*2**$i++:$s%($b-=2)||die(decbin($b));

かかるN最初のコマンドライン引数から、その後の値。オンラインで実行する-r、オンラインでテストします
2進数(形式10001)を出力します。無効なソリューションを出力するか、有効なソリューションがない場合は動作しなくなります。

無効な入力に対して何も出力しない最初のバージョン(現在は97バイト):オンラインでテストする

for($b=1+$m=2**$argv[1];$m/2<=$b;)--$argc>1?$s+=$argv[$argc]*2**$i++:$s%($b-=2)||die(decbin($b));

壊す

for($b=1+$m=2**$argv[1];$m/2<=$b;)  # second loop: loop $b from 2^N-1 by -2 to 2^(N-1)
--$argc>1                           # first loop: decrease $argc ...
    ?$s+=$argv[$argc]*2**$i++           # while $argc>1: binary sum from last to 2nd argument
    :$s%($b-=2)||die(decbin($b));       # later: if $b divides $s, print in binary and exit

ニース、100未満のバイトカウントに到達できませんでしたか?
ヨルクヒュルサーマン

1
@JörgHülsermannできました。
タイタス

重い思考。この前にあなたが優れていることを知っています。最低のバイト数を保持できることを願っています
ヨルグヒュルサーマン

1
N = 3、A = [ 1、0、2、0、2、0、1111 ]では、正しい結果が[ 1、0、1 ] のみである場合に誤って返されます
アンデルスカセオルグ

8

PHP、219バイト

<?for(list($g,$z)=$_GET,$d=~-$l=2**$z;$d>=$l/2;max(array_diff_assoc($r,$g)?:[0])?:$o[]=$b,$d-=2)for($r=[],$b=decbin($d),$k=0;$k<count($g);$k++)for($u=$g[$k]-$r[$k],$i=0;$i<$z;$i++)$u<1?:$r[$k+$i]+=$u*$b[$i];print_r($o);

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

-4バイトの[$g,$z]=$_GET代わりにPHP 7.1 を使用list($g,$z)=$_GET


最後のテストケースに対して有効な([1,0,1,0,1,0,1,0,1])および無効な回答([1,0,0,0,1,0,1,1,1])の両方を出力するようです。
アーナウルド

-8バイト:while($_GET[0])$s+=2**$i++*array_pop($_GET[0]);。-5バイト:range(1|.5*$m=2**$_GET[1],$m,2)
タイタス

@Arnauldはい、私は出力として与える必要がある唯一の最高binarrayもこのソリューションは有効にする
イェルクHülsermann

2
@ fəˈnɛtɪk私はあなたの数学に同意しますが、挑戦は、同等の配置ではなく、Aに正確に合計できるパターンを見つけることです。ここで、取得し[ 1,0,1,1,1,0,2,2,2,2,2,1 ]ます。
アーナルド

1
-1バイトとfor($g=$_GET[0];$g;)
タイタス

3

Python、166バイト

def f(a,n):
 for i in range(1<<n-1,1<<n):
  b=bin(i)[2:];u,v=(int(('0{:0>%d}'%sum(a)*len(s)).format(*s))for s in[a,b])
  if u%v<1>int(str(u//v*10)[::~sum(a)]):yield b

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

使い方

AおよびBを基数kの数字uおよびvとして考えます。例(説明のためにk = 1000を使用します):

A = [1、2、1、3、2、1、2]
B = [ 1、0、0、1 ]
u = 1 002 001 003 002 001 002
v = 1 000 000 001

他の回答者の多くが気づいたように、Bが有効な回答である場合、uvで割り切れます。この場合、

uが 1 002 001 002 =⋅ V

配列[1、2、1、2]に戻されるこの商は、各位置にシフトする必要のあるBのコピー数を正確に示します。

  [1, 0, 0, 1]
+    [1, 0, 0, 1]
+    [1, 0, 0, 1]
+       [1, 0, 0, 1]
+          [1, 0, 0, 1]
+          [1, 0, 0, 1]
-----------------------
  [1, 2, 1, 3, 2, 1, 2]

(理由は、それが底kで乗算が行われる正確な時間だからです。)

他の回答者が気づかなかったのは、上記の条件が十分でないということです。例えば:

A = [1、2、1、3、2、1、2]
B = [ 1、1、1、1 ]
u = 1 002 001 003 002 001 002
v = 1 001 001 001
u = 1 000 999 002⋅ v

数学的に言えば、その商を配列[1、1、-1、2]に戻すことができます。これは、Bのネガティブコピーを使用できる場合は正常に機能します。

  [1, 1, 1, 1]
+    [1, 1, 1, 1]
       [1, 1, 1, 1]
+          [1, 1, 1, 1]
+          [1, 1, 1, 1]
-----------------------
  [1, 2, 1, 3, 2, 1, 2]

ただし、もちろん、このチャレンジではネガティブコピーは許可されません。したがって、追加のチェックが必要です。

そのために、我々は、基本選択し、K = 10 、E K塩基のいずれも> 10⋅和(A)、およびチェックないK次ベースに桁溢れをk個の 10によって、我々は乗算商デジットを。つまり、商10の10進表記で、末尾から始まるeの 10進ごとに0でなければなりません。これにより、商が非負の要素を持つ配列に変換されることが保証されます。


1
10の大きな累乗をベースとして使用して、ベースの変換を簡単にするトリックが大好きです。
ニール

2

PHP、213バイト

少しゴルフをした同じ方法

<?for($b=2**~-$l=$_GET[1];$b<2**$l;array_filter($t[$b++])?:$d[]=$o)for($g=count($t[$b]=$_GET[$i=0]);min($t[$b])>-1&$i<=$g-$l;$i++)for($e=$t[$b][$i],$k=0,$o=decbin($b);$k<$l;)$t[$b][$k+$i]-=$o[$k++]*$e;print_r($d);

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

PHP、最初に動作する344バイト

最初の回答の後、すべての有効な解決策を提供するより長い試行を行うことにしました。

<?foreach(range(2**($l=$_GET[1])-1,2**($l-1))as$b){$t[$b]=($g=$_GET[0]);for($i=0;$t[$b]&&$i<=count($g)-$l;$i++){$e=reset($y=array_slice($t[$b],$i,$l));foreach(str_split(decbin($b))as$k=>$v)$t[$b][$k+$i]=$y[$k]-$e*$v;if(min($t[$b])<0)unset($t[$b]);}}foreach($t as$k=>$v)if(max($v)>0)unset($t[$k]);echo join(",",array_map(decbin,array_keys($t)));

オンライン版

壊す

foreach(
    range(2**($l=$_GET[1])-1
    ,2**($l-1)
    ) # make decimal range of a binarray with given length
    as$b){
$t[$b]=($g=$_GET[0]); # make a copy for each possible solution pattern
    for($i=0;$t[$b]&&$i<=count($g)-$l;$i++){ # Loop till solution is valid or reach last digit
        $e=reset($y=array_slice($t[$b],$i,$l)); # take first value of a sequence with the length
        foreach(str_split(decbin($b))as$k=>$v)
            $t[$b][$k+$i]=$y[$k]-$e*$v; # replace values in copy
        if(min($t[$b])<0)unset($t[$b]); # kill solution if a minimum <0 exists
    }
}
foreach($t as$k=>$v)if(max($v)>0)unset($t[$k]); # drop all solutions where the sum is not zero 


echo join(",",array_map(decbin,array_keys($t))); #Output all solutions

これはN≥2で機能するようですが、チャレンジの最初のテストケースなど、N = 1のケースでは失敗します。
アンデルスカセオルグ

@AndersKaseorgは、今ではそれが設定するだけN = 1ケースをサポートし=、それは4バイト削除する必要が大きい版で短いバージョンのための最初のループで
イェルクHülsermann

1

Python、205バイト

def f(a,l):
 b=lambda s:b(s[:-1])*sum(a)*8+int(s[-1])if s else 0
 c=lambda n:n and(n/sum(a)/4%2 or c(n/sum(a)/8))
 for i in range(2**~-l,2**l):
  j=bin(i)[2:]
  if b(a)%b(j)<1 and not c(b(a)/b(j)):return j

セパレータなしのバイナリ文字列を返します。@AndersKaseorgが指摘しているように、除算が負の係数を表しているために許可されないため、@ fəˈnɛtɪkの解が機能しない入力があります。これを回避するには、非常に大きなベースを使用して、部門に借用がないことをテストします。


さて、これは実際の反例だと思いf([1, 1, 1, 0, 0, 0, 1, 1, 1], 3)ます101
アンデルスカセオルグ

@AndersKaseorgうーん、ループの順序を逆にするのは助けになりますか、それともアルゴリズムは根本的に壊れていますか?
ニール

追加チェックなしで根本的に壊れていると思います。逆の異形は失敗しますf([1, 0, 2, 0, 2, 0, 1], 3)、そして、前方と逆の異形は失敗しf([1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0], 5)ます。
アンデルスカセオルグ

そしてi、それが奇数であることを確認したとしても、フォワードバリアントとリバースバリアントの両方が失敗しf([1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0]*10, 5)ます。
アンダースカセオルグ

1
@AndersKaseorgあ、はい、gcd(k、n)= 1の場合、(x^kn-1)/(x^k-1)常に(x^n-1)/(x-1)要因として、@ fəˈnɛtɪkの任意のベースのソリューションをだます。
ニール

1

Pyth、32バイト

f!|%FKiRJysQ,QT>#sQj/FKJ+L1^U2tE

オンラインで試す

使い方

                           ^U2tE   Cartesian power [0, 1]^(N - 1)
                        +L1        prepend 1 to every list
f                                  filter for lists T such that:
          sQ                         sum(A)
         y                           double
        J                            assign to J
      iR    ,QT                      convert [A, T] from base J
     K                               assign to K
   %F                                fold modulo
  |                                  logical OR with
                    /FK                fold integer division over K
                   j   J               convert to base J
               >#sQ                    filter for digits greater than sum(A)
 !                                   logical NOT

戦略は私のPythonの答えに似ていますが、Pythにはベース変換用のビルトインがあるため、より効率的なベースk = 2⋅sum (A)を使用でき、商のすべての桁が最大でsum(A )。


1

パリ/ GP77 74 96 80バイト

n->a->[v|d<-divisors(b=Pol(a)),(v=Vec(d))%2==v&&vecmin(Vec(b/d))>=0&&d%x&&#d==n]

すべてのソリューションを返します。

最初に配列aを多項式に変換しbます。次に、の係数がすべておよびであり、の係数がすべて非負であり、およびでbあるdような多項式を除数から選択します。最後に、それらを配列に戻します。d10b / dd(0) = 1deg(d) = n + 1

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

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