Maksimum yığın mı?


14

Öncelik kuyruğu olarak da bilinen bir yığın , soyut bir veri türüdür. Kavramsal olarak, her düğümün çocuklarının düğümün kendisinden daha küçük veya ona eşit olduğu ikili bir ağaçtır. (Bir maks-yığın olduğu varsayılarak.) Bir öğe itildiğinde veya patlatıldığında, yığın kendisini yeniden düzenler, böylece en büyük öğe patlatılacak bir sonraki öğedir. Kolayca ağaç veya dizi olarak uygulanabilir.

Eğer kabul ederseniz, meydan okuma, bir dizinin geçerli bir yığın olup olmadığını belirlemektir. Her öğenin alt öğeleri öğenin kendisinden küçük veya ona eşitse bir dizi yığın biçimindedir. Aşağıdaki diziyi örnek olarak alalım:

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

Gerçekten, bu bir dizi şeklinde düzenlenmiş bir ikili ağaçtır. Çünkü her elementin çocukları vardır. 90'ın 15 ve 10 olmak üzere iki çocuğu vardır.

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

15'in ayrıca 7 ve 12 çocukları vardır:

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

10 çocuk sahibi:

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

ve bir sonraki eleman da yer olmadığı için 10 kişilik bir çocuk olurdu. Dizi yeterince uzun olsaydı 7, 12 ve 2 de çocuk sahibi olurdu. Yığın başka bir örneği:

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

Ve işte önceki dizinin yaptığı ağacın bir görselleştirmesi:

resim açıklamasını buraya girin

Bunun yeterince açık olmaması durumunda, i'th elementinin çocuklarını elde etmek için açık formül

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

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

Boş olmayan bir diziyi girdi olarak almalı ve dizi yığın düzenindeyse bir doğruluk değeri, aksi halde bir yanlış değeri vermelisiniz. Programınızın / işlevinizin hangi biçimi beklediğini belirlediğiniz sürece, 0 dizinli bir yığın veya 1 dizinli bir yığın olabilir. Tüm dizilerin yalnızca pozitif tamsayılar içereceğini varsayabilirsiniz. Sen olabilir değil herhangi yığın-yerleşiklerini kullanın. Bu, bunlarla sınırlı olmamak üzere

  • Bir dizinin yığın biçiminde olup olmadığını belirleyen işlevler
  • Bir diziyi bir öbeğe veya yığın biçimine dönüştüren işlevler
  • Bir diziyi girdi olarak alan ve yığın veri yapısını döndüren işlevler

Bir dizinin yığın biçiminde olup olmadığını doğrulamak için bu python komut dosyasını kullanabilirsiniz (0 dizinli):

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

Test G / Ç:

Bu girdilerin tümü True döndürmelidir:

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

Ve tüm bu girdiler Yanlış döndürmelidir:

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

Her zamanki gibi, bu kod golf, bu yüzden standart boşluklar geçerlidir ve bayttaki en kısa cevap kazanır!



Tekrarlanan elemanlar varsa, bu tanıma göre bir yığın oluşturmanın imkansız olabileceği doğru mu?
feersum

@feersum Ne olmuş [3, 2, 1, 1]?
Neil

@feersum Bu harika bir nokta, bunu hiç düşünmemiştim. Bir yığının açıklamasını güncelledim ve yinelenen öğelerle bazı örnekler ekledim. Teşekkür ederim!
James

5
Bir yığın, öncelik sırası olarak da bilinmez. Öncelik kuyruğu soyut veri türüdür. Yığın, bazen öncelik kuyruğunu uygulamak için kullanılan veri yapısıdır (Yığın kendisi, daha fazla veri kaynağı yapısının üstüne uygulanır, ancak bu noktanın yanındadır). Öncelik kuyrukları, bağlantılı listeler gibi diğer veri yapılarının üzerine uygulanabilir.
Lyndon White

Yanıtlar:


7

Jöle, 11 9 5 bayt

x2:ḊṂ

Dennis sayesinde 4 bayt kaldı!

Burada deneyin.

açıklama

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 bayt

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

Düzenleme: Kodumun spesifikasyon maliyeti 1 bayt için düzeltilmesi, böylece 4 bayt tasarrufu için @ edc65 sayesinde.


[93, 15, 87, 7, 15, 5][5, 5, 5, 5, 5, 5, 5, 5]
Testcase

Bu daha iyi çalışıyor ve 3 karakter daha kısaa=>!a.some((e,i)=>e>a[i-1>>1])
edc65

