Aggiunta capovolta alla piramide ... INVERSO!


22

L'aggiunta capovolta della piramide è il processo di prendere un elenco di numeri e aggiungerli consecutivamente fino a raggiungere un numero.

Quando vengono indicati i numeri 2, 1, 1, si verifica la seguente procedura:

 2   1   1
   3   2 
     5

Questo termina con il numero 5.


IL TUO COMPITO

Dato il lato destro di una piramide capovolta (crescente), scrivere un programma o una funzione che restituirà l'elenco originale.

Nuova sfida extra : prova a farlo in meno di O (n ^ 2)

ESEMPIO

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

NOTA: la piramide capovolta non sarà mai vuota e sarà sempre composta SOLO di numeri interi positivi.


6
Benvenuti in PP&CG! Questa sfida è decente, sebbene possa essere migliorata. Ti consiglio di pubblicare le tue sfide nella Sandbox per migliorare il post prima che venga messo in primo piano.
Tau,

13
Comprensione libera che non riesco a trovare una lingua in cui è più breve:
f([a,b,c,d,e])=[1464101331001210001100001][abcde]
Lynn,

4
Cordiali saluti, questo è lo stesso del kata CodeWars .
ggorlen,

6
@ggorlen lo so. Sono quello che ha fatto il kata :)
Whimpers

8
Try doing this in less than O(n)sicuramente è impossibile allocare un array di dimensioni n o modificare gli elementi O (n) in esso più velocemente della complessità O (n)?
mio pronome è monicareinstate

Risposte:


17

JavaScript (ES6),  62 58 49  46 byte

3 byte salvati grazie a @Oliver

Restituisce l'elenco come una stringa separata da virgola.

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

Provalo online!

Commentate

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 byte

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

L'input è l'elenco del lato destro del triangolo in Ans, come descritto nella sfida.
L'output è la riga superiore di detto triangolo.

Esempi:

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

Spiegazione:
Questa soluzione abusa del fatto che il triangolo si è formato usando il lato destro del triangolo quando l'inizio finisce per essere il cambiamento in ogni elemento.

In altre parole,

2 1 1
 3 2
  5

diventa:

5 2 1
 3 1
  2

Pertanto, l'elenco risultante è il lato destro di questo nuovo triangolo, che può essere formato impostando l'ultimo elemento sull'indice della lunghezza dell'elenco padre nell'elenco risultante.

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"

Nota: TI-BASIC è un linguaggio tokenizzato. Il conteggio dei caratteri non equivale al conteggio dei byte.


4

Gelatina , 6 byte

ṚIƬZḢṚ

Un collegamento monadico che accetta un elenco di numeri interi che produce un elenco di numeri interi.

Provalo online!

Come?

Crea l'intero triangolo quindi estrae gli elementi richiesti.

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

Aveva una soluzione quasi identica ma con Us invece di !
Nick Kennedy,

IƬUZḢAfunzionerebbe anche con la domanda data; Mi chiedo se ci sia un byte da qualche parte ...
Jonathan Allan,

ạƝƬZṪ€funziona anche ma è di nuovo un sei.
Nick Kennedy,

Sì, ho notato quella variante; Sono meno fiducioso ora.
Jonathan Allan,

Ho appena pubblicato un 5-byter, ma è un po 'diverso dal tuo approccio riguardo alla parte dopo la costruzione della piramide.
Erik the Outgolfer,

4

MathGolf , 14 11 byte

xÆ‼├│?;∟;]x

Provalo online!

Spiegazione

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

Python 2 , 56 byte

f=lambda a:a and f([l-r for l,r in zip(a,a[1:])])+a[-1:]

Una funzione ricorsiva che accetta un elenco di numeri interi positivi che restituisce un elenco di numeri interi non negativi.

Provalo online!



3

Pari / GP , 36 byte

Basato sul commento di @Lynn :

Informazioni gratuite sul fatto che non riesco a trovare una lingua in cui è più breve:

f([un',B,c,d,e])=[1-46-4101-33-1001-210001-100001][un'Bcde]

Pari / GP ha un built-in per la matrice Pascal e il suo inverso è esattamente la matrice di cui abbiamo bisogno:

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

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

Provalo online!


3

R , 69 67 byte

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

Provalo online!

Restituisce un vettore di colonna.

-2 byte grazie a Kirill L.

Basato anche sul commento di Lynn :

Informazioni gratuite sul fatto che non riesco a trovare una lingua in cui è più breve:

f([un',B,c,d,e])=[1-46-4101-33-1001-210001-100001][un'Bcde]

È più lungo dell'altra risposta R, ma è stato un approccio interessante da prendere e provare a giocare a golf.


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}

Codice originale

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, ho perso come ... molto ... alla risposta precedente ...



2

05AB1E , 12 11 byte

R.¥.Γ¥}¨ζнR

La risposta di Jelly di Port of @JonathanAllan , anche se in questo caso sono gelatina dei buildins più convenienti di Jelly. ;)
-1 byte grazie a @Emigna .

Provalo online o verifica tutti i casi di test .

Spiegazione:

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
È possibile salvare un byte con R.¥.Γ¥}¨partendo dall'elenco il cui delta è l'input.
Emigna,

@Emigna Ah, undelta in un ciclo con delta per salvare un byte sul prepend. :) Grazie!
Kevin Cruijssen,


2

Perl 6 , 37 byte

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

Provalo online!

Riduce ripetutamente per sottrazione elementwise, quindi restituisce l'ultimo numero di ciascun elenco al contrario.

Spiegazione:

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

Carbone , 19 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

Fθ«

Ripeti ciclicamente una volta per ogni termine nell'elenco originale.

PI§θ±¹↑

Stampa l'ultimo termine nell'elenco, ma sposta il cursore all'inizio della riga precedente, in modo che i termini vengano emessi in ordine inverso.

UMθ⁻§θ⊖λκ

Calcola i delta, inserendo all'inizio un valore fittizio in modo da poter utilizzare un'operazione che non modifica la lunghezza dell'elenco.



1

Attache , 29 byte

{y.=Delta@-_If[_,$@y'_@-1,y]}

Provalo online!

Basta iterare la Deltafunzione fino a quando non è vuota. Molto più breve della PeriodicStepssoluzione molto dettagliata ...


1

C, 76 byte

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

Spiegazione
va dal lato destro verso l'alto, poiché gli ultimi elementi sono gli stessi sia in input che in output, la funzione loop inside trova semplicemente i successivi numeri più alti nel triangolo che raggiungono gradualmente la parte superiore lasciando intatta la risposta alla fine.

ungolfed (dal 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 byte

Nc¡=äa
yÌ

Provalo

2 byte salvati grazie a Oliver.

12 11 byte

_äa}hUÊN yÌ

Provalo

1 byte salvato grazie a Oliver.



@Oliver, non pensare di usare y(f)è abbastanza male, ma dimenticare completamente la newline è imperdonabile! Si aggiornerà a breve. Grazie :)
Shaggy

1

Julia 0.6 , 44 byte

x->reverse([(j=x[end];x=-diff(x);j)for i=x])

Provalo online!

Stesso principio iterativo della mia risposta R.

Julia 0.6 , 55 byte

x->inv([binomial(i,j)for i=(l=length(x)-1:-1:0),j=l])*x

Provalo online!

Algoritmo di @ Lynn (inverso della matrice Pascal moltiplicato per l'input).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.