Dağ bölgemde kaç tane tepe var?


27

Pozitif tamsayıların listesi, her bir liste girişinin dağların dikey bir bölümünün yüksekliğini temsil ettiği, nicelenmiş bir dağ silsilesi olarak görselleştirilebilir.

Örneğin, liste

1, 2, 2, 3, 4, 3, 5, 3, 2, 1, 2, 3, 3, 3, 2, 2, 1, 3

menzil olabilir

      x
    x x      
   xxxxx   xxx   x
 xxxxxxxx xxxxxx x
xxxxxxxxxxxxxxxxxx

(Daha az şiirsel insanlar buna çubuk grafik diyebilir, ancak dalıyorum.)

Bu zorluktaki soru şudur: Bazı keyfi listelerin dağ aralığında kaç tepe var? Esasen, listede kaç tane yerel makam var?

Bir tepe, hemen hemen sola ve sağın sütunlarının yüksekliklerinin düşük olduğu dağ aralığının bir veya daha fazla sütununun yüksekliğinde eşit olan bitişik bir bölümü olarak tanımlanır.

Örneğin parantez içindeki bu yerlerde dört tepe noktası olduğunu görsel olarak söylemek kolaydır:

1, 2, 2, 3, (4), 3, (5), 3, 2, 1, 2, (3, 3, 3), 2, 2, 1, (3)

(3, 3, 3)Plato bölümünün tepe noktası olarak nasıl sayıldığına dikkat edin, çünkü komşu sütunlarından daha yüksek, aynı yükseklikte sütunlar kümesidir.

Sonuncusu (3)da bir zirve olarak sayılır, çünkü bu zorluğun amaçları için en soldaki sütunun sol komşusunu ve en sağdaki sütunun sağ komşusunu hem sıfır yüksek olacak şekilde tanımlayacağız.

Tek bir değer ile bir liste, örneğin, bu araçlar 1, 1, 1, olarak yorumlanabilir 0, 1, 1, 1, 0, böylece, bir tepe değil, hiç var 0, (1, 1, 1), 0.

Sıfır tepe noktası olan tek liste boş listedir.

Meydan okuma

Olumlu tamsayıların rastgele bir listesine giren ve karşılık gelen dağlık aralıktaki tepe sayısını yazdıran veya döndüren bir işlev veya program yazın.

Bayt cinsinden en kısa kod kazanır. Tiebreaker daha önce yayınlandı.

Test Kılıfları

Input List -> Output Peak Count
[empty list] -> 0
1, 1, 1 -> 1
1, 2, 2, 3, 4, 3, 5, 3, 2, 1, 2, 3, 3, 3, 2, 2, 1, 3 -> 4
1 -> 1
1, 1 -> 1
2, 2, 2, 2, 2 -> 1
90 -> 1
2, 1, 2 -> 2
5, 2, 5, 2, 5 -> 3
2, 5, 2, 5, 2, 5, 2 -> 3
1, 2, 3, 4 -> 1
1, 2, 3, 4, 1, 2 -> 2
1, 3, 5, 3, 1 -> 1
7, 4, 2, 1, 2, 3, 7 -> 2
7, 4, 2, 1, 2, 1, 2, 3, 7 -> 3
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2 -> 10
1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1 -> 10
2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2 -> 10
1, 3, 3, 3, 1, 3, 3, 1, 3, 1, 3, 3, 3, 3, 1 -> 4
12, 1, 2, 1, 2, 3, 3, 3, 2, 4, 4, 4, 1, 5, 5, 4, 7, 9 -> 6
87, 356, 37673, 3676, 386, 909, 909, 909, 909, 454, 909, 909 -> 3
87, 356, 37673, 3676, 386, 909, 909, 909, 909, 454, 909, 908, 909 -> 4

Yani, plato keyfi uzun olabilir?
nicael

@nicael Evet, olabilir
Calvin'in Hobileri

Girdiyi dizge olarak değil dizge olarak alabilir miyiz?
nicael

