ยอดเขากี่ลูกในยอดเขา


27

รายการจำนวนเต็มบวกสามารถมองเห็นเป็นเทือกเขาเชิงปริมาณโดยที่แต่ละรายการแสดงถึงความสูงของส่วนแนวตั้งหนึ่งส่วนของภูเขา

ตัวอย่างเช่นรายการ

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

สามารถกลายเป็นช่วง

      x
    x x      
   xxxxx   xxx   x
 xxxxxxxx xxxxxx x
xxxxxxxxxxxxxxxxxx

(คนบทกวีน้อยอาจเรียกแผนภูมิแท่งนี้ว่า แต่ฉันพูดนอกเรื่อง)

คำถามในการท้าทายนี้คือ: มีพีคส์จำนวนเท่าใดที่อยู่ในเทือกเขาของรายการโดยพลการ? โดยพื้นฐานแล้วจำนวนท้องถิ่นสูงสุดอยู่ในรายการ?

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

เป็นเรื่องง่ายที่จะบอกด้วยสายตาว่าตัวอย่างมีสี่จุดสูงสุดในตำแหน่งที่วงเล็บเหล่านี้:

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

สังเกตได้อย่างไรว่า (3, 3, 3)ส่วนที่ราบสูงนับเป็นจุดสูงสุดเนื่องจากเป็นชุดของคอลัมน์ที่ต่อเนื่องกันซึ่งมีความสูงเท่ากับคอลัมน์ที่อยู่ใกล้เคียง

สุดท้าย(3)นับว่าเป็นจุดสูงสุดด้วยเช่นกันเพราะสำหรับจุดประสงค์ของการท้าทายนี้เราจะกำหนดเพื่อนบ้านด้านซ้ายของคอลัมน์ด้านซ้ายสุดและเพื่อนบ้านด้านขวาของคอลัมน์ด้านขวาสุดให้เป็นศูนย์สูง

ซึ่งหมายความว่ารายการที่มีเพียงหนึ่งค่าเท่านั้น1, 1, 1สามารถตีความได้ว่าเป็นเช่น0, 1, 1, 1, 0นั้นและมียอดเขาหนึ่งไม่ใช่ไม่ใช่:0, (1, 1, 1), 0และทำให้มีหนึ่งสูงสุดไม่ไม่มี:

รายการเดียวที่มีศูนย์จุดสูงสุดเป็นรายการที่ว่างเปล่า

ท้าทาย

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

รหัสที่สั้นที่สุดในหน่วยไบต์ชนะTiebreaker เป็นโพสต์ก่อนหน้า

กรณีทดสอบ

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

ดังนั้นที่ราบสูงสามารถอยู่ได้นานไหม?
nicael

@nicael ใช่มันอาจเป็น
งานอดิเรกของ Calvin

เราสามารถรับอินพุตเป็นอาร์เรย์ไม่ใช่เป็นสตริงได้หรือไม่
nicael

@nicael ใช่ทุกอย่างสมเหตุสมผล
งานอดิเรกของ Calvin

คำตอบ:


2

Pyth, 18 ไบต์

su_>VGtG2eMr++ZQZ8

จาก @ PeterTaylor ซ้ำแล้วซ้ำอีกมากกว่าการแก้ปัญหา แต่ด้วยการบิด

++ZQZ: เพิ่มศูนย์ทั้งสองด้าน

eMr ... 8: ลบการทำซ้ำ

u ... 2 ...: ใช้สิ่งต่อไปนี้สองครั้ง:

>VGTG: แมปตัวเลขแต่ละคู่กับว่าอยู่ในลำดับที่ลดลงหรือไม่

_: และย้อนกลับ

1 ในผลลัพธ์สอดคล้องกับ1, 0ขั้นตอนก่อนหน้าซึ่งสอดคล้องกับa < b > cในอินพุตเนื่องจากการกลับรายการ

s: ผลรวม (และพิมพ์)


10

CJam ( 32 26 24 21 ไบต์)

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

อินพุตที่คาดไว้คือตัวเลขคั่นด้วยช่องว่าง

สาธิตออนไลน์ ; ชุดทดสอบเต็มรูปแบบ (เอาต์พุตที่คาดหวังคือ1กรณีทดสอบต่อ)

ขอขอบคุณมาร์ตินที่แจ้งให้ฉันทราบว่า CJam เวอร์ชันปัจจุบันช่วยปรับปรุงหนึ่งในผู้ดำเนินการที่ใช้ประหยัด 2 ตัวอักษร; และสำหรับการประหยัดอีก 3 ถ่าน

การผ่า

สองเฟส: deduplicate จากนั้นระบุ maxima ท้องถิ่นในแต่ละชุด

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

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

