Обратные дельты массива


17

Обратные дельты массива

Ваша задача состоит в том, чтобы, учитывая массив 32-битных целых чисел со знаком, перекомпилировать его с обратными дельтами. Например, список

1  3  4  2  8

содержит дельты:

  2  1 -2  6

которые затем отрицаются, давая:

 -2 -1  2 -6

и перекомпилирован, получая:

1 -1 -2  0 -6

как конечный результат.

Ввод, вывод

Вам будет предоставлен список / массив / таблица / кортеж / стек / и т. Д. целых чисел со знаком в качестве ввода через любой стандартный метод ввода.

Вы должны снова вывести измененные данные в любой приемлемой форме, следуя описанному выше методу дельта-инверсии.

Вы получите N входов, 0 < N < 10где каждое число попадает в диапазон-1000 < X < 1000

Тестовые случаи

5 6 7 8          -> 5 4 3 2
1 3 4 2 8        -> 1 -1 -2 0 -6
32 18 25 192 199 -> 32 46 39 -128 -135

Примечания

  • Вы не ограничены дельта-методом: если вы можете разработать более простой метод (который не должен быть слишком сложным) , вы можете свободно его использовать.
  • Как указано выше, вы всегда будете получать по крайней мере 1 вход, и не более 9.
  • Первый номер вывода всегда должен быть первым номером ввода, если это не так, ваш метод неверен.
  • Только стандартные входные данные принимаются
  • Применяются стандартные лазейки
  • Это , поэтому побеждает самый низкий счетчик байтов!
  • Веселиться!

У нас есть победитель.

Dennis «s Jelly Ответ на крошечном 3 Bytes взял домой золото, из - за того , что я нахожусь под впечатлением , он не может быть избит.

Я был слегка разочарован, что не смог увидеть ответ, основанный на оригинальной спецификации, однако позже я могу назначить награду именно за это.


1
Я не понимаю шаг перекомпиляции? Как вы получите от -2, -1, 2, -6 до 1, -1, -2, 0, -6 ??
Fogmeister

@Fogmeister вы начинаете с того же начального значения, а затем применяете эти различия вместо исходных.
Мартин Эндер

Стандартный ввод-вывод - я не слышал, чтобы он использовался в задании раньше, но я делаю вывод, что это НЕ означает stdin / stdout, так как в противном случае все ответы здесь кажутся неправильными. Я полагаю, это означает, что вы не можете принимать входные данные в виде церковных цифр или чего-то еще? В любом случае, если это то, что это означает, это, вероятно, должно называться как-то иначе, поскольку стандартный вывод / ввод также имеет другое значение.
Харальд Корнелиуссен

@MartinEnder 1 + 0 = 1, 3-2 = -1 ?, 4-1 = -2 ?? Я так и думал, но эти цифры не складываются. Ой! Ничего. Я только что видел его. Вы создаете новый массив, начиная с исходного значения, но с новыми отличиями. Таким образом, 1 с разницей -2 переходит в -1, затем с разницей -1 это переходит в -2 и так далее.
Fogmeister

1
@HaraldKorneliussen Это, вероятно, относится к этому (и это, вероятно, все предполагают)
Мартин Эндер

Ответы:


26

Желе , 7 3 байта

ḤḢ_

Попробуйте онлайн!

Фон

Дельты (a, b, c, d) - это b - a , c - b и d - c . Кумулятивное уменьшение (a, b - a, c - b, d - c) путем вычитания g дает a - (b - a) = 2a - b , 2a - b - (c - b) = 2a - c и 2a - c - (d - c) = 2a - d , поэтому правильный результат - (2a - a, 2a - b, 2a - c, 2a - d) .

Как это устроено

ḤḢ_  Main link. Argument: A (array)

Ḥ    Unhalve; multiply all integers in A by 2.
 Ḣ   Head; extract first element of 2A.
  _  Subtract the elements of A from the result.

1
Ну, собери это. Здесь ничего не поделаешь, кроме как уползти в поражении.
Стивен Х.

3
Деннис просто ждет, когда я напишу вопрос, и подстригает меня этими крошечными ответами. У меня нет жалоб.
ATaco

10

Python 2, 30 байт

lambda x:[x[0]*2-n for n in x]

Проверьте это на Ideone .

Как это устроено

Дельты (a, b, c, d) - это b - a , c - b и d - c . Кумулятивное уменьшение (a, b - a, c - b, d - c) путем вычитания g дает a - (b - a) = 2a - b , 2a - b - (c - b) = 2a - c и 2a - c - (d - c) = 2a - d , поэтому правильный результат - (2a - a, 2a - b, 2a - c, 2a - d) .


