การนับในปิรามิด


17

คุณควรเขียนโปรแกรมหรือฟังก์ชั่นที่รับรายการจำนวนเต็มที่แตกต่างกันเป็นอินพุตและเอาต์พุตหรือส่งกลับจำนวนการเกิดขึ้นของหมายเลขอินพุตในปิรามิดหมายเลขคว่ำด้านล่างดังต่อไปนี้

เริ่มต้นจากรายการต้นฉบับในทุกขั้นตอนเราสร้างรายการใหม่ที่มีค่าสูงสุดของตัวเลขที่อยู่ติดกันทุกคู่ (เช่น5 1 2 6กลายเป็น5 2 6) เราหยุดเมื่อมีเพียงหนึ่งหมายเลขในรายการ

ปิรามิดเต็มรูปแบบสำหรับ5 1 2 6คือ

5 1 2 6
 5 2 6 
  5 6  
   6   

จำนวนผลลัพธ์ที่เกิดขึ้นคือ3 1 2 4( 5 1 2 6ตามลำดับ)

อินพุต

  • รายการจำนวนเต็มหนึ่งรายการขึ้นไปโดยไม่มีการซ้ำซ้อน (เช่น1 5 1 6ไม่ถูกต้อง)

เอาท์พุต

  • รายการของจำนวนเต็มบวก iองค์ประกอบ TH ของรายการคือจำนวนของการเกิดขึ้นของiการป้อนตัวเลขจำนวนวันในปิรามิด

ตัวอย่าง

อินพุต => เอาท์พุท

-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

นี่คือรหัสกอล์ฟเพื่อให้รายการที่สั้นที่สุดชนะ

ตัวต่อโบนัส: คุณสามารถแก้ปัญหาได้O(n*log n)ทันเวลาหรือไม่?


สำหรับการส่งฟังก์ชั่นฉันต้องพิมพ์มันไปที่ STDOUT หรือส่งออกมันหรือไม่?
เครื่องมือเพิ่มประสิทธิภาพ

คำตอบ:


4

Pyth, 19 17 ไบต์

m/smmeSb.:QhkUQdQ

ตรวจสอบ สาธิตออนไลน์หรือชุดทดสอบที่สมบูรณ์(4 ไบต์แรกวนซ้ำตามตัวอย่าง)

อันนี้ค่อนข้างฉลาดกว่าความไร้เดียงสาเล็กน้อย Qจำนวนของรูปสามเหลี่ยมแต่ละคนสามารถแสดงเป็นค่าสูงสุดของส่วนย่อยที่เกี่ยวโยงกันของ ในบรรทัดแรกจะใช้ส่วนย่อยของความยาว 1 บรรทัดที่สองของรูปสามเหลี่ยมใช้ส่วนย่อยของความยาว 2 ...

คำอธิบาย

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

เมื่อต้องการเห็นภาพนี้เล็กน้อย m.:QhdUQและอินพุต[5, 1, 2, 6]ทำให้ฉันเซ็ตย่อยที่เป็นไปได้ทั้งหมด:

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

และ mmeSk.:QhdUQให้ค่าสูงสุดแต่ละค่าแก่ฉัน (ซึ่งตรงกับแถวในพีระมิด):

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

Pyth, 23 22 ไบต์

|u&aYGmeSd.:G2QQm/sYdQ

นี่เป็นเพียงวิธีการ "ทำในสิ่งที่คุณได้รับ" อย่างง่าย

ตรวจสอบการสาธิตออนไลน์หรือแบบสมบูรณ์ชุดทดสอบที่ (4 ไบต์แรกวนซ้ำตามตัวอย่าง)

คำอธิบาย

meSd.:G2 จับคู่แต่ละคู่ของ [(G[0], G[1]), (G[1], G[2]), ...]กับองค์ประกอบสูงสุด

Yเป็นรายการว่างดังนั้นจึงaYGผนวกGเข้ากับYกับ

u...QQใช้ฟังก์ชั่นทั้งสองนี้ซ้ำ ( len(Q)ครั้ง) ที่เริ่มต้นด้วยG = QและปรับปรุงGหลังจากการวิ่งแต่ละครั้ง

m/sYdQจับคู่แต่ละองค์ประกอบของรายการอินพุตเข้ากับจำนวนของพวกเขาในYรายการที่แบน


เวอร์ชั่น 17 ไบต์ของคุณใช้อัลกอริทึมเดียวกับของฉันฉันเดาว่าตอนนี้ไร้เดียงสาเช่นกัน: P
เครื่องมือเพิ่มประสิทธิภาพ

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

วิธีการแบ่งและพิชิต อิลิเมนต์สูงสุดMซึมลงไปจนถึงพีระมิดโดยแบ่งออกเป็นสี่เหลี่ยมผืนผ้าย่อยMและสองส่วน

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

ดังนั้นผลลัพธ์โดยรวมคือผลลัพธ์สำหรับรายการย่อยด้านซ้ายตามด้วยพื้นที่ของสี่เหลี่ยมผืนผ้าตามด้วยผลลัพธ์สำหรับรายการย่อยด้านขวา

ตัวแปรอินพุตLถูกใช้ซ้ำเพื่อเก็บผลลัพธ์เพื่อให้รายการว่างถูกแม็พกับรายการว่าง

โครงสร้างในการแก้ปัญหาเป็นคำใน Python บางทีภาษาที่มีการจับคู่รูปแบบอาจใช้ pseudocode ต่อไปนี้หรือไม่

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

ฉันสามารถทำหนึ่งไบต์ให้สั้นลงด้วยการจับคู่รูปแบบของ Mathematica แต่มันก็ไม่ชนะการส่ง Mathematica ที่มีอยู่: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 ไบต์

