Conteggio nelle piramidi


17

È necessario scrivere un programma o una funzione che riceve un elenco di numeri interi distinti come input e output o restituisce il numero di occorrenze dei numeri di input nella seguente piramide numerica capovolta.

A partire dall'elenco originale in ogni passaggio ne creiamo uno nuovo con i valori massimi di ogni coppia di numeri adiacenti (ad esempio 5 1 2 6diventa 5 2 6). Ci fermiamo quando c'è un solo numero nell'elenco.

La piramide completa per 5 1 2 6è

5 1 2 6
 5 2 6 
  5 6  
   6   

Il numero risultante di occorrenze è 3 1 2 4( 5 1 2 6rispettivamente).

Ingresso

  • Un elenco di uno o più numeri interi senza ripetizione. (ad es 1 5 1 6. non è valido.)

Produzione

  • Un elenco di numeri interi positivi. L' ielemento th dell'elenco è il numero di occorrenze del inumero th di input nella piramide.

Esempi

Input => Output

-5 => 1

8 4 => 2 1

5 9 7 => 1 4 1

1 2 3 9 8 6 7 => 1 2 3 16 3 1 2

6 4 2 1 3 5 => 6 4 2 1 3 5

5 2 9 1 6 0 => 2 1 12 1 4 1

120 5 -60 9 12 1 3 0 1200 => 8 2 1 3 16 1 4 1 9

68 61 92 58 19 84 75 71 46 69 25 56 78 10 89 => 2 1 39 2 1 27 6 5 1 6 1 2 14 1 12

Questo è code-golf, quindi vince l'ingresso più breve.

Puzzle bonus: puoi risolvere il problema in O(n*log n)tempo?


Per l'invio di una funzione, devo stamparli su STDOUT o semplicemente inviarli?
Ottimizzatore il

Risposte:


4

Pyth, 19 17 byte

m/smmeSb.:QhkUQdQ

Dai un'occhiata alla dimostrazione online o alla suite di test completa (i primi 4 byte ripetono gli esempi).

Questo è un po 'più intelligente dell'approccio ingenuo. Ogni numero del triangolo può essere rappresentato come il valore massimo di un sottoinsieme collegato di Q. Nella prima riga utilizza i sottoinsiemi di lunghezza 1, la seconda riga del triangolo utilizza i sottoinsiemi di lunghezza 2, ...

Spiegazione

m/smmeSb.:QhkUQdQ    implicit: Q = input()
   m         UQ         map each k in [0, 1, 2, ..., len(Q)-1] to:
        .:Qhk              all subsets of Q of length (k + 1)
    meSb                   mapped to their maximum
  s                     join these lists together
m               Q    map each d of Q to:
 /             d        its count in the computed list

Per visualizzare questo un po '. m.:QhdUQe l'input [5, 1, 2, 6]mi dà tutti i possibili sottoinsiemi:

[[[5], [1], [2], [6]], [[5, 1], [1, 2], [2, 6]], [[5, 1, 2], [1, 2, 6]], [[5, 1, 2, 6]]]

E mmeSk.:QhdUQmi dà ciascuno dei loro massimi (che corrisponde esattamente alle file nella piramide):

[[5, 1, 2, 6], [5, 2, 6], [5, 6], [6]]

Pyth, 23 22 byte

|u&aYGmeSd.:G2QQm/sYdQ

Questo è solo il semplice approccio "fai quello che ti viene detto".

Dai un'occhiata alla dimostrazione online o a una suite di test completa (i primi 4 byte ripetono gli esempi).

Spiegazione

meSd.:G2mappa ogni coppia di [(G[0], G[1]), (G[1], G[2]), ...]all'elemento massimo.

Yè un elenco vuoto, pertanto viene aYGaggiunto Ga Y.

u...QQapplica ripetutamente queste due funzioni ( len(Q)tempi) iniziando con G = Qe aggiornando Gdopo ogni esecuzione.

m/sYdQassocia ciascun elemento dell'elenco di input al loro conteggio Ynell'elenco appiattito .


la tua versione a 17 byte utilizza lo stesso algoritmo del mio, immagino che ora sia anche ingenuo: P
Ottimizzatore

13

Python, 81

def f(L):
 if L:i=L.index(max(L));L=f(L[:i])+[~i*(i-len(L))]+f(L[i+1:])
 return L

Una soluzione di divisione e conquista. L'elemento massimo Mfiltra fino in fondo alla piramide, dividendola in un rettangolo di Mdue sottopiramidi.

* * * M * *
 * * M M *
  * M M M
   M M M
    M M
     M

Pertanto, il risultato complessivo è l'output per l'elenco secondario sinistro, seguito dall'area del rettangolo, seguito dall'output per l'elenco secondario destro.

