Let's decrease the monotony

33

1

...but hey, no need to be strict.

Given a non-empty array of strictly positive integers, determine if it is:

  1. Monotone strictly decreasing. This means that each entry is strictly less than the previous one.
  2. Monotone non-increasing, but not strictly decreasing. This means that each entry is less than or equal to the preceding, and the array does not fall in the above category.
  3. None of the above.

Note the following corner cases:

  • An array with a single number is monotone strictly decreasing (vacuously so).
  • An array with the same number repeated is monotone non-increasing, but not strictly decreasing.

Rules

You may provide a program or a function

Input can be taken in any reasonable format: array, list, string with numbers separated by spaces, ...

You can choose any three consistent outputs for the three categories respectively. For example, outputs can be numbers 0, 1, 2; or strings 1 1, 1 0, empty string.

Shortest code in bytes wins

Test cases

Monotone strictly decreasing:

7 5 4 3 1
42 41
5

Monotone non-increasing, but not strictly decreasing:

27 19 19 10 3
6 4 2 2 2
9 9 9 9

None of the above:

1 2 3 2
10 9 8 7 12
4 6 4 4 2

Luis Mendo

Posted 2016-11-24T23:53:20.103

Reputation: 87 464

Does writing a variadic function (where the input values aren't wrapped in any kind of data type at all but are all passed straight to the function as arguments) fall under "any reasonable format"? – Martin Ender – 2016-11-25T07:54:43.437

@Martin Yes, it does! – Luis Mendo – 2016-11-25T08:50:44.330

Answers

9

Jelly, 10 9 5 bytes

-Method found by DrMcMoylex, go give some credit!

;0IṠṀ

TryItOnline! or run all tests

Returns :-1=monotone strictly decreasing; 0=monotone non-increasing; 1=other.

How?

;0IṠṀ - Main link: list
;0    - concatenate with a zero
  I   - incremental differences
   Ṡ  - sign
    Ṁ - maximum

Jonathan Allan

Posted 2016-11-24T23:53:20.103

Reputation: 67 804

Is diacrtic M a part of any 8bit character map? You cannot say that it is 5 bytes because it is not. CP1252 does not have it for example.

– Euri Pinhollow – 2016-11-25T12:51:21.437

2

@EuriPinhollow Jelly uses this custom code page to count bytes, which is linked in the word byte in the header of this post.

– Fatalize – 2016-11-25T13:22:12.000

@Fatalize: thx, got it. – Euri Pinhollow – 2016-11-25T13:24:22.303

22

Perl 6, 17 bytes

{[>](@_)+[>=] @_}
  • Monotone strictly decreasing: 2
  • Monotone non-increasing: 1
  • Other: 0

Expanded:

{            # bare block lambda with implicit parameter list 「@_」
  [>]( @_ )  # reduce using 「&infix:« > »」
  +
  [>=] @_    # reduce using 「&infix:« >= »」
}

Brad Gilbert b2gills

Posted 2016-11-24T23:53:20.103

Reputation: 12 713

4Perl is magical – Fund Monica's Lawsuit – 2016-11-25T06:05:24.100

This can be extended to work with any type if > was switched with after and >= with !before. say {[after](@_)+[!before] @_}(<d c b a>) #=> 2 – Brad Gilbert b2gills – 2016-11-25T14:35:59.540

13

MATL, 10, 7 bytes

0hdX>ZS

Try it online! or verify all test cases!

3 bytes saved, thanks to @LuisMendo!

The outputs are

  • Strictly decreasing: -1

  • Non-increasing: 0

  • Other: 1

Explanation:

0           % Push a '0'
 h          % Join the 0 to the end of the input array.
  d         % Get consecutive differences
   X>       % Get the largest difference
     ZS     % Get its sign
            % Implicitly print it

James

Posted 2016-11-24T23:53:20.103

Reputation: 54 537

1Can't you append a 0 instead of prepending the last plus 1? Something like 0hdX>ZS – Luis Mendo – 2016-11-25T01:11:27.597

2@LuisMendo Ah, that's genius! Thankyou! – James – 2016-11-25T01:16:54.190

Doesn't help, but for obfuscation you could also use: 0hdX>0/ -- Question for you and @LuisMendo : Is it possible to leverage the fact that sort is only 1 char (opposed to X>), by somehow implicitly using the last value? – Dennis Jaheruddin – 2016-11-25T08:52:00.870

@DennisJaheruddin I also thought about using S, but I haven't found a way to make it shorter... – Luis Mendo – 2016-11-25T09:36:29.587

9

Mathematica, 22 bytes

Sign@*Max@*Differences

Unnamed function taking a list of numbers as input. Returns -1 if the list is strictly decreasing, 0 if it's nonincreasing but not strictly decreasing, and 1 if it's neither.

Pretty simple algorithm: take the differences of consecutive pairs, take the largest one, and take the sign of that largest one.

(I feel like there must exist some language in which this algorithm is 3 bytes....)

Regarding an array with a single entry: Differences yields an empty list; Max of an empty list gives -∞ (!); and Sign[-∞] evaluates to -1 (!!). So it actually works on this corner case. Gotta love Mathematica sometimes. (Indeed, the function also correctly labels an empty list as strictly decreasing.)

Greg Martin

Posted 2016-11-24T23:53:20.103

Reputation: 13 940

I see DrMcMoylex beat me by 7 minutes! :) – Greg Martin – 2016-11-25T01:39:20.910

