私の配列にエコーがあります...私の配列にエコーがあります...私の配列


34

助けて!私のアレイのいくつかに迷惑なエコーがあるようで、それを取り除きたいです。これが発生すると、元の配列が中央のどこかで繰り返され、値が互いに加算されます。

たとえば、配列に[ 422, 375, 527, 375, 859, 451, 754, 451 ]は次のような自身のエコーが含まれます。

[ 422, 375, 527, 375, 859, 451, 754, 451 ] <-- array with echo (input)

[ 422, 375, 105,   0, 754, 451           ] <-- original array (output)
[           422, 375, 105,   0, 754, 451 ] <-- echo of original array

例2:

[ 321, 526, 1072, 899, 6563, 798, 7038, 3302, 3032, 3478, 1806, 601 ] <-- input

[ 321, 526,  751, 373, 5812, 425, 1226, 2877, 1806,  601            ] <-- output
[            321, 526,  751, 373, 5812,  425, 1226, 2877, 1806, 601 ]

配列にエコーがない場合もあります。その場合、元の配列を返します。

例3:

[ 623, 533, 494, 382 ] <-- input
[ 623, 533, 494, 382 ] <-- output

チャレンジ:

エコーを含む可能性のある配列を指定して、それを削除し、エコーなしで配列を返します。

入力:

  • 配列、リスト、区切られた文字列、パンチカードまたはプラットフォームに適切な等価の範囲内で、三つ以上の整数を含む0n<10000少なくとも一つの元素と>0
  • エコーは、最初の要素または最後の要素の後に開始できません。
  • エコーは入力内で1回だけ発生するか、まったく発生しません。

出力:

  • 整数の配列、リスト、等0n<10000エコーとは、除去されます。
  • エコーがない場合は、元の配列を返します。

ルールとスコアリング:

テストケース:

エコーあり:

[ 422, 375, 527, 375, 859, 451, 754, 451 ]
[ 422, 375, 105, 0, 754, 451 ]

[ 321, 526, 1072, 899, 6563, 798, 7038, 3302, 3032, 3478, 1806, 601 ]
[ 321, 526, 751, 373, 5812, 425, 1226, 2877, 1806, 601 ]

[ 4330, 3748, 363, 135, 2758, 3299, 1674, 1336, 4834, 2486, 4087, 1099, 4098, 4942, 2159, 460, 4400, 4106, 1216, 3257, 1638, 2848, 3616, 3554, 1605, 490, 1308, 2773, 3322, 3284, 4037, 7109, 4171, 5349, 2675, 3056, 4702, 4229, 1726, 5423, 6039, 8076, 6047, 7088, 9437, 4894, 1946, 7501, 5331, 3625, 5810, 6289, 2858, 6610, 4063, 5565, 2200, 3493, 4573, 4906, 3585, 4147, 3748, 3488, 5625, 6173, 3842, 5671, 2555, 390, 589, 3553, 3989, 4948, 2990, 4495, 2735, 1486, 3101, 1225, 2409, 2553, 4651, 10, 2994, 509, 3960, 1710, 2185, 1800, 1584, 301, 110, 969, 3065, 639, 3633, 3544, 4268 ]
[ 4330, 3748, 363, 135, 2758, 3299, 1674, 1336, 4834, 2486, 4087, 1099, 4098, 4942, 2159, 460, 4400, 4106, 1216, 3257, 1638, 2848, 3616, 3554, 1605, 490, 1308, 2773, 3322, 3284, 4037, 2779, 423, 4986, 2540, 298, 1403, 2555, 390, 589, 3553, 3989, 4948, 2990, 4495, 2735, 1486, 3101, 1225, 2409, 2553, 4651, 10, 2994, 509, 3960, 1710, 2185, 1800, 1584, 301, 110, 969, 3065, 639, 3633, 3544, 4268 ]