7

Mathematica, 8 байт

2#-{##}&

Безымянная функция принимает неопределенное количество аргументов. Это использует «легкий» способ: сводит на нет весь список и добавляет в два раза (оригинальный) первый элемент.

Вызывается, например, как 2#-{##}&[1,3,4,2,8]; возвращает список вроде {1,-1,-2,0,-6}.


Действительно, спасибо - просто опечатка.
Грег Мартин



2

Python, 44 байта

lambda l:[l[0]]+[x-(x-l[0])*2for x in l[1:]]

Это использует «более простой метод».





2

Perl 6 ,  40  16 байтов

{[\+] .[0],|.rotor(2=>-1).map({[-] @_})}
{.map(.[0]*2-*)}

Expanded:

{ # bare block lambda with single implicit parameter 「$_」 ( input is a List )

  [\[+]]  # triangle reduce the following using 「&infix:<+>」

    .[0], # the first value

    |(    # Slip this list into outer one ( Perl 6 doesn't auto flatten )

      .rotor( 2 => -1 ) # take the input 2 at a time, backing up 1
      .map({ [-] @_ })  # reduce the pairs using 「&infix:<->」

    )
}
{ # bare block lambda with single implicit parameter 「$_」 ( input is a List )

  .map(          # map over the inputs
    .[0] * 2 - * # take the first value multiply by 2 and subtract the current value
    #          ^- this makes the statement a WhateverCode, and is the input
  )
}

2

Brain-Flak , 76 байт

([][()]){{}(({})<(({}){}[{}]<>)<>>)([][()])}{}({}<<>([]){{}({}<>)<>([])}<>>)

Попробуйте онлайн!

Объяснение:

Part 1:
(      )                                        # Push:
 []                                             # the height of the stack
   [()]                                         # minus 1
        {                                  }    # While the height - 1 != 0:
         {}                                     # Pop the height
           (({})<                               # Hold onto the top value, but put it back.
                                                # This ensures that the top value is always
                                                # what was the first element of input
                 (            )                 # Push:
                  ({}){}                        # Top * 2
                        [{}]                    # minus the next element
                            <> <>               # onto the other stack

                                 >)             # Put back the element we held onto.
                                   (      )     # Push:
                                    []          # The height of the stack
                                      [()]      # Minus 1  
                                            {}  # Pop the counter used for the height
Part 2:
({}<                                            # Hold onto the top element.
                                                # This was the first number for input
                                                # so it needs to end up on top
    <>                                          # Switch stacks
      ([])                                      # Push the height of the stack
          {              }                      # While the height != 0:
           {}                                   # Pop the height
             (    )                             # Push:
              {}                                # The top element of this stack
                <>                              # onto the other stack
                   <>                           # and switch back
                     ([])                       # Push the new height of the stack
                          <>                    # After every element has switched stacks
                                                # (which reverses their order),
                                                # switch stacks
                            >)                  # Push the first element back on

2

Haskell, 20 19 байтов

f(x:r)=x:map(2*x-)r

То же решение, что и у Денниса, спасибо за идею 2a - x.

Спасен один байт благодаря Кристиану Северсу.


сохранить один байт:f(x:r)=x:map(2*x-)r
Кристиан Сиверс

Спасибо, я пробовал несколько разных подходов с @ и без, но не думал просто поставить xвперед.
Renzeee


1

PHP, 48 байт

for(;''<$c=$argv[++$i];)echo-$c+2*$a=$a??$c,' ';

Используя технику от Дениса. Используйте как:

php -r "for(;''<$c=$argv[++$i];)echo-$c+2*$a=$a??$c,' ';" 1 3 4 2 8

Не байтовая версия Dennis 55:

for(;''<$c=$argv[++$i];$l=$c)echo$a+=($l??$c*2)-$c,' ';

Сохраните один байт с помощью a&вместо ''<и два байта с помощью _вместо ' '.
Титус

1

APL, 8 байт

+\⊃,2-/+

Объяснение:

+\           ⍝ running sum of
  ⊃          ⍝ first item of list
   ,         ⍝ followed by
    2-/      ⍝ differences between every pair in
       +     ⍝ input list

Тестовые случаи:

      ( +\⊃,2-/+ ) ¨ (5 6 7 8) (1 3 4 2 8) (32 18 25 192 199)
┌───────┬────────────┬──────────────────┐
│5 4 3 2│1 ¯1 ¯2 0 ¯6│32 46 39 ¯128 ¯135│
└───────┴────────────┴──────────────────┘

1

Лабиринт , 34 байта

