Інший шлях вперед


23

Даний список цілих чисел створює різницю вперед у визначеному порядку / глибині.

Список цілих чисел:

(10, 18, -12, 4, 8, -3, -5, 67, 9, 14)

Відмінності вперед в різних порядках / глибинах:

0   10,   18,  -12,    4,    8,   -3,   -5,  67,  9,  14
1      8,  -30,   16,    4,  -11,   -2,   72, -58,  5
2       -38,   46,  -12,  -15,    9,   74, -130, 63
3           84,  -58,   -3,   24,   65, -204, 193
4            -142,   55,   27,   41, -269, 397
5               197,  -28,   14, -310, 666
6                 -225,   42, -324, 976
7                    267, -366, 1300
8                      -633, 1666
9                         2299

Так із введенням

4, (10, 18, -12, 4, 8, -3, -5, 67, 9, 14)

Ви б повернули список

(-142,   55,   27,   41, -269, 397)

Вхідні дані

Вхід може бути через STDIN або функціональні параметри.

Ціле число, що визначає глибину повернення. Це буде 0 до довжини списку мінус 1

Список цілих чисел для обчислення різниці вперед для

Вихід

Вихід може бути через STDOUT або повернутись функцією.

Відмінності в прямому напрямку для вказаної глибини у вигляді списку цілих чисел

Правила

Вбудовані та сторонні функції, які роблять це безпосередньо, заборонені.

Застосовуються стандартні обмеження лазівки .

Найкоротший код виграє

Відповіді:


19

J, 15 9 7 байт

Дуже легко. Розглядає глибину та список як аргументи зліва та справа.

-~/\~&2

Як чітке визначення без усієї прислівникової хитрості, це зводиться до

4 : '(2 -~/\ ])^:x y'
  • -~/\~&2 y- різниця форвардів y.
  • x -~/\~&2 y- xрізниця форматів -ої форвард y.

Якби я мав би зробити серйозне (тобто не-гольф) визначення цієї функції, я, певно, зробив би щось подібне:

(}. - }:) : ($:@[&0)

Монадичний випадок обчислює пряму різницю, тоді як діадичний випадок обчислює x-му різницю вперед.

Ще простіше, але не зовсім рівно:

+/\inv

+/\дає вектор суми префіксів аргументу. inv(визначається як ^:_1) - це сполучник, який перевертає дієслово. Це працює там, де J знає, як перевернути дієслово, а для випадку +/\J - це вміє.


3
Це показує силу прислівників та сполучників, як -єдине дієслово в цій функції.
randomra

14

Пітон, 61 59 байт

f=lambda n,L:n and f(n-1,[x-y for x,y in zip(L[1:],L)])or L

Тут ми виконуємо віднімання, переносячи всі, крім останнього списку, всі, крім першої у списку. zip(L[1:],L)еквівалентний zip(L[1:],L[:-1]), завдяки zipприроді прийняття мінімальної довжини двох списків:

>>> zip([1,2,3],[4,5])
[(1, 4), (2, 5)]

Альтернатива, яка настільки ж тривала (лише для Python 2):

f=lambda n,L:n and f(n-1,map(int.__sub__,L[1:],L[:-1]))or L

На жаль, Python 2 не відрізає кінця списку, тому я не можу цього зробити map(int.__sub__,L,L[1:]). Прикро, Python 3 робить , але mapбільше не повертає список, і це в кінцевому підсумку стає більше байтом (60 байт):

f=lambda n,L:n and f(n-1,list(map(int.__sub__,L[1:],L)))or L

Однак, якщо дозволити вхід бути глибиною, за якою слід список f(3, 2, 5, 6, 7, 5, 10, 25)(наприклад, глибина 3 та список [2, 5, 6, 7, 5, 10, 25]), то це 56 байт :

f=lambda n,*T:n and f(n-1,*map(int.__sub__,T[1:],T))or T

Ось ще одна альтернатива, яка дійсно би роздратувала тих, хто бачив це у виробничому коді (цей знищує оригінальний список):

f=lambda n,L:n and f(n-1,[L[1]-L.pop(0)for _ in L[1:]])or L

Ваш останній код невірний. L[1]-L.pop(0)Натомість вам знадобиться .
mbomb007

@ mbomb007 Дякую за улов. Це було незручно - я весь час аргументував неправильно.
Sp3000

Це було близько, але щось, як і на кожній іншій глибині, знаки переверталися.
mbomb007

9

Mathematica 23 57 23 байт

Пропозиція Мартіна Бюттнера, що використовує класифікацію віднімання.

 Rest@#-Most@#&~Nest~##&

напр

Rest@# - Most@# &~Nest~## & @@ {{10, 18, -12, 4, 8, -3, -5, 67, 9, 14}, 4}

{-142, 55, 27, 41, -269, 397}


Rest@#-Most@# здійснює віднімання, що дає різниці.

Nest виконує вказану операцію вказану кількість разів, оперуючи завжди в останньому списку.


7

Haskell, 40 34 байт

n#l=iterate(zipWith(-)=<<tail)l!!n

Приклад використання: 4 # [10,18,-12,4,8,-3,-5,67,9,14]які виходи [-142,55,27,41,-269,397].

Як це працює: кілька разів обчислюйте різницю між сусідніми елементами і зберігайте проміжні результати у списку. Візьміть цей nелемент із цього списку.

Редагувати: @Zgarb знайшов 6 байт для збереження. Дивовижно!


Ви можете використовувати функцію монаду і скоротити лямбду до (zipWith(-)=<<tail).
Згарб

7

JavaScript (ES6), 52 49 байт

Проста рекурсивна функція, що використовує mapдля сканування масиву та sliceскидання першого елемента на кожен рекурсивний виклик.

Редагуйте 3 байти, збережені, дякую @DocMax, дуже розумна пропозиція

F=(n,l)=>n?F(n-1,l.slice(1).map((a,k)=>a-l[k])):l

Тест у консолі Firefox / FireBug

for(i=0;i<10;i++)console.log(F(i,[10, 18, -12, 4, 8, -3, -5, 67, 9, 14]))

[10, 18, -12, 4, 8, -3, -5, 67, 9, 14]
[8, -30, 16, 4, -11, -2, 72, -58, 5]
[-38 , 46, -12, -15, 9, 74, -130, 63]
[84, -58, -3, 24, 65, -204, 193]
[-142, 55, 27, 41, -269, 397 ]
[197, -28, 14, -310, 666]
[-225, 42, -324, 976]
[267, -366, 1300]
[-633, 1666]
[2299]


1
Шматочок перед тим карті , щоб ефективно уникнути необхідності pі зберегти 3 символів: H=(n,l)=>n?H(n-1,l.slice(1).map((a,k)=>a-l[k])):l.
DocMax

6

CJam, 15 байт

l~{{_@-\}*;]}*p

Приймає дані як масив у стилі CJam, а потім глибину:

[10 18 -12 4 8 -3 -5 67 9 14] 4

і друкує результат у вигляді масиву у стилі CJam.

Перевірте це тут.

Пояснення

l~              "Read and eval input.";
  {         }*  "Repeat this block N times, which computes the forward differences.";
   {    }*      "Fold this block onto the list - this is quite an abuse of folding semantics.";
    _           "Duplicate the current element (for the use in the next difference).";
     @          "Pull up the other copy of the last element.";
      -         "Subtract.";
       \        "Swap the difference and the other copy of the current element.";
          ;     "Discard the last element.";
           ]    "Wrap everything in an array again.";

5

Java, 122 119 байт

int[]a(int[]a,int b){if(b<1)return a;int e=a.length-1,c[]=new int[e],i=e;for(;i-->0;)c[i]=a[i+1]-a[i];return a(c,b-1);}

Приклад використання: http://ideone.com/ALgYez

3 байти завдяки Geobits: v)>


Вам слід позбутися другого int і просто призначити i=eз іншими.
Геобіт

5

> <> 53 50 байт

l:[2-&\~~]r1-:?!vr
&}-@:$/!?&:-1
:;!? &&  lo*84n~<       

