Đếm trong kim tự tháp


17

Bạn nên viết một chương trình hoặc hàm nhận danh sách các số nguyên riêng biệt làm đầu vào và đầu ra hoặc trả về số lần xuất hiện của các số đầu vào trong kim tự tháp số lộn ngược sau đây.

Bắt đầu từ danh sách ban đầu trong mỗi bước, chúng tôi tạo một danh sách mới với các giá trị tối đa của mỗi cặp số liền kề (ví dụ: 5 1 2 6trở thành5 2 6 ). Chúng tôi dừng lại khi chỉ có một số trong danh sách.

Kim tự tháp đầy đủ cho 5 1 2 6

5 1 2 6
 5 2 6 
  5 6  
   6   

Số lần xuất hiện là 3 1 2 4(cho5 1 2 6 tương ứng).

Đầu vào

  • Một danh sách của một hoặc nhiều số nguyên không có sự lặp lại. (ví dụ: 1 5 1 6không hợp lệ.)

Đầu ra

  • Một danh sách các số nguyên dương. Phần itử thứ của danh sách là số lần xuất hiện của isố đầu vào thứ trong kim tự tháp.

Ví dụ

Đầu vào => Đầu ra

-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

Đây là môn đánh gôn nên bài dự thi ngắn nhất sẽ thắng.

Phần thưởng câu đố: bạn có thể giải quyết vấn đề O(n*log n)kịp thời không?


Để gửi chức năng, tôi có phải in chúng ra STDOUT hay đơn giản là xuất chúng?
Trình tối ưu hóa

Câu trả lời:


4

Pyth, 19 17 byte

m/smmeSb.:QhkUQdQ

Kiểm tra Trình diễn trực tuyến hoặc Bộ kiểm tra hoàn chỉnh (lặp 4 byte đầu tiên qua các ví dụ).

Đây là một chút thông minh hơn so với cách tiếp cận ngây thơ. Mỗi số của tam giác có thể được biểu diễn dưới dạng giá trị tối đa của một tập hợp con được kết nối củaQ . Trong dòng đầu tiên, nó sử dụng các tập hợp con có độ dài 1, dòng thứ hai của tam giác sử dụng các tập hợp con có độ dài 2, ...

Giải trình

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

Để hình dung điều này một chút. m.:QhdUQvà đầu vào [5, 1, 2, 6]cung cấp cho tôi tất cả các tập hợp con có thể:

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

mmeSk.:QhdUQđưa cho tôi từng cực đại của chúng (tương ứng chính xác với các hàng trong kim tự tháp):

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

Bình thường, 23 22 byte

|u&aYGmeSd.:G2QQm/sYdQ

Đây chỉ là cách tiếp cận "làm những gì bạn đã nói" đơn giản.

Kiểm tra Trình diễn trực tuyến hoặc Bộ kiểm tra hoàn chỉnh (lặp 4 byte đầu tiên qua các ví dụ).

Giải trình

meSd.:G2ánh xạ từng cặp [(G[0], G[1]), (G[1], G[2]), ...]thành phần tử cực đại.

Ylà một danh sách trống, do đó aYGnối Gvào Y.

u...QQliên tục áp dụng hai chức năng ( len(Q)thời gian) này bắt đầu G = Qvà cập nhật Gsau mỗi lần chạy.

m/sYdQánh xạ từng phần tử của danh sách đầu vào vào số của chúng trong Ydanh sách dẹt .


phiên bản 17 byte của bạn sử dụng thuật toán tương tự như của tôi, tôi đoán bây giờ cũng ngây thơ: P
Trình tối ưu hóa

13

Con trăn, 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

Một giải pháp phân chia và chinh phục. Phần tử tối đa Mthấm tất cả các kim tự tháp xuống, chia nó thành một hình chữ nhật gồm Mhai hình con.

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

Vì vậy, kết quả tổng thể là đầu ra cho danh sách con bên trái, tiếp theo là diện tích của hình chữ nhật, tiếp theo là đầu ra cho danh sách con bên phải.

Biến đầu vào Lđược sử dụng lại để lưu trữ kết quả sao cho danh sách trống được ánh xạ vào danh sách trống.

Các cấu trúc trong giải pháp là dài dòng trong Python. Có lẽ một số ngôn ngữ với khớp mẫu có thể thực hiện mã giả sau đây?

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

Tôi có thể thực hiện ngắn hơn một byte với khớp mẫu của Mathicala, nhưng nó thậm chí không đánh bại được đệ trình Mathicala hiện có: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

Vẫn đang tìm kiếm các lựa chọn chơi golf.

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