?:_2*}
@    _
)\?_1"
,    ;
!`-}:{

Попробуйте онлайн!

Использует @Dennis «ы (2a - a, 2a - b, 2a - c, 2a - d)подход.

введите описание изображения здесь

Желтые плитки для контроля потока. На этом двумерном языке программирования программа начинается с самого верхнего левого тайла, чтобы начать движение на восток. На перекрестках направление определяется знаком вершины основного стека. Пустые плитки - это стены.

зеленый

Этот раздел сохраняет 2a во вспомогательный стек.

  • ? Получить первое число и подтолкнуть его к вершине основного стека
  • : Дублируйте вершину стека
  • _2 Нажмите два к вершине стека
  • *Поп y, поп x, толчокx*y
  • } Переместите верхнюю часть основного стека в верхнюю часть вспомогательного стека.
  • _ Нажмите ноль на вершину стека

апельсин

Этот раздел вычитает 2a из текущего числа, отменяет результат, выводит результат, получает следующий символ (разделитель), завершается, если EOF, выводит новую строку, получает следующее число.

  • "Нооп. Если он идет с севера, вершина стека будет равна нулю, и программа продолжится на юг. Если он идет с запада, вершина стека будет одна, и программа повернет направо (продолжая юг)
  • ;Откажитесь от вершины стека. Поскольку ноль или единица используются только для потока управления, нам нужно отбросить эти
  • { Переместите верхнюю часть вспомогательной стопки (2a) на верхнюю часть основной стопки.
  • : Дублируйте верхнюю часть основного стека
  • } Переместить верхнюю часть основного стека в верхнюю часть вспомогательного стека
  • -Поп y, поп x, толчокx-y
  • \`` Negate the top of the stack. This and the previous three operations have the effect of- (х-2а) = 2а-х`
  • ! Вставьте вершину стека и выведите его в виде числа
  • , Нажмите следующий символ (который будет разделителем) или отрицательный, если EOF
  • )Увеличьте вершину стека. Если последним символом является EOF, то вершина стека теперь будет равна нулю, и программа продолжит прямиком до @и завершится . Если последний символ был разделителем, то вершина стека будет положительной, что приведет к повороту программы вправо и продолжению на восток до\
  • \ Вывести новую строку
  • ? Получить следующий номер
  • _1 Нажмите один на вершину стека, чтобы повернуть направо на перекрестке

Да, это напоминает мне, что я также решил эту проблему, но совершенно забыл опубликовать решения. У меня есть три различных решения по 24 байта (и я почти уверен, что они не оптимальны), поэтому я думаю, что я дам вам пару дней или около того, чтобы соответствовать или побить это, прежде чем отправлять свои. Хорошая работа, все же! :)
Мартин Эндер

@ MartinEnder, не надо меня ждать. Я сомневаюсь, что смогу найти лучшее решение в ближайшее время. Я все еще привыкаю к ​​решению проблем на основе стека. Мне просто нравится изучать новый способ думать о программировании.
Роберт Хикман

1

Лабиринт , 24 байта

+:}:?
}
<}}?;%):,\!-{:{>

Формат ввода и вывода - это отдельные списки перевода строки (хотя формат ввода на самом деле гораздо более гибкий). Программа завершается с ошибкой.

Попробуйте онлайн!

У меня есть два других решения с таким количеством байтов, которые работают в основном одинаково, но используют несколько иной поток управления.

:+:}:?
{
,}-!
?  {
:";\@
{:+:}:?
_
<>__-?:;%):,\!

объяснение

Указатель инструкций (IP) начинает двигаться на восток вдоль первой строки, но все команды перед ним в ?основном не выполняют никаких операций в глобальном состоянии, поскольку мы нигде не используем команды глубины стека. Таким образом, код действительно начинается на ?западе, так как IP поворачивается, когда попадает в тупик.

Поэтому код начинается со следующего линейного бита кода:

?:}:+}

Это просто устанавливает нас с копией 2aиспользовать [2a - a, 2a - b, 2a - c, ...]формулу.

?   Read first integer a.
:}  Move a copy off to the auxiliary stack.
:+  Multiply a by 2 (by adding it to itself).
}   Move that off to the auxiliary stack as well.

Теперь мы входим в основной цикл программы, используя довольно стандартный прием для обхода одной строки кода:

<...>

Обратите внимание, что стек будет пустым всякий раз, когда мы попадем в него, <поэтому мы знаем, что там мы получим нули. <Затем вращается вся линия слева, принимая IP с ним, так что мы получаем это:

...><

Затем IP должен переместиться влево, где линия >сдвигается обратно в исходное место (чтобы подготовить ее к следующей итерации). Затем строка просто выполняется справа налево, поэтому итерация одного цикла выглядит так:

{:{-!\,:)%;?}}

Подвох при работе с циклом этого типа заключается в том, что вы не можете работать ни с какой формой условного выполнения, поскольку в Лабиринте нет способа пропустить код. Поэтому мы завершим программу делением на ноль, когда нажмем EOF. Вот разбивка каждой итерации цикла.

{:   Pull 2a back to the main stack and make a copy.
{    Pull the latest value i of the input list back to main as well.
-    Compute 2a-i/
!\   Print it with a trailing linefeed.
,    Read a character. If there are input elements left, this will be some
     form of separator character, and therefore a positive value x. However,
     at the end of the program, this will give -1.
:)   Make an incremented copy.
%    Try to to compute x%(x+1). This will error out at EOF.
;    Discard the result of the division.
?    Read the next input value.
}}   Move that and the remaining copy of 2a back to the auxiliary stack.

Эти решения великолепны. Здорово изучить их и узнать о мышлении в Лабиринте.
Роберт Хикман

0

C ++ 14, 36 байт

Как безымянная лямбда изменяет свой ввод:

[](auto&c){for(auto&x:c)x=2*c[0]-x;}

Используя технику от Дениса. Работает для любого контейнера, как int[]или vector<int>.

Использование:

#include<iostream>

auto f=
[](auto&c){for(auto&x:c)x=2*c[0]-x;}
;

int main(){
  int a[] = {1,  3,  4,  2,  8};
  f(a);
  for(auto&x:a)
    std::cout << x << ", ";
  std::cout<<"\n";
}

0

CJam, 16 байтов

Формат ввода: [1 2 3 4]. Использует простую формулу.

l~_(2*/;a/,@@*.-

Объяснение:

l~_(2*/;a/,@@*.-
l~_                     e#Read input twice into an array. Stack: [1 2 3 4] [1 2 3 4]
   (                    e#Get first element of the array. Stack: [1 2 3 4] [2 3 4] 1
    2*                  e#Multiply by two. Stack: [1 2 3 4] [2 3 4] 2
      /;                e#Discard second element. Stack: [1 2 3 4] 2
        a               e#Wrap into an array. Stack: [1 2 3 4] [2]
         /,             e#Rotate and get length. Stack: [2] [1 2 3 4] 4
           @@           e#Rotate twice. Stack: [1 2 3 4] 4 [2]
            *           e#Repeat len times. Stack: [1 2 3 4] [2 2 2 2]
             .-         e#Vectorized substraction. Stack: [-1 0 1 2]
                        e#Implictly print

Извините за отсутствие тестовой ссылки. Я полагаю, что SE не нравятся ссылки внутри скобок.


Есть также cjam.tryitonline.net , который base64 кодирует все поля. Оба переводчика дают мне ошибку, хотя.
Деннис

0

Напористый , 9 байт

{&}2*K~-_

Задайте аргументы в виде значений, разделенных запятыми, в строке cmd: $ pushy invdeltas.pshy 1,3,4,2,8 . Вот разбивка с примером стека:

           % Implicit: Input on stack              [1, 3, 4, 2, 8]
{&}        % Copy first item, put at end of stack  [1, 3, 4, 2, 8, 1]
   2*      % Multiply by 2                         [1, 3, 4, 2, 8, 2]
     K~    % Negate everything on stack            [-1, -3, -4, -2, -8, -2]
       -   % Subtract last item from all           [1, -1, -2, 0, -6]
        _  % Print whole stack

Примечание: это может быть 8 байтов, если разрешен обратный вывод: @&2*K~-_


0

Perl, 26 + 3 ( -plaфлаг) = 29 байт

$_="@{[map$F[0]*2-$_,@F]}"

или

$_=join$",map$F[0]*2-$_,@F

С помощью:

perl -plae '$_="@{[map$F[0]*2-$_,@F]}"' <<< "32 18 25 192 199"

0

Дьялог АПЛ , 5 байт

-+2×⊃

это 5 поездов, он разбирается как два вложенных 3 поезда ("вилки"): -+(2×⊃)

читается как: отрицание ( -) всего массива плюс ( +) дважды ( ) первый элемент ( )


0

ised, 11 байт

2*$1_0-$1

Призвание: ised --l 'file with input.txt' '2*$1_0-$1

(редактировать: исправлено путем кражи алгебры у Денниса)


0

Чудо , 17 байт

@->#@- *2:0#1#0#0

Не уверен, почему я не опубликовал это раньше. Использование:

(@->#@- *2:0#1#0#0)[5 6 7 8]

Более читабельно:

@(map @
  - (
    * 2 get 0 #1
  ) #0
) #0
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.