La variabile di input L viene riutilizzata per archiviare il risultato in modo che l'elenco vuoto sia mappato sull'elenco vuoto.

I costrutti in soluzione sono prolissi in Python. Forse un linguaggio con pattern-matching può implementare il seguente pseudocodice?

def f(L):
 [] -> []
 A+[max(L)]+B -> f(A)+[(len(A)+1)*(len(B)+1)]+f(B)

Posso accorciare di un byte il pattern matching di Mathematica, ma non batte nemmeno l'invio di Mathematica esistente:f@{}=##&@@{};f@{a___,l_,b___}/;l>a~Max~b:={f@{a},Length@{a,0}Length@{b,0},f@{b}}
Martin Ender,

6

CJam, 23 22 byte

Ancora alla ricerca di opzioni per il golf.

{]_,{)W$ew::e>~}%fe=~}

Questa è una funzione CJam (sorta di). Questo si aspetta i numeri di input nello stack e restituisce anche i conteggi di output corrispondenti nello stack. Un esempio:

5 1 2 6 {]_,{)W$ew::e>~}%fe=~}~

le foglie

3 1 2 4

in pila.

Abbastanza sicuro che non ci sia O(n log n) tempo.

Espansione del codice :

]_                     e# Wrap the input numbers on stack in an array and take a copy
  ,{          }%       e# Take length of the copy and run the loop from 0 to length - 1
    )W$                e# Increment the iterating index and copy the parsed input array
       ew              e# Get overlapping slices of iterating index + 1 size
         ::e>          e# Get maximum from each slice
             ~         e# Unwrap so that there can be finally only 1 level array
                fe=    e# For each of the original array, get the occurrence in this
                       e# final array created by the { ... }%
                   ~   e# Unwrap the count array and leave it on stack

Diamo un'occhiata a come funziona elaborando un esempio di 5 1 2 6

Nella seconda riga, 5 1 2 6diventa 5 2 6perché 5, 2 and 6sono il massimo di [5 1], [1 2] and [2 6]rispettivamente. Nella terza riga, diventa 5 6perché 5 and 6sono [5 2] and [2 6]rispettivamente il massimo di . Questo può anche essere scritto come massimo di [5 1 2] and [1 2 6]rispettivamente. Allo stesso modo per l'ultima riga, 6è massimo di [5 1 2 6].

Quindi fondamentalmente creiamo le sezioni di lunghezza appropriate a partire da una porzione di lunghezza 1, che è fondamentalmente i numeri originali, ciascuno racchiuso in un array, fino a una fetta di lunghezza Nper l'ultima riga, dove Nè il numero di numeri interi di input.

Provalo online qui


3

Mathematica, 72 byte

