最小数量的连续单调子序列


23

挑战说明

单调序列是数字的序列[a1, a2, ..., an],使得

a1 <= a2 <= ... <= ana1 >= a2 >= ... >= an[1, 3, 3, 7, 9, 13, 13, 100]是单调(不递减)的子序列,以及[9, 4, 4, 3, 0, -10, -12](此不递增),但[1, 3, 6, 9, 8]不是。给定一个整数列表(以任何合理的格式),输出最小的数字N,以便可以将这些整数的序列拆分为N单调序列。

例子

[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

为了澄清,子序列必须是连续的,对不对?
Zgarb

@Zgarb是的,他们愿意。
shooqie

3
我建议添加一个测试用例,其中的序列不一定总是反向: [4,4,8,8,1,4,5] -> 2
Nathan Merrill

@NathanMerrill:好一点,补充一点。
shooqie

当您将其写为一个空字符串时,结果为0 / undefined,听起来应该为0或undefined以我们的语言表示,但是从您对Jonathan Allan的Jelly答案的评论来看,它的undefined意思是anything... ...是哪一个? ?在第二种情况下,我建议写anything而不是undefined
Dada

Answers:


6

Brachylog,12个字节

~c:{<=|>=}al

在线尝试!

返回false.空列表[]

说明

(?)~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

这将返回最小的一个,因为~c它将生成从最小数量的子列表到最大子列表的选择点。


TIO链接中的参数“ Z”是什么?(它似乎是程序的一部分,就像命令行参数一样)。
乔纳森·艾伦

@JonathanAllan此参数是输出。理想情况下,如果我们可以自定义TIO的接口,则将有Input和Output且没有参数。该参数是Z因为Z是变量名。所以我们说的是“以Output作为变量调用此程序”。您可以更改Z其他任何大写字母;它只是一个变量名。该参数存在的原因是允许实际将输出设置为某种值而不是变量。
致命

(例如,如果4在该示例中将Output设置为,它将告诉您这是否正确
Fatalize

1
@JonathanAllan任何类似于语言的Prolog都是这样的:谓词只能成功或失败,并且不返回任何值。因此,要获得输出,必须对谓词有一个变量参数,该变量将统一到结果中。
致命

1
@JonathanAllan它最终将失败,3因为它将找不到所有单调且长度不一的子列表3。这将花费很长时间,因为它将尝试所有可能的子列表列表,即使实际上长度超过3个元素的子列表也是如此,因为查找列表后会检查其长度。因为5true的确存在,因为确实存在至少一个长度列表,5且具有单调子列表。因此,当输出为变量时,此程序将返回最小长度;如果输出为整数,则该程序是否返回该长度的任何列表。
致命

4

Perl,65个字节

62个字节的代码+ 3个字节的-n标志。

monot_seq.pl:

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

输入不带最后换行符的输入,数字之间用空格分隔:

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

-5个字节,感谢@Gabriel Benamy。


($&<=>$1)*($1<=>$2)||$1==$2($&<=>$1)*($1<=>$2)>=0
Gabriel Benamy,2013年

@GabrielBenamy的确,谢谢。
达达

2

Mathematica,111个字节

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]

命名函数f采用非空数字列表(整数或实数)。从前到后工作,重复丢弃第一个元素,并跟踪需要多少个子序列。更详细:

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-#&@@#&;同样,将f或定义g为一元运算符±可能会节省一些字节。
马丁·恩德

2

果冻,19 字节

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

TryItOnline!运行所有测试(中的空列表结果1

怎么样?

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

(尽管我不相信这是最小化字节数的最合适方法)


@shooqie- 考虑到“未定义”的注释,我们可以为空列表返回任何值吗?这样返回1(我实际上认为比有意义0)。
乔纳森·艾伦

1
我的意思是,那undefined意味着-结果无关紧要。
shooqie '16

2

Perl,98 97 96 79字节

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

输入是在运行时提供的数字列表,用空格隔开。

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

(4是输出)

可读性:

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

<=>如果LHS <RHS,“太空船运营商” 返回-1,如果LHS = RHS,则返回0,如果LHS> RHS,则返回+1。当比较三个连续的元素$a,$b,$c,以确定它们是否是单调的,它只是需要确定,它不是的情况是正好一个$a<=>$b$b<=>$c是1,另一个是-1 -当他们的产品是只发生-1。如果$a==$b$b==$c,则序列是单调的,且乘积为0。如果$a < $b < $c,则两者均导致-1,并且-1 * -1 =1。如果$a > $b > $c,则两者均导致1,并且1 * 1 = 1。无论哪种情况,序列都是单调的,我们希望继续。

如果乘积小于0,我们就知道该序列不是单调的,我们将舍弃$a,$b当前持有的值,并增加子序列计数器。否则,我们向前移动一个数字。

如果输入为空,则不返回任何内容,否则返回最小数量的连续单调子序列


1和之间不需要空格if(或者您可能在旧的Perl上需要空格,但在最近的Perl上则不需要)。您也可以(可能)替换shiftpop。但是,在某些测试用例中,您的代码不起作用:(6 3 6 3打印3而不是2),4 3 2 1(打印2而不是1)。使用pop而不是shift解决这些问题,而是创建新的问题(1 2 3 4打印3而不是1)...
Dada

1

C#6,297个 209字节

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;

毫无解释

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个字节

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

将输入作为多个参数。通过递归比较前三个元素以查看它们是否单调来进行工作(如果是),则删除中间元素(因为没有用);否则,删除前两个元素并开始新的序列。


0

Clojure,97个字节

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

reduce跟踪当前子序列并计算失败次数<=>=条件。Last 1从结果中获取第二个元素(是counter i)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.