Доповнення піраміди вгору ...


22

Доповнення піраміди вгору - це процес складання списку чисел і послідовного їх додавання, поки ви не досягнете одного числа.

При дачі чисел 2, 1, 1відбувається наступний процес:

 2   1   1
   3   2 
     5

На цьому закінчується число 5.


ВАШ ЗАВДАННЯ

З огляду на праву частину перевернутої піраміди (Зростання), напишіть програму або функцію, яка поверне початковий список.

Новий додатковий виклик : спробуйте зробити це менше, ніж O (n ^ 2)

ПРИКЛАД

f([5, 2, 1]) => [2, 1, 1]
f([84,42,21,10,2]) => [4,7,3,8,2]

ПРИМІТКА: Піраміда з нижньої сторони ніколи не буде порожньою і завжди буде складатися ТІЛЬКИ з додатних цілих чисел.


6
Ласкаво просимо до PP&CG! Ця проблема є гідною, хоча її можна вдосконалити. Я рекомендую опублікувати свої виклики в Пісочниці спочатку, щоб покращити публікацію, перш ніж вона буде розміщена на головному.
Тау

13
Вільне розуміння того, що я не можу знайти мову, якою вона коротша:
f([a,b,c,d,e])=[1464101331001210001100001][abcde]
Лінн

4
Просто FYI, це те саме, що і в кодах CodeWars .
ggorlen

6
@ggorlen я знаю. Я той, хто зробив ката :)
Шепіт

8
Try doing this in less than O(n)напевно, неможливо виділити масив n розмірів або змінити в ньому елементи O (n) швидше, ніж складність O (n)?
мій займенник monicareinstate

Відповіді:


17

JavaScript (ES6),  62 58 49  46 байт

Збережено 3 байти завдяки @Oliver

Повертає список у вигляді рядка, розділеного комою.

f=a=>+a||f(a.map(n=>a-(a=n),a=a.shift()))+[,a]

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

Прокоментував

f = a =>              // f = recursive function taking the input list a[]
  +a                  // if a[] consists of a single positive integer:
                      //   stop recursion and return this integer
  ||                  // else:
    f(                //   do a recursive call to f:
      a.map(n =>      //     for each value n in a[]:
        a - (a = n),  //       yield the difference between the previous value and n
                      //       and update a to n
        a = a.shift() //       start by removing the first element and saving it in a
                      //       (because of the recursion, it's important here to reuse
                      //       a variable which is defined in the scope of f)
      )               //     end of map()
    )                 //   end of recursive call
    + [, a]           //   append the last entry from a[]

@Oliver, так
Shaggy



6

TI-BASIC, 54 байти