2

"I feel like there must exist some language in which this algorithm is 3 bytes" http://chat.stackexchange.com/transcript/message/33720906#33720906 :(

– Martin Ender – 2016-11-25T06:50:23.210

7

Haskell, 40 38 37 bytes

foldl min GT.(zipWith compare<*>tail)

Returns

  • GT for Monotone strictly decreasing
  • EQ for Monotone non-increasing
  • LT else

compare compares two numbers and returns GT (EQ, LT) if the first number is greater than (equal to, less than) the second number. zipWith compare<*>tail compares neighbor elements. foldl min GT reduces the list of the comparison results with the min function starting with GT (note: LT < EQ < GT).

Edit: @xnor found 2 3 bytes. Thanks!

nimi

Posted 2016-11-24T23:53:20.103

Reputation: 34 639

Can you prepend a LT instead of appending 0? – xnor – 2016-11-25T08:46:53.897

@xnor: Yes, thanks, but it must be a GT, because we need the minimum of the list (I had maximum, which was wrong and a relict from an early version where I used =<< instead of <*>). – nimi – 2016-11-25T13:25:13.030

1I see. Actually, how about foldl min GT? – xnor – 2016-11-25T17:46:13.110

6

Common Lisp, 43 40 bytes

(defun f(x)`(,(apply'> x),(apply'>= x)))

This takes input as a Lisp list, and returns (T T), (NIL T) and (NIL NIL) to distinguish the 3 categories. Here it is running on the provided test cases:

CL-USER> (mapcar #'f '((7 5 4 3 1)
                       (42 41)
                       (5)
                       (27 19 19 10 3)
                       (6 4 2 2 2)
                       (9 9 9 9)
                       (1 2 3 2)
                       (10 9 8 7 12)
                       (4 6 4 4 2)))
((T T) (T T) (T T) (NIL T) (NIL T) (NIL T) (NIL NIL) (NIL NIL) (NIL NIL))

Omar

Posted 2016-11-24T23:53:20.103

Reputation: 1 154

1The exact same number of bytes as (defun f(x)(mapcar'apply'(> >=)\(,x,x))). Note that you can just write(lambda(x)...)` to be shorter. – coredump – 2016-11-25T12:24:03.363

6

Python 2, 30 bytes

lambda l:max(map(cmp,l[1:],l))

-1 for strictly decreasing, 0 for weakly decreasing, +1 for non-decreasing

Using cmp to compare consecutive elements, and takes the maximum. This is done by removing the first element of one copy of the list, then mapping cmp . For example, l=[2,2,1] gives

l[1:]  2   1   None
l      2   2   1
cmp    0  -1   -1

which has max 0 because an equality exists.

The shorter list is automatically extended with None, which is less than all numbers and so harmless. This phantom element also insulates against taking the min of an empty list when the input has length 1.

xnor

Posted 2016-11-24T23:53:20.103

Reputation: 115 687

Even with the very little Python I know I can appreciate how great this answer is – Luis Mendo – 2016-11-25T23:36:30.437

5

Brachylog, 7 bytes

>,1|>=,

Try it online!

This prints 1 for strictly decreasing, 0 for non-increasing and false. otherwise.

Explanation

  (?)>              Input is a strictly decreasing list
      ,1(.)         Output = 1
|                 Or
  (?)>=             Input is a non-increasing list
       ,(.)         Output is a free variable; gets automatically labeled as an integer at
                      the end of execution. Since its domain is [-inf, +inf], the first
                      value it takes is 0
                  Or
                    No other possibility, thus this main predicate is false.

Other 7 bytes solutions

>=!>,;1           Returns 0 for strictly decreasing, false. for non-increasing, 1 otherwise.

>=!>,1|           Returns 1 for strictly decreasing, false. for non-increasing, 0 otherwise.

Fatalize

Posted 2016-11-24T23:53:20.103

Reputation: 32 976

4

R, 44 bytes

d=diff(scan());c(any(!d)&all(d<=0),all(d<0))

Reads input from stdin and prints the following depending on the input:

Output:

[1] FALSE TRUE: Monotone non-increasing

[1] TRUE FALSE: Monotone strictly decreasing

[1] FALSE FALSE: None of the above

Billywob

Posted 2016-11-24T23:53:20.103

Reputation: 3 363

d=diff(scan());ifelse(all(d<=0),!prod(d),2) is 1 byte shorter. It returns 0 if monotone strictly, 1 if monotone non-increasing and 2 if none of the above. Not sure if it is allowed to return nothing if none of the above, but then you could simplify further to d=diff(scan());if(all(d<=0))!prod(d). – JAD – 2016-11-26T09:54:02.650

Actually, d=diff(scan());if(all(d<=0))any(!d) is one byte better. – JAD – 2016-11-26T10:00:01.573

3

JavaScript (ES6), 51 bytes

a=>a.some((e,i)=>e>a[i-1])+a.some((e,i)=>e>=a[i-1])

Returns 0 for strict decreasing, 1 for non-increasing, 2 otherwise.

Neil

Posted 2016-11-24T23:53:20.103

Reputation: 95 035

3

05AB1E, 5 8 bytes

Bug fixed by Emigna, thanks! It uses the same method as DrMcMoylex's.

®¸ì¥Z0.S

®¸ì   Implicitly take input and appends -1 to it
¥     Yield deltas
 Z    Take the largest delta
  0.S Take its sign and implicitly display it

Try it online!

Output is:

-1 if strictly decreasing sequence
 0 if non-strictly decreasing sequence
 1 otherwise

Osable

Posted 2016-11-24T23:53:20.103

Reputation: 1 321

1®¸ì¥Z0.S would fix the single element issue. – Emigna – 2016-11-25T09:02:33.980

Nice, thanks! I think 0 at the beginning would also work since all numbers are positive (strictly by default I guess). – Osable – 2016-11-25T09:06:34.190

Yes 0 would work as well, but it's nice that it works for input containing 0 (even though by definition it wont) :) – Emigna – 2016-11-25T09:17:44.843

Fun fact: in French "positive" means positive or zero and you have to specify "strictly positive" to reach the same meaning as "positive" in English. – Osable – 2016-11-25T09:19:39.527

3

Ruby, 37 bytes

->l{[d=l==l.sort.reverse,d&&l|[]==l]}

Output:[true,true], [true,false] or [false,false]

G B

Posted 2016-11-24T23:53:20.103

Reputation: 11 099

2

Racket, 44 bytes

(λ(x)(map(λ(p)(apply p`(,@x 0)))`(,>,>=)))

Invoked:

(map (λ(x)(map(λ(p)(apply p`(,@x 0)))`(,>,>=)))
 '((7 5 4 3 1)
   (42 41)
   (5)
   (27 19 19 10 3)
   (6 4 2 2 2)
   (9 9 9 9)
   (1 2 3 2)
   (10 9 8 7 12)
   (4 6 4 4 2)))

Result:

'((#t #t)
 (#t #t)
 (#t #t)
 (#f #t)
 (#f #t)
 (#f #t)
 (#f #f)
 (#f #f)
 (#f #f))

Matthew Butterick

Posted 2016-11-24T23:53:20.103

Reputation: 401

It's a shame Racket doesn't define the arity 1 case of > as true. Common Lisp gets that right, but fails to define the arity 0 case (which should also be true). – Omar – 2016-11-25T02:21:51.363

2

Mathematica, 15 11 bytes

##>0|##>=0&

This is a variadic function, taking all input integers as separate arguments.

  • Strictly decreasing: True | True
  • Non-increasing: False | True
  • Neither: False | False

Note that | is not Or but Alternatives, which is part of pattern matching syntax, which explains why these expressions don't get evaluated to True, True, False, respectively.

The code itself is mostly an application of this tip. For example ##>0 is Greater[##, 0] but then ## expands to all the input values so we get something like Greater[5, 3, 2, 0], which itself means 5>3>2>0.

Martin Ender

Posted 2016-11-24T23:53:20.103

Reputation: 184 808

2

Python 3, 81 52 bytes (Thanks to FryAmTheEggMan)

e=sorted
lambda a:(a==e(a)[::-1])+(e({*a})[::-1]==a)

Try it online !

Sygmei

Posted 2016-11-24T23:53:20.103

Reputation: 1 137

sorted(s)[::-1] is shorter for reversing a sorted list. In Python 3 you can do {*a} to get a set of the elements of a. sorted returns a list so you don't have to cast the set to a list either. Also adding booleans is perfectly kosher! Finally you can submit an anonymous lambda, so you don't need f=. I get 52 bytes in the end. https://repl.it/E7eG/2 – FryAmTheEggman – 2016-11-25T15:32:47.140

2

C++14, 85 bytes

int f(int x){return 3;}int f(int x,int y,auto...p){return((x>=y)+2*(x>y))&f(y,p...);}

Returns 3 (0b11) for strict decreasing, 1 (0b01) for non-increasing and 0 otherwise.

Ungolfed:

int f(int x) {return 3;}
int f(int x,int y,auto...p){
  return ((x>=y)+2*(x>y)) & f(y,p...);
}

I thought this was a perfect problem for C++17's folding expressions:

int g(auto...x){return(x>...)+(x>=...);}

Unfortunately it does not chain the relational operators but does

((x1>x2)>x3)>x4)...

which is not was wanted.

Karl Napf

Posted 2016-11-24T23:53:20.103

Reputation: 4 131

2

Python 2, 61 74 bytes

+13 bytes for the single number input

x=map(str,input())
print[2,eval(">".join(x))+eval(">=".join(x))][len(x)>1]

Requires input in bracket list form like [3,2,1]. Returns 2 for strict decreasing, 1 for non-increasing and 0 otherwise.

Old solution:

print eval(">".join(x))+eval(">=".join(x))

Karl Napf

Posted 2016-11-24T23:53:20.103

Reputation: 4 131

2

Befunge, 50 bytes

&: >~1+#^_v>:0`|
1\:^  @.$$<-@.2_
-: ^    >& ^   >

Try it online!

Accepts input as a sequence of int separated by spaces, and returns 0 if strictly decreasing, 1 if non-strictly decreasing, 2 otherwise.

Since reading befunge is kind of impossible if you don't know the language, this is the algorithm in pseudocode:

push(input())

while( getchar()!=EOF ){
  push(input())
  subtract()
  duplicate()
  if(pop()>0){
    subtract() //we are doing a-(a-b), so b is now on top
    duplicate()
  }
  else{
    if(pop()==0){
      push(1) //the sequence is not strictly decreasing
      swap()
      duplicate()
    }
    else{
      push(2) //the sequence has just increased
      output(pop)
      return
    }
  }
}
pop()
pop()
output(pop())

*in befunge memory is a stack which starts with an infinite amount of 0 on it. pop(), push(x), input() and output(x) are self-explainatory, the other pseudofunctions i used work like this:

function duplicate(){
  a=pop()
  push(a)
  push(a)
}

function subtract(){
  a=pop()
  b=pop()
  push(b-a)
}

function swap(){
  a=pop()
  b=pop()
  push(a)
  push(b)
}

Funge!


Previous version, just 41 bytes but invalid since it requires a 0 to terminate the input sequence (or using an interpreter like this)

&:  >&:|>:0`|
1\v@.$_<-@.2_
- >:v  >^   >

Try it online!

Leo

Posted 2016-11-24T23:53:20.103

Reputation: 8 482

I'm afraid a trailing 0 doesn't count as a valid input format. I think it falls under the "preprocessed input" category. In fact, some answers append a 0 in the code (thus including that in the byte count). I would be acceptable if you could Can you replace the 0 by some non-numeric character? That would be acceptable – Luis Mendo – 2016-11-25T15:21:43.457

@LuisMendo Actually, with this interpreter (which is the one I used to develop the code) EOF does return 0, so there is no need to add anything to the input. I wasn't able to discover what the intended behaviour should be, so I don't know if this assumption is standard or not. A thing that I may have misinterpreted, though, is: can zeroes be part of the input sequence? If so, I would need to modify the code anyway.

– Leo – 2016-11-25T15:56:01.453

No, zeros can't be part of the sequence (Given a non-empty array of positive integers_ I meant strictly positive integers). But some answers do use a 0 inserted by the code to deal with the case that the input has only one entry. That's one reason why I consider that including that 0 in the input is not valid. Anyway, if there is an interpreter that doesn't need it, you can use that interpreter to prove that your answer is valid without the 0. If the Try-it-online interpreter needs that 0, you can include it for demonstration purposes, with an appropriate explanation note – Luis Mendo – 2016-11-25T16:03:18.507

@JamesHolderness while on tryonline ~ works as it should, & has a strange behaviour on EOF, apparently repeating the last input forever. See here for an example

– Leo – 2016-11-25T16:43:51.603

1I edited the answer using James's approach, now input is terminated by EOF – Leo – 2016-11-26T10:34:27.813

2

J, 14 bytes

Monadic verb taking the list on the right, returning 1 for strictly decreasing, 0 for weakly decreasing, and _1 otherwise.

*@([:<./2-/\])

Takes the sign * of the minimum <./ of consecutive differences 2-/\ of the list. J doesn't swap the order of the differences when taking them so e.g. the sequence is strictly decreasing if these are all positive. Notably, <./ returns positive infinity on zero-element lists.

In use at the REPL:

   *@([:<./2-/\]) 3
1
   *@([:<./2-/\]) 3 2
1
   *@([:<./2-/\]) 3 2 2
0
   *@([:<./2-/\]) 3 2 2 3
_1

algorithmshark

Posted 2016-11-24T23:53:20.103

Reputation: 8 144

2

C, 68 67 Bytes

A function f, which is passed an array of ints (l) preceded by its length (n, also an int). Returns 3 if monotone strictly decreasing, 1 if monotone non-increasing, but not strictly decreasing, 0 otherwise.

f(int n,int*l){return n<2?3:((l[0]>l[1])*2|l[0]>=l[1])&f(n-1,l+1);}

Un-golfed slightly for readability:

int f_semiungolfed(int n, int* l) {
    return (n < 2) ? 3 : ((l[0] > l[1]) * 2 | l[0] >= l[1]) & f(n - 1, l + 1);
}

Rearranged and commented to show logic:

int f_ungolfed(int n, int* l) {
    int case1 = 0, case2 = 0, recursion = 0;
    if (n < 2) { // Analogous to the ternary conditional I used - n < 2 means we have a single-element/empty list
        return 3; // Handles the vacuous-truth scenario for single lists
    } else {
        case1 = l[0] > l[1]; // The first case - are the two numbers in the list strictly decreasing? (case1 is 1 if so)
        case2 = l[0] >= l[1]; // The second case - are the two numbers strictly non-increasing (case2 is 1 if so)
        recursion = f_ungolfed(n - 1, l + 1); // Recursively call ourselves on the "rest" of the list (that is, everything other than the first element). Consider that comparison is transitive, and that we already have a vacuous-truth scenario covered.
        case1 *= 2; // Shift case1's value over to the left by one bit by multiplying by 2. If case1 was 1 (0b01), it's now 2 (0b10) - otherwise it's still 0 (0b00)
        return (case1 | case2) & recursion; 
        // The bitwise OR operator (|) will combine any 1-bits from case1's value (either 0b10 or 0b00) or case2's value (either 0b01 or 0b00) into either 3, 2, 1, or 0 (0b11, 0b10, 0b01, or 0b00 respectively).
        // The bitwise AND operator (&) will combine only matching 1-bits from (case1|case2) and the return value of the recursive call - if recursion = 0b11 and case1|case2 = 0b01, then the return value will be 0b01.
    }
}

Test cases (courtesy IDEOne):

{7, 5, 4, 3, 1}: 3
{42, 41}: 3
{5}: 3
{27, 19, 19, 10, 3}: 1
{6, 4, 2, 2, 2}: 1
{9, 9, 9, 9}: 1
{1, 2, 3, 2}: 0
{10, 9, 8, 7, 12}: 0
{4, 6, 4, 4, 2}: 0

hmmwhatsthisdo

Posted 2016-11-24T23:53:20.103

Reputation: 21

2

Retina, 41 bytes

\d+
$*
A`\b(1+) 1\1
S`\b$
\b(1+) \1\b.*|$

Try it online! (The first line enables a linefeed-separated test suite.)

  • Strictly decreasing: 2
  • Non-increasing: 3
  • Neither: 1

Explanation

\d+
$*

Converts the input unary.

A`\b(1+) 1\1

The regex here matches an increasing pair of consecutive numbers. If this is the case, the input can clearly not be non-increasing. The A denotes it as an "anti-grep" stage which means that the input line is discarded and replaced with the empty string if the regex matches.

S`\b$

This is a split stage which is used to append a linefeed to the input only if the input wasn't discarded. So we've got two possible outcomes so far: non-increasing inputs get a linefeed at the end and others are still empty.

\b(1+) \1\b.*|$

Finally, we count the number of matches of this regex. The regex either matches to identical numbers (and then everything to the end of the string to avoid multiple matches of this kind for inputs like 1 1 1 1), or the "end of the input". Let's go through the three types of inputs:

  • Strictly decreasing: the first part of the regex can't match because all values are unique, but the $ matches. Now $ isn't exactly "the end of the string". It can also match in front of a trailing linefeed. So we'll actually get two matches from it, one at the end of the input, and one after the linefeed we inserted.
  • Non-increasing: now the first part of the regex also provides a match, and we end up with three matches.
  • Neither: remember that we took care to turn the input into an empty string, so now $ matches only once.

Martin Ender

Posted 2016-11-24T23:53:20.103

Reputation: 184 808

1

Axiom, 114 bytes

m(c:List(INT)):INT==(i:=r:=1;repeat(~index?(i+1,c)=>break;c.i<c.(i+1)=>return 0;if c.i=c.(i+1)then r:=2;i:=i+1);r)

Ungolfed

-- if [a,b,..n] decrescente ritorna 1
--          non crescente   ritorna 2
--          altrimenti      ritorna 0  
m(c:List(INT)):INT==
   i:=r:=1
   repeat
      ~index?(i+1,c)=>break 
      c.i<c.(i+1)   =>return 0
      if c.i=c.(i+1) then r:=2
      i:=i+1
   r

Results

(x) -> m([3,1])=1, m([1,1])=2, m([])=1, m([1])=1, m([1,3])=0
   (x)  [1= 1,2= 2,1= 1,1= 1,0= 0] 

RosLuP

Posted 2016-11-24T23:53:20.103

Reputation: 3 036

1Forse dovresti tradurre i commenti all'inglese :-) – Luis Mendo – 2016-11-25T10:16:40.407

1

APL, 16 bytes

(a≡a[⍒a])×1+a≡∪a

Note: enter one element array as eg a←1⍴3 otherwise: a←4 3 2 1

Interpreting output:

2 Monotone strictly decreasing
1 Monotone non-increasing, but not strictly decreasing
0 None of the above

Idea: test for monotonicity by comparing original to sorted array, check for non-increasing by comparing to array with removed duplications.

(And I think it can be improved...)

Roman Susi

Posted 2016-11-24T23:53:20.103

Reputation: 111

Changed to one number. Bytes increased by 2... – Roman Susi – 2016-11-25T21:18:54.370

1

Haskell, 36 bytes

f l=[scanl1(min.(+x))l==l|x<-[0,-1]]

(+x) is because haskell mis-interprets (-x) as a value instead of a section. I wonder if the whole expression can be profitably made pointfree.

xnor

Posted 2016-11-24T23:53:20.103

Reputation: 115 687

1

LabVIEW, 12 nodes, 18 wires ==> 48 bytes by convention

enter image description here

No functions hidden in the other case frames, just a single wire across.

SRM

Posted 2016-11-24T23:53:20.103

Reputation: 111

1

Ceylon, 86 bytes

Object m(Integer+l)=>let(c=l.paired.map(([x,y])=>x<=>y))[if(!smaller in c)equal in c];

The function takes the input as its parameters, and returns a tuple of zero or one booleans – [false] for Monotone strictly decreasing, [true] for Monotone non-increasing, but not strictly decreasing, and [] for None of the above.

It can be used like this:

shared void run() {
    print("Monotone strictly decreasing:");
    print(m(7, 5, 4, 3, 1));
    print(m(42, 41));
    print(m(5));

    print("Monotone non-increasing, but not strictly decreasing:");
    print(m(27, 19, 19, 10, 3));
    print(m(6, 4, 2, 2, 2));
    print(m(9, 9, 9, 9));

    print("None of the above:");
    print(m(1, 2, 3, 2));
    print(m(10, 9, 8, 7, 12));
    print(m(4, 6, 4, 4, 2));
}

Output:

Monotone strictly decreasing:
[false]
[false]
[false]
Monotone non-increasing, but not strictly decreasing:
[true]
[true]
[true]
None of the above:
[]
[]
[]

An ungolfed and commented version:

// Let's decrease the monotony! 
//
// Question:  http://codegolf.stackexchange.com/q/101036/2338
// My Answer: http://codegolf.stackexchange.com/a/101309/2338


// Define a function which takes a non-empty list `l` of Integers)
// (which arrive as a tuple) and returns an Object (actually
// a `[Boolean*]`, but that is longer.) 
Object m(Integer+ l) =>
        // the let-clause declares a variable c, which is created by taking
        // pairs of consecutive elements in the input, and then comparing
        // them. This results in lists like those (for the example inputs):
        // { larger, larger, larger, larger }
        // { larger }
        // {}
        // { larger, equal, larger, larger }
        // { larger, larger, equal, equal }
        // { equal, equal, equal }
        // { smaller, smaller, larger }
        // { larger, larger, larger, smaller }
        // { smaller, larger, equal, larger }  
        let (c = l.paired.map( ([x,y]) => x<=>y) )
            // now we analyze c ...
            // If it contains `smaller`, we have an non-decreasing sequence.
            // We return `[]` in this case (an empty tuple).
            // Otherwise we check whether `equal` is in the list, returning
            // `[true]` (a non-strictly decreasing sequence) if so,
            // and `[false]` (a strictly decreasing sequence) otherwise.
            [if(!smaller in c) equal in c];

Paŭlo Ebermann

Posted 2016-11-24T23:53:20.103

Reputation: 1 010

1

Actually, 9 8 bytes

This answer is based on Jonathan Allan's excellent Jelly answer, and returns -1 for a strictly decreasing array, 0 for a non-increasing array, and 1 for none of the above. Golfing suggestions welcome! Try it online!

;\♀-dXMs

Ungolfing

     Implicit input a.
;\   Duplicate a and rotate that duplicate left by 1.
♀-   Vectorized subtract the two duplicates.
dX   Discard the last element, leaving only the first differences of a.
M    Get the maximum first difference.
s    Push the sign of the maximum first difference, returning -1, 0, or 1 as described above.
     Implicit return.

Sherlock9

Posted 2016-11-24T23:53:20.103

Reputation: 11 664

Dennis's? Are you sure? :P – Erik the Outgolfer – 2018-02-15T16:23:43.030

@ErikTheOutgolfer Whoops. Thanks for letting me know – Sherlock9 – 2018-02-15T21:21:22.807

1

Clojure, 34 bytes

#(if(apply > %)1(if(apply >= %)2))

Very straight-forward, returns 1 for if strictly decreasing, 2 if non-increasin and nil otherwise.

Also tried avoiding apply with macro's ~@ but it is just longer at 43 chars (this results in [1 2 nil]):

(defmacro f[& i]`(if(> ~@i)1(if(>= ~@i)2)))

[(f 7 5 4 3 1)
 (f 27 19 19 10 3)
 (f 1 2 3 2)]

NikoNyrh

Posted 2016-11-24T23:53:20.103

Reputation: 2 361

1

Pip, 8 bytes

O$>g$>=g

Full program. Takes the input list as command-line arguments. Outputs 11 for strictly decreasing, 01 for non-increasing, 00 for neither.

Try it online!

Explanation

This approach works because Pip's comparison operators, like Python's, chain together: 4>3>2 is true, rather than being (4>3)>2 (false) as in C. And the same behavior holds when the comparison operators are modified with the $ fold meta-operator.

          g is list of command-line args (implicit)
 $>g      Fold g on >
O         Output without newline
    $>=g  Fold g on >=
          Print (implicit)

DLosc

Posted 2016-11-24T23:53:20.103

Reputation: 21 213

1

Japt, 9 8 7 bytes

Outputs -1 for "monotone strictly decreasing", 0 for "monotone non-incresing" and 1 otherwise.

än rw g

Try it

1 byte saved thank to Oliver.

Shaggy

Posted 2016-11-24T23:53:20.103

Reputation: 24 623

@Oliver, yes; otherwise it will default to ... Wait, what? Why does that work?! än mg rw returns the wrong results without the J but that's not the case with än rw g. Weird. – Shaggy – 2018-02-15T17:15:34.160

1

R, 34 bytes

function(x)max(sign(diff(c(x,0))))

Try it online!

Ports DJ's MATL answer.

R, 43 bytes

function(x)all(diff(x)<0)+all(x==cummin(x))

Try it online!

Returns 2 for strictly decreasing, 1 for non-increasing, and 0 otherwise.

all(x==cummin(x)) is TRUE (converts to 1 when used in arithmetic) if and only if f is non-increasing, including the strict case.

all(diff(x)<0) is TRUE only when f is strictly decreasing.

Giuseppe

Posted 2016-11-24T23:53:20.103

Reputation: 21 077