คำอธิบาย

ใช้อาร์เรย์ของตัวเลข

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)

ทดสอบ


5

Pyth, 25 23 ไบต์

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

คำอธิบาย:

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              

ดี ผิดปกติพอร์ตไปยัง CJam จะสั้นกว่า: 0q~0]{2ew::-:g0-}2*1-,สำหรับ 22.
Peter Taylor

4

จูเลียอายุ 66 ปี

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

แผ่นแยกความแตกต่าง: y=diff([0;x;0]). ละเว้นที่ราบไปนี้:
นับไปศูนย์นํ้า:y=y[y.!=0]
+-sum((y[1:end-1].>0)&(y[2:end].<0))


3

MATLAB, 29 27 ไบต์

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

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

สิ่งนี้จะทำงานกับอ็อกเทฟ คุณสามารถลองออนไลน์ได้ที่นี่ เพียงวางโค้ดด้านบนลงในบรรทัดคำสั่งแล้วเรียกใช้ด้วยans([1,2,1,3,4,5,6,1])(หรืออินพุตอื่น ๆ )


ในฐานะที่เป็นตัวเลขที่มีเสมอ + ve เราสามารถสันนิษฐานได้ว่าพวกเขาเป็นมากกว่าศูนย์เพื่อให้สามารถบันทึก 2 ไบต์โดยใช้แทนnnznumel


3

Python 3, 75 ไบต์

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

นี่เป็น codegolf ครั้งแรกของฉันดังนั้นอาจมีบางที่ที่จะตัดมันลงโดยเฉพาะd=((n==p)&d)+(n>p)ส่วน อย่างไรก็ตามมันใช้ได้กับทุกกรณีทดสอบ


นั่นไม่ใช่ขนาด 78 ไบต์ใช่ไหม
Jonathan Frech

3

Mathematica, 42 36 33 32 ไบต์

ขอบคุณ Martin Büttnerที่ช่วยประหยัด 1 ไบต์

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

PeakDetect ทำเกือบทุกอย่าง!

กรณีทดสอบ:

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 *)

ฉันพบว่าคำตอบของฉันแตกต่างจากคุณพอที่จะโพสต์อีก
LegionMammal978

@ LegionMammal978 ผลลัพธ์ของอินพุต {1} คือ 1 ตามที่คาดไว้
njpipeorgan

ฉันหมายถึง {1, 2, 2, 3, 4, 3, 5, 3, 2, 1, 2, 3, 3, 3, 2, 2, 1, 3}
LegionMammal978

@ LegionMammal978 นั่นเป็นเรื่องยาก ฉันไม่พบวิธีแก้ปัญหา
njpipeorgan

โซลูชันที่อัปเดตของฉันเพียงแค่ "ที่ราบสูง" เรียบ
LegionMammal978

2

CJam, 27 26 ไบต์

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

ใช้การเข้ารหัสความยาวรันเพื่อลบข้อมูลซ้ำ หลังจากนั้นเราตรวจสอบทุก triplet ว่าอันที่หนึ่งตรงกลางเป็นจำนวนมากที่สุด

ลองที่นี่! ผ่านชุดทดสอบปีเตอร์เทย์เลอร์


2

MATL , 22 ไบต์

0ih0hdZS49+c'21*?0'XXn

ใช้ภาษา / คอมไพเลอร์เวอร์ชันปัจจุบัน

ตัวอย่าง

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

คำอธิบาย

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 bytes

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

ตอนนี้ใช้ได้กับทุกกรณีทดสอบ!


เย็น! แต่ FindPeaks [#, 0,0, -∞] เป็นสิ่งจำเป็นมิฉะนั้นจะล้มเหลวในกรณีทดสอบครั้งสุดท้าย
njpipeorgan

Last / @ บันทึกไบต์ และสุดท้าย ", 0" อาจไม่จำเป็น?
njpipeorgan

เคล็ดลับเดียวกันสำหรับคุณ: Last/@->#&@@@
Martin Ender

2

เรติน่า , 33 31 ไบต์

ขอบคุณ Neil สำหรับการบันทึก 2 ไบต์

\b(1+)(?<!\1,\1)(,\1)*\b(?!,\1)

ลองออนไลน์!

รับอินพุตเป็นรายการunary ที่คั่นด้วยเครื่องหมายจุลภาค


\b(1+)(?<!\1 \1)( \1)*\b(?! \1)ดูเหมือนว่าจะบันทึก 2 ไบต์?
Neil

@ แน่นอนว่าขอบคุณ! :)
Martin Ender

1

JavaScript ES6 96 94 ไบต์

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

