มันเป็นจำนวนสูงสุดหรือไม่


14

กองยังเป็นที่รู้จักลำดับความสำคัญคิวเป็นชนิดข้อมูลนามธรรม โดยหลักการแล้วมันเป็นต้นไม้ไบนารีที่ลูกของทุกโหนดมีขนาดเล็กกว่าหรือเท่ากับโหนดเอง (สมมติว่าเป็น max-heap.) เมื่อองค์ประกอบถูกผลักหรือผุด heap จะจัดเรียงตัวเองใหม่ดังนั้นองค์ประกอบที่ใหญ่ที่สุดคือถัดไปที่จะถูกตอก มันสามารถนำมาใช้เป็นต้นไม้หรือเป็นอาร์เรย์ได้อย่างง่ายดาย

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

[90, 15, 10, 7, 12, 2]

จริงๆนี่คือต้นไม้ไบนารีที่จัดเรียงในรูปแบบของอาร์เรย์ นี่เป็นเพราะทุกองค์ประกอบมีลูก 90 มีลูกสองคน 15 และ 10

       15, 10,
[(90),         7, 12, 2]

15 มีเด็ก 7 และ 12:

               7, 12,
[90, (15), 10,        2]

10 มีลูก:

                      2
[90, 15, (10), 7, 12,  ]

และองค์ประกอบต่อไปก็จะเป็นลูกของ 10 ยกเว้นว่าไม่มีที่ว่าง 7, 12 และ 2 ทุกคนจะมีลูกด้วยเช่นกันถ้าอาเรย์นั้นยาวพอ นี่เป็นอีกตัวอย่างหนึ่งของกอง:

[16, 14, 10, 8, 7, 9, 3, 2, 4, 1]

และนี่คือการสร้างภาพต้นไม้ที่อาร์เรย์ก่อนหน้าสร้างขึ้น:

ป้อนคำอธิบายรูปภาพที่นี่

ในกรณีที่มันไม่ชัดเจนพอนี่คือสูตรที่ชัดเจนเพื่อให้เด็ก ๆ ขององค์ประกอบที่ฉัน

//0-indexing:
child1 = (i * 2) + 1
child2 = (i * 2) + 2

//1-indexing:
child1 = (i * 2)
child2 = (i * 2) + 1

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

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

คุณสามารถใช้สคริปต์ python นี้เพื่อตรวจสอบว่าอาร์เรย์อยู่ในรูปแบบฮีปหรือไม่ (ดัชนี 0):

def is_heap(l):
    for head in range(0, len(l)):
        c1, c2 = head * 2 + 1, head * 2 + 2
        if c1 < len(l) and l[head] < l[c1]:
            return False
        if c2 < len(l) and l[head] < l[c2]:
            return False

    return True

ทดสอบ IO:

อินพุตทั้งหมดเหล่านี้ควรส่งคืน True:

[90, 15, 10, 7, 12, 2]
[93, 15, 87, 7, 15, 5]
[16, 14, 10, 8, 7, 9, 3, 2, 4, 1]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
[100, 19, 36, 17, 3, 25, 1, 2, 7]
[5, 5, 5, 5, 5, 5, 5, 5]

และอินพุตเหล่านี้ทั้งหมดควรส่งคืนค่าเท็จ:

[4, 5, 5, 5, 5, 5, 5, 5]
[90, 15, 10, 7, 12, 11]
[1, 2, 3, 4, 5]
[4, 8, 15, 16, 23, 42]
[2, 1, 3]

ตามปกตินี่คือ code-golf ดังนั้นช่องโหว่มาตรฐานจึงนำมาใช้และคำตอบที่สั้นที่สุดในการชนะไบต์!



ถูกต้องหรือไม่หากมีองค์ประกอบที่ซ้ำกันอาจเป็นไปไม่ได้ที่จะรวมกองตามคำจำกัดความนี้?
feersum

@feersum เกี่ยวกับอะไร[3, 2, 1, 1]?
Neil

@feersum นั่นเป็นจุดที่ดีฉันไม่ได้คิดอย่างนั้น ฉันอัปเดตคำอธิบายของฮีปและเพิ่มตัวอย่างด้วยองค์ประกอบที่ซ้ำกัน ขอขอบคุณ!
James

5
ฮีปไม่รู้จักในชื่อคิวลำดับความสำคัญ คิวลำดับความสำคัญเป็นชนิดข้อมูลนามธรรม บางครั้งฮีปคือโครงสร้างข้อมูลที่ใช้ในการสร้างคิวลำดับความสำคัญ (heap นั้นถูกนำไปใช้กับโครงสร้างข้อมูล fundermental มากขึ้น แต่นั่นอยู่ด้านข้าง) คิวลำดับความสำคัญสามารถใช้งานได้ที่ด้านบนของโครงสร้างข้อมูลอื่น - เช่นรายการที่เชื่อมโยง
Lyndon White

คำตอบ:


7

เยลลี่ 11 9 5 ไบต์

x2:ḊṂ

ลบ 4 ไบต์ด้วย Dennis!

ลองที่นี่

