Số lượng nhỏ nhất của các chuỗi đơn điệu liền kề


23

Mô tả thử thách

Một chuỗi đơn điệu là một chuỗi các số [a1, a2, ..., an]sao cho

a1 <= a2 <= ... <= anhoặc a1 >= a2 >= ... >= an. [1, 3, 3, 7, 9, 13, 13, 100]là một chuỗi con đơn điệu (không giảm), cũng như [9, 4, 4, 3, 0, -10, -12](cái này không tăng), nhưng [1, 3, 6, 9, 8]không. Đưa ra một danh sách các số nguyên (ở bất kỳ định dạng hợp lý nào), xuất ra số nhỏ nhất Nsao cho chuỗi các số nguyên này có thể được chia thành Ncác chuỗi đơn điệu.

Ví dụ

[1, 3, 7, 5, 4, 2] -> [[1, 3, 7], [5, 4, 2]] -> 2
[1, 2, 3, 4, 5, 6] -> [1, 2, 3, 4, 5, 6]     -> 1
[3, 1, 5, 5, 6]    -> [[3, 1], [5, 5, 6]]    -> 2
[4, 6, 8, 9, 1, 6] -> [[4, 6, 8, 9], [1, 6]] -> 2
[3, 3, 3, 3]       -> [[3, 3, 3, 3]]         -> 1
[7]                -> [[7]]                  -> 1
[]                 -> []                     -> anything (you don't actually have to handle an empty list case)
[1, 3, 2, -1, 6, 9, 10, 2, 1, -12] -> [[1, 3], [2, -1], [6, 9, 10], [2, 1, -12]] -> 4

Để làm rõ, các phần tiếp theo phải được tiếp giáp, phải không?
Zgarb

@Zgarb Vâng, họ làm.
shooqie

3
Tôi khuyên bạn nên thêm một trường hợp thử nghiệm trong đó các chuỗi không luôn luôn đi theo hướng ngược lại: [4,4,8,8,1,4,5] -> 2
Nathan Merrill

@NathanMerrill: Điểm tốt, đã thêm một điểm.
shooqie

Khi bạn viết rằng đối với một chuỗi rỗng, kết quả là 0 / undefined, nó có vẻ như là 0 hoặc đại diện undefinedtrong ngôn ngữ của chúng tôi, nhưng từ nhận xét của bạn về câu trả lời Jelly của Jonathan Allan, có vẻ như đó undefinedanything... ? Trong trường hợp thứ hai, tôi sẽ đề nghị viết anythingthay vìundefined
Dada

Câu trả lời:


6

Brachylog , 12 byte

~c:{<=|>=}al

Hãy thử trực tuyến!

Điều này trả về false.cho danh sách trống [].

Giải trình

(?)~c                 Take a list of sublists which when concatenated result in the Input
     :{<=|>=}a        Each sublist must be either increasing or decreasing
              l(.)    Output is the length of that list

Điều này sẽ trả về điểm nhỏ nhất vì ~csẽ tạo các điểm lựa chọn từ số lượng danh sách con nhỏ nhất đến lớn nhất.


Đối số "Z" trong liên kết TIO là gì? (Nó dường như là một phần của chương trình giống như một đối số dòng lệnh).
Jonathan Allan

@Jonathan ALLan Đối số này là đầu ra. Lý tưởng nhất là nếu chúng ta có thể tùy chỉnh giao diện của TIO, sẽ có Đầu vào và Đầu ra và không có đối số. Đối số là Zbởi vì Zlà một tên biến; vì vậy chúng tôi đang nói "gọi chương trình này với Đầu ra là một biến". Bạn có thể thay đổi Zthành bất kỳ chữ in hoa nào khác ; nó chỉ là một tên biến. Lý do tồn tại đối số này là để cho phép khả năng thực sự đặt đầu ra thành một cái gì đó, thay vì một biến.
Gây tử vong vào

(Ví dụ: nếu bạn đặt Đầu ra thành 4trong ví dụ đó , nó sẽ cho bạn biết điều đó có đúng hay không )
Fatalize

1
@Jonathan ALLan Bất kỳ ngôn ngữ như Prolog nào cũng như thế này: các vị từ chỉ có thể thành công hoặc thất bại và không trả về bất kỳ giá trị nào. Vì vậy, để có được một đầu ra, người ta phải có một đối số biến với vị từ sẽ thống nhất với kết quả.
Gây tử vong vào

1
@Jonathan ALLan Cuối cùng nó sẽ thất bại 3vì nó không tìm thấy bất kỳ danh sách các danh sách con nào trong đó tất cả đều đơn điệu và có độ dài 3. Nó chỉ mất một thời gian dài vì nó sẽ thử tất cả các danh sách danh sách phụ có thể, ngay cả những danh sách thực sự dài hơn 3 yếu tố vì độ dài được kiểm tra sau khi tìm thấy danh sách. Đối với 5nó nói truebởi vì thực sự có ít nhất một danh sách độ dài 5với danh sách con đơn điệu hoạt động. Vì vậy, chương trình này trả về độ dài nhỏ nhất khi đầu ra là một biến và liệu có bất kỳ danh sách độ dài nào hoạt động nếu đầu ra là một số nguyên.
Gây tử vong vào

4

Perl, 65 byte

62 byte mã + 3 byte cho -ncờ.

monot_seq.pl:

#!perl -n
s/\S+ /($_<=>$&)*($&<=>$')-$g>=0?$g=1:$.++;$g--;$_=$&/ge,$_=$.

Đưa ra đầu vào mà không có dòng mới cuối cùng, với các số được phân tách bằng dấu cách:

$ echo -n "1 3 2 -1 6 9 10 2 1 -12" | perl -M5.010 monot_seq.pl
4

-5 byte nhờ @Gabriel Benamy.


Lưu 5 byte bằng cách chuyển ($&<=>$1)*($1<=>$2)||$1==$2thành($&<=>$1)*($1<=>$2)>=0
Gabriel Benamy

@GabrielBenamy Thật vậy, cảm ơn.
Dada

2

Toán học, 111 byte

d=#[[2]]-#[[1]]&;r=Rest;f@{n_}:=1;f@k__:=If[d@k==0,f@r@k,g[k Sign@d@k]];g@{n_}:=1;g@k__:=If[d@k>0,g@r@k,1+f@r@k]

Hàm được đặt tên flấy một danh sách các số không trống (số nguyên hoặc thậm chí là số thực). Hoạt động từ trước ra sau, liên tục loại bỏ phần tử đầu tiên và theo dõi xem cần bao nhiêu phần tiếp theo. Chi tiết hơn:

d = #[[2]] - #[[1]] &;         function: difference of the first two elements
r = Rest;                      function: a list with its first element dropped
f@{n_} := 1;                   f of a length-1 list equals 1
f@k__ := If[d@k == 0, f@r@k,   if the first two elements are equal, drop one
                                 element and call f again ...
            g[k Sign@d@k]];  ... otherwise call the helper function g on the
                                 list, multiplying by -1 if necessary to ensure
                                 that the list starts with an increase
g@{n_} := 1;                   g of a length-1 list equals 1
g@k__ := If[d@k > 0, g@r@k,    if the list starts with an increase, drop one
                                 element and call g again ...
            1 + f@r@k];        ... otherwise drop one element, call f on the
                                 resulting list, and add 1

d=#2-#&@@#&;ngoài ra, việc xác định fhoặc glà toán tử đơn nguyên ±có thể sẽ lưu một số byte.
Martin Ender

2

Thạch , 19 byte

IṠḟ0E
ŒṖÇ€€0e$Ðḟḅ1Ṃ

Dùng thử trực tuyến! hoặc chạy tất cả các bài kiểm tra (kết quả danh sách trống trong1)

Làm sao?

IṠḟ0E - Link 1, test for monotonicity: a sublist
I     - incremental differences
 Ṡ    - sign {fall:-1; same:0; rise:1}
  ḟ0  - filter out the zeros
    E - all equal?

ŒṖÇ€€0e$Ðḟḅ1Ṃ - Main link
ŒṖ            - all partitions of the input list
  Ç€€         - call last link (1) as a monad for €ach for €ach
        Ðḟ    - filter out results:
       $      -    last two links as a monad
     0e       -        contains zero?
          ḅ1  - convert from unary (vectorises)
            Ṃ - minimum

(Tôi không tin rằng đây là phương pháp phù hợp nhất để giảm thiểu số lượng byte)


@shooqie - Chúng tôi có thể trả lại bất kỳ giá trị nào cho danh sách trống được đưa ra nhận xét "không xác định" không? Điều này trở lại 1(mà tôi thực sự nghĩ có ý nghĩa hơn 0).
Jonathan Allan

1
Ý tôi là, đó là những gì undefinedcó nghĩa - kết quả là không liên quan.
shooqie

2

Perl, 98 97 96 79 byte

($a,$b)=($a<=>$b)*($b<=>$c)<0?($c,shift,$d++):($b,$c)while$c=shift;say$d+1 if$a

Đầu vào được cung cấp dưới dạng danh sách các số, được phân tách bằng dấu cách, được cung cấp khi chạy, ví dụ:

perl -M5.010 monotonic.pl 1 3 2 -1 6 9 10 2 1 -12
4

(4 là đầu ra)

Có thể đọc được

($a,$b)=($a<=>$b)*($b<=>$c)<0
    ?($c,shift,$d++)
    :($b,$c)
  while$c=shift;
say$d+1
  if$a

Toán tử 'tàu vũ trụ' <=>trả về -1 nếu LHS <RHS, 0 nếu LHS = RHS và +1 nếu LHS> RHS. Khi so sánh ba yếu tố liên tiếp $a,$b,$cđể xác định xem chúng có đơn điệu hay không, chỉ cần xác định rằng đó không phải là trường hợp chính xác $a<=>$b, $b<=>$clà 1 và yếu tố kia là -1 - chỉ xảy ra khi sản phẩm của chúng là -1. Nếu một trong hai $a==$bhoặc $b==$csau đó, chuỗi là đơn điệu và sản phẩm là 0. Nếu $a < $b < $c, cả hai đều có kết quả là -1 và -1 * -1 = 1. Nếu $a > $b > $c, cả hai đều có kết quả là 1 và 1 * 1 = 1. Trong cả hai trường hợp, trình tự là đơn điệu, và chúng tôi muốn tiếp tục.

Nếu sản phẩm nhỏ hơn 0, chúng tôi biết rằng chuỗi đó không đơn điệu và chúng tôi sẽ loại bỏ các giá trị $a,$bmà chúng tôi hiện đang giữ và tăng bộ đếm tiếp theo của chúng tôi. Nếu không, chúng tôi di chuyển về phía trước một số.

Trả về không có gì nếu đầu vào trống, nếu không sẽ trả về số lượng nhỏ nhất của các chuỗi đơn điệu liền kề


Bạn không cần một khoảng trống giữa 1if(hoặc có thể bạn làm trên những cái cũ, nhưng trên những cái gần đây bạn không có). Ngoài ra, bạn có thể (có thể) thay thế shiftbằng pop. Tuy nhiên, có một số trường hợp thử nghiệm mà mã của bạn không hoạt động: 6 3 6 3(bạn in 3 thay vì 2), 4 3 2 1(bạn in 2 thay vì 1). Sử dụng popthay vì shiftgiải quyết những vấn đề đó nhưng tạo ra những cái mới ( 1 2 3 4in 3 thay vì 1) ...
Dada

1

C # 6, 297 209 byte

using System.Linq;int G(int[] a)=>a.Any()?a.SkipWhile((x,i)=>i<1||x>=a[i-1]).Count()<a.SkipWhile((x,i)=>i<1||x<=a[i-1]).Count()?G(a.Select(x=>-x).ToArray()):G(a.SkipWhile((x,i)=>i<1||x<=a[i-1]).ToArray())+1:0;

Ung dung với lời giải thích

int G(int[] a)=>
    a.Any()
        ?a.SkipWhile((x,i)=>i<1||x>=a[i-1]).Count()<a.SkipWhile((x,i)=>i<1||x<=a[i-1]).Count()   // If a begins by decreasing (including whole a decreasing)...
            ?G(a.Select(x=>-x).ToArray())   // ... Then flip sign to make a begins by increasing
            :G(a.SkipWhile((x,i)=>i<1||x<=a[i-1]).ToArray())+1   // ... Else skip the increasing part, recursively find the remaining part number, then add 1
        :0;   // Return 0 if a is empty

1

JavaScript (ES6), 69 byte

f=(d,c,b,...a)=>1/b?(d>c)*(b>c)+(d<c)*(b<c)?1+f(b,...a):f(d,b,...a):1

Lấy đầu vào là nhiều tham số. Hoạt động bằng cách so sánh đệ quy ba yếu tố đầu tiên để xem liệu chúng có đơn điệu hay không, nếu vậy, loại bỏ yếu tố trung gian vì nó vô dụng, nếu không, loại bỏ hai yếu tố đầu tiên và bắt đầu một chuỗi mới.


0

Clojure, 97 byte

#((reduce(fn[[C i]s](let[S(conj C s)](if(or(apply <= S)(apply >= S))[S i][[s](inc i)])))[[]1]%)1)

reducetheo dõi các hiện tại và tính toán bao nhiêu lần <=>=điều kiện không thành công. Lần cuối 1lấy yếu tố thứ 2 từ kết quả (là bộ đếm i).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.