@nicael Evet, makul olan herhangi bir şey
Calvin'in Hobileri

Yanıtlar:


2

Pyth, 18 bayt

su_>VGtG2eMr++ZQZ8

@ PeterTaylor'un çözümü, çözümden daha fazla tekrarlandı, ancak bir bükülme ile.

++ZQZ: Her iki tarafa da sıfır ekleyin.

eMr ... 8: Tekrarları kaldır.

u ... 2 ...: Aşağıdakileri iki kez uygulayın:

>VGTG: Her bir sayı çiftini azalan sırada olup olmadıklarına göre eşleyin.

_: Ve tersi.

Çıktıdaki A 1 , tersine çevrme nedeniyle girdiye 1, 0karşılık gelen önceki bir basamağa karşılık gelir a < b > c.

s: Toplam (ve yazdır)


10

CJam ( 32 26 24 21 bayt)

0q~0]e`1f=2ew::>2,/,(

Beklenen girdi boşlukla ayrılmış sayılardır.

Çevrimiçi demo ; tam test paketi (beklenen çıktı bir1 test başına başınadır).

Martin'e, CJam'ın şu anki sürümünün kullanılan operatörlerden birini iyileştirdiğini ve 2 karakter kazandırdığını bildirdiği için teşekkürler; ve 3 char daha tasarruf için.

teşrih

İki faz: veri tekilleştirin, ardından her üçlü sette yerel maksimum değerleri tanımlayın.

0q~0]      e# Put the input in an array wrapped in [0 ... 0]
e`1f=      e# Use run-length encoding to deduplicate
2ew::>     e# Map [a b c ...] to [(a>b) (b>c) ...]
2,/        e# Split on [0 1], which since we've deduplicated occurs when (a<b) (b>c)
,(         e# Count the parts and decrement to give the number of [0 1]s

7

JavaScript (ES6), 54 51 bayt

m=>m.map(n=>{h=n<p?h&&!++r:n>p||h;p=n},r=h=p=0)|r+h

açıklama

Bir dizi numara alır

m=>
  m.map(n=>{       // for each number n in the mountain range
      h=
        n<p?       // if the number is less than the previous number:
          h&&      // if the previous number was greater than the number before it
          !++r     // increment the number of peaks and set h to 0
        :n>p||h;   // if the number is greater than the previous number, set h to 1
      p=n          // set p to the current number
    },
    r=             // r = number of peaks
    h=             // h = 1 if the previous number was higher than the one before it
    p=0            // p = previous number
  )|r+h            // return the output (+ 1 if the last number was higher)

Ölçek


5

Pyth, 25 23 bayt

L._M-M.:b2s<R0y-y+Z+QZZ

Açıklama:

L              y = lambda b:
  ._M -M .:          signs of subsets
           b          of b
           2          of length 2. That is, signs of differences.

s <R              number of elements less than
     0              0 in
     y -            y of ... with zeroes removed
         y +          y of
             Z        the input with zeroes tacked on both sides
             + Q Z
       Z              

Güzel. Alışılmadık bir şekilde, CJam limanı daha kısa: 0q~0]{2ew::-:g0-}2*1-,22 için.
Peter Taylor

4

Julia, 66

x->(y=diff([0;x;0]);y=y[y.!=0];sum((y[1:end-1].>0)&(y[2:end].<0)))

Tampon, ayırt: y=diff([0;x;0]).
Yaylaları Ignore: y=y[y.!=0].
Sayım +için -sıfır geçişleri: sum((y[1:end-1].>0)&(y[2:end].<0)).


3

MATLAB, 29 27 bayt

@(a)nnz(findpeaks([0 a 0]))

Verideki zirveleri bulan ve kaç tane bulunduğunu sayan isimsiz fonksiyon. En uçtaki tepe noktalarının soruya göre tespit edilmesini sağlamak için verilere 0 hazırlanır ve eklenir.

