17
\$\begingroup\$

Provided that the input is a monotone sequence of three or more integers:

  • Output -2 if the sequence strictly decreases. Example: [7,4,3,2]

  • Output -1 if the sequence monotone decreases but is neither strict nor constant. Example: [6,5,5]

  • Output 0 if the sequence is constant. Example: [0,0,0]

  • Output +1 if the sequence monotone increases but is neither strict nor constant. Example: [-1,2,2,2,4]

  • Output +2 if the sequence strictly increases. Example: [0,1,2]

I/O format is flexible. Standard loopholes apply.

\$\endgroup\$
7
  • 1
    \$\begingroup\$ Please add at least 1 worked example and some test cases. \$\endgroup\$
    – Shaggy
    Commented Nov 14, 2023 at 9:18
  • \$\begingroup\$ If the sequence is [-1,2,3,2,4], is it considered increasing ? \$\endgroup\$
    – gobes
    Commented Nov 14, 2023 at 9:57
  • 4
    \$\begingroup\$ @gobes It is not monotone. \$\endgroup\$
    – Arnauld
    Commented Nov 14, 2023 at 9:58
  • \$\begingroup\$ Related \$\endgroup\$
    – Luis Mendo
    Commented Nov 14, 2023 at 10:55
  • \$\begingroup\$ The addition of the word "constant" in the description confuses me. As an example, what should the return for [1,2,5] be? It is strictly increasing, but it is a constant interval. \$\endgroup\$
    – Xcali
    Commented Jan 4 at 5:24

23 Answers 23

10
\$\begingroup\$

05AB1E, 8 7 6 bytes

¥.±Z+W

Attempt This Online!

¥      deltas
.±     sign
Z      maximum without popping
+      add (vectorized)
W      minimum
\$\endgroup\$
7
\$\begingroup\$

Jelly, 6 bytes

IṠQ.ịS

Try it online!

Port of Command Master's 05AB1E answer. A monadic link taking a list of integers and returning an integer.

Explanation

I      | Increments
 Ṡ     | Signs
  Q    | Uniquify
   .ị  | Last and first
     S | Sum
\$\endgroup\$
3
  • \$\begingroup\$ I think uniquify is not necessary Try it online! \$\endgroup\$
    – pajonk
    Commented Nov 14, 2023 at 7:05
  • \$\begingroup\$ @pajonk it is if the input is something like [1,2,2,3] \$\endgroup\$ Commented Nov 14, 2023 at 7:34
  • \$\begingroup\$ Ah, I get it now. It's "Last and first" (as described) not min and max. \$\endgroup\$
    – pajonk
    Commented Nov 14, 2023 at 8:25
6
\$\begingroup\$

Uiua, 11 bytes

⊢+⇌.⊝±≡/-◫2

Try it!

Port of Command Master's 05AB1E answer.

⊢+⇌.⊝±≡/-◫2
      ≡/-◫2  # deltas
     ±       # sign
    ⊝        # deduplicate
   .         # duplicate
  ⇌          # reverse
 +           # add
⊢            # first
\$\endgroup\$
6
\$\begingroup\$

JavaScript (ES6), 47 bytes

a=>(a.reduce((p,v)=>(a|=p<v?5:p>v?-2:3,v)),a%3)

Try it online!

Method

Because the input array a contains at least 3 elements, it is guaranteed to be evaluated to \$0\$ when coerced to an integer. So we can safely re-use it as a signed 32-bit mask.

For each pair of consecutive elements \$(p,\:v)\$ in the input array, we apply to a a bitwise OR with:

  • \$5\$ if \$p<v\$
  • \$-2\$ if \$p>v\$
  • \$3\$ if \$p=v\$

These values were chosen such that the expected output in \$[-2\dots2]\$ is obtained by reducing the final bitmask modulo \$3\$.

List of cases

Because the sequence is monotone, there are only 5 possible cases:

\$p<v\$ \$p>v\$ \$p=v\$ operations final bitmask modulo 3
no no yes 0 | 3 3 0
no yes no 0 | -2 -2 -2
no yes yes 0 | -2 | 3 -1 -1
yes no no 0 | 5 5 2
yes no yes 0 | 5 | 3 7 1
\$\endgroup\$
6
\$\begingroup\$

Scala 3, 71 63 bytes

Saved 8 bytes thanks to the comment of @corvus_192


x=>x zip x.tail map{case(a,b)=>b compare a}pipe(x=>x.min+x.max)

Attempt This Online!

\$\endgroup\$
1
  • \$\begingroup\$ 63 bytes: x=>x zip x.tail map{case(a,b)=>b compare a}pipe(x=>x.min+x.max) \$\endgroup\$
    – corvus_192
    Commented Nov 15, 2023 at 20:14
5
\$\begingroup\$

Python, 55 bytes

lambda S,*s:min(x:={(S<t)-(S>(S:=t))for t in s})+max(x)

Attempt This Online!

Python 2, 53 bytes

def f(s):t=map(cmp,s[1:],s[:-1]);return min(t)+max(t)

Attempt This Online!

\$\endgroup\$
0
5
\$\begingroup\$

Nekomata, 5 bytes