[ 24, 12, 52, 125, 154, 3, 567, 198, 49, 382, 53, 911, 166, 18, 635, 213, 113, 718, 56, 811, 67, 94, 80, 241, 343, 548, 68, 481, 96, 79, 12, 226, 255, 200, 13, 456, 41 ]
[ 24, 12, 52, 125, 154, 3, 567, 198, 25, 370, 1, 786, 12, 15, 68, 15, 88, 348, 55, 25, 55, 79, 12, 226, 255, 200, 13, 456, 41 ]

[ 1, 3, 2 ]
[ 1, 2 ]

[ 0, 1, 3, 2, 0 ]
[ 0, 1, 2, 0 ]

エコーなし:

[ 623, 533, 494, 382 ]
[ 623, 533, 494, 382 ]

[ 1141, 1198, 3106, 538, 3442, 4597, 4380, 3653, 1370, 3987, 1964, 4615, 1844, 5035, 2463, 6345, 4964, 4111, 5192, 8555, 5331, 3331, 4875, 6586, 5728, 4532, 5972, 2305, 3491, 6317, 2256, 2415, 5788, 4873, 6480, 2080, 5319, 4551, 6527, 5267, 4315, 2178, 2615, 5735, 5950, 6220, 7114, 6259, 5000, 4183, 6822, 6927, 7150, 8003, 5603, 3154, 8231, 5005, 5743, 6779, 4530, 4029, 5336, 6105, 4777, 6183, 6838, 5725, 6819, 8584, 3142, 3840, 3291, 4284, 2933, 4859, 2906, 5176, 2853, 2110, 2048, 4389, 4501, 2267, 2704, 431, 1495, 2712, 3008, 187, 3487, 630 ]
[ 1141, 1198, 3106, 538, 3442, 4597, 4380, 3653, 1370, 3987, 1964, 4615, 1844, 5035, 2463, 6345, 4964, 4111, 5192, 8555, 5331, 3331, 4875, 6586, 5728, 4532, 5972, 2305, 3491, 6317, 2256, 2415, 5788, 4873, 6480, 2080, 5319, 4551, 6527, 5267, 4315, 2178, 2615, 5735, 5950, 6220, 7114, 6259, 5000, 4183, 6822, 6927, 7150, 8003, 5603, 3154, 8231, 5005, 5743, 6779, 4530, 4029, 5336, 6105, 4777, 6183, 6838, 5725, 6819, 8584, 3142, 3840, 3291, 4284, 2933, 4859, 2906, 5176, 2853, 2110, 2048, 4389, 4501, 2267, 2704, 431, 1495, 2712, 3008, 187, 3487, 630 ]

[ 4791, 1647, 480, 3994, 1507, 99, 61, 3245, 2932, 8358, 6618, 1083, 5391, 3498, 4865, 1441, 3729, 5322, 5371, 6271, 2392, 1649, 5553, 9126, 3945, 2179, 3672, 2201, 4433, 5473, 4924, 6585, 6407, 3862, 6505, 1530, 5293, 4792, 6419, 6739, 3258, 3839, 3891, 7599, 2576, 5969, 5659, 6077, 5189, 1325, 4490, 5694, 6567, 6367, 5724, 5756, 6450, 5863, 4360, 2697, 3100, 3779, 4040, 4653, 1755, 3109, 2741, 3269 ]
[ 4791, 1647, 480, 3994, 1507, 99, 61, 3245, 2932, 8358, 6618, 1083, 5391, 3498, 4865, 1441, 3729, 5322, 5371, 6271, 2392, 1649, 5553, 9126, 3945, 2179, 3672, 2201, 4433, 5473, 4924, 6585, 6407, 3862, 6505, 1530, 5293, 4792, 6419, 6739, 3258, 3839, 3891, 7599, 2576, 5969, 5659, 6077, 5189, 1325, 4490, 5694, 6567, 6367, 5724, 5756, 6450, 5863, 4360, 2697, 3100, 3779, 4040, 4653, 1755, 3109, 2741, 3269 ]