Ans→L₁:dim(L₁→dim(L₂:While 1-Ans:L₁(Ans→L₂(Ans:-ΔList(L₁→L₁:dim(Ans:End:L₁(Ans→L₂(Ans:L₂

Введення - це список правої сторони трикутника в Ans, як це описано в виклику.
Вихід - це верхній ряд згаданого трикутника.

Приклади:

{5,2,1
         {5 2 1}
prgmCDGF19
         {2 1 1}
{84,42,21,10,2
 {84 42 21 10 2}
prgmCDGF19
     {4 7 3 8 2}

Пояснення:
Це рішення зловживає тим, що трикутник, утворений за допомогою правої сторони трикутника, як початок закінчується зміною кожного елемента.

Іншими словами,

2 1 1
 3 2
  5

стає:

5 2 1
 3 1
  2

Таким чином, отриманий список є правою стороною цього нового трикутника, який можна сформувати, встановивши останній елемент на індекс довжини його батьківського списку в отриманому списку.

Ans→L₁          ;store the input list in L₁
dim(L₁→dim(L₂   ;set the length of L₂ to the length of L₁
While 1-Ans     ;while the L₁'s length is not 1
L₁(Ans→L₂(Ans   ;set the last element of L₁ to the corresponding index in L₂
-ΔList(L₁→L₁    ;get the change in each element, then negate
                ; (elements are in descending order so the change in each
                ;  element will be negative)
                ; and store the resulting list in L₁
dim(Ans         ;leave the length of L₁ in "Ans"
End
L₁(Ans→L₂(Ans   ;set the element again
                ; (needed for final step)
L₂              ;leave L₂ in "Ans"
                ;implicit print of "Ans"

Примітка: TI-BASIC - це токенізована мова. Кількість символів не дорівнює кількості байтів.


4

Желе , 6 байт

ṚIƬZḢṚ

Монадична посилання, що приймає список цілих чисел, що дає список цілих чисел.

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

Як?

Побудує весь трикутник, потім витягує потрібні елементи.

ṚIƬZḢṚ - Link: list of integers          e.g.  [84,42,21,10,2]
Ṛ      - reverse                               [2,10,21,42,84]
  Ƭ    - collect & apply until a fixed point:
 I     -   incremental differences            [[2,10,21,42,84],[8,11,21,42],[3,10,21],[7,11],[4],[]]
   Z   - transpose                            [[2,8,3,7,4],[10,11,10,11],[21,21,21],[42,42],[84]]
    Ḣ  - head                                  [2,8,3,7,4]
     Ṛ - reverse                               [4,7,3,8,2]

Мав майже однакове рішення, але Uзамість s замість !
Нік Кеннеді

IƬUZḢAпрацювали б і з даним питанням; Цікаво, чи є десь збережений байт ...
Джонатан Аллан

ạƝƬZṪ€працює теж, але знову шість.
Нік Кеннеді

Так, я помітив цей варіант; Я зараз менш сподіваюся.
Джонатан Аллан

Я щойно опублікував 5-байтний, але це трохи інакше, ніж ваш підхід щодо частини після побудови піраміди.
Ерік Аутгольфер

4

MathGolf , 14 11 байт

xÆ‼├│?;∟;]x

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

Пояснення

x             reverse int/array/string
 Æ     ∟      do while true without popping using 5 operators
  ‼           apply next 2 operators to TOS
   ├          pop from left of list
    │         get differences of list
     ?        rot3
      ;       discard TOS (removes rest from ├ command)
              loop ends here
        ;     discard TOS (removes empty array from stack)
         ]    wrap stack in array
          x   reverse array



3

Pari/GP, 36 bytes

Based on @Lynn's comment:

Free insight that I can't find a language it's shorter in:

f([a,b,c,d,e])=[1464101331001210001100001][abcde]

Pari/GP has a built-in for the Pascal matrix, and its inverse is exactly the matrix we need:

[1000011000121001331014641]1=[1000011000121001331014641]

a->r=Vecrev;r(r(a)/matpascal(#a-1)~)

Try it online!


3

R, 69 67 bytes

function(n,x=sum(n|1):1-1,`[`=outer)(x[x,choose]*(-1)^x[x,"+"])%*%n

Try it online!

Returns a column vector.

-2 bytes thanks to Kirill L.

Also based on Lynn's comment:

Free insight that I can't find a language it's shorter in:

f([a,b,c,d,e])=[1464101331001210001100001][abcde]

It's longer than the other R answer, but it was an interesting approach to take and try to golf.


2

Javascript (ES6), 127 bytes

f=a=>{for(e=[a],a=[a[l=a.length-1]],i=0;i<l;i++){for(e.push(g=[]),j=-1;j<l;)g.push(e[i][j]-e[i][++j]);r.unshift(g[j])}return r}

Original code

function f(a){
  var e=[a];
  var r=[a[a.length-1]];
  for (var i=1;i<a.length;i++){
    var g=[];
    for (var j=0;j<a.length;j++){
      g.push(e[i-1][j-1]-e[i-1][j]);
    }
    e.push(g);
    r.unshift(g[j-1]);
  }
  return r;
}

Oh, I lost like... a lot... to the previous answer...



2

05AB1E, 12 11 bytes

R.¥.Γ¥}¨ζнR

Port of @JonathanAllan's Jelly answer, although I'm jelly about Jelly's more convenient builtins in this case. ;)
-1 byte thanks to @Emigna.

Try it online or verify all test cases.

Explanation:

R            # Reverse the (implicit) input-list
             #  i.e. [16,7,4,3] → [3,4,7,16]
           # Undelta it (with leading 0)
             #  → [0,3,7,14,30]
    }      # Continue until the result no longer changes, and collect all steps:
     ¥       #  Get the deltas / forward differences of the current list
             #  → [[3,4,7,16],[1,3,9],[2,6],[4],[]]
       ¨     # Remove the trailing empty list
             #  → [[3,4,7,16],[1,3,9],[2,6],[4]]
        ζ    # Zip/transpose; swapping rows/column (with space as default filler)
             #  → [[3,1,2,4],[4,3,6," "],[7,9," "," "],[16," "," "," "]]
         н   # Only leave the first inner list
             #  → [3,1,2,4]
          R  # Revert it back
             #  → [4,2,1,3]
             # (after which it's output implicitly as result)

2
You can save a byte with R.¥.Γ¥}¨ by starting from the list whose delta is the input.
Emigna

@Emigna Ah, undelta into a loop with deltas to save a byte on the prepend. :) Thanks!
Kevin Cruijssen


2

Perl 6, 37 bytes

{[R,]($_,{@(.[]Z-.skip)}...1)[*;*-1]}

Try it online!

Repeatedly reduces by elementwise subtraction, and then returns the last number of each list in reverse.

Explanation:

{                                  }  # Anonymous code block
      $_,               ...   # Create a sequence starting from the input
         {             }      # Where each element is
            .[]Z-.skip          # Each element minus the next element
          @(          )         # Arrayified
                           1  # Until the list has one element left
 [R,]                                # Reverse the sequence
     (                     )[*;   ]  # For every list
                               *-1   # Take the last element



1

Charcoal, 19 bytes

Fθ«PI§θ±¹↑UMθ⁻§θ⊖λκ

Try it online! Link is to verbose version of code. Explanation:

Fθ«

Loop once for each term in the original list.

PI§θ±¹↑

Print the last term in the list, but move the cursor to the beginning of the previous line, so that the terms are output in reverse order.

UMθ⁻§θ⊖λκ

Compute the deltas, inserting a dummy value at the beginning so that we can use an operation that doesn't change the length of the list.




1

C, 76 bytes

i=0;int*f(int*a,int n){for(;i<n;a[i++]=a[i]-a[i+1]);if(!n)return a;f(a,n-1);}  

input : (*a = pointer to array, n = last element's index of that array)
output : return int* = output

Explanation
going from right side to up, as the last elements are same in both input and output the loop inside function simply finds next higher numbers in the triangle gradually reaching to the top leaving the answer intact in the end.

ungolfed(from C++)

#include <iostream>
#define SIZE_F 5

int*recFind(int*a, int n) {
    int i = 0;
    while (i < n)
        a[i++] = a[i] - a[i+1];
    if (!n) return a;
        recFind(a, n - 1);
}
int main()
{
    int first[SIZE_F],*n;
    for (int i = 0; i < SIZE_F; i++)
        std::cin >> first[i];

    n = recFind(first, SIZE_F - 1);//size - 1
    for (int i = 0; i < SIZE_F; i++)
        std::cout << n[i];
}

1

Japt, 11 9 bytes

Nc¡=äa
yÌ

Try it

2 bytes saved thanks to Oliver.

12 11 bytes

_äa}hUÊN yÌ

Try it

1 byte saved thanks to Oliver.



@Oliver, not thinking to use y(f) is bad enough, but completely forgetting the newline is unforgivable! Will update shortly. Thanks :)
Shaggy

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