Menghitung di piramida

17

Anda harus menulis program atau fungsi yang menerima daftar bilangan bulat yang berbeda sebagai input dan output atau mengembalikan jumlah kemunculan nomor input dalam piramida angka terbalik berikut.

Mulai dari daftar asli di setiap langkah kami membuat yang baru dengan nilai maksimal dari setiap pasangan angka yang berdekatan (misalnya 5 1 2 6menjadi 5 2 6). Kami berhenti ketika hanya ada satu nomor dalam daftar.

Piramida penuh 5 1 2 6adalah

5 1 2 6
 5 2 6 
  5 6  
   6   

Jumlah kejadian yang dihasilkan adalah 3 1 2 4(untuk 5 1 2 6masing - masing).

Memasukkan

  • Daftar satu atau lebih bilangan bulat tanpa pengulangan. (mis 1 5 1 6. tidak valid.)

Keluaran

  • Daftar bilangan bulat positif. The ielemen th daftar adalah jumlah kejadian dari ijumlah masukan th di piramida.

Contohnya

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

Ini adalah kode-golf sehingga entri terpendek menang.

Teka-teki bonus: dapatkah Anda menyelesaikan masalah O(n*log n)tepat waktu?

randomra
sumber
Untuk pengiriman fungsi, apakah saya harus mencetaknya ke STDOUT atau hanya menampilkannya?
Pengoptimal

Jawaban:

4

Pyth, 19 17 byte

m/smmeSb.:QhkUQdQ

Lihat Peragaan Online atau Test Suite lengkap (iterasi 4 byte pertama di atas contoh).

Yang ini sedikit lebih pintar daripada pendekatan naif. Setiap angka segitiga dapat direpresentasikan sebagai nilai maksimal dari subset terhubung Q. Di baris pertama menggunakan himpunan bagian panjang 1, baris kedua dari segitiga menggunakan himpunan bagian panjang 2, ...

Penjelasan

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

Untuk memvisualisasikan ini sedikit. m.:QhdUQdan input [5, 1, 2, 6]memberi saya semua himpunan bagian yang mungkin:

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

Dan mmeSk.:QhdUQmemberi saya masing-masing maksimum (yang sesuai persis dengan baris di piramida):

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

Pyth, 23 22 byte

|u&aYGmeSd.:G2QQm/sYdQ

Ini hanya pendekatan sederhana "lakukan apa yang diperintahkan" kepada Anda.

Lihat Demonstrasi Online atau Test Suite lengkap (iterasi 4 byte pertama di atas contoh).

Penjelasan

meSd.:G2memetakan setiap pasangan [(G[0], G[1]), (G[1], G[2]), ...]ke elemen maksimal.

Yadalah daftar kosong, oleh karena itu aYGditambahkan Gke Y.

u...QQberulang kali menerapkan kedua fungsi ini ( len(Q)waktu) dimulai dengan G = Qdan memperbarui Gsetelah setiap kali dijalankan.

m/sYdQmemetakan setiap elemen dari daftar input ke hitungannya dalam Ydaftar yang diratakan .

Jakube
sumber
versi 17 byte Anda menggunakan algoritma yang sama dengan saya, saya kira itu sekarang naif juga: 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

Solusi membagi dan menaklukkan. Elemen maksimum Mmerembes sampai ke piramida, membelahnya menjadi empat persegi panjang Mdan dua sub-piramida.

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

Jadi, hasil keseluruhan adalah output untuk sublist kiri, diikuti oleh luas persegi panjang, diikuti oleh output untuk sublist kanan.

Variabel input Ldigunakan kembali untuk menyimpan hasil sehingga daftar kosong dipetakan ke daftar kosong.

Konstruk dalam solusi bertele-tele dengan Python. Mungkin beberapa bahasa dengan pencocokan pola dapat mengimplementasikan kodesemu berikut?

def f(L):
 [] -> []
 A+[max(L)]+B -> f(A)+[(len(A)+1)*(len(B)+1)]+f(B)
Tidak
sumber
Saya dapat melakukan satu byte lebih pendek dengan pencocokan pola Mathematica, tetapi bahkan tidak mengalahkan pengajuan Mathematica yang ada: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

Masih mencari opsi bermain golf.

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

