| Bytes | Lang | Time | Link |
|---|---|---|---|
| 568 | Python3 | 240626T023857Z | Ajax1234 |
| 161 | Clean | 180518T005757Z | Οurous |
| 038 | Jelly | 180517T171244Z | Mr. Xcod |
| 302 | JavaScript Node.js | 180517T173215Z | l4m2 |
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
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]
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.ịḊṖ$€Ɗ€ƊȦ)Ṁ
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]))))
Checks if flowing from a point can't reach the border, while border can walk to every point