66 65 62 60 bytes
Takes input as a string, returns
true for undulant numbers, an empty string (falsey) for single digit numbers and
Run the Snippet below to test
0-9 and 25 random numbers
o.innerText=[...tests].map(x=>(x=x+``).padStart(7)+` = `+JSON.stringify(f(x))).join`\n`
A few fun little tricks in this one so I think it warrants a rare explanation to a JS solution from me.
We start, simply, with an anonymous function which takes the integer string as an argument when called.
That argument is immediately destructured into 2 parameters:
s being the first character in the string and
a being an array containing the remaining characters (e.g.
First, we concatenate
a with itself, which casts both occurrences to strings. If the input is a single digit number then
a will be empty and, therefore, become and empty string; an empty string plus an empty string is still an empty string and, because that's falsey in JS, we stop processing at the logical AND and output our empty string. In all other cases
a+a will be truthy and so we continue on to the next part of the function.
We'll be checking if every element
true when passed through a function.
This determines what our first comparison will be (
>) and then we'll alternate from there. We check if the string
s is less than the array
a, which gets cast to a string in the process so, if
s is less than the first character in
y will be
false if it's not.
We build a string with the current value of
s at the beginning and
x at the end. In between, we index into the string
"<>" by incrementing
y, casting its initial boolean value to an integer, and modulo by 2, giving us
Eval that string.
Finally, we pass a second argument to
eval, which it ignores, and use it to set the value of
s to the current value of
x for the next iteration.