[ 235, 121, 52, 1249, 154, 26, 5672, 1975, 482, 3817, 532, 9104, 1661, 171, 6347, 2124, 1122, 7175, 558, 8101, 667, 934, 798, 2404, 3424, 5479, 672, 4808, 956, 789, 123, 2255, 2549, 200, 126, 4562, 41 ]
[ 235, 121, 52, 1249, 154, 26, 5672, 1975, 482, 3817, 532, 9104, 1661, 171, 6347, 2124, 1122, 7175, 558, 8101, 667, 934, 798, 2404, 3424, 5479, 672, 4808, 956, 789, 123, 2255, 2549, 200, 126, 4562, 41 ]

[ 1, 1, 1, 1, 1 ]
[ 1, 1, 1, 1, 1 ]

3
複数の可能な出力がある場合はどうなりますか?入力:[1, 2, 2, 2, 1]; 出力:[1, 1, 1, 1]vs.[1, 2, 1]
tsh

3
予想出力は何か[1, 2, 3, 1, 2, 3][1, 2, 3, 0, 1, 2, 3][0, 1, 3, 2, 0]?現在の答えは、これらの入力のすべてについては一致しません。
tsh

@tshどちらか([1, 1, 1, 1]vs. [1, 2, 1])が許容されます。最初に選択するルールがありましたが、少数のエッジケースにのみ適用されるように思われたため、サンドボックスでそれを削除しました。
640KB

@tsh、 [0, 1, 3, 2, 0]必要があります[0, 1, 2, 0]-テストケースに追加しました。他の2つの予想された答えは[1, 2, 3]、規則に従って以来私がそれらの有効なテストケースを考慮しないであろうことであるかもしれませんthe original array repeats itself somewhere in the middle
640KB

1
@nimiいいね。私はそれが曖昧だと言うでしょう[0,0,0](またはサイズのすべて0の配列が)何かのエコーを表すのか、または[0,0,0](エコーなし)がこの特別な場合にも有効な答えになるのかは、どちらを判断するのに十分な情報がないため、そうです。既存の回答を無効にしたり変更したりしないため、これを有効な入力から制限するようにルールを更新します。
640KB

回答:


8

MATL、16バイト

t"GX@WQB&Y-~?w]x

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

説明

勝利のための多項式除算!

t      % Implicit input. Duplicate
"      % For each (do the following as many times as input length)
  G    %   Push input again. This will be the output if no solution exists
  X@   %   Push current iteration index, k
  WQB  %   2 raised to that, add 1, convert to binary. Gives [1 0 ... 0 1] (k-1 zeros)
  &Y-  %   Two-output polynomial division (deconvolution). Gives quotient and remainder
  ~    %   Logical negate: transforms zeros into 1, nonzeros into 0
  ?    %   If all values are nonzero (i.e. if remainder was all zeros): solution found
    w  %      Swap. This moves the copy of the input to top (to be deleted)
  ]    %   End
  x    %   Delete. This deletes the quotient if it was not a solution, or else deletes
       %   the copy of the input
       % End (implicit). Since it is guaranteed that at most one solution exists, at this
       % point the stack contains either the solution or the input
       % Implicit display

これに関する「eso」または「historic」言語の恩恵を受ける人はいません...賞金は人気になります!
640KB

1
@ 640KBこのチャレンジには賞金があるとは知りませんでした!ありがとうございました!
ルイスメンドー

7

Haskell、167バイト

最初に、エコーが存在する場合、入力配列は別の配列との配列の畳み込みであることに注意することが重要[1,1],[1,0,1],[1,0,0,1],...です。

これは、これらすべての配列についてこれをチェックする必要があることを意味します。しかし、離散畳み込み/デコンボリューションは多項式乗算/長除算と同じです。したがって、これは多項式を使用した実装であり、可能な場合は常に商を返します。

[1]他の配列が機能しない場合、デコンボリューション[1]は機能し、元の多項式を返すので、全体を少し短くした1つのトリックは、上記の配列に加えてベースケースとしてもチェックしました。

