# Mountain range number

A number is a mountain range number if the inequalities satisfied by their consecutive digits alternate. In a way, looking at the number's digits should exhibit a /\/\/\... or a \/\/\/... pattern.

More formally, if our number n has $$\k$/extract_tex] digits $$n = d_1d_2d_3\cdots d_k$$ then n is a mountain range number if $$\begin{cases}d_1 > d_2 \\ d_2 < d_3 \\ d_3 > d_4 \\ \cdots \end{cases} \vee \begin{cases}d_1 < d_2 \\ d_2 > d_3 \\ d_3 < d_4 \\ \cdots \end{cases}$$ # Your task Given an integer with 3 or more digits, output a Truthy value if the number is a mountain range number or Falsy otherwise. # Input A positive integer n with 3 or more digits, in any reasonable format, e.g. • Integer • String • List of digits # Test cases ### Truthy 1324 -> Truthy 9191 -> Truthy 12121 -> Truthy 121212 -> Truthy 1212121 -> Truthy 19898 -> Truthy  ### Falsy (Added another Falsy test case as per the comments, some answers might not cover the 4422 test case) 123 -> Falsy 321 -> Falsy 4103 -> Falsy 2232 -> Falsy 1919199 -> Falsy 4422 -> Falsy  This is so shortest answer in bytes wins! Standard loopholes are forbidden. • May we take input as a list of digits rather than an integer? – Robin Ryder Feb 6 '20 at 17:03 • @RobinRyder yes you may – RGS Feb 6 '20 at 17:10 • @AdmBorkBork this one has an input relaxation (k>=3); also the other challenge is so old that many of the answers there wouldn't be close to competitive on this one; I'd actually rather remove the old one as a dupe of this. – Giuseppe Feb 6 '20 at 19:27 • @Giuseppe That's what I was leaning towards as well, hence why I didn't hammer it. I have now just hammered the old one. Thanks! – AdmBorkBork Feb 6 '20 at 19:52 • Related with a source restriction – Jo King Feb 7 '20 at 0:39 ## 25 Answers # 05AB1E, 6 bytes ¥ü*0‹P  Try it online! With truthy and falsy reversed, this would be 5 bytes: ¥ü*dZ  TIO • Good job! +1 Why would the truthy <> falsy reversal make it shorter? – RGS Feb 6 '20 at 17:38 • @RGS 05AB1E has a single-byte built-in for x >= 0, but not for its negation x < 0. – Grimmy Feb 6 '20 at 17:39 • I see, thanks for the tip. – RGS Feb 6 '20 at 17:40 • I've used your answer to golf my answer in the same challenge with source restriction. If you want to post it as your own answer there I will of course revert back to my 7-byter and allow you to. – Kevin Cruijssen Feb 7 '20 at 7:38 # R, 44 40 bytes crossed out 44 is still regular 44 -1 byte thanks to Giuseppe. function(x,d=diff)all(d(sign(d(x)))^2>3)  Try it online! Computes the differences of the signs of the differences of the input. These must all be equal to 2 or -2, i.e. the square must equal 4; checking that the square is >3 is sufficient. If two consecutive digits are equal, there will be a 0 in the signs of differences, leading to a difference of signs of differences equal to 1 or -1. If three consecutive digits are in ascending or descending order, then the corresponding differences will be of the same sign, leading to a difference of signs of differences equal to 0. If neither of these occurs, the number is a mountain range number. Old version (included as it might be golfable): # R, 44 43 bytes -1 byte thanks to Giuseppe. function(x)all(s<-sign(diff(x)),rle(s)l<2)  Try it online! Computes the signs of the differences of consecutive digits. Then verifies that • none of the signs are 0s (would correspond to 2 equal consecutive digits); • the runs of the signs are all equal to 1, i.e. no 2 consecutive signs are equal. • Good job, I like the usage of the run length function! +1 – RGS Feb 6 '20 at 17:23 • all(.^2>3) is a bit shorter, since we know that the absolute value of the diff of the signs is bounded between -2 and 2. – Giuseppe Feb 6 '20 at 19:22 • similarly, for your old version, you can do rle(s)l<2 since we know there aren't zero-length runs. – Giuseppe Feb 6 '20 at 19:28 • @Giuseppe Thanks! – Robin Ryder Feb 6 '20 at 20:14 • +1 for the clever squaring approach. You could have saved another 6 by using scan for input, but (as I acknowledged in my own answer) this doesn't seem particularly clever, and seems more like a sneaky trick... – Dominic van Essen May 20 '20 at 10:08 # JavaScript (ES6), 35 33 bytes a=>!a.some(p=v=>a*(a=p-(p=v))>=0)  Try it online! ### Commented a => // a[] = input list of digits, // re-used to store the last difference !a.some( // p = // initialize p to a non-numeric value v => // for each v in a[]: a * ( // multiply a by a = // the new value of a defined as p - // the difference between p and (p = v) // the new value of p, which is v ) // >= 0 // the test fails if this is non-negative ) // end of some()  • +1 for your weird expression used. I haven't been around for a long time but I keep noticing you like to post JS answers! JS does incredibly well at golfing, does it not? – RGS Feb 6 '20 at 19:07 • Also, could you explain a bit what is going on in x=p=v=>x*(x=p-(p=v))>=0 ? – RGS Feb 6 '20 at 19:07 • @RGS We assign the arrow function v=>... to both x and p. Because this is non-numeric, the arithmetic operations in which these values are involved will result in NaN which is neither >=0 or <0. So the first 2 iterations will always be falsy, which is the expected behavior. – Arnauld Feb 6 '20 at 19:16 • @RGS Initializing variables this way in the callback of a loop is a rather common trick in JS (err... I mean golfed JS, obviously). This also works if we want them to be zero'ish in some bitwise operations. – Arnauld Feb 6 '20 at 19:22 • ah I get it! Thanks for the explanation! – RGS Feb 6 '20 at 19:22 # Jelly, 7 6 bytes A benchmarking solution. A monadic link taking as input the list of digits I×Ɲ<0Ạ  You can try it online or verify all test cases. I Take the forward differences Ɲ and for each pair, × multiply them together. <0 Check if those are below 0. Ạ Check if this array of booleans only contains Truthy values.  -1 byte thanks to @79037662 • I don't know Jelly, but could it be shorter to simply check for negativity, instead of taking the sign and then checking it's equal to -1? – 79037662 Feb 6 '20 at 17:31 • @79037662 yes it would! Thanks for the alert! – RGS Feb 6 '20 at 17:37 • Nice answer. However, in general I’d consider holding back from answering your own question for a few days; as far as I understand that’s the general etiquette here. – Nick Kennedy Feb 6 '20 at 18:54 • @NickKennedy oh sorry, will do so for the next challenges. Thanks for letting me know. – RGS Feb 6 '20 at 18:58 • @RGS no worries! And nice challenge. – Nick Kennedy Feb 6 '20 at 19:20 # Japt-!, 7 bytes Takes input as a digit array. äÎä* dÄ  Try it • Don't flags usually add up to the byte count? – RGS Feb 6 '20 at 17:12 • Your code currently gives a truthy value for 122, which is not a mountain range number. – RGS Feb 6 '20 at 17:14 • @RGS Flags used to be part of the byte count indeed, but now there's consensus that they can be used for free (Personally I don't like that, but...) – Luis Mendo Feb 6 '20 at 17:32 • @LuisMendo They can be used but they count as a different language. – S.S. Anne Feb 6 '20 at 20:01 • @RGS, fixed. And if you'd followed the link I very deliberately include with the flags in all my solutions ... – Shaggy Feb 6 '20 at 22:54 # Haskell, 57554744 42 bytes all(<0).z(*).z(-) z f(x:s)=zipWith(f)sx:s  Try it online! Takes input as a list of digits. • -2 by swapping the order of s and x:s • -8 by using a different helper function • -3 by using partial application and pointfree code • -2 by excluding f= from the submission (which I didn't realize was allowed :P) xnor improved my answer using >>=. • Good job on this one! I like Haskell :D +1 – RGS Feb 6 '20 at 17:39 # Python, 47 bytes f=lambda a,b,*l:l==()or(a-b)*(b-l[0])*f(b,*l)<0  Try it online! Takes input splatted like f(1,2,3,4). Same idea as my second Haskell answer. • Ah wow, you guys keep surprising me every time! +1 – RGS Feb 7 '20 at 9:04 # Excel (Insider build ver. 1912), 122 Bytes A1 'Input B1 =SEQUENCE(LEN(A1)) C1 =MID(A1,B1#,1) D1 =SIGN(IF(NOT(B1#-1),C1-C2,C1#-INDEX(C1#,B1#-1))) E1 =(SUM(D1#)=D1*ISODD(LEN(A1)))*PRODUCT(D1#) 'Output  Returns ±1 (truthy) or 0 (falsy) Explanation (can add more detail if people are interested) B1 =SEQUENCE(LEN(A1)) ' Generates a spill array from 1 to the length of the input C1 =MID(A1,B1#,1) ' Splits characters into rows. Using each value in the spill array B1# ' as a charcter index D1 =SIGN(IF(NOT(B1#-1), ' Choose different value on the first cell C1-C2, ' Use the opposite of the first difference between digits C1#-INDEX(C1#,B1#-1))) ' get the difference between each digit and the previous E1 =(SUM(D1#)=D1*ISODD(LEN(A1))) ' Sum the digit differences, if the ' input length is even check if 0, else check if equal to ' thefirst row of the differences *PRODUCT(D1#)) ' ensure there aren't any repeated digits  Tests • Hey there, thanks for your Excel submission! Very unusual :D +1 – RGS Feb 7 '20 at 23:57 • Excel lent work! (sorry, I couldn't help myself) – cschultz2048 Oct 4 '20 at 2:40 # APL+WIN, 171512 11 bytes 5 bytes saved thanks to Jo King & 1 byte thanks to Bubbler. Turning into a real team effort! Prompts for list of digits: ×/0>2×/2-/⎕  Try it online! (Dyalog Classic) • Good job on this one! +1 – RGS Feb 6 '20 at 22:11 • Is there a point to assigning the input to n? – Jo King Feb 7 '20 at 9:47 • Jo. No! There is no point. It was left over from an earlier version. Old age :( Thanks for spotting it. – Graham Feb 7 '20 at 16:32 • I believe there's no point to the 1= either, unless APL+WIN has a different result for 0>. Oh, and the second × too! – Jo King May 15 '20 at 13:15 • @JoKing Thanks again. Same excuse I am afraid! – Graham May 20 '20 at 6:56 # Husk, 7 bytes Λ<0Ẋ*Ẋ-  Try it online! Algorithm taken from the APL answer. ## Explanation Λ<0Ẋ*Ẋ- Ẋ- subtract pairs of consecutive elements Ẋ* multiply pairs of consecutive elements Λ return truthy value if all elements are: <0 lesser than 0  # Jelly, (5?) 6 bytes 5 if we may invert the truthy/falsey output (strip the trailing ¬). IṠIỊẸ¬  Try it online! • Really clever solution! +1 it took me a bit to understand why you wanted to use the Ị after the second I but then I realized you were building the opposite result – RGS Feb 6 '20 at 19:04 • Fun fact, the codepoints of this answer themselves (in Jelly encoding) are also a mountain/dale (same as this answer on the source-restriction challenge). – Kevin Cruijssen Feb 7 '20 at 7:27 # Haskell, 37 bytes all(<0).g(*).g(-) g=(=<<tail).zipWith  Try it online! Takes the zipWith-based answer of 79037662 and generalizes out the pattern of g(?) = \s->zipWith(?)(tail s)s  that applies the operator (?) to pairs of adjacent elements. This is shortened to the pointfree g=(=<<tail).zipWith. We first apply g(-) to the input to take differences of consecutive elements, then g(*) to take products of those consecutive differences. Then, we check that these products are all negative, which means that consecutive differences must be opposite in sign. # Haskell, 40 bytes f(a:b:t)=t==[]||(a-b)*(b-t!!0)<0&&f(b:t)  Try it online! The idea is a bit clearer to see in the slightly less-golfed form: 42 bytes f(a:b:c:t)=(a-b)*(b-c)<0&&f(b:c:t) f _=1>0  Try it online! We check that the first three digits (a,b,c) have the a->b steps and b->c steps going opposite directions by checking that the differences a-b and b-c have opposite signs, that is, their product is negative. Then we recurse to the list without its first element until the list has fewer than 3 elements, where it's vacuously true. An alternative to check suffixes directly turned out longer: 43 bytes f l=and[(a-b)*(b-c)<0|a:b:c:t<-scanr(:)[]l]  Try it online! • Good job, as per usual. +1 because I see functions I know used in weird ways – RGS Feb 7 '20 at 0:27 • Nice answer, I didn't know about =<<. – 79037662 Feb 7 '20 at 0:34 • @79037662 And nice method from you! It looks like you converged to basically that same answer. I didn't think of doing this problem mostly pointfree -- I thought it would be long compared to the explicit recursion. – xnor Feb 7 '20 at 0:41 # Python 2, 65 58 bytes lambda A:all((x-y)*(y-z)<0for x,y,z in zip(A,A[1:],A[2:]))  Try it online! • Nice solution with the zip function +1 and this one handles gracefully the 1 and 2 digit cases (probably not the only answer here doing that, but this one I can easily spot ;) ) – RGS Feb 7 '20 at 9:03 # Brachylog, 9 bytes ¬{s₃.o↙Ḋ}  Try it online! Takes a list of digits as input. ### Explanation ¬{ } It is impossible… s₃ …to find a subsequence of 3 elements… .o↙Ḋ …which is already ordered  Slight subtility: o↙Ḋ is used to check whether the digits are increasing or decreasing. By default, o (which is the same as o₀) is for increasing order, and o₁ is for decreasing order. By using o↙Ḋ (Ḋ being an integer between 0 and 9), we check that the whole predicate is impossible for o₀, or o₁, or o₂, …, o₉. o₂ to o₉ are not implemented and thus will fail, which doesn’t impact the program as a whole. If true. is an acceptable falsy value, and false. an acceptable truthy value (which I don’t think it should be), then you should be able to remove these 3 bytes: ¬{…}. • Thanks for your submission! And I agree with you, using "false" as a Truthy value and vice versa is questionable :p it looks like a lot of answers would've benefited from that, though. +1 – RGS Feb 7 '20 at 14:00 # Ruby-nl, 57 41 bytes Replaces each character in the input string with the cmp comparison (<=> in Ruby) between it and the next character '[0] (if there is no next character, remove the character instead). Then, check if the resulting string consists entirely of alternating 1 and -1. gsub(/./){&<=>'[0]} p~/^1?(-11)*(-1)?/  Try it online! ### Old Solution, 57 bytes Check for duplicate consecutive numbers first by checking if the input string matches /(.)\1/ and inverting it. If no such pairs are found, replace each character with true or false based on whether its cmp style comparisons (<=>) to the character before it [-1] and after it '[0] are not equal. (If there is no character before or after it, the <=> returns nil, which is definitely not equal to whatever the other character comparison returns.) Finally, it checks if the result does not contain an f (meaning no falses were returned). p ! ~/(.)\1/&&gsub(/./){([-1]<=>&)!=(&<=>'[0])}!~/f/  Try it online! • Really cool answer +1 ! – RGS Feb 7 '20 at 9:05 • Doesn't work for 212 – G B Feb 7 '20 at 9:48 • @GB found the regex error. Fixed for no byte count change. – Value Ink Feb 7 '20 at 23:54 # Bash, 147 144 bytes M(){ a={1:0:1} d=x i=1 while [ i -lt {#1} ] do b={1:i:1} case d((a-b)) in [ux]-*)d=d;;*0|u*|d-*)return 1;;*)d=u;;esac a=b let i++ done }  Try it online! I seem to like trying shell submissions, and learned some bash-isms in golfing this one. ((a-b)) is equivalent to (( a - b )) -- apparently you don't need the  inside a (( )) construct. There is a ++ operator, works in (( )) and in let Subtracting letters is accepted, strangely. One of my samples in the TIO reads "xy", and apparently ((a-b)) evaluates a to x, and then variable x to an empty string and the empty string as numeric zero, and comparable for b and y. If I set x and y in the environment, those values are used. Edit: -3 bytes by not putting whitespace after ;;, thanks to S.S.Anne • +1 nice submission! – RGS Feb 6 '20 at 22:09 • @RGS I think it is a very nice touch that you are commenting on (and upvoting) each answer. Thank You. +1 – David G. Feb 6 '20 at 22:25 • Thanks David! I just want to acknowledge every submission ;) – RGS Feb 6 '20 at 22:39 • @S.S.Anne My output looks like my input because the trailer code deliberately matches the format from the original sample data. – David G. Feb 9 '20 at 19:38 • @S.S.Anne I tested it too, and must have done the same thing. Reverted back to 144. Ah well. – David G. Feb 9 '20 at 19:45 # J, 15 bytes [:*/0>2*/\2-/$