Last/@Tally[Join@@NestList[MapThread[Max,{Most@#,Rest@#}]&,#,Length@#]]&

3

Python, 81

lambda L:[sum(x==max(L[i:j])for j in range(len(L)+1)for i in range(j))for x in L]

Ogni voce della piramide è il massimo dell'elenco secondario in cima al suo cono verso l'alto. Quindi, generiamo tutte queste liste secondarie, indicizzate da intervalli [i,j]con0 < i < j <= len(L) , e contiamo quante volte ciascuno appare come elemento massimo.

Un modo più breve per enumerare i sottointervalli probabilmente salverà i caratteri. Una parametrizzazione a indice singolo delle coppie [i,j]sarebbe un approccio plausibile.


1

Pip , 56 + 1 = 57 byte

Non ho molta concorrenza con il voodoo CJam, temo. Sembra che abbia bisogno di un algoritmo migliore. Esegui con -sflag per ottenere output delimitato da spazi.

l:gr:0*,#gg:0*g+1WrFir:{c:r@[a--a]c@($<l@c)}M1,#r++(gi)g

Ungolfed, con commenti:

l:g                              l = input from cmdline args
r:0*,#g                          r = current row as a list of indices into l
g:0*g+1                          Repurpose g to store the frequencies
Wr                               Loop until r becomes empty
 Fir:{c:r@[a--a]c@($<l@c)}M1,#r  Redefine r (see below) and loop over each i in it
  ++(gi)                         Increment g[i]
g                                Output g

La ridefinizione di rogni volta attraverso funziona come segue:

{c:r@[a--a]c@($<l@c)}M1,#r
{                   }M1,#r       Map this function to each a from 1 to len(r) - 1:
 c:r@[a--a]                      c is a two-item list containing r[a] and r[a-1]
                l@c              The values of l at the indices contained in c
              $<                 Fold/less-than: true iff l[c[0]] < l[c[1]]
           c@(     )             Return c[0] if the former is greater, c[1] otherwise

1

APL (24)

{+/⍵∘.={⍵≡⍬:⍵⋄⍵,∇2⌈/⍵}⍵}

Questa è una funzione che accetta un elenco, in questo modo;

      {+/⍵∘.={⍵≡⍬:⍵⋄⍵,∇2⌈/⍵}⍵}68 61 92 58 19 84 75 71 46 69 25 56 78 10 89
2 1 39 2 1 27 6 5 1 6 1 2 14 1 12

Spiegazione:

  • {... }⍵: applica la seguente funzione a ⍵:
    • ⍵≡⍬:⍵: se ⍵ è vuoto, ritorna ⍵
    • 2⌈/⍵: genera l'elenco successivo
    • ⍵,∇: return ⍵, seguito dal risultato dell'applicazione di questa funzione all'elenco successivo
  • ⍵∘.=: confronta ciascun elemento in ⍵ con ciascun elemento nel risultato della funzione
  • +/: somma le righe (che rappresentano gli elementi in ⍵)

1

Haskell, 78 byte

l=length
f x=[l[b|b<-concat$take(l x)$iterate(zipWith max=<<tail)x,a==b]|a<-x]

Uso: f [68,61,92,58,19,84,75,71,46,69,25,56,78,10,89] -> [2,1,39,2,1,27,6,5,1,6,1,2,14,1,12].

Come funziona

zipWith max=<<tail   -- apply 'max' on neighbor elements of a list
iterate (...) x      -- repeatedly apply the above max-thing on the
                     -- input list and build a list of the intermediate
                     -- results
take (l x) ...       -- take the first n elements of the above list
                     -- where n is the length of the input list
concat               -- concatenate into a single list. Now we have
                     -- all elements of the pyramid in a single list.
[ [b|b<-...,a==b] | a<-x]
                     -- for all elements 'a' of the input list make a 
                     -- list of 'b's from the pyramid-list where a==b.
 l                   -- take the length of each of these lists    

1

JavaScript, 109 byte

Penso di aver trovato un modo interessante di procedere, ma solo dopo che mi sono reso conto che il codice era troppo lungo per competere. Vabbè, pubblicando questo comunque nel caso in cui qualcuno veda un ulteriore potenziale di golf.

f=s=>{t=[];for(i=-1;s.length>++i;){j=k=i;l=r=1;for(;s[--j]<s[i];l++);for(;s[++k]<s[i];r++);t[i]=l*r}return t}

Sto usando la seguente formula qui:

occorrenze di i = (quantità di numeri consecutivi più piccoli di i alla sua sinistra + 1) * (quantità di numeri consecutivi più piccoli di i alla sua destra + 1)

In questo modo non è necessario generare effettivamente l'intera piramide o sottoinsiemi di essa. (Questo è il motivo per cui inizialmente pensavo che avrebbe funzionato in O (n), ma per fortuna, abbiamo ancora bisogno di anelli interni.)


1

MATLAB: (266 b)

  • la correzione del codice costa più byte, farò fatica a ridurlo in seguito.
v=input('');h=numel(v);for i=1:h,f=(v(i)>v(1));l=(v(i)>v(h));for j=h-1:-1:i+1,l=(v(i)>v(j))*(1+l);end,if(i>1),l=l+(v(i)>v(i-1))*l;end;for j=2:i-1,f=(v(i)>v(j))*(1+f);end,if(i<h),f=f+(v(i)>v(i+1))*f;end;s=f+l+1;if(i<h&&i>1),s=s-((v(i)>v(i+1))*(v(i)>v(i-1)));end;s
end

INGRESSO

un vettore deve essere nella forma [abcd ...]

  • esempio:

    [2 4 7 11 3]

PRODUZIONE

ricorrenze del modello.

s =

 1


s =

 2


s =

 3


s =

 8


s =

 1

SPIEGAZIONE:

se [abcd] è un input il programma calcola il risultato ghij come

g = (a> b) + (a> b) (a> c) + (a> b) (a> c) * (a> d) = (a> b) (1+ (a> c) ( 1+ (a> c))))

h = (b> a) + (b> c) + (b> a) (b> c) + (b> c) (b> d) + (b> a) (b> c) (b> d ) = ... "semplificato"

i = (c> b) + (c> d) + (c> b) (c> d) + (c> b) (c> a) + (c> d) (c> b) (c> a ) = ..

j = (d> c) + (d> c) (d> b) + (d> c) (d> b) * (d> a) = ...


0

J (49)

Suppongo che ci sia qualche margine di miglioramento ...

[:+/~.="1 0[:;([:i.#)<@:(4 :'(}:>.}.)^:x y')"0 1]
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.