1

Trying to create a function to check for a tall number (i.e., every digit is less than or equal to the digit to its right, such as 123, 059, etc.).

Following code is the issue:

const n = parseInt(readline());
if (n.toString().length === 1)
    console.log('true');
else
{
    var z = n.toString().split('');
    console.log(z.reduce((a, b) => b > a));
}

This test fails: 01223047 (returns true when it should return false).

It worked on numerous other tests, but not this value. Shouldn't reduce be testing each pair and returning true/false? If there's one false, it should return false, correct? Am I using reduce incorrectly? Is there another function I could use to shorthand this test instead of writing a loop?

3
  • 01223047 is 337447 as an integer, you need to have n as a string and parse them to an int in your reduce function Commented Mar 18, 2019 at 11:27
  • also: your braces are kinda weird... Commented Mar 18, 2019 at 11:28
  • 2
    It seems odd to parse the string from readline only to then repeatedly convert it back to a string... It's particularly odd if one of your examples has a leading digit "0" as doing that removes the leading digit. Commented Mar 18, 2019 at 11:30

1 Answer 1

5

Remember that with reduce, the first argument supplied to your callback is the return value of the previous call to the callback. (In the first call, if you haven't provided a seed value — and you haven't — the first value will be the first entry in the array.)

So no, that reduce doesn't test each pair. It tests the first pair, and then it tests the rest of the values (individually) against the previous callback's returned flag.

For what you're doing, you probably want a simple loop, or some, or every (probably every). With some and every you'd use the index supplied as the second argument to the callback to get the next (or previous) character. Using every would also eliminate the special case for a single-character string:

function test(str, expect) {
    const z = str.split(""); // I'd probably use `= Array.from(str);` on ES2015+
    const result = z.every((ch, i) => i === 0 || ch > z[i - 1]);
    console.log(str, result, !result === !expect ? "Good" : "ERRROR");
}


test("123", true);
test("1", true);
test("21", false);

(There's probably an argument for using localCompare in that: ch.localeCompare(z[i - 1]) > 0 instead of ch > z[i - 1].)

Sign up to request clarification or add additional context in comments.

5 Comments

Beat me to it! :D
As a matter of interest, there's another way to look at this problem through the lens of combinatorials. How many combinations of these digits are there where every digit is greater than or equal to the digit to its left? There's only 1 possible combination! That means we're basically checking for sort order:
``` const isTall = n => { const arr = (''+n).split(''); return arr === arr.sort(); } ```
@JamieDixon - :-) Quite true. (You'll want to convert those arrays back to strings for the === check.)
Yep! This also reminded me that sort is mutative. I did wonder why ['b', 'a'] === ['a', 'b'] was always returning true :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.