Try it online!

-7 bytes thanks to RGS's technique

• Nice submission :) what does RGS's technique mean? +1 – RGS Feb 6 '20 at 22:11
• Meaning the logic is essentially the same as yours, translated into J, and was shorter than the initial approach i tried – Jonah Feb 6 '20 at 23:01

# Charcoal, 29 27 bytes

ＵＭθ⁻ι§θ⊕κＵＭθ×ι§θ⊕κ›⁰⌈…θ⁻Ｌθ²


Try it online! Link is to verbose version of code. Takes input as a list of digits and outputs as a Charcoal boolean (- for a mountain range number, otherwise no output). Explanation:

ＵＭθ⁻ι§θ⊕κ


Take consecutive differences (cyclic, so includes difference between last and first digit).

ＵＭθ×ι§θ⊕κ


Take consecutive products (again, cyclic).

›⁰⌈…θ⁻Ｌθ²


All results bar the last two must be negative.

• Interesting submission! +1 – RGS Feb 6 '20 at 22:10

# Burlesque, 22 bytes

XX2COqcm^m2COPD{0.<}al


Try it online!

XX      # Explode into digits
2CO     # 2-grams ("abc"->{"ab" "bc"})
qcm^m   # Compare each via UFO operator
2CO     # 2-grams
PD      # Product
{0.<}al # All less than 0