∆±uĵ

Attempt This Online!

∆±uĵ
∆       Delta
 ±      Sign
  u     Uniquify
   Ä    Multiply by 2
    µ   Mean
\$\endgroup\$
5
\$\begingroup\$

K (ngn/k), 14 bytes

+/2#?0 1'1_-':

Try it online!

A slight variation on Nick Kennedy's Jelly answer. 0 1' is from coltim's comment on another K answer.

+/2#?0 1'1_-':
         1_-':    differences
     0 1'         binary search into 0 1; negative -> -1, 0 -> 0, positive -> 1
    ?             keep unique elements
  2#              cycle the elements to length 2
+/                sum
\$\endgroup\$
5
\$\begingroup\$

Python 2, 43 bytes

lambda s:cmp(s[::-1],s)<<len(set(s))/len(s)

Attempt This Online!

Logs:

  • My original answer (49 bytes):
lambda s:cmp(s[-1],s[0])*(2-(len(set(s))<len(s)))
  • Neil's suggestion: *(2-(len(set(s))<len(s))) -> -~(len(set(s))==len(s))
  • xnor's suggestion: *(2-(len(set(s))<len(s))) -> <<(len(set(s))==len(s)) ; cmp(s[-1],s[0]) -> cmp(s[::-1],s)
  • Albert.Lang's suggestion: *(2-(len(set(s))<len(s))) -> <<len(set(s))/len(s)

Thank for amazing suggestions!

\$\endgroup\$
4
  • 2
    \$\begingroup\$ -~(len(set(s))==len(s)) is a byte shorter than (2-(len(set(s))<len(s))). \$\endgroup\$
    – Neil
    Commented Nov 14, 2023 at 9:43
  • 2
    \$\begingroup\$ Better yet, <<(len(set(s))==len(s)) without *. Also, cmp(s[::-1],s) saves a byte \$\endgroup\$
    – xnor
    Commented Nov 14, 2023 at 10:02
  • 4
    \$\begingroup\$ Even more betterer: lambda s:cmp(s[::-1],s)<<len(set(s))/len(s) \$\endgroup\$ Commented Nov 14, 2023 at 18:18
  • \$\begingroup\$ Thanks for y'all amazing suggestions. Was busy so just checked cg now. \$\endgroup\$ Commented Nov 17, 2023 at 16:17
4
\$\begingroup\$

R, 32 29 bytes

\(x)sum(range(sign(diff(x))))

Attempt This Online!

A function taking a vector and returning the relevant result. Based on Command Master's 05AB1E answer.

Thanks to @pajonk for saving three bytes!

\$\endgroup\$
3
  • \$\begingroup\$ -3 bytes by porting your own Jelly answer :) \$\endgroup\$
    – pajonk
    Commented Nov 14, 2023 at 6:18
  • \$\begingroup\$ I don't know R, but it doesn't look like you need the range. \$\endgroup\$
    – Shaggy
    Commented Nov 14, 2023 at 9:23
  • 1
    \$\begingroup\$ Thanks @Shaggy. You don’t for the examples used but would if the sequences were longer than 3 integers. \$\endgroup\$ Commented Nov 14, 2023 at 12:57
4
\$\begingroup\$

K (ngn/k), 21 16 bytes

Port of 05AB1E answer

-5 thanks to @coltim

&/+/|/\0 1'1_-':

Try it online!

           1_-': deltas
       0 1'      sign
  +/|/\          add maximum
&/               minimum
\$\endgroup\$
1
  • \$\begingroup\$ I think you can use |/\ rather than 1|/\ , since the input is going to be a list (so the max-reduce-converges will end after a single iteration). There's also the golfy 0 1'intList sign version that saves several bytes. \$\endgroup\$
    – coltim
    Commented Nov 14, 2023 at 15:29
3
\$\begingroup\$

JavaScript (Node.js), 50 bytes

a=>~!a.some(p=x=>p==(p=x))*Math.sign(a[0]-a.pop())

Try it online!

Use begin and end to detect direction

\$\endgroup\$
3
\$\begingroup\$

sclin, 23 bytes

_"-"2%map0<=>"|/"Q + &/

Try it on scline! Port of Command Master's answer.

Explanation

Prettified:

_ \- 2%map 0<=> \|/ Q + &/
  • _ \- 2%map negated delta (via pairwise difference)
  • 0<=> sign (i.e. compare to 0)
  • \|/ Q dup and get max
  • + &/ vectorized-add and get min
\$\endgroup\$
3
\$\begingroup\$

Desmos, 33 bytes

f(L)=D.max+D.min
D=sgn(L[2...]-L)

Port of 05AB1E.

Try It On Desmos!

Try It On Desmos! - Prettified

\$\endgroup\$
3
\$\begingroup\$

Retina, 57 51 bytes

\d+
*
Lv`\b_+,_+
+`_,_
,
O^`
,,G`
^_
-_
/[^-]+/_`_+

Try it online! Link includes test cases. Only accepts positive integer lists, but will output -2 to 2 as required. Explanation:

\d+
*

Convert to unary.

Lv`\b_+,_+
+`_,_
,

For each overlapping pair of integers, get a substring representing the delta: _+, for negative, , for 0 and ,_+ for positive.

O^`

