У моєму масиві є відлуння… ехо в моєму масиві… мій масив


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 .
  • Відлуння не може починатися на першому або після останнього елемента.
  • Відлуння відбудеться лише один раз або зовсім не буде в межах введення.

Вихід:

  • Масив, список тощо з цілими числами 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]проти [1, 2, 1]) прийнятний. Спочатку у мене було правило вибирати, але його зняли в пісочниці, оскільки, здавалося, воно стосується лише невеликої кількості крайових справ.
640 Кб

@tsh, [0, 1, 3, 2, 0]повинно бути [0, 1, 2, 0]- я додав до тестових випадків. Очікувана відповідь на два інших могла бути, [1, 2, 3]хоча я б не вважав ці дійсні тестові випадки, оскільки згідно з правилами the original array repeats itself somewhere in the middle.
640 Кб

1
@nimi Добрий. Я б сказав, що неоднозначно, чи [0,0,0](чи будь-який розмірний 0масив загального розміру ) являє собою відлуння чогось, або якщо [0,0,0](без відлуння) також буде вагомою відповіддю і для цього особливого випадку, оскільки просто не вистачає інформації, щоб визначити, який Це є. Я оновлю правила, щоб обмежити це неправдивим вводом, оскільки це не призведе до недійсності та зміни будь-яких існуючих відповідей.
640 Кб

Відповіді:


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

Ніяких прихильників "есо" чи "історичної" мовної винагороди на це ... так що щедрість стає популярною!
640 Кб

1
@ 640KB Я не знав, що з цього виклику було щедро! Дякую!
Луїс Мендо

7

Haskell , 167 байт

Спочатку важливо зауважити, що якщо присутній ехо, то вхідний масив - це згортання іншого масиву з деяким масивом форми [1,1],[1,0,1],[1,0,0,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}

Спробуйте в Інтернеті

40 байт від Kevin Cruijssen

Ще 26 байт з Арнальда

Моя перша відповідь на гольф з кодом, анулює потенційні компенсації та повертає або оригінал, або новий масив залежно від того, що він знаходить. Якщо хтось знає, як зробити це коротше, будь ласка, мені це здається веселою грою.


1
Я не надто досвідчений в JavaScript, але з деякими основними гольфами (наприклад, видалення непотрібних дужок, зміна місця розташування ++, перехід &&на &першу перевірку, зміна обох .toString()і +''т. Д.) Я знизив ваш код до 181 байта . Якщо ви їх ще не бачили, Поради щодо гольфу в JavaScript та Поради щодо гольфу на всіх мовах можуть бути цікавими для прочитання. :)
Кевін Кройсейсен

1
О, забув одне ( function q(s)може бути s=>): 171 байт . Насолодитися перебуванням! :)
Кевін Кройсейсен

Дякую за це, я прочитаю. Я не дуже зручний з javascript, але мені довелося зробити це останнім часом, і я вважав, що це може бути гарним способом трохи почистити час простою
Levi Faid

1
Гольфував ще трохи (без усіх тестів, щоб він відповідав прямій URL у цьому коментарі)
Арнольд

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

Мова Вольфрама (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)&

Спробуйте в Інтернеті!

-1 байт завдяки attinat : ми можемо писати L=Tr[1^#]замість того, L=Length@#коли аргументом є список чисел.

Пояснення коду: Ітерація через усадку d(різниця між вхідними та вихідними довжинами). Для кожної довжини списку вихідних даних побудуйте список невідомих v={x[1],x[2],...,x[L-d]}і додайте його до лівої та правої підкладки довжині L( PadLeft[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Ṫ⁼¥Ƈȯ

Спробуйте в Інтернеті!

Монадічне посилання, яке приймає і повертає список цілих чисел. Технічно успішні результати вкладені в два наступні списки, але при запуску в якості повноцінної програми неявний вихід на stdout ігнорує надлишкові списки.


2

Python 2 , 113 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

Спробуйте в Інтернеті!

1 байт thx для TFeld ; та 1 байт thx Себастьяну Крефту .

Під час кожного заклику fми створюємо потенційне відлуння довжини len(a)-i. Перша частина - це лише перші iбайти a; решта обчислюється таким чином, що "ехо-сума" буде правильною для "перекритого" розділу ехо-суми (тобто, сума відлуння є правильною до 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

ви можете поголити ще одного персонажа, виконуючиi<=len(a)/2
Себастьян Крефт,

2

Мова Вольфрама (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}.
Роман

@ Роман Хіба немає відлуння в жодному з цих випадків?
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υ

Передайте рядок для неявного виводу в окремі рядки.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.