• Nice answer. It looks kind of funny +1 can't you save some bytes by taking a list of digits as input? – RGS Feb 6 '20 at 23:49
• It makes very little difference, as I'd need to parse them with ps or pe anyway. This sneakily operates on strings and relies on ASCII comparison. – DeathIncarnate Feb 6 '20 at 23:51

# K (ngn/k), 14 bytes

&/0>2_*':-':$:  Try it online! $: as string

-': subtract (as ascii codes) each prior; implicit 0 before first

*': multiply by each prior; implicit 1 before first

2_ drop first 2 elements

&/0> all negative?

• The TIO link has 16 bytes? Is it 'cuz you assign your function to f? +1 for the good work :D – RGS Feb 7 '20 at 0:29
• @RGS thanks. yes, by convention function naming is not counted unless it's used for (non-anonymous) recursion. here i use the name f only for testing. – ngn Feb 7 '20 at 0:33

# Python 3, 101 $$\\cdots\$$ 103 94 bytes

Added 13 bytes to fix error kindly pointed out by @ChasBrown.
Saved 9 bytes thanks to @ChasBrown!!!

def f(l):x=[a<b for a,b in zip(l[1:],l)];return all(a!=b for a,b in zip(x[1:]+l[1:],x[:-1]+l))


Try it online!

