g | x | w | all
Bytes Lang Time Link
064AWK241125T195208Zxrs
005Japt180215T153739ZShaggy
005Thunno 2 G230815T125046ZThe Thon
008Pyth210418T182130Zhakr14
069Vim210417T220916Zkops
034Haskell210412T095005Zkops
113Python 3210417T210345ZSymmetr1
008Actually161129T025956ZSherlock
034R180215T172915ZGiuseppe
008Pip180215T035516ZDLosc
034Clojure161212T210137ZNikoNyrh
086Ceylon161127T222941ZPaŭlo Eb
041Retina161127T185035ZMartin E
067C161127T045958Zhmmwhats
014J161127T010936Zalgorith
050Befunge161125T145326ZLeo
1848LabVIEW161126T054456ZSRM
037Haskell161125T013121Znimi
030Python 2161125T233105Zxnor
036Haskell161125T232629Zxnor
016APL161125T203101ZRoman Su
052Python 3161125T102157ZSygmei
037Ruby161125T151027ZG B
007Brachylog161125T074629ZFatalize
074Python 2161125T132225ZKarl Nap
114Axiom161125T100225Zuser5898
085C++14161125T124924ZKarl Nap
044R161125T095129ZBillywob
044Racket161125T014503ZMatthew
05805AB1E161125T085247ZOsable
011Mathematica161125T075556ZMartin E
040Common Lisp161125T001751ZOmar
005Jelly161125T005507ZJonathan
051JavaScript ES6161125T012923ZNeil
007MATL161125T004222ZDJMcMayh
022Mathematica161125T004927ZGreg Mar
017Perl 6161125T003834ZBrad Gil

AWK, 64 bytes

{for(x=1;i++<NF;$i==$(i+1)&&x&&x=0)if($i<$(i+1)&&x=-1)break}$0=x

Prints 1, nothing, or -1.

Try it online!

{for(x=1;i++<NF;            # default to descending
$i==$(i+1)&&x&&x=0)         # test if equal and set output to 0/nothing
if($i<$(i+1)&&x=-1)break}   # if increasing set to -1
$0=x                        # set output

Japt, 9 8 7 5 bytes

Outputs 1 for "monotone strictly decreasing", 0 for "monotone non-incresing" and -1 otherwise. +2 bytes to handle the edge case of singleton arrays

äÎÍp1

Try it or run all test cases

äÎÍp1     :Implicit input of array
ä         :Consecutive pairs reduced by
 Î        :  Sign of difference
  Í       :Sort
   p1     :Push 1
          :Implicit output of first element

Thunno 2 G, 5 bytes

0aṢ€ʂ

Try it online!

Port of DJMcMayhem's MATL answer. Gives -1 for strictly deceasing, 0 for non-increasing, and 1 for none of the above.

Explanation

0aṢ€ʂ  # Implicit input
0a     # Append a 0
  Ṣ    # Deltas of the list
   €ʂ  # Sign of each
       # Take the maximum
       # Implicit output

Pyth, 8 bytes

._eS.+aZ

Try it online!

Literal translation of James's MATL answer.

Vim, 69 bytes

V}JYu:sor!n
V}JP:%s/^\(.*\)\n\1/m\r\1
:%s/\vm\n.*<(.+) \1.*/n
:g/\d/d

Try it online!

This is vanilla vim (TIO supports V (vim), which is backwards compatible). Takes input as a list of integers, one per line. Outputs m for strictly monotonic, n for non-increasing, and empty string otherwise.

V}              " select everything
  J             " space-join it all into one line
   Y            " yank that
    u           " undo back to one per line
     :sor!n     " reverse sort (the whole file, by line) numerically
V}J             " space join again
   P            " paste the previously yanked original list
                " now we have the list on line 1 and a sorted copy on line 2

Next we have two regexes.

:%s/^\(.*\)\n\1/m\r\1

Matches two copies of the same line and replaces the first with "m".

:%s/\vm\n.*<(\d+) \1.*/n

Matches that "m" followed by a line containing <(.+) \1, i.e. a word boundary followed by <foo> <foo>, and if found replaces everything with n. The \v at the start says "all characters are special" so we don't have to escape any of <()+.

There's a bit of careful cleverness here: we don't need a word boundary after the \1 because the first number can't be a prefix of the second in a reverse sorted list. Furthermore, even though (.+) can match several numbers (as opposed to (\d+) which would match only one for an extra byte), this won't result in any false positives for the same reason: we can't have a repeated string of multiple numbers in a reverse sorted list unless they're all the same, in which case we want to match them anyway.

The state after all this is one of:

monotonic     non-increasing      other
---------     --------------      -----
m             n                   3 1 2
3 2 1                             3 2 1

So, to collapse these states, we just delete any line which still has a digit: :g/\d/d, resulting in the desired output.

I do wonder whether the regexes can be golfed some (maybe avoiding some cross-line stuff?) but the corner cases can be a bit tricky.

Haskell, 34 bytes

maximum.(zipWith compare<*>(1/0:))

Try it online!

Outputs LT,EQ,GT for strictly monotonic, non-increasing, and otherwise, respectively. Thanks to @xnor for pointing out that my previous version failed on singleton lists and suggesting this alternative.

Takes the maximum of the sighn of the differences between adjacent pairs, prepending with inf. (zipWith compare<*>(1/0:) applied to l computes compare l inf:l elementwise).

This is competitive with the existing Haskell answers and ekes out ahead by being pointfree and anonymous.

Python 3, 113 bytes

def f(L):
 z=0
 for i in range(0,len(L)-1):
  if L[i]-L[i+1]<0:
   return 2
  if L[i]-L[i+1]==0:
   z=1
 return z

Try it online!

Could be shorter if there were a sign function. This outputs 0 for strictly decreasing, 1 for weakly decreasing and 2 for none of the above.

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.

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.

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)

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

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

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

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:

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

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

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!

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.

Haskell, 40 38 37 bytes

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

Returns

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!

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.

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.

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

Python 3, 81 52 bytes (Thanks to FryAmTheEggMan)

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

Try it online !

Ruby, 37 bytes

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

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

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.

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

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] 

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.

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

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

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

Mathematica, 15 11 bytes

##>0|##>=0&

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

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.

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

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

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.

MATL, 10, 7 bytes

0hdX>ZS

Try it online! or verify all test cases!

3 bytes saved, thanks to @LuisMendo!

The outputs are

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

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

Perl 6, 17 bytes

{[>](@_)+[>=] @_}

Expanded:

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