คำอธิบาย

x2          Duplicate each element.
:Ḋ          Each element divided by the input with the first element removed,
            as integer, so there is a 0 only if some element in the duplicated
            list is less than the corresponding element in the other.
            There are also elements left unchanged, but it doesn't matter as
            the input is all positive.
Ṃ           Minimum in the list.

10

JavaScript (ES6), 34 30 ไบต์

a=>!a.some((e,i)=>e>a[i-1>>1])

แก้ไข: แก้ไขรหัสของฉันสำหรับข้อมูลจำเพาะการชี้แจงค่าใช้จ่าย 1 ไบต์ดังนั้นต้องขอบคุณ @ edc65 สำหรับการบันทึก 4 ไบต์


มันล้มเหลวในการทดสอบ 2 [93, 15, 87, 7, 15, 5]และ 6[5, 5, 5, 5, 5, 5, 5, 5]
edc65

วิธีนี้ใช้งานได้ดีกว่าและสั้นกว่า 3 ถ่านa=>!a.some((e,i)=>e>a[i-1>>1])
edc65

1
@ edc65 มีการเพิ่มข้อความทดสอบเหล่านั้นหลังจากฉันเขียนคำตอบแล้ว
Neil


4

J, 24 ไบต์

*/@:<:]{~0}:@,<.@-:@i.@#

คำอธิบาย

*/@:<:]{~0}:@,<.@-:@i.@#  Input: s
                       #  Count of s
                    i.@   Create range [0, 1, ..., len(s)-1]
                 -:@      Halve each
              <.@         Floor each
         0   ,            Prepend a zero to it
          }:@             Remove the last value to get the parent indices of each
      ]                   Identity function to get s
       {~                 Take the values from s at the parent indices
    <:                    For each, 1 if it is less than or equal to its parent else 0
*/@:                      Reduce using multiplication and return

3

MATL , 13 12 ไบต์

ttf2/k)>~4L)

ลองออนไลน์!หรือตรวจสอบกรณีทดสอบทั้งหมด

อาร์เรย์เป็นจริงถ้าไม่ว่างเปล่าและรายการทั้งหมดเป็นค่าที่ไม่ใช่ศูนย์ มิฉะนั้นมันจะเป็นเท็จ นี่ตัวอย่างบางส่วน

คำอธิบาย

t     % Take input implicitly. Duplicate
tf    % Duplicate and push indices of nonzero entries. This gives [1 2 ... n] where n
      % is input size
2/k   % Divide by 2 and round down
)     % Index into input. Gives array of parents, except for the first entry
>~    % True for entries of the input that don't exceed those in the array of parents
4L)   % Discard first entry

2

Python 2, 45 ไบต์

f=lambda l:l==[]or l[len(l)/2-1]/l.pop()*f(l)

เอาต์พุต 0 สำหรับ Falsy ไม่ใช่ศูนย์สำหรับ Truthy

len(l)/2-1ตรวจสอบว่าองค์ประกอบสุดท้ายคือน้อยกว่าหรือเท่ากับแม่ที่ดัชนี จากนั้นซ้ำอีกครั้งเพื่อตรวจสอบว่าเป็นจริงพร้อมกับองค์ประกอบสุดท้ายของรายการที่ถูกลบและอื่น ๆ จนกว่ารายการจะว่างเปล่า


48 ไบต์:

f=lambda l,i=1:l==l[:i]or l[~-i/2]/l[i]*f(l,i+1)

ตรวจสอบว่าในแต่ละดัชนี iอิลิเมนต์จะเป็นพาเรนต์ที่ดัชนีมากที่สุด(i-1)/2องค์ประกอบที่ส่วนใหญ่ผู้ปกครองที่ดัชนีการแบ่งพื้นผลิต 0 ถ้าไม่ใช่กรณี

การทำเคสฐานi/len(l)orให้มีความยาวเท่ากัน ตอนแรกฉันลองซิปแล้ว แต่ได้รหัสยาวกว่า (57 ไบต์)

lambda l:all(map(lambda a,b,c:b<=a>=c,l,l[1::2],l[2::2]))

1

R, 97 88 82 ไบต์

หวังว่าฉันจะเข้าใจเรื่องนี้ถูกต้อง ทีนี้เพื่อดูว่าฉันสามารถกำจัดไบต์ได้มากกว่านี้หรือไม่ ทิ้ง rbind แล้วใส่ลงไปในแก้วและจัดการกับเวกเตอร์ที่ใช้ 1 ตัวได้อย่างถูกต้อง

ใช้งานเป็นฟังก์ชั่นที่ไม่มีชื่อ

function(Y)all(sapply(1:length(Y),function(X)Y[X]>=Y[X*2]&Y[X]>=Y[X*2+1]),na.rm=T)

ด้วยกรณีทดสอบบางอย่าง

> f=
+ function(Y)all(sapply(1:length(Y),function(X)Y[X]>=Y[X*2]&Y[X]>=Y[X*2+1]),na.rm=T)
> f(c(90, 15, 10, 7, 12, 2))
[1] TRUE
> f(c(93, 15, 87, 7, 15, 5))
[1] TRUE
> f(c(10, 9, 8, 7, 6, 5, 4, 3, 2, 1))
[1] TRUE
> f(c(5, 5, 5, 5, 5, 5, 5, 5))
[1] TRUE
> f(c(4, 5, 5, 5, 5, 5, 5, 5))
[1] FALSE
> f(c(90, 15, 10, 7, 12, 11))
[1] FALSE
> f(c(4, 8, 15, 16, 23, 42))
[1] FALSE

คุณสามารถใช้แทนseq(Y) 1:length(Y)
rturnbull




0

C ++ 14, 134 105 ไบต์

#define M(d) (2*i+d<c.size()&&(c[i]<c[2*i+d]||f(c,2*i+d)==0))
int f(auto&c,int i=0){return!(M(1)||M(2));}

ต้องcเป็นภาชนะรองรับ.operator[](int)และ.size()std::vector<int>เช่น

Ungolfed:

int f(auto& c, int i=0) {
    if (2*i+1<c.size() && c[i] < c[2*i+1]) return 0;
    if (2*i+2<c.size() && c[i] < c[2*i+2]) return 0;
    if (2*i+1<c.size() && (f(c,2*i+1) == 0)) return 0;
    if (2*i+2<c.size() && (f(c,2*i+2) == 0)) return 0;
    return 1;
}

อาจมีขนาดเล็กลงหากความจริง = 0และเท็จ = 1จะได้รับอนุญาต


0

R, 72 ไบต์

วิธีการที่แตกต่างกันเล็กน้อยจากคำตอบที่ R อื่น ๆ

x=scan();all(diff(x[c(a<-1:(N<-sum(1|x)),a,a*2,a*2+1)],l=N*2)<1,na.rm=T)

อ่านอินพุตจาก stdin สร้างเวกเตอร์ของคู่เปรียบเทียบทั้งหมดลบออกจากกันและตรวจสอบว่าผลลัพธ์นั้นเป็นจำนวนลบหรือศูนย์

คำอธิบาย

อ่านข้อมูลจาก stdin:

x=scan();

สร้างคู่ของเรา เราสร้างดัชนีของ1...N(โดยที่Nคือความยาวx) สำหรับโหนดพาเรนต์ เราใช้เวลาสองครั้งในขณะที่ผู้ปกครองแต่ละคนมีลูกสองคน (สูงสุด) นอกจากนี้เรายังใช้เด็กและ(1...N)*2 (1...N)*2+1สำหรับดัชนีที่เกินความยาวxR จะส่งคืนNA'ไม่พร้อมใช้งาน' สำหรับการป้อนรหัสนี้จะช่วยให้เรา90 15 10 7 12 290 15 10 7 12 2 90 15 10 7 12 2 15 7 2 NA NA NA 10 12 NA NA NA NA

                  x[c(a<-1:(N<-sum(1|x)),a,a*2,a*2+1)]

ในเวกเตอร์ของคู่นี้แต่ละองค์ประกอบมีคู่ของมันในระยะทางที่ไกลN*2ออกไป ตัวอย่างเช่นพันธมิตรของรายการ 1 ตั้งอยู่ที่ตำแหน่ง 12 (6 * 2) เราใช้diffในการคำนวณความแตกต่างระหว่างคู่เหล่านี้โดยระบุlag=N*2เพื่อเปรียบเทียบรายการกับพันธมิตรที่ถูกต้อง การดำเนินการใด ๆ เกี่ยวกับองค์ประกอบก็กลับNANA

             diff(x[c(a<-1:(N<-sum(1|x)),a,a*2,a*2+1)],l=N*2)

สุดท้ายเราตรวจสอบว่าค่าที่ส่งคืนทั้งหมดเหล่านี้น้อยกว่า1(นั่นคือหมายเลขแรกคือพาเรนต์ใหญ่กว่าหมายเลขที่สองคือลูก) ไม่รวมNAค่าจากการพิจารณา

         all(diff(x[c(a<-1:(N<-sum(1|x)),a,a*2,a*2+1)],l=N*2)<1,na.rm=T)

0

จริงแล้ว 16 ไบต์

คำตอบนี้ส่วนใหญ่จะขึ้นอยู่กับjimmy23013 คำตอบของวุ้น ยินดีต้อนรับคำแนะนำการเล่นกอล์ฟ! ลองออนไลน์!

;;2╟┬Σ1(tZ`i<`Mm

Ungolfing

         Implicit input a.
;;       Duplicate a twice.
2╟       Wrap two of the duplicates into a list.
┬        Transpose the duplicates.
Σ        Sum all of the columns to get a flat list like this:
           [a_0, a_0, a_1, a_1, ..., a_n, a_n]
         This gets the parent nodes of the heap.
1(t      Get a[1:] using the remaining duplicate of a.
         This is a list of the child nodes of the heap.
Z`i<`M   Check if every child node is less than its parent node.
m        Get the minimum. This returns 1 if a is a max-heap, else 0.
         Implicit return.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.