import Math.Polynomial
import Data.Ratio
p=poly LE
c z=last[polyCoeffs LE q|k<-zipWith const[p(take k(1:repeat 0)++[1])|k<-[0..]]z,(q,r)<-[quotRemPoly(p z)k],r==zero] 

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


ベースケースの良いトリック!私はそれを答えに取り入れようとしましたが、コードを短くすることができました
ルイス・メンド

4

JavaScriptの211の 171 145バイト

s=>{for(n=x=0,y=s.length;++x<y/2&!n;)for(n=s.slice(i=0,x);i+x<y-x&&n;)n=(n[i+x]=s[i+x]-n[i++])<0?0:n;return n&&n.slice(1-x)+''==s.slice(1-x)?n:s}

オンラインで試す

Kevin Cruijssenから40バイト

Arnauldからさらに26バイト

私の最初のコードのゴルフの答えは、潜在的なオフセットを無効にし、見つかったものに応じて元の配列または新しい配列を返します。誰かがそれを短くする方法を知っているなら、私に知らせてください、楽しいゲームのようです。


1
私もJavaScriptで習熟していないんだけど、いくつかの基本的なgolfs(すなわち、不要な括弧を取り除くの配置変更で++、変更&&する&最初のチェックでは、その両方を変更.toString()する+''など、)私はまであなたのコードを得た181バイト。あなたがそれらをまだ見ていない場合は、JavaScriptでゴルフのヒント、すべての言語でのゴルフのためのヒントをお読みも面白いかもしれません。:)
ケビン・クルーッセン

1
ああ、忘れました(function q(s)することができますs=>):171バイト。滞在を楽しんで!:)
ケビン・クルーッセン

そのおかげで、私は読んでいるでしょう。私はjavascriptをあまり使いませんが、最近少ししなければならなかったので、これはダウンタイムを少し
改善

1
さらにゴルフをしました(このコメントの直接のURLとして収まるようにすべてのテストなしで)
Arnauld

1
Code Golf SEへようこそ!ここでゴルフを楽しんでください。
ジュゼッペ

3

Haskell、112 111 110バイト

l=length
(!)=splitAt
f a=last$a:[x|i<-[1..l a],let (h,t)=i!a;o=h++zipWith(-)t o;(x,y)=l t!o,all(>=0)o,sum y<1]

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

f a=                
      i<-[1..l a]                -- for all indices 'i' of the input array 'a'
      (h,t)=i!a                  -- split 'a' at 'i' into 'h' and 't'
                                 -- e.g. a: [1,2,3,4], i: 1 -> h: [1], t:[2,3,4] 
      o=                         -- calculate the original array by
        h++                      --   prepended 'h' to
        zipWith(-)t o            --   the (element-wise) difference of
                                 --   't' and itself
      (x,y)=l t!o                -- split 'o' at position <length of t>
                                 --
                                 -- example:
                                 --      a: [0,1,3,2,0]
                                 --      h: [0]
                                 --      t: [1,3,2,0]
                                 --   now
                                 --      o: [0,1,2,0,0]
                                 --      x: [0,1,2,0]
                                 --      y: [0]
                                 --
    ,                            -- 'o' is valid, if
     all(>=0)o                   --   all elements of 'o' are not negative
    ,sum y<1                     --   and 'y' is all zeros
  [x|         ]                  -- keep 'x' (a valid echo array) if 'o' is valid

 last $ a :[  ]                  -- if there's no echo, the list of 'x's is empty
                                 -- and 'a' is picked, else the last of the 'x's 

3

Wolfram Language(Mathematica)131 129 120 119 102 98 97 96 95バイト