Group identical substrings together and sort _, first.

,,G`

Keep only one of each group, but if there is only one group, keep two of it.

^_
-_

If there was a _, then prefix a - sign.

/[^-]+/_`_+

Count the runs of _s.

Edit: Saved 6 bytes by porting my answer to Retina 0.8.2 for 61 bytes and then backporting the golfs:

\d+
$*
M!&`\b1+,1+
+`1,1
,
O^`
+`¶.+¶
¶
^1
-1
((1+)|,|¶)+
$#2

Try it online! Link includes test cases. Only accepts positive integer lists, but will output -2 to 2 as required. Explanation: Retina 0.8.2 uses $* (which produces 1s) instead of * (which produces _s) for unary, needs to use M!& instead of Lv, and doesn't have an equivalent of ,,G or _ (as a command), so I had to emulate those.

\$\endgroup\$
2
\$\begingroup\$

Vyxal g, 29 bitsv2, 3.625 bytes

¯±:G+

Try it Online!

Bitstring:

11001100111100010001111111001

Port of the 05ab1e answer

\$\endgroup\$
2
\$\begingroup\$

Charcoal, 23 bytes

≔EΦθκ⁻›ι§θκ‹ι§θκθI⁺⌊θ⌈θ

Try it online! Link is to verbose version of code. Explanation: Port of @Albert.Lang's Python answer.

≔EΦθκ⁻›ι§θκ‹ι§θκθ

Get the signs of the deltas.

I⁺⌊θ⌈θ

Add the minimum and maximum of them.

\$\endgroup\$
2
\$\begingroup\$

JavaScript (Node.js), 54 bytes

a=>a.map(n=p=o=v=>[n|=a>v,p|=a<v,o|=a==v,a=v])|p-n<<!o

Try it online!

\$\endgroup\$
1
\$\begingroup\$

C (gcc), 63 bytes

Port of my JS answer.

m,p;f(a,n)int*a;{for(m=0;p=*a++,--n;)m|=p<*a?5:p>*a?-2:3;m%=3;}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

APL+WIN, 52 bytes

Prompts for vector:

+/2 1 0×(×n)×(s=⍴v),((s<⍴v)^s>0),0=s←1+|n←+/×-2-/v←⎕

Try it online! Thanks to Dyalog Classic

\$\endgroup\$
1
\$\begingroup\$

Go, 193 183 bytes


Saved 10 bytes thanks to the comment of @corvus_192


Golfed version. Attempt this online!

func c(a,b int)int{if a<b{return 1};if a>b{return -1};return 0}
func f(n[]int)int{z:=math.MaxInt64;Z:=^z;for i:=0;i<len(n)-1;i++{r:=c(n[i],n[i+1]);if r<z{z=r};if r>Z{Z=r}};return z+Z}

Ungolfed version. Attempt This Online!

package main

import (
	"fmt"
	"math"
)

func compare(a, b int) int {
	if a < b {
		return 1
	}
	if a > b {
		return -1
	}
	return 0
}

func f(nums []int) int {
	min, max := math.MaxInt64, math.MinInt64
	for i := 0; i < len(nums)-1; i++ {
		result := compare(nums[i], nums[i+1])
		if result < min {
			min = result
		}
		if result > max {
			max = result
		}
	}
	return min + max
}

func main() {
	fmt.Println(f([]int{1, 2, 3, 5, 9}))
	fmt.Println(f([]int{1, 2, 3, 5, 5}))
	fmt.Println(f([]int{1, 1, 1, 1, 1}))
	fmt.Println(f([]int{1, 1, -3, -5, -9}))
	fmt.Println(f([]int{-1, -2, -3, -5, -9}))
}
\$\endgroup\$
1
  • \$\begingroup\$ -9 bytes: z:=math.MaxInt64;Z:=-~z; \$\endgroup\$
    – corvus_192
    Commented Nov 15, 2023 at 20:27
1
\$\begingroup\$

Swift, 175 bytes

Short version:

func m(_ n:[Int])->Int{var r=0,s=0>1;for i in 0..<n.count-1{let(y,x)=(n[i+1],n[i]);if y>x{r=r>0 && !s ?2:1}else if y<x{r=r<0 && !s ? -2:-1}else{r=r.signum();s=0<1}};return r}

Verbose version:

Basically update the return value to be 2 or -2 as long as the elements differ from each other and "clamp" it to -1,0,+1 as soon as two same elements are found.

func m(_ n:[Int])->Int{
    var r=0,
        s=0>1
    for i in 0..<n.count-1{
        let(y,x)=(n[i+1],n[i]);
        if y>x{
            r=r>0 && !s ?2:1
        }else if y<x{
            r=r<0 && !s ? -2:-1
        }else{
            r=r.signum();
            s=0<1
        }
    };
    return r
}
\$\endgroup\$
1
\$\begingroup\$

Perl 5 -p, 53 bytes

s/\S+/$'&&$'-$&/ge;$_=2*(/^(\S+ )\1+$/?$1<=>0:.5-/-/)

Try it online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.