Bu Octave ile de çalışacak . Şunları yapabilirsiniz buraya çevrimiçi deneyin . Yukarıdaki kodu komut satırına yapıştırın ve sonra ans([1,2,1,3,4,5,6,1])(veya ne olursa olsun) ile çalıştırın .


Sayılar her zaman + ve olduğu için sıfırdan büyük olduklarını varsayabiliriz, bu yüzden nnzyerine 2 bayt tasarruf edebiliriz numel.


3

Python 3, 75 bayt

def m(t):
 a=p=d=0
 for n in t+[0]:a+=(n<p)&d;d=((n==p)&d)+(n>p);p=n
 return a

Bu benim ilk kodgolf'um, bu yüzden kısaltması gereken yerler olabilir, özellikle d=((n==p)&d)+(n>p)kısmı. Ancak tüm test durumlarında çalışır


Bunlar 78 bayt değil mi?
Jonathan Frech

3

Mathematica, 42 36 33 32 bayt

Martin Büttner'e 1 byte tasarruf ettiğin için teşekkürler.

Tr@PeakDetect[#&@@@Split@#,0,0]&

PeakDetect sadece hemen hemen her şeyi yapar!

Test durumları:

Total@PeakDetect[#&@@@Split@#,0,0]&@{12,1,2,1,2,3,3,3,2,4,4,4,1,5,5,4,7,9}
(* 6 *)
Total@PeakDetect[#&@@@Split@#,0,0]&@{87,356,37673,3676,386,909,909,909,909,454,909,908,909}
(* 4 *)

Cevabımı , sizinkinden bir başkasını göndermek için yeterince farklı buluyorum .
LegionMammal978

@ LegionMammal978 {1} girişinin sonucu beklendiği gibi 1'dir.
njpipeorgan

Yani {1, 2, 2, 3, 4, 3, 5, 3, 2, 1, 2, 3, 3, 3, 2, 2, 1, 3}
LegionMammal978

@ LegionMammal978 Bu çok zor. Bir çözüm bulamadım.
njpipeorgan

Güncelleştirilmiş çözümüm sadece "plato" düzleştiriyor.
LegionMammal978

2

CJam, 27 26 bayt

A0q~0A]e`1f=3ew{~@e>>}%1e=

Kopyaları kaldırmak için çalışma uzunluğu kodlamasını kullanır. Bundan sonra, ortadaki en büyük sayı olup olmadığını her üçlüyü kontrol ederiz.

Burada dene! Peter Taylor'ın test odasını geçiyor .


2

MATL , 22 bayt

0ih0hdZS49+c'21*?0'XXn

Dilin / derleyicinin geçerli sürümünü kullanır .

Örnek

>> matl
 > 0ih0hdZS49+c'21*?0'XXn
 >
> [1, 2, 2, 3, 4, 3, 5, 3, 2, 1, 2, 3, 3, 3, 2, 2, 1, 3]
4

açıklama

0ih0h           % input array. Append and prepend 0
dZS             % sign of difference between consecutive elements. Gives -1, 0, 1
49+c            % convert to a string of '0','1','2' 
'21*?0'XX       % use (lazy) regular expression to detect peaks: '20' or '210' or '2110'...
n               % number of matches. Implicity print

2

Mathematica, 55 39 36 35 bayt

Length@FindPeaks[#&@@@Split@#,0,0]&

Şimdi tüm test durumlarında çalışıyor!


Güzel! Ancak FindPeaks [#, 0,0, -∞] gereklidir, aksi takdirde son test durumu için başarısız olur.
njpipeorgan

Son / @ bir bayt kaydeder. Ve son ", 0" gereksiz olabilir?
njpipeorgan

Senin için aynı numara: Last/@->#&@@@
Martin Ender


1

JavaScript ES6, 96 94 bayt

t=>(a=t.filter((x,i)=>x!=t[i-1])).filter((x,i)=>(x>(b=a[i-1])||!b)&&(x>(c=a[i+1])||!c)).length

İlke: platoları tek zirvelere daraltın, sonraki ve önceki elementlerden daha yüksek olarak tanımlanmış olan seçicileri bulun.

Diziyi girdi olarak alır.

Demo:

f=t=>
(a=t.filter((x,i)=>x!=t[i-1]))    //collapse every plateau into the pick
    .filter((x,i)=>
       (x>(b=a[i-1])||!b)&&(x>(c=a[i+1])||!c)    //leave only those values which are greater than the succeeding and preceding ones
    ).length

document.write(
  f([])+"<br>"+
  f([1, 1, 1])+"<br>"+
  f([1, 2, 2, 3, 4, 3, 5, 3, 2, 1, 2, 3, 3, 3, 2, 2, 1, 3])+"<br>"+
  f([1])+"<br>"+
  f([1, 1])+"<br>"+
  f([2, 2, 2, 2, 2])+"<br>"+
  f([90])+"<br>"+
  f([2, 1, 2])+"<br>"+
  f([5, 2, 5, 2, 5])+"<br>"+
  f([2, 5, 2, 5, 2, 5, 2])+"<br>"+
  f([1, 2, 3, 4])+"<br>"+
  f([1, 2, 3, 4, 1, 2])+"<br>"+
  f([1, 3, 5, 3, 1])+"<br>"+
  f([7, 4, 2, 1, 2, 3, 7])+"<br>"+
  f([7, 4, 2, 1, 2, 1, 2, 3, 7])+"<br>"+
  f([1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2])+"<br>"+
  f([1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1])+"<br>"+
  f([2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2])+"<br>"+
  f([1, 3, 3, 3, 1, 3, 3, 1, 3, 1, 3, 3, 3, 3, 1])+"<br>"+
  f([12, 1, 2, 1, 2, 3, 3, 3, 2, 4, 4, 4, 1, 5, 5, 4, 7, 9])+"<br>"+
  f([87, 356, 37673, 3676, 386, 909, 909, 909, 909, 454, 909, 909])+"<br>"+
  f([87, 356, 37673, 3676, 386, 909, 909, 909, 909, 454, 909, 908, 909])
)


1

ES6, 50 48 bayt

m=>m.map(h=>{f=h>p?c+=!f:f&&h==p;p=h},p=c=f=0)|c

@ User81655 sayesinde 2 bayt kaydedildi.

Ungolfed:

function peaks(mountains) {
    var previous = 0;
    var count = 0;
    var plateau = false;
    for (var height of mountains) {
        if (height > previous) {
            if (!plateau) count++;
            plateau = true;
        } else if (height != previous) {
            plateau = false;
        }
    }
    return count;
}

@ user81655 Dikkatimi bu incelikle çizdiğiniz için teşekkür ederiz. (Daha .map()|önce kullanmadım.)
Neil

1

MATL, 23

Rekabetçi olabilmek için yığın temelli kablolar kullanmamız gerektiğinden, Julia çözümümü MATL'de yeniden uyguladım.

0i0hhdtg)t5L)0>w6L)0<*s

İtme 0, giriş, 0iki kez birleştirme. 0i0hh=>x = [0, input(''), 0]

Ayırt etmek. d=>x = diff(x)

Çoğaltın t, birini boole dönüştürün ve diğerini dizine almak için kullanın. tg)=>x=x(x!=0)

Tekrar çoğalt. t

İlk önce: [1,G])0>=>y1 = x(1:end-1)>0

Değiş tokuş. w

İkincisi: [2,0])0<=>y2 = x(2:end)<0

Mantık ve truthy değerlerini saymak. *s=>sum(y1 & y2)


Ya da usule uygun / işlevsel bir golf dili olan Pyth?
isaacg,

Tamam, MATL golf oynamak için MATLAB'dir, fakat MATLAB, MATL'yi yenmektedir.
Genel Kullanıcı

Çok hoş! Bazı ipuçları: [1,G]-> 5L3 bayt kaydeder. [2,0]-> 6L3 bayt kazandırır
Luis Mendo,

1
@GenericUser Artık değil :-) codegolf.stackexchange.com/a/69050/36398
Luis Mendo

@Rainer MATL'den and( &) kaldırmayı düşünüyorum (ve aynı şey için or). Her zaman , bu durumda olduğu gibi *o, her zaman yerine *koyulabilir. Ne düşünüyorsun? Bu şekilde karakterler &ve |gelecekte diğer işlevler için kullanılabilir.
Luis Mendo

1

Japt, 19 bayt

Düşündüğümden daha kolaydı, ama başlangıç ​​bir böcek yüzünden biraz boşa gitti.

Uu0;Up0 ä< ä> f_} l

Çevrimiçi deneyin!

Nasıl çalışır

Uu0;Up0 ä< ä> f_} l  // Implicit: U = input
Uu0;Up0              // Add 0 to the beginning and end of U. If this isn't done, the algorithm fails on peaks at the end.
        ä<           // Compare each pair of items, returning true if the first is less than the second, false otherwise.
                     // This leaves us with a list e.g. [true, false, false, true, false].
           ä>        // Repeat the above process, but with greater-than instead of less-than.
                     // JS compares true as greater than false, so this returns a list filled with false, with true wherever there is a peak.
              f_} l  // Filter out the falsy items and return the length.

Rekabet etmeyen sürüm, 15 bayt

Uu0 p0 ä< ä> è_

Bugün erken saatlerde, èişlevi olan, fancak eşleşmelerin kendisinden çok eşleşme sayısını döndüren işlevi ekledim . Ben de bir hata düzelttimArray.u dizinin kendisinden ziyade dizinin uzunluğunu döndürecek .

Çevrimiçi deneyin!


1

05AB1E , 9 bayt

Ô0.ø¥0‹ÔO

Çevrimiçi deneyin!

Açıklama:

Ô0.ø¥0‹ÔO      Full program
Ô              Uniquify (= remove plateaus)
 0.ø           Surround with zeros
    ¥          Push deltas
     0‹        Test each element if lower than 0
               --- we now have a list with 0's (= going uphill) and 
                   1's (going downhill). Since we removed plateaus, all
                   we have to do now is to count the number of ramps
                   going downhill
       Ô       Uniquify (reduce ramps to length 1)
        O      Total sum of the list


0

GolfScript, 35

~0+0\{.@=!},+:a,2-,{a\>3<.$2=?1=},,

Çevrimiçi test

Temel olarak kopyaları kaldırır, her iki uca da 0 ekler ve merkezde maksimum üç tane olduğunu kontrol eder.


0

Java 8, 141 bytes

l->{int r=0,i=1,t;for(l.add(0,0),l.add(0);i<l.size()-1;r+=t>l.get(i-1)&t>l.get(++i)?1:0)for(;(t=l.get(i))==l.get(i+1);)l.remove(i);return r;}

Can probably be golfed by using a different approach, or an array as input instead of List.

Explanation:

Try it here.

l->{                     // Method with ArrayList<Integer> parameter and int return-type
  int r=0,               //  Result-integer
      i=1,               //  Index-integer
      t;                 //  Temp integer
  for(l.add(0,0),        //  Add a 0 at the start of the list
      l.add(0);          //  Add a 0 at the end of the list
      i<l.size()-1;      //  Loop (1) from index 1 through length-1 (0-indexed)
      r+=                //    After every iteration, raise the result-integer by:
         t>l.get(i-1)    //     If the current item is larger than the previous
         &t>l.get(++i)?  //     and larger than the next:
          1              //      Increase `r` by 1
         :               //     Else:
          0)             //      `r` remains the same
    for(;(t=l.get(i))==l.get(i+1);
                         //   Inner loop (2) as long as there are two adjacent equal items
      l.remove(i)        //    And remove one of those two equal integers
    );                   //   End of inner loop (2)
                         //  End of loop (1) (implicit / single-line body)
  return r;              //  Return the result-integer
}                        // End of method
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.