Contando em pirâmides

17

Você deve escrever um programa ou função que receba uma lista de números inteiros distintos como entrada e saída ou retorne o número de ocorrências dos números de entrada na seguinte pirâmide de número invertida.

A partir da lista original em cada etapa, criamos uma nova com os valores máximos de cada par de números adjacentes (por exemplo, 5 1 2 6torna-se 5 2 6). Paramos quando há apenas um número na lista.

A pirâmide completa para 5 1 2 6é

5 1 2 6
 5 2 6 
  5 6  
   6   

O número resultante de ocorrências é 3 1 2 4(para 5 1 2 6respectivamente).

Entrada

  • Uma lista de um ou mais números inteiros sem repetição. (por exemplo, 1 5 1 6é inválido.)

Resultado

  • Uma lista de números inteiros positivos. O ielemento th da lista é o número de ocorrências do inúmero th de entrada na pirâmide.

Exemplos

Entrada => Saída

-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

Isso é código-golfe, portanto a entrada mais curta vence.

Quebra-cabeça bônus: você pode resolver o problema a O(n*log n)tempo?

randomra
fonte
Para o envio de uma função, preciso imprimi-los em STDOUT ou simplesmente imprimi-los?
Otimizador

Respostas:

4

Pitão, 19 17 bytes

m/smmeSb.:QhkUQdQ

Confira a demonstração on - line ou o conjunto de testes completo (os primeiros 4 bytes repetem os exemplos).

Este é um pouco mais inteligente que a abordagem ingênua. Cada número do triângulo pode ser representado como o valor máximo de um subconjunto conectado deQ . Na primeira linha, ele usa os subconjuntos de comprimento 1, a segunda linha do triângulo usa os subconjuntos de comprimento 2, ...

Explicação

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

Para visualizar isso um pouco. m.:QhdUQe a entrada [5, 1, 2, 6]me fornece todos os subconjuntos possíveis:

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

E mmeSk.:QhdUQme dá cada um dos seus máximos (que corresponde exatamente às linhas da pirâmide):

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

Pitão, 23 22 bytes

|u&aYGmeSd.:G2QQm/sYdQ

Essa é apenas a abordagem simples "faça o que você mandou".

Confira a demonstração on - line ou um conjunto de testes completo (os primeiros 4 bytes repetem os exemplos).

Explicação

meSd.:G2 mapeia cada par de [(G[0], G[1]), (G[1], G[2]), ...] para o elemento máximo.

Yé uma lista vazia, portanto, aYGanexa Gao Y.

u...QQaplica repetidamente essas duas funções ( len(Q)horas) iniciando G = Qe atualizando Gapós cada execução.

m/sYdQmapeia cada elemento da lista de entrada para sua contagem na Ylista nivelada .

Jakube
fonte
sua versão 17 byte usa o mesmo algoritmo como o meu, eu acho que agora é ingênuo demais: P
Optimizer
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

Uma solução de dividir e conquistar. O elemento máximo Mescoa até a pirâmide, dividindo-o em um retângulo de M's e duas sub-pirâmides.

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

Portanto, o resultado geral é a saída da sublist esquerda, seguida pela área do retângulo, seguida pela saída da sublist direita.

A variável de entrada Lé reutilizada para armazenar o resultado, para que a lista vazia seja mapeada para a lista vazia.

As construções na solução são variadas em Python. Talvez alguma linguagem com correspondência de padrões possa implementar o seguinte pseudocódigo?

def f(L):
 [] -> []
 A+[max(L)]+B -> f(A)+[(len(A)+1)*(len(B)+1)]+f(B)
xnor
fonte
Eu posso fazer um byte mais curto com correspondência de padrão do Mathematica, mas não até mesmo bater a apresentação Mathematica existente: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 bytes

Ainda à procura de opções de golfe.

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

Esta é uma função CJam (mais ou menos). Isso espera os números de entrada na pilha e retorna as contagens de saída correspondentes na pilha também. Um exemplo:

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

folhas

3 1 2 4

na pilha.

Certeza de que isso não está dentro O(n log n) hora.

