g | x | w | all
Bytes Lang Time Link
568Python3240626T023857ZAjax1234
161Clean180518T005757ZΟurous
038Jelly180517T171244ZMr. Xcod
302JavaScript Node.js180517T173215Zl4m2

Python3, 568 bytes

E=enumerate
M=[(0,1),(0,-1),(1,0),(-1,0)]
def G(n,d):
 q=[i for i in d if d[i]==n]
 while q:
  v=q.pop(0)
  Q,S=[v],[v]
  for x,y in Q:
   for X,Y in M:
    if d.get(t:=(x+X,y+Y))and d[t]<=n and t not in S:Q+=[t];S+=[t];q=[*{*q}-{t}]
  yield S
def f(b):
 d={(x,y):v for x,r in E(b)for y,v in E(r)}
 for i in{*d.values()}:
  for g in G(i,d):
   e={(x+X,y+Y)for x,y in g for X,Y in M}-{*g}
   if all(d.get(t,0)>i for t in e):
    s,*e=e;q=[s];e={*e}
    for x,y in q:t=[u for X,Y in M+[(-1,-1),(1,1),(1,-1),(-1,1)]if(u:=(x+X,y+Y))in e];q+=t;e-={*t}
    if not e:return 1

Try it online!

Clean, 224 ... 161 bytes

import StdEnv,StdLib
p=prod
~ =map
^ =reverse o$
@ =transpose o~(^o^)
$l=:[h:t]|h>1=l=[1: $t]
$e=e
?m=p[p(~p(limit(iterate(@o@)(~(~(\a|a>b=2=0))m))))\\n<-m,b<-n]

Try it online!

Defines the function ? :: [[Int]] -> Int, returning 0 if there is an ring, and 1 otherwise.

Works by turning the matrix into 2s for mountains and 0s for valleys, then floods in with 1s until the result stops changing. If any 0s still exist for any mountain height, the product will be 0.

Jelly, 38 bytes

Ẇ€Z$⁺Ẏµ,ZẈ>2ẠµƇµḊṖZƊ⁺FṀ<,Z.ịḊṖ$€Ɗ€ƊȦ)Ṁ

Try it online!

Outputs 1 if the matrix contains mountain ranges, 0 otherwise.

How it works (slightly outdated)

I may be able to shorten the code a bit, so this section will probably undergo heavy editing.

The helper link

,Z.ịḊṖ$€Ɗ€ – Helper link. Let S be the input matrix.
,Z         – Pair S with its transpose.
        Ɗ€ – For each matrix (S and Sᵀ), Apply the previous 3 links as a monad.
  .ị       – Element at index 0.5; In Jelly, the ị atom returns the elements at
             indices floor(x) and ceil(x) for non-integer x, and therefore this
             returns the 0th and 1st elements. As Jelly is 1-indexed, this is the
             same as retrieving the first and last elements in a list.
    ḊṖ$€   – And for each list, remove the first and last elements.

For example, given a matrix in the form:

A(1,1) A(1,2) A(1,3) ... A(1,n)
A(2,1) A(2,2) A(2,3) ... A(2,n)
A(3,1) A(3,2) A(3,3) ... A(3,n)
...
A(m,1) A(m,2) A(m,3) ... A(m,n)

This returns the arrays (the order doesn't matter):

A(1,2), A(1,3), ..., A(1,n-1)
A(m,2), A(m,3), ..., A(m,n-1)
A(2,1), A(3,1), ..., A(m-1,1)
A(2,n), A(3,n), ..., A(m-1,n)

Long story short, this generates the outermost rows and columns, with the corners removed.

The main link

Ẇ€Z$⁺Ẏµ,ZẈ>2ẠµƇµḊṖZƊ⁺FṀ<ÇȦ)Ṁ – Main link. Let M be the input matrix.
Ẇ€                           – For each row of M, get all its sublists.
  Z$                         – Transpose and group into a single link with the above.
    ⁺                        – Do twice. So far, we have all contiguous sub-matrices.
     Ẏ                       – Flatten by 1 level.
      µ      µƇ              – Filter-keep those that are at least 3 by 3:
       ,Z                      – Pair each sub-matrix S with Sᵀ.
         Ẉ                     – Get the length of each (no. rows, no. columns).
          >2                   – Element-wise, check if it's greater than 2.
            Ạ                  – All.
               µ          )  – Map over each sub-matrix S that's at least 3 by 3
                ḊṖ           – Remove the first and last elements.
                  ZƊ         – Zip and group the last 3 atoms as a single monad.
                    ⁺        – Do twice (generates the inner cells).
                     FṀ      – Flatten, and get the maximum.
                       <Ç    – Element-wise, check if the results of the helper
                               link are greater than those in this list.
                         Ȧ   – Any and all. 0 if it is empty, or contains a falsey
                               value when flattened, else 1.
                           Ṁ – Maximum.

JavaScript (Node.js), 302 bytes

a=>a.some((b,i)=>b.some((n,j)=>(Q=(W=(i,j,f)=>[a.map((b,I)=>b.map((t,J)=>I==i&J==j)),...a+0].reduce(A=>A.map((b,I)=>b.map((t,J)=>f(I)(J)&&(A[I-1]||b)[J]|(A[I+1]||b)[J]|b[J-1]|b[J+1]|t))))(i,j,I=>J=>a[I][J]<=n)).some((b,i)=>b.some((d,j)=>d&&!i|!j|!Q[i+1]|b[j+1]==b.b))<!/0/.test(W(0,0,I=>J=>!Q[I][J]))))

Try it online!

Checks if flowing from a point can't reach the border, while border can walk to every point