Ini adalah fungsi CJam (semacam). Ini mengharapkan nomor input pada stack dan mengembalikan jumlah output yang sesuai pada stack juga. Sebuah contoh:

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

Daun-daun

3 1 2 4

di tumpukan.

Cukup yakin bahwa ini tidak O(n log n)tepat waktu.

Perluasan kode :

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

Mari kita lihat cara kerjanya dengan membuat contoh 5 1 2 6

Di baris kedua, 5 1 2 6menjadi 5 2 6karena 5, 2 and 6adalah maksimum [5 1], [1 2] and [2 6]masing - masing. Di baris ketiga, itu menjadi 5 6karena masing 5 and 6- [5 2] and [2 6]masing maksimum . Ini juga dapat ditulis sebagai maksimum [5 1 2] and [1 2 6]masing - masing. Demikian pula untuk baris terakhir, 6maksimum [5 1 2 6].

Jadi pada dasarnya kita membuat irisan panjang yang tepat mulai dari irisan panjang 1, yang pada dasarnya adalah angka asli, masing-masing dibungkus dalam array, hingga akhirnya irisan panjang Nuntuk baris terakhir, di mana Nadalah jumlah bilangan input.

Cobalah online di sini

Pengoptimal
sumber
3

Mathematica, 72 byte

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

Setiap entri piramida adalah maksimum dari sublist di atas kerucut atasnya. Jadi, kami membuat semua daftar ini, diindeks dengan interval [i,j]dengan 0 < i < j <= len(L), dan menghitung berapa banyak waktu setiap elemen muncul sebagai maksimum.

Cara yang lebih pendek untuk menghitung sub-intervensi kemungkinan akan menghemat karakter. Parametriisasi indeks tunggal dari pasangan [i,j]akan menjadi pendekatan yang masuk akal.

Tidak
sumber
1

Pip , 56 + 1 = 57 byte

Tidak bersaing banyak dengan voodoo CJam, saya khawatir. Sepertinya saya perlu algoritma yang lebih baik. Jalankan dengan -sbendera untuk mendapatkan output yang dibatasi ruang.

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

Tidak disatukan, dengan komentar:

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

Redefinisi rsetiap kali melalui karya sebagai berikut:

{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
sumber
1

APL (24)

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

Ini adalah fungsi yang mengambil daftar, seperti itu;

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

Penjelasan:

  • {...}⍵ : terapkan fungsi berikut untuk ⍵:
    • ⍵≡⍬:⍵: jika ⍵ kosong, kembalikan ⍵
    • 2⌈/⍵: buat daftar berikutnya
    • ⍵,∇: return ⍵, diikuti oleh hasil menerapkan fungsi ini ke daftar berikutnya
  • ⍵∘.=: bandingkan setiap elemen dalam ⍵ dengan setiap elemen dalam hasil fungsi
  • +/: jumlah baris (mewakili elemen dalam ⍵)
marinus
sumber
1

Haskell, 78 byte

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

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

Bagaimana itu bekerja

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
sumber
1

JavaScript, 109 byte

Saya pikir saya menemukan cara yang menarik untuk melakukan ini, tetapi hanya setelah saya selesai menyadari kode terlalu lama untuk bersaing. Oh well, tetap posting ini kalau-kalau seseorang melihat potensi golf lebih lanjut.

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}

Saya menggunakan rumus berikut di sini:

kemunculan i = (jumlah angka berurutan lebih kecil dari i ke kiri + 1) * (jumlah angka berurutan lebih kecil dari i ke kanan + 1)

Dengan cara ini orang tidak perlu benar-benar menghasilkan seluruh piramida atau himpunan bagian dari itu. (Itulah sebabnya saya awalnya berpikir itu akan berjalan di O (n), tapi untungnya, kita masih membutuhkan loop dalam.)

ay
sumber
1

MATLAB: (266 b)

  • koreksi kode membutuhkan lebih banyak byte, saya akan berjuang bagaimana menguranginya nanti.
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

MEMASUKKAN

vektor harus dalam bentuk [abcd ...]

  • contoh:

    [2 4 7 11 3]

KELUARAN

kejadian pola.

s =

 1


s =

 2


s =

 3


s =

 8


s =

 1

PENJELASAN:

jika [abcd] adalah input, program menghitung ghij hasil sebagai

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

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
sumber
0

J (49)

Saya kira ada beberapa ruang untuk perbaikan ...

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