Expansão do código :

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

Vamos dar uma olhada em como funciona, elaborando um exemplo de 5 1 2 6

Na segunda linha, 5 1 2 6torna-se 5 2 6porque 5, 2 and 6são os máximos [5 1], [1 2] and [2 6]respectivamente. Na terceira linha, torna-se5 6 porque 5 and 6são máximos, [5 2] and [2 6]respectivamente. Isso também pode ser escrito no máximo, [5 1 2] and [1 2 6]respectivamente. Da mesma forma, para a última linha, 6é o máximo de [5 1 2 6].

Então, basicamente criamos as fatias de comprimento adequadas, começando pela fatia de comprimento 1, que é basicamente os números originais, cada um envolvido em uma matriz, para finalmente uma fatia de comprimento Npara a última linha, onde Né o número de números inteiros de entrada.

Experimente online aqui

Optimizer
fonte
3

Mathematica, 72 bytes

Last/@Tally[Join@@NestList[MapThread[Max,{Most@#,Rest@#}]&,#,Length@#]]&
alefalpha
fonte
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]

Cada entrada da pirâmide é o máximo da sub-lista no topo de seu cone para cima. Então, geramos todas essas sublistas, indexadas por intervalos [i,j]com0 < i < j <= len(L) , e contamos quantas vezes cada elemento aparece no máximo.

Uma maneira mais curta de enumerar os subintervalos provavelmente salvaria caracteres. Uma parametrização de um único índice dos pares [i,j]seria uma abordagem plausível.

xnor
fonte
1

Pip , 56 + 1 = 57 bytes

Receio que não esteja competindo muito com o vodu CJam. Parece que preciso de um algoritmo melhor. Execute com o -ssinalizador para obter saída delimitada por espaço.

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

Ungolfed, com comentários:

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

A redefinição de rcada vez funciona da seguinte maneira:

{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
DLosc
fonte
1

APL (24)

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

Esta é uma função que leva uma lista, assim;

      {+/⍵∘.={⍵≡⍬:⍵⋄⍵,∇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

Explicação:

  • {... }⍵: aplique a seguinte função a ⍵:
    • ⍵≡⍬:⍵: se ⍵ estiver vazio, retorne ⍵
    • 2⌈/⍵: gerar a próxima lista
    • ⍵,∇: return ⍵, seguido pelo resultado da aplicação desta função na próxima lista
  • ⍵∘.=: compare cada elemento em ⍵ com cada elemento no resultado da função
  • +/: soma as linhas (representando elementos em ⍵)
marinus
fonte
1

Haskell, 78 bytes

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

Como funciona

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    
nimi
fonte
1

JavaScript, 109 bytes

Acho que encontrei uma maneira interessante de fazer isso, mas somente depois que terminei percebi que o código era muito longo para competir. Bem, publicando isso de qualquer maneira, caso alguém veja mais potencial de golfe.

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}

Estou usando a seguinte fórmula aqui:

ocorrências de i = (quantidade de números consecutivos menores que i à esquerda + 1) * (quantidade de números consecutivos menores que i à direita + 1)

Dessa forma, não é necessário gerar a pirâmide inteira ou seus subconjuntos. (Foi por isso que inicialmente pensei que seria executado em O (n), mas, por sorte, ainda precisamos de loops internos.)

vvye
fonte
1

MATLAB: (266 b)

  • a correção do código custa mais bytes, vou tentar como reduzi-lo mais tarde.
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

ENTRADA

um vetor deve estar no formato [abcd ...]

  • exemplo:

    [2 4 7 11 3]

RESULTADO

ocorrências padrão.

s =

 1


s =

 2


s =

 3


s =

 8


s =

 1

EXPLICAÇÃO:

se [abcd] for uma entrada, o programa calcula o resultado ghij como

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 ) = ... 'simplificado'

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) = ...

Abr001am
fonte
0

J (49)

Suponho que há espaço para melhorias ...

[:+/~.="1 0[:;([:i.#)<@:(4 :'(}:>.}.)^:x y')"0 1]
ɐɔıʇǝɥʇuʎs
fonte