(w=#;Do[(w=v/.#)&/@Thread[#==PadLeft[v=Array[x,L-d],L]+v~PadRight~L]~Solve~v,{d,L=Tr[1^#]}];w)&

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

attinatのおかげで-1バイト:引数が数字のリストである場合のL=Tr[1^#]代わりに書くことができL=Length@#ます。

コードの説明:収縮d(入力と出力の長さの差)を反復処理します。出力リストの長さごとに、未知数のリストを作成し、v={x[1],x[2],...,x[L-d]}それを長さLPadLeft[v,L]+PadRight[v,L])に左詰めおよび右詰めして自分自身に追加し、この合計を入力リストと等しく設定して、未知数を解決しx[1]...x[L-d]ます。最後に生成された最短のソリューションを選択しますw。ソリューションが見つかるたびに変数を上書きし続けるだけです。

非ゴルフバージョン:

F = Function[A,                                  (* A is the input list *)
  Module[{L = Length[A],                         (* length of A *)
          v,                                     (* list of unknowns *)
          x,                                     (* unknowns in v *)
          w = A},                                (* variable for solution, defaults to A *)
    Do[                                          (* loop over shrinkage: d = Length[A]-Length[output] *)
      v = Array[x, L - d];                       (* list of unknowns to be determined *)
      (w = v /. #) & /@                          (* overwrite w with every... *) 
        Solve[                                   (* ...solution of... *)
          Thread[PadLeft[v,L]+PadRight[v,L]==A], (* ...v added to itself, left-padded and right-padded, equals A *)
          v],                                    (* solve for elements of v *)
    {d, L}];                                     (* loop for shrinkage from 1 to L (the last case d=L is trivial) *)
    w]];                                         (* return the last solution found *)

-1のTr[1^#]代わりにLength@#
attinat

2

ゼリー25 24バイト

ðsạ\FḣL_¥,+¥Ż⁹¡$µⱮLṪ⁼¥Ƈȯ

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

整数のリストを受け取って返す単項リンク。技術的には、成功した結果はさらに2つのリストにネストされますが、完全なプログラムとして実行すると、stdoutへの暗黙的な出力は冗長リストを無視します。


2

パイソン2113の 123 128 127 123 122バイト

def f(a,i=1):
 e=a[:i]
 for v in a[i:-i]:e+=v-e[-i],
 return i<=len(a)/2and(min(e)>=0<e[-i:]==a[-i:]and e or f(a,i+1))or a

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

TFeldへの1バイトthx ; Sebastian Kreftへの1バイトthx 。

への各呼び出しでf、長さの潜在的なエコーを構築しlen(a)-iます。最初の部分はia の最初のバイトです。エコーサムの「重複」セクションに対して「エコーサム」が正しくなるように剰余が計算されます(つまり、エコーサムはまで正確a[:-i]です)。

それから、ゴルフのない非常に近道の比較は以下を与えます:

if i>=len(a)/2+1:
    return a # because it can't be that short, so there is no echo
else:
    if min(e)>=0                       # all elements are non-negative
                 and e[-i:]==a[-i:]:   # and the tails are the same
        return e                       # it's a match!
    else:
        return f(a,i+1)                # recurse

e+=[v-e[-i]]することができe+=v-e[-i],
TFeld

することでもう1つのキャラクターを剃ることができますi<=len(a)/2
セバスチャンクレフ

2

Wolfram言語(Mathematica)、93バイト

(b=#;Do[a=#;Do[a[[i+j]]-=a[[j]],{j,2k}];a/.{__?(#>=0&),0}:>(b=a~Drop~-i),{i,k=Tr[1^#]/2}];b)&

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

リストにある最短のエコーを返します。


これは、上で失敗するように見えます{1,1,1}し、上{1,0,1}
ローマ

@Romanは、これらのいずれの場合にもエコーがありませんか?
attinat

以下のために{1,1,1}そこにはエコーがありませんので、あなたは、元の配列を返す必要があります。以下のために{1,0,1}私はエコーがあると言うだろう{1}が、それはルールが何であるかを少し不明だ認めます。
ローマ

ああ、そう。キャッチしてくれてありがとう!
attinat

2

PHP、124バイト

function($a){while(!$z&&++$y<$c=count($b=$a))for($x=0;$x<$c&$z=0<=$b[$x+$y]-=$b[$x++];);return array_slice($b,0,$c-$y)?:$a;}

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

説明:

入力配列のコピーを作成し、エコーの可能な各オフセットをループします。各列について、元の位置の対応する値からオフセット位置の値を引き、入力に加算するために必要な値を決定します。有効な場合(>0)、その列の内容をその値に置き換えます。最後まで続行し、無効な値がない場合は正解です。

function( $a ) {
  // iterate through all possible offsets of echo
  while( ! $b && ++$y < $c = count( $b = $a ) ) {
    // create a copy of input array, iterate through all elements
    for( $x = 0; $b && $x < $c; ) {
      // if difference between the elements in the offset copy of 
      // the array is positive, subtract the value in the input array
      // from the offset array in the same column
      if ( ( $b[ $x+$y ] -= $b[ $x++ ] ) < 0 ) {
        // result is not valid, erase array and break out of loop
        $b = 0;
      }
    }
  }
  // truncate output array to correct size. if still contains values, 
  // it is a valid result. otherwise return the original array
  return array_slice( $b, 0, $c-$y ) ?: $a;
}

2

Python 3、111バイト

def f(r,l=1):o=r[:l];o+=(v-o[-l]for v in r[l:]);return l<len(r)and(min(o)<any(o[-l:])and f(r,l+1)or o[:-l])or r

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

このソリューションは、再帰構造や出力配列の構築など、@ Chas Brownのソリューションからいくつかのアイデアを取り入れています。一方、判定基準にいくつかの変更を加え、ジェネレーター式にforループを挿入して、単一行ソリューションを可能にします。以下に、バージョン化されていないバージョンを示します。ここでは、配列outは入力配列の最後まで計算され、最後のl要素がすべてゼロします。その場合、len(arr)-lすべての要素が負でない場合、最初の要素が答えとして返されます。

非ゴルフ、非再帰バージョン

def remove_echo(arr):
    l = 1
    while l < len(arr):
        out = arr[:l]
        out += (v - out[-l] for v in arr[l:])
        if min(out) >= 0 and out[-l:] == [0] * l:
            return out[:-l]
        l += 1
    return arr

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


1
@ 640KB返された回答がコードで予想される結果と一致するかどうかを確認し、不一致がある場合にのみメッセージを出力します。したがって、出力がないということはすべてが正しいことを意味します。これは一見混乱する可能性があることは認めますが、後で更新して試合で「修正」を印刷します。
ジョエル

1
@ 640KB更新。
ジョエル

1

木炭、62バイト

≔⁰ζF⊘Lθ«≔E⊕ι⁰ηFLθ§≔ηκ⁻§θκ§ηκ¿⬤η¬κ≔⊕ιζ»F⁻Lθζ⊞υ⁻§θι∧ζ∧¬‹ιζ§υ±ζIυ

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

≔⁰ζ

エコーがないと仮定します。

F⊘Lθ«

エコーの可能なすべての開始点を試してください。注:質問を読み間違えた可能性があり、十分なサイズのエコーを試行していない可能性があります。その場合、。必要ありません。

≔E⊕ι⁰η

エコーの開始点と同じサイズのゼロの配列から始めます。

FLθ§≔ηκ⁻§θκ§ηκ

元の配列の各要素について、エコー配列の要素を周期的に減算します。したがって、エコー配列の各要素は、離れている要素の交互の合計を構築します。

¿⬤η¬κ≔⊕ιζ»

すべての交互合計がゼロの場合、これを可能な開始点として保存します。(複数の可能性がある場合、可能な限り最大の開始点が使用されます。)

F⁻Lθζ⊞υ⁻§θι∧ζ∧¬‹ιζ§υ±ζ

前に計算された適切な要素から開始点の後の要素を減算して、エコー配列を構築します。

Iυ

別の行に暗黙的に出力するために文字列にキャストします。

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