Piramitlerde sayma


17

Girdi ve çıktılar olarak farklı tamsayıların bir listesini alan ya da aşağıdaki baş aşağı sayı piramidindeki girdi sayılarının oluşum sayısını döndüren bir program ya da işlev yazmalısınız.

Her adımda orijinal listeden başlayarak, her bir bitişik sayı çiftinin (örn. 5 1 2 6Olur 5 2 6) maksimum değerlerini içeren yeni bir liste oluştururuz . Listede yalnızca bir numara olduğunda duruyoruz.

Tam piramit 5 1 2 6DİR

5 1 2 6
 5 2 6 
  5 6  
   6   

Ortaya çıkan olay sayısı 3 1 2 4( 5 1 2 6sırasıyla).

Giriş

  • Tekrarlama yapılmayan bir veya daha fazla tamsayının listesi. (ör 1 5 1 6. geçersiz.)

Çıktı

  • Pozitif tamsayıların listesi. iListenin inci elemanı geçiş sayısı olan ipiramidin th giriş numarası.

Örnekler

Giriş => Çıkış

-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

Bu kod golf bu yüzden en kısa giriş kazanır.

Bonus bulmaca: sorunu O(n*log n)zamanında çözebilir misin ?


Bir işlev gönderimi için bunları STDOUT'a yazdırmam veya basitçe çıkarmam gerekir mi?
Doktor

Yanıtlar:


4

Pyth, 19 17 bayt

m/smmeSb.:QhkUQdQ

Çevrimiçi Gösteriye veya tüm Test Paketine göz atın (örnekler üzerinden ilk 4 bayt yineleme).

Bu, saf yaklaşımdan biraz daha zekidir. Üçgenin her sayısı, bağlı bir alt kümesinin maksimum değeri olarak temsil edilebilir Q. İlk satırda 1 uzunluğunun alt kümelerini kullanır, üçgenin ikinci satırı 2 uzunluğunun alt kümelerini kullanır ...

açıklama

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

Bunu biraz görselleştirmek için. m.:QhdUQve girdi [5, 1, 2, 6]bana tüm olası altkümeleri verir:

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

Ve mmeSk.:QhdUQbana her bir maksimumlarını (piramitteki satırlara tam olarak karşılık gelir) verir:

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

Pyth, 23 22 bayt

|u&aYGmeSd.:G2QQm/sYdQ

Bu basitçe "size söylediklerinizi yapın" yaklaşımıdır.

Çevrimiçi Gösteriye veya eksiksiz bir Test Paketine (örnekler üzerinden ilk 4 bayt yineleme) göz atın .

açıklama

meSd.:G2her çiftini [(G[0], G[1]), (G[1], G[2]), ...]maksimum elemanla eşler .

YBoş bir liste bu nedenle, aYGekler Giçin Y.

u...QQbu iki işlevi ( len(Q)süreleri) her çalıştırmadan sonra G = Qve Gher güncellemeden sonra tekrar tekrar uygular .

m/sYdQgiriş listesindeki her öğeyi düzleştirilmiş Ylistedeki sayılarıyla eşler .


17 baytlık sürümü benimkiyle aynı algoritmayı kullanıyor, sanırım şimdi de naif: 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

Böl ve ele geçir çözümü. Maksimum eleman M, piramidin aşağısına doğru sızar ve onu bir dikdörtgen Mve iki alt piramidin bir dikdörtgenine böler.

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

Böylece, genel sonuç sol alt liste için çıktı, ardından dikdörtgenin alanı ve ardından sağ alt liste için çıktı olur.

Girdi değişkeni Lsonucu saklamak için yeniden kullanılır, böylece boş liste boş listeyle eşlenir.

Çözeltideki yapılar Python'da ifade edilir. Belki de desen eşleştirmeli bir dil aşağıdaki sahte kodu uygulayabilir?

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

Mathematica'nın desen eşleşmesi ile bir bayt daha kısa yapabilirim, ancak mevcut Mathematica sunumunu bile geçmez: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 bayt

Hala golf seçenekleri arıyor.

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

Bu bir CJam fonksiyonudur (bir çeşit). Bu, yığındaki giriş numaralarını bekler ve yığındaki karşılık gelen çıkış sayılarını da döndürür. Bir örnek:

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