Використання: Спершу попередньо заселіть стек (-v в інтерпретаторі пітона), а потім цілі числа.

Наприклад:

forward.fish -v 3 2 5 6 7 5 10 25

Повертається

2 -3 10 3

Дякуємо Sp3000 за допомогу.


1
Чи можливо використовувати ?!та переміщувати деякі компоненти навколо, а не 0=??
Sp3000

Приємний улов! Це допомагає купу
цир

5

Прелюдія , 95 92 79 78 байт

?    (1-vv- # ) v  !
  ?     #   ^   #
?(1-)   1  (#)  1)(#)
  1   #(# ) 1  (#

Формат вводу є

N
M
n_1
n_2
...
n_M

де Nглибина різниць і Mкількість цілих чисел у вхідних даних. Додавання Mбуло необхідним, оскільки Prelude не може відрізнити a 0від кінця введення. Вихід також є новим рядком списку цілих чисел. Мені довелося припустити трохи відрегульовану специфікацію Prelude, яку ми розробили для цього виклику , оскільки стандартний Prelude читає цілі числа як значення байтів, що унеможливлює введення негативних чисел. По суті, це інтерпретатор Python з додатковим NUMERIC_INPUTпрапором.

Для довідки лише 48 38 37 символів, що не містять пробілів, - все інше потрібно було просто для вирівнювання коду.

Пояснення

У прелюдії кожен рядок - це окремий "голос", який працює на власному стеку. Програма виконується колонка за стовпцем, де окремі голоси приймаються для роботи «паралельно». Усі команди - це поодинокі символи, а дужки - це петлі, схожі на Brainfuck (які вводяться та повторюються, коли верхня частина стека не дорівнює нулю). Зауважте, що вертикальне положення дужок, що закриваються, не має значення - розміщення його в іншому голосі все ще вважається збігом із останніми дужками, що відкриваються, а стек, який перевіряється на стан циклу, завжди є голосом, де він (з’явився. Тепер до цієї програми ...

В основному програму можна розділити на дві частини. Дві нижні рядки використовуються лише для більшості циклів програми (за винятком основного циклу N), пропускаючи 1s вперед і назад. Два верхніх рядки містять основний цикл і фактичне розходження. У наведеному нижче примітці перенесений код, тому я можу коментувати окремі стовпці:

? ?   # Read two integers. Read instructions are processed top to bottom, so the first voice 
      # reads N and the third voice reads M.
  (   # Start a loop on the third voice. This loop will execute M times, reading the input list
      # and pushing M 1s onto the fourth voice - i.e. a unary representation of M.
 ?11  # Read an integer onto the second voice, push 1s onto the third and fourth voice.
  -   # Subtract the 1 from the third voice, decrementing M down to 0.
  )   # End of loop, if the third voice is not 0 yet, to back two columns.
(     # Start a loop on the first voice. This is the main loop and will execute N times. Each
      # iteration will compute the forward differences once and thereby shorten the list by one
      # element and also reduce the stack of 1s on the bottom voice by one.
1  #  # Push a 1 onto the first voice and pop a 1 from the last. Together with the next column,
      # this decrements both N and (the unary) M.
-  (  # Subtract the 1 from the first voice (decrementing N), and start a loop on the fourth 
      # voice over whatever is left of M (the length of the resulting difference list). Note 
      # that this column is *not* part of the loop, so the - on the first voice will only be 
      # executed once. This loop builds the differences in reverse order on the first voice.
v#1#  # Pop a 1 from the fourth voice and push a 1 onto the third. This loops over M while
      # shifting its unary representation to the other stack. In addition, shift the top stack
      # element from the second to the first voice.
v     # Copy the next element from the second voice to the first, without popping.
-  )  # Subtract the two elements on the first voice and end the loop if the fourth voice is 
      # empty. Note that his column *is* part of the loop.
  (   # Start a loop on the third voice. This is another loop over M, shifting the stack of 1s 
      # back to the fourth voice, and reversing the differences by shifting them onto the 
      # second.
#^#1  # As stated above, shift an element from the first to the second voice, a 1 from the
      # third to the fourth.
  )   # End the loop. After this point, we're back to the original situation, except that the
      # second voice has been replaced by its differences. The bottom stack element the
      # previous list is also still on that stack, but the decreasing loop lengths on the third
      # and fourth voices ensures that this element is never touched again.
)     # End the main loop when N has been reduced to 0.
   (  # Start another loop over the remaining list length, shifting and reversing the result.
v#1#  # Shift a 1 back to the third voice and an element from the second to the first voice.
  )   # End the loop. Note that this parenthesis is not on the same voice as the corresponding
      # opening parenthesis, but its exact position is irrelevant. Moving it to this voice
      # saves a byte.
  (   # Start one last loop over the length of the result.
! #   # Pop a 1 from the third voice while printing (and popping) one element of the result.
  )   # End the loop.

5

Пітон, 70 68 67 59 байт

f=lambda x,n:n and f([x[1]-x.pop(0)for i in x[1:]],n-1)or x

Не гольф-версія до того, як я став рекурсивним:

def f(x,n):
    for j in range(n):
        for i in range(len(x)-1):
            x[i]=x[i+1]-x[i]
    return x[:-n]

5

R, 48 39 46 44 байт

Рекурсія!

function(x,y)if(x)Recall(x-1,diff(y)) else y
  • x- кількість ітерацій, які слід виконати, і yє вектором цілих чисел.
  • if(x)вірно до тих пір, поки x>0.
  • Recall викликає поточну функцію, але з новими аргументами.
  • Diff виводить відмінності між послідовними елементами списку / вектора.

Попередні версії:

#does not work for x=0:
function(x,y){for(i in 1:x)y=diff(y);y}

#does not use diff function:
function(x,y){for(i in 1:x)y=y[-1]-head(y,-1);y}

y[-1]       is a list minus its first element
head(y,-1)  is a list minus its last element

Чи є кращий спосіб повторити функцію diff x разів? Використовуючи цикл for, відчувається надмірним.
freekvd

Існує скорочення, але це би коштувало більше символів.
MickyT

Є одна невелика проблема. При
дзвінку

Пішов на інший підхід, вирішити проблему, але довелося додати 7 знаків.
freekvd

2
Гарне використання Recall().
Алекс А.

3

Пітон, 92 87 86 байт

def a(b,c):
 if c<1:return b
 d=[];e=b[0]
 for f in b[1:]:d+=f-e,;e=f
 return a(d,c-1)

Це мій перший гольф Python. Будь-які пропозиції будуть вдячні :)

5 6 байт завдяки Sp3000: D


Я рекомендую зрозуміти список.
mbomb007

Ви можете перетворити appendна d+=f-e,. Взагалі для коду-гольфу вам ніколи не потрібно використовувати L.appendчерез це.
Sp3000

3

c, 68 55 байт

f(int *l){for(--l[-1]?f(l):0;*l;l++)*l=l[1]-*l;*--l=0;}

Це може зайняти трохи свобод із специфікацією введення. Масив int побудований таким чином, що елемент 0 - це глибина, а елементи 1 до (n + 1) - елементи вхідного списку від 0 до n. Потім адреса елемента 1 передається функції.

Масив повинен бути нульовим завершеним. Масив відредагований на місці.

Наприклад:

#include <stdio.h>

f(int *l){for(--l[-1]?f(l):0;*l;l++)*l=l[1]-*l;*--l=0;}

int main (int argc, char **argv)
{
  int list[] = {4, 10, 18, -12, 4, 8, -3, -5, 67, 9, 14, 0};
  int *elem;

  f(list + 1);

  for (elem = list + 1; *elem; elem++) {
    printf("%d, ", *elem);
  }
}

http://ideone.com/m5PDgF


Чому ви залишили місце в int *l?
Джонатан Фрех

2

Потужність 115 111 байт

$p={param($a, $b)0..($a-1)|%{$b=@($l=$b.length;for($i=0;$i-lt$l;$i++){$b[$i+1]-$b[$i]})[0..($l-2)]};$b-join','}

Виконайте як таке:

.$p 4 @(10,18,-12,4,8,-3,-5,67,9,14)

Вихід:

-142,55,27,41,-269,397

Переміщення фігурної дужки на інше місце дозволяє це відображати кожен крок до відповіді.

8,-30,16,4,-11,-2,72,-58,5
-38,46,-12,-15,9,74,-130,63
84,-58,-3,24,65,-204,193
-142,55,27,41,-269,397

2

STATA, 126 байт

di _r(a)_r(b)
token $b
gl $c=wordcount($b)
forv x=1/$a{
gl $c--
forv y=1/$c{
loc `y'=``y'+1'-``y''
}
}
forv z=1/$c{
di ``z''
}

Очікує введення як ціле число, що представляє глибину з подальшим пробілом списком цілих чисел, обидва дані за допомогою стандартного запиту. Вихід - це розділений рядком цілих чисел у новому рядку.

Спочатку він перетворює список цілих чисел (який він вважає 1 довгою рядком) у список локальних змінних, імена яких 1,2,3, ... Потім він обчислює перепади вперед, встановлюючи значення y-ї локальної змінної в таке значення y + 1-ї локальної змінної мінус значення y-ї локальної змінної (тобто 18-10 = 8), яка перезаписує існуючі значення лише після використання. Це робить це $ a (значення глобальної змінної a) разів. Потім воно відображає значення кожної локальної змінної, 1 за один раз.


+1 для пояснення. Це надзвичайно складний спосіб обробки списків.
Згарб

@ Zgarb, я не знаю способу STATA приймати дані як масив / список, за винятком файлу (який би не працював тут через іншого введення). Ось чому воно має працювати так.
позначки

2

T-SQL, занадто багато :)

Коли я вперше побачив цю проблему, я задумався, чи є спосіб це зробити в запиті. Хоча тривіально для більшості мов, це не стільки для SQL запиту.

Вхід переходить у змінні @ (для глибини) та @ L для цілого списку. @L - тип таблиці, визначений користувачем

CREATE TYPE L AS TABLE(n INT IDENTITY(0,1),v INT)

Налаштування вводу

DECLARE @L L,@ INT=4
INSERT @L(v)values(10),(18),(-12),(4),(8),(-3),(-5),(67),(9),(14)

Запит з коментарями

WITH R AS( 
    -- Recursive query to calculate the level of a pascal triangle with alternating negatives
    -- For 4 this is 1 -4  6 -4  1  
    SELECT 1c,0g UNION ALL SELECT-c*(@-g)/(g+1),g+1FROM r WHERE g<@
    ),
    O AS( 
    --Multiple N values of list by reversed pascal triangle values
    --shifting the start for each iteration (list length) - N
    SELECT c*v v,F 
    FROM @L L 
        CROSS APPLY(
            SELECT TOP((SELECT COUNT(*)FROM @L)-@)ROW_NUMBER()OVER(ORDER BY(SELECT\))-1F FROM sys.all_views a,sys.all_views b)c 
        JOIN R ON N=F+@-G
    )
-- Sum the multiplied values
SELECT SUM(V)FROM o GROUP BY F ORDER BY F

Результат

-142
55
27
41
-269
397

2

Japt -h , 17 5 байт

12 байт збережено завдяки @Shaggy

VÆ=än

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



Або інша реалізація дає 12 байт
Shaggy

Ви можете замінити äÏ-Xз änв обох з них , щоб врятувати більше 2 байта.
Кудлатий

Знизили його на 5 байт !
Кудлатий

@Shaggy чорт ти занадто хороший у japt xD Ви повинні опублікувати свою 5-байтну відповідь
Luis felipe De jesus Munoz

0

SmileBASIC, 76 байт

Нарешті привід використовувати ARYOP!

DEF F L,D
IF!D THEN@R
DIM B[0]COPY B,L
T=SHIFT(L)ARYOP 1,L,L,B
F L,D-1@R
END

0

Clojure, 47 байт

#(if(= 0 %)%2(recur(dec %)(map -(rest %2)%2))))

Проста рекурсія на анонімну функцію. Ви зберігаєте 1 байт, якщо порядок аргументів змінюється тим, що %2відбувається частіше, ніж зараз %.



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