Đây là một chức năng CJam (loại). Điều này hy vọng các số đầu vào trên ngăn xếp và cũng trả về số lượng đầu ra tương ứng trên ngăn xếp. Một ví dụ:

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

3 1 2 4

trên ngăn xếp.

Khá chắc chắn rằng điều này không O(n log n)đúng lúc.

Mở rộng mã :

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

Hãy xem cách nó hoạt động bằng cách làm một ví dụ về 5 1 2 6

Trong hàng thứ hai, 5 1 2 6trở thành 5 2 6bởi vì 5, 2 and 6là tối đa [5 1], [1 2] and [2 6]tương ứng. Trong hàng thứ ba, nó trở thành 5 6bởi vì 5 and 6tối đa [5 2] and [2 6]tương ứng. Điều này cũng có thể được viết là tối đa [5 1 2] and [1 2 6]tương ứng. Tương tự cho hàng cuối cùng, 6là tối đa [5 1 2 6].

Vì vậy, về cơ bản, chúng ta tạo các lát có độ dài phù hợp bắt đầu từ lát cắt 1, về cơ bản là các số gốc, mỗi số được gói trong một mảng, cuối cùng là một lát dài Ncho hàng cuối cùng, trong đó Nsố lượng số nguyên đầu vào.

Dùng thử trực tuyến tại đây


3

Toán học, 72 byte

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

3

Con trăn, 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]

Mỗi mục của kim tự tháp là tối đa của danh sách con trên đỉnh hình nón hướng lên của nó. Vì vậy, chúng tôi tạo ra tất cả các danh sách phụ, lập chỉ mục bởi khoảng cách [i,j]với 0 < i < j <= len(L), và đếm có bao nhiêu thời gian mỗi phần tử xuất hiện như một tối đa.

Một cách ngắn hơn để liệt kê các khoảng thời gian có thể sẽ lưu các ký tự. Một tham số đơn lẻ của các cặp [i,j]sẽ là một cách tiếp cận hợp lý.


1

Pip , 56 + 1 = 57 byte

Không cạnh tranh nhiều với voodoo CJam, tôi sợ. Có vẻ như tôi cần một thuật toán tốt hơn. Chạy với -scờ để có đầu ra phân cách không gian.

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

Ungolfed, với ý kiến:

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

Việc xác định lại rmỗi lần thông qua các công việc như sau:

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

Đây là một chức năng có một danh sách, như vậy;

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

Giải trình:

  • {... }⍵: áp dụng chức năng sau cho:
    • ⍵≡⍬:⍵: nếu trống, trả về
    • 2⌈/⍵: tạo danh sách tiếp theo
    • ⍵,∇: return ⍵, theo sau là kết quả của việc áp dụng hàm này vào danh sách tiếp theo
  • ⍵∘.=: so sánh từng phần tử trong với từng phần tử trong kết quả của hàm
  • +/: tính tổng các hàng (biểu thị các phần tử trong ⍵)

1

Haskell, 78 byte

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

Cách sử dụng: 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].

Làm thế nào nó hoạt động

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

Tôi nghĩ rằng tôi đã tìm thấy một cách thú vị để thực hiện điều này, nhưng chỉ sau khi tôi hoàn thành, nhận ra mã quá dài để cạnh tranh. Oh tốt, dù sao đăng bài này trong trường hợp ai đó nhìn thấy tiềm năng chơi gôn hơn nữa.

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}

Tôi đang sử dụng công thức sau đây:

số lần xuất hiện của i = (số lượng các số liên tiếp nhỏ hơn i ở bên trái + 1) * (số lượng các số liên tiếp nhỏ hơn i bên phải + 1)

Bằng cách này, người ta không cần phải thực sự tạo ra toàn bộ kim tự tháp hoặc tập hợp con của nó. (Đó là lý do tại sao ban đầu tôi nghĩ nó sẽ chạy trong O (n), nhưng may mắn khó khăn, chúng ta vẫn cần các vòng lặp bên trong.)


1

MATLAB: (266 b)

  • Việc sửa mã tốn nhiều byte hơn, tôi sẽ đấu tranh làm thế nào để giảm nó sau.
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

ĐẦU VÀO

một vectơ phải có dạng [abcd ...]

  • thí dụ:

    [2 4 7 11 3]

ĐẦU RA

mô hình xảy ra.

s =

 1


s =

 2


s =

 3


s =

 8


s =

 1

GIẢI TRÌNH:

if [abcd] là một đầu vào, chương trình tính kết quả ghij là

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 ) = ... 'đơn giản hóa'

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)

Tôi cho rằng có một số chỗ để cải thiện ...

[:+/~.="1 0[:;([:i.#)<@:(4 :'(}:>.}.)^:x y')"0 1]
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.