yapraklar

3 1 2 4

yığını.

Bunun O(n log n)zamanında olmadığından eminim .

Kod genişletme :

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

Bir örnek oluşturarak nasıl çalıştığına bir bakalım 5 1 2 6

İkinci sırada, sırasıyla en fazla olduğu için 5 1 2 6olur . Üçüncü sırada, sırasıyla en fazla olduğu için olur . Bu, sırasıyla maksimum olarak da yazılabilir . Benzer şekilde son satır için de maksimumdur .5 2 65, 2 and 6[5 1], [1 2] and [2 6]5 65 and 6[5 2] and [2 6][5 1 2] and [1 2 6]6[5 1 2 6]

Bu nedenle 1, temel olarak her biri bir diziye sarılmış orijinal sayılar olan uzunluk diliminden başlayarak Nson satır için Ngiriş tamsayılarının sayısı olan bir uzunluk dilimine kadar uygun uzunluk dilimleri oluşturuyoruz .

Buradan çevrimiçi deneyin


3

Mathematica, 72 bayt

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]

Piramidin her girişi, yukarı doğru konisinin üzerindeki alt listenin maksimumudur. Yani, biz aralıklarla endeksli Bütün bu sublists oluşturmak [i,j]ile 0 < i < j <= len(L)ve kaç sefer maksimum olarak her eleman görüntülenir sayılır.

Alt aralıkları numaralandırmanın daha kısa bir yolu muhtemelen karakterleri kurtarır. Çiftlerin tek endeksli bir parametrelendirmesi [i,j]makul bir yaklaşım olacaktır.


1

Pip , 56 + 1 = 57 bayt

CJam vudu ile pek rekabet etmiyorum, korkarım. Görünüşe göre daha iyi bir algoritmaya ihtiyacım var. Alanla -ssınırlı çıktı almak için bayrakla çalıştırın .

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

Ungolfed, yorumlarla:

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

rHer zamanın yeniden tanımlanması aşağıdaki gibi çalışır:

{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⌈/⍵}⍵}

Bu bir liste alan bir işlevdir, şöyle;

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

Açıklama:

  • {... }⍵: function öğesine şu işlevi uygulayın:
    • ⍵≡⍬:⍵: ⍵ boşsa, return
    • 2⌈/⍵: sonraki listeyi oluştur
    • ⍵,∇: return ⍵, ardından bu işlevi bir sonraki listeye uygulama sonucu
  • ⍵∘.=: in içindeki her öğeyi işlevin sonucundaki her öğeyle karşılaştırın
  • +/: satırları topla (in içindeki öğeleri temsil eder)

1

Haskell, 78 bayt

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

Kullanımı: 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].

Nasıl çalışır

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 bayt

Bu konuda gitmek için ilginç bir yol buldum, ama sadece bittikten sonra kodun rekabet etmek için çok uzun olduğunu fark ettim. Oh, birisinin daha fazla golf potansiyeli görmesi durumunda bunu yine de yayınlamak

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}

Burada aşağıdaki formülü kullanıyorum:

i = (solda + 1'den küçük ardışık sayıların miktarı + 1) * (sağda + 1'den küçük ardışık sayıların miktarı)

Bu şekilde, aslında tüm piramidi veya alt kümesini oluşturmaya gerek yoktur. (Bu yüzden başlangıçta O (n) 'de çalışacağını düşündüm, ama zor şanslar, hala iç döngülere ihtiyacımız var.)


1

MATLAB: (266 b)

  • kodun düzeltilmesi daha fazla bayt maliyeti, daha sonra azaltmak için nasıl mücadele edecek.
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

GİRİŞ

bir vektör [abcd ...] biçiminde olmalıdır

  • misal:

    [2 4 7 11 3]

ÇIKTI

örüntü oluşumları.

s =

 1


s =

 2


s =

 3


s =

 8


s =

 1

AÇIKLAMA:

[abcd] bir girdi ise, program ghij sonucunu şu şekilde hesaplar:

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 ) = ... 'basitleştirilmiş'

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)

Sanırım iyileştirilmesi gereken bir yer var ...

[:+/~.="1 0[:;([:i.#)<@:(4 :'(}:>.}.)^:x y')"0 1]
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.