• Interesting submission! +1 – RGS Feb 6 '20 at 23:40
• 94 bytes – Chas Brown Feb 7 '20 at 1:17
• @ChasBrown Nice one zip auto truncates the larger - thanks! :-) – Noodle9 Feb 7 '20 at 1:27

# C (gcc), 59 bytes

d;m(int*s){for(d=*s/s[1];s[1]&&s[1]/ *s-d;d^=1)s++;s=s[1];}


Takes as input a wide string of digits and returns zero if that number is a mountain range number.

-12 bytes thanks to ceilingcat!

Try it online!

• @ceilingcat Thanks! – S.S. Anne Feb 9 '20 at 20:13
• +1 for the cool submission, but can you help me understand how the return here works? – RGS Feb 9 '20 at 20:13
• @RGS Closest I can find is codegolf.stackexchange.com/a/106067/89298. It exploits GCC's behavior when compiling without optimization in which temporary results are stored in the return register. – S.S. Anne Feb 9 '20 at 20:15

# Java (JDK), 95 83 bytes

p->{int i=0,j=1;for(;p.length>-~++i;)j=(p[i-1]-p[i])*(p[i]-p[i+1])<0?j:0;return j;}


Try it online!

Thanks to all in the comments for improvements - especially bit-shifting which I never would have thought of!!

• Thanks for your submission! +1 for you. You can save 7 bytes by using 0/1 as Falsy/Truthy values! – RGS Feb 7 '20 at 15:28
• Thanks! I hadn't thought to do that – simonalexander2005 Feb 7 '20 at 15:33
• you may be able to shave 2 more bytes by returning nothing for Falsy. I think that is still reasonable. – RGS Feb 7 '20 at 15:42
• An index shift could possibly save three further bytes. – Jonathan Frech Feb 7 '20 at 16:18

# R, 34 bytes

all((d=diff(scan()))[1]*d*.5:-1>0)


Try it online!

Alternately reverses signs of all differences, and then multiplies them all by first difference: mountain range sequences will all be positive

Would be 40 bytes if defined as a function instead, so apologies to Robin with whom this would tie without the scan for input.

# Scala, 63 bytes

_.sliding(3).forall(t=>t(0)<t(1)&t(1)>t(2)|t(0)>t(1)&t(1)<t(2))


Checks whether for all sliding triplets the center is strictly larger (or strictly smaller) than the previous element and the next element.

Try it online!