หลักการ: ยุบที่ราบลงเป็นยอดเขาเดี่ยวหาของที่เลือกซึ่งถูกกำหนดว่าสูงกว่าทั้งองค์ประกอบถัดไปและก่อนหน้า

รับอินพุตเป็นอาร์เรย์

การสาธิต:

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

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

บันทึก 2 ไบต์ด้วย @ user81655

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 ขอบคุณที่ดึงความสนใจของฉันไปที่ความละเอียดอ่อน (ฉันไม่เคยใช้มา.map()|ก่อน)
Neil

1

MATL, 23

เนื่องจากเราต้องใช้ esolangs แบบกองซ้อนเพื่อให้สามารถแข่งขันได้ฉันจึงนำJulia solution ของฉันไปใช้ใหม่ใน MATL

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

ดัน0ป้อนข้อมูล0เรียงต่อกันสองครั้ง0i0hh=>x = [0, input(''), 0]

ความแตกต่าง d=>x = diff(x)

ทำซ้ำtแปลงหนึ่งเป็นบูลีนและใช้เป็นดัชนีอื่นtg)=>x=x(x!=0)

ทำซ้ำอีกครั้ง t

ครั้งแรก: [1,G])0> =>y1 = x(1:end-1)>0

แลกเปลี่ยน. w

ประการที่สอง: [2,0])0< =>y2 = x(2:end)<0

ตรรกะและนับค่าความจริง *s=>sum(y1 & y2)


หรือคุณอาจจะใช้ภาษา Pyth ซึ่งเป็นภาษากอล์ฟขั้นตอน / การใช้งาน!
isaacg

ตกลง MATL เป็น MATLAB สำหรับการเล่นกอล์ฟ แต่ MATLAB กำลังเต้น MATL
ผู้ใช้ทั่วไป

ดีมาก! เคล็ดลับบางประการ: [1,G]-> 5Lบันทึก 3 ไบต์ [2,0]-> 6Lบันทึก 3 ไบต์
Luis Mendo

1
@GenericUser ไม่อีกแล้ว :-) codegolf.stackexchange.com/a/69050/36398
Luis Mendo

@ คนที่แต่งตัวประหลาดฉันกำลังคิดที่จะลบand( &) จาก MATL (และเหมือนกันor) มันสามารถถูกแทนที่ด้วย*oและมักจะเพียงแค่*ในกรณีนี้ คุณคิดอย่างไร? วิธีนี้จะทำให้ตัวละคร&และ|สามารถใช้กับฟังก์ชั่นอื่น ๆ ในอนาคต
Luis Mendo

1

Japt, 19 ไบต์

นั่นง่ายกว่าที่ฉันคิด แต่จุดเริ่มต้นนั้นสิ้นเปลืองเพียงเล็กน้อยเนื่องจากข้อผิดพลาด

Uu0;Up0 ä< ä> f_} l

ลองออนไลน์!

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

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.

รุ่นที่ไม่ใช่คู่แข่งขนาด 15 ไบต์

Uu0 p0 ä< ä> è_

ก่อนหน้านี้วันนี้ฉันเพิ่มèฟังก์ชั่นซึ่งเป็นเหมือนfแต่คืนจำนวนการแข่งขันมากกว่าการแข่งขัน ฉันยังแก้ไขข้อผิดพลาดที่Array.uจะกลับความยาวของอาร์เรย์มากกว่าอาร์เรย์เอง

ลองออนไลน์!


1

05AB1E , 9 ไบต์

Ô0.ø¥0‹ÔO

ลองออนไลน์!

คำอธิบาย:

Ô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

1

เยลลี่ , 27 ไบต์

ṡ2EÐḟFs2ḣ€1S€ṡ3M€Fċ2
0;⁸;0Ç

ลองออนไลน์!


เยลลี่ที่ไม่มี TIO ??? lol
Christopher

นี่เป็นเวลานานแล้วก่อนที่ฉันจะรู้วิธีเชื่อมโยงไปยัง TIO ฉันจะปล่อยให้มันเป็นเช่นนี้เพื่อลูกหลาน
Zacharý

สกรู dat ฉันแก้ไข
Christopher

> _ <_> _ <_> _ <_> _ <
Zacharý

0

GolfScript, 35

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

ทดสอบออนไลน์

โดยทั่วไปจะลบรายการที่ซ้ำกันเพิ่ม 0 ให้กับทั้งสองด้านและตรวจสอบว่ามีสามอเนกประสงค์ที่มีค่าสูงสุดในกึ่งกลาง


0

Java 8, 141 ไบต์

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

สามารถเล่นกอล์ฟได้โดยใช้วิธีการอื่นหรือใช้อาร์เรย์เป็นอินพุตแทนที่จะเป็นรายการ

คำอธิบาย:

ลองที่นี่

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