ยังคงมองหาตัวเลือกการเล่นกอล์ฟ

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

นี่คือฟังก์ชั่น CJam (เรียงลำดับจาก) สิ่งนี้คาดว่าหมายเลขอินพุตบนสแต็กและส่งคืนเอาต์พุตที่สอดคล้องกันบนสแต็กด้วย ตัวอย่าง:

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

ใบไม้

3 1 2 4

บนสแต็ก

ค่อนข้างแน่ใจว่านี่ไม่ใช่O(n log n)เวลา

การขยายรหัส :

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

ให้ดูที่การทำงานโดยการทำตัวอย่างของ 5 1 2 6

ในแถวที่สอง5 1 2 6กลายเป็น5 2 6เพราะ5, 2 and 6มีค่าสูงสุด[5 1], [1 2] and [2 6]ตามลำดับ ในแถวที่สามมันจะกลายเป็น5 6เพราะมาก5 and 6ที่สุด[5 2] and [2 6]ตามลำดับ สิ่งนี้สามารถเขียนได้สูงสุด[5 1 2] and [1 2 6]ตามลำดับ ในทำนองเดียวกันสำหรับแถวที่ผ่านมาเป็นจำนวนสูงสุดของ6[5 1 2 6]

โดยทั่วไปแล้วเราสร้างชิ้นความยาวที่เหมาะสมเริ่มต้นจากส่วนของความยาว1ซึ่งโดยทั่วไปแล้วจะเป็นตัวเลขดั้งเดิมซึ่งแต่ละส่วนจะถูกห่อในอาร์เรย์และในที่สุดก็จะเป็นความยาวNของแถวสุดท้ายซึ่งNเป็นจำนวนเต็มเข้า

ลองออนไลน์ได้ที่นี่



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]

แต่ละรายการของพีระมิดเป็นจำนวนสูงสุดของรายการย่อยที่อยู่ด้านบนของกรวย ดังนั้นเราจึงสร้างรายการย่อยทั้งหมดเหล่านี้จัดทำดัชนีตามช่วงเวลา[i,j]ด้วย0 < i < j <= len(L)และนับจำนวนครั้งที่แต่ละองค์ประกอบปรากฏเป็นค่าสูงสุด

วิธีที่สั้นกว่าในการแจกแจงช่วงย่อยน่าจะช่วยประหยัดอักขระได้ การหาค่าดัชนีแบบคู่ของคู่[i,j]จะเป็นวิธีที่น่าเชื่อถือ


1

Pip , 56 + 1 = 57 bytes

ไม่ได้แข่งขันมากกับวูดูของ CJam ฉันกลัว ดูเหมือนว่าฉันต้องการอัลกอริทึมที่ดีกว่า รันด้วย-sแฟล็กเพื่อรับเอาต์พุตที่คั่นด้วยช่องว่าง

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

Ungolfed พร้อมความคิดเห็น:

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

นิยามใหม่ของ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⌈/⍵}⍵}

นี่คือฟังก์ชั่นที่ใช้ในรายการเช่นนั้น

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

คำอธิบาย:

  • {... }⍵: ใช้ฟังก์ชันต่อไปนี้กับ⍵:
    • ⍵≡⍬:⍵: ถ้า⍵ว่างเปล่าส่งคืน⍵
    • 2⌈/⍵: สร้างรายการถัดไป
    • ⍵,∇: return ⍵ตามด้วยผลลัพธ์ของการใช้ฟังก์ชั่นนี้กับรายการถัดไป
  • ⍵∘.=: เปรียบเทียบแต่ละองค์ประกอบใน⍵กับแต่ละองค์ประกอบในผลลัพธ์ของฟังก์ชัน
  • +/: รวมแถว (แสดงองค์ประกอบใน representing)

1

Haskell, 78 ไบต์

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

การใช้งาน: ->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]

มันทำงานอย่างไร

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 ไบต์

ฉันคิดว่าฉันพบวิธีที่น่าสนใจในการทำสิ่งนี้ แต่หลังจากฉันทำเสร็จแล้วก็ตระหนักว่ารหัสนั้นยาวเกินไปที่จะแข่งขัน แหมดีโพสต์สิ่งนี้ต่อไปในกรณีที่มีคนเห็นศักยภาพการเล่นกอล์ฟต่อไป

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}

ฉันใช้สูตรต่อไปนี้ที่นี่:

การเกิดขึ้นของ i = (จำนวนของตัวเลขที่ต่อเนื่องกันน้อยกว่า i ไปทางซ้าย + 1) * (จำนวนของตัวเลขที่ต่อเนื่องกันน้อยกว่า i ไปทางขวา + 1)

วิธีนี้ไม่จำเป็นต้องสร้างปิรามิดหรือชุดย่อยทั้งหมด (ซึ่งเป็นสาเหตุที่ฉันเริ่มคิดว่ามันจะทำงานใน O (n) แต่โชคดีเรายังต้องใช้วงใน)


1

MATLAB: (266 b)

  • การแก้ไขรหัสมีค่าใช้จ่ายมากกว่านั้นฉันจะพยายามหาวิธีลดรหัสในภายหลัง
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

INPUT

เวกเตอร์ต้องอยู่ในรูปแบบ [abcd ... ]

  • ตัวอย่าง:

    [2 4 7 11 3]

เอาท์พุท

รูปแบบที่เกิดขึ้น

s =

 1


s =

 2


s =

 3


s =

 8


s =

 1

คำอธิบาย:

ถ้า [abcd] เป็นอินพุตโปรแกรมจะคำนวณผลลัพธ์ ghij เป็น

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 ) = ... 'เรียบง่าย'

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


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.