Upside-Down Pyramid Addition… UMGEKEHRT!


22

Upside-Down Pyramid Addition ist der Vorgang, bei dem eine Liste von Zahlen erstellt und nacheinander addiert wird, bis eine Zahl erreicht ist.

Wenn die Zahlen angegeben 2, 1, 1werden, geschieht Folgendes:

 2   1   1
   3   2 
     5

Dies endet in der Nummer 5.


DEINE AUFGABE

Schreiben Sie auf der rechten Seite einer auf dem Kopf stehenden Pyramide (aufsteigend) ein Programm oder eine Funktion, die die ursprüngliche Liste zurückgibt.

Neue Extra-Herausforderung : Versuchen Sie dies in weniger als O (n ^ 2)

BEISPIEL

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

HINWEIS: Die umgedrehte Pyramide ist niemals leer und besteht NUR aus positiven ganzen Zahlen.


6
Willkommen bei PP & CG! Diese Herausforderung ist anständig, könnte aber verbessert werden. Ich würde empfehlen, Ihre Herausforderungen zuerst in der Sandbox zu veröffentlichen, um den Beitrag zu verbessern, bevor er auf den Haupt-Post gesetzt wird.
Tau

13
Freie Einsicht, dass ich keine Sprache finde, in der sie kürzer ist:
f([ein,b,c,d,e])=[1-46-4101-33-1001-210001-100001][einbcde]
Lynn

4
Nur zu Ihrer Information , dies ist dasselbe wie die CodeWars-Kata .
Ggorlen

6
@ ggorlen ich weiß. Ich bin derjenige, der die Kata gemacht hat :)
Whimpers

8
Try doing this in less than O(n)Sicherlich ist es unmöglich, ein Array der Größe n zuzuweisen oder O (n) Elemente darin schneller als O (n) Komplexität zu ändern.
Mein Pronomen ist monicareinstate

Antworten:


17

JavaScript (ES6),  62 58 49  46 Bytes

3 Bytes gespart dank @Oliver

Gibt die Liste als durch Kommas getrennte Zeichenfolge zurück.

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

Probieren Sie es online!

Kommentiert

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, ja
Shaggy



6

TI-BASIC, 54 Bytes

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

Eingabe ist die Liste der rechten Seite des Dreiecks in Ans, wie in der Challenge beschrieben.
Die Ausgabe ist die oberste Reihe des Dreiecks.

Beispiele:

{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}

Erläuterung: Bei
dieser Lösung wird die Tatsache missbraucht, dass das Dreieck, das mit der rechten Seite des Dreiecks als Start gebildet wird, die Änderung in jedem Element ist.

Mit anderen Worten,

2 1 1
 3 2
  5

wird:

5 2 1
 3 1
  2

Die resultierende Liste ist somit die rechte Seite dieses neuen Dreiecks, das durch Setzen des letzten Elements auf den Index der Länge der übergeordneten Liste in der resultierenden Liste gebildet werden kann.

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"

Hinweis: TI-BASIC ist eine Token-Sprache. Die Anzahl der Zeichen entspricht nicht der Anzahl der Bytes.


4

Gelee , 6 Bytes

ṚIƬZḢṚ

Ein monadischer Link, der eine Liste von ganzen Zahlen akzeptiert, die eine Liste von ganzen Zahlen ergibt.

Probieren Sie es online!

Wie?

Bildet das gesamte Dreieck und extrahiert dann die erforderlichen Elemente.

Ṛ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]

Hatte eine fast identische Lösung aber mit Us statt !
Nick Kennedy

IƬUZḢAwürde auch mit der gegebenen Frage arbeiten; Ich frage mich, ob irgendwo ein Byte gespeichert ist ...
Jonathan Allan

ạƝƬZṪ€funktioniert auch, ist aber wieder eine Sechs.
Nick Kennedy

Ja, ich habe diese Variante bemerkt; Ich bin jetzt weniger hoffnungsvoll.
Jonathan Allan

Ich habe gerade ein 5-Byte-Modell gepostet, aber es ist ein bisschen anders als Ihr Ansatz in Bezug auf den Teil nach der Pyramidenkonstruktion.
Erik der Outgolfer

4

MathGolf , 14 11 Bytes

xÆ‼├│?;∟;]x

Probieren Sie es online!

Erläuterung

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

Basierend auf @Lynns Kommentar:

f([ein,b,c,d,e])=[1-46-4101-33-1001-210001-100001][einbcde]

In Pari / GP ist eine Pascal-Matrix integriert, deren Inverse genau die Matrix ist, die wir benötigen:

[1000011000121001331014641]-1=[10000-110001-2100-13-3101-46-41]

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

Probieren Sie es online!


3

R , 69 67 Bytes

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

Probieren Sie es online!

Gibt einen Spaltenvektor zurück.

-2 Bytes dank Kirill L.

Auch basierend auf Lynns Kommentar:

f([ein,b,c,d,e])=[1-46-4101-33-1001-210001-100001][einbcde]

Es ist länger als die andere Antwort von R, aber es war ein interessanter Ansatz, Golf zu spielen und zu versuchen.


2

Javascript (ES6), 127 Byte

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}

Originalcode

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, ich habe gerne ... viel verloren ... auf die vorherige Antwort ...



2

05AB1E , 12 11 Bytes

R.¥.Γ¥}¨ζнR

Port of @JonathanAllan ‚s Jelly Antwort , obwohl ich Gelee über Jelly bequemen builtins in diesem Fall. ;)
-1 byte dank @Emigna .

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

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
Sie können ein Byte mit speichern, R.¥.Γ¥}¨indem Sie von der Liste ausgehen, deren Delta die Eingabe ist.
Emigna

@Emigna Ah, mach eine Schleife mit Deltas rückgängig, um ein Byte im Voraus zu speichern. :) Vielen Dank!
Kevin Cruijssen


2

Perl 6 , 37 Bytes

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

Probieren Sie es online!

Reduziert wiederholt um elementweise Subtraktion und gibt dann die letzte Nummer jeder Liste in umgekehrter Reihenfolge zurück.

Erläuterung:

{                                  }  # 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

Holzkohle , 19 Bytes

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

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Erläuterung:

Fθ«

Wiederholen Sie einmal für jeden Begriff in der ursprünglichen Liste.

PI§θ±¹↑

Geben Sie den letzten Begriff in der Liste aus, bewegen Sie den Cursor jedoch an den Anfang der vorherigen Zeile, damit die Begriffe in umgekehrter Reihenfolge ausgegeben werden.

UMθ⁻§θ⊖λκ

Berechnen Sie die Deltas, indem Sie am Anfang einen Dummy-Wert einfügen, damit wir eine Operation verwenden können, die die Länge der Liste nicht ändert.




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);}  

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

Erklärung
von rechts nach oben, da die letzten Elemente sowohl in der Eingabe als auch in der Ausgabe gleich sind, findet die Funktion "Schleife innen" einfach die nächsthöheren Zahlen im Dreieck, die allmählich nach oben reichen und die Antwort am Ende intakt lassen.

ungolfed (aus 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Ì

Versuch es

2 Bytes gespart dank Oliver.

12 11 Bytes

_äa}hUÊN yÌ

Versuch es

Dank Oliver 1 Byte gespart.



@Oliver, nicht daran zu denken, es zu benutzen, y(f)ist schon schlimm genug, aber die Newline komplett zu vergessen, ist unverzeihlich! Wird in Kürze aktualisiert. Danke :)
Shaggy

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.