1
@ edc65 Cevabımı yazdıktan sonra bu test kılıfları eklendi.
Neil

5

Haskell, 33 bayt

f(a:b)=and$zipWith(<=)b$a:b<*"xx"

veya

and.(zipWith(<=).tail<*>(<*"xx"))

4

J, 24 bayt

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

açıklama

*/@:<:]{~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 bayt

ttf2/k)>~4L)

Çevrimiçi deneyin! Veya tüm test senaryolarını doğrulayın .

Bir dizi boş değilse ve tüm girdileri sıfırdan farklıysa doğrudur. Aksi takdirde sahtelik. İşte bazı örnekler .

açıklama

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 bayt

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

Falsy için 0, Truthy için sıfır olmayan çıkışlar.

Son öğenin dizindeki üst öğesinden küçük veya ona eşit olup olmadığını denetler len(l)/2-1. Daha sonra, listenin son öğesi kaldırılmış olarak aynı olup olmadığını kontrol etmek için tekrarlar ve liste boş olana kadar devam edin.


48 bayt:

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

Her bir dizinde i, öğenin en fazla dizinde üst öğesi olup olmadığını denetler (i-1)/2. Durum böyle değilse, taban bölümü 0 üretir.

Temel kasayı i/len(l)oraynı uzunlukta yapmak. İlk başta sıkıştırmayı denemiştim, ancak daha uzun kod aldım (57 bayt).

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

1

R, 97 88 82 bayt

Umarım bunu doğru anladım. Şimdi biraz daha bayttan kurtulabileceğimi görmek için. Ardı ardına attı ve bir aptal koyun ve 1 tabanlı vektör ile düzgün bir şekilde ilgilenin.

Adsız bir işlev olarak uygulanır

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

Birkaç test vakasıyla

> 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

Bunun seq(Y)yerine kullanabilirsiniz 1:length(Y).
rturnbull


1

Pyth, 8 bayt

.AgV.i+h

       hQ      first element of input
      +  Q     plus input
    .i    Q    interleaved with input
  gV       Q   vectorized greater-than-or-equal comparison with input
.A             check if all results are true

Çevrimiçi deneyin


1

Retina , 51 bayt

\d+
$*
^(?!(1+ )*(1+) 1* ?(?<-1>1+ )*(?(1)(?!))1\2)

Çevrimiçi deneyin!


Girdi olarak boşlukla ayrılmış bir sayı listesi alır. Çıktılar 1/ 0doğru / yanlış için


0

C ++ 14, 134105 bayt

#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));}

Gerektirir cbir kap destek olmak .operator[](int)ve .size()benzeri 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;
}

Doğruluk = 0ve falsiye = 1izin verilirse daha küçük olabilir .


0

R, 72 bayt

Diğer R cevabından biraz farklı bir yaklaşım .

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'den girdi okur, karşılaştırma çiftlerinin bir vektörünü oluşturur, birbirinden çıkartır ve sonucun negatif bir sayı veya sıfır olup olmadığını kontrol eder.

açıklama

Stdin'den girişi okuyun:

x=scan();

Çiftlerimizi oluşturun. Üst düğümler için endeksler oluştururuz 1...N( Nuzunluğu burada x). Her ebeveynin (en fazla) iki çocuğu olduğu için bunu iki kez alıyoruz. Çocukları da alıyoruz (1...N)*2ve (1...N)*2+1. Uzunluğunun ötesindeki indeksler için x, R geri döner NA, 'kullanılamaz'. Giriş için90 15 10 7 12 2 bu kod bize verir 90 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)]

Bu çift vektöründe, her elemanın N*2uzak mesafeden ortağı vardır . Örneğin, madde 1'in ortağı 12 pozisyonunda (6 * 2) bulunmaktadır. Öğeleri doğru ortaklarıyla karşılaştırmayı diffbelirterek, bu çiftler arasındaki farkı hesaplamak için kullanırız lag=N*2. NAElemanlar üzerindeki herhangi bir işlem geri dönerNA .

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

Son olarak, bu döndürülen değerlerin, dikkate alınan değerler 1hariç olmak üzere , tüm değerlerden daha düşük (yani, ilk sayı, üst öğe, ikinci sayıdan, çocuktan büyük) olduğunu kontrol ederiz 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

Aslında 16 bayt

Bu cevap büyük ölçüde jimmy23013'ün Jelly cevabına dayanmaktadır . Golf önerileri hoş geldiniz! Çevrimiçi deneyin!

;;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.
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.