My goal is given an integer number to deduce if its digits increase (or remain the same) from left to right or not.

Example: $1236, 123336$ are both considered numbers with increasing digits, but $1203$ is not.

This is the code that I came up with during my first attempt:

incQ[n_] := 
    And @@ (#[[1]] - #[[2]] <= 0 &) /@ Partition[IntegerDigits@n, 2, 1];

I'd like to know:

  1. Whether an experienced user could, by looking at this construct, detect the bottleneck.
  2. Whether it can be rewritten to speed things up, without completely altering its logic though.
  3. If there's a way, besides Workbench, to measure how much time the parts of a compound expression consume (e.g., is the partitioning, the difference'ing or the AND'ing the offender here ?)

EDIT 1: By slow, I mean that it takes ~2.6secs to check the first $10^5$ integers in Mac OSX 10.9.1, Mathematica 9.0.1, i5 @ 1.7 GHz.

EDIT 2: As expected, I got lots of great answers (basically for Q2). Before accepting one, what would be the moral of this story?

Perhaps, that built-in functions are more likely to be faster than their custom-made equivalent versions?

  • $\begingroup$ Perhaps I should say non-descending instead of increasing ? Do you agree that it makes the question more concise? $\endgroup$ – stathisk Jan 27 '14 at 15:35
  • $\begingroup$ I think it is good word (or two) but the example shows what you want with no doubt now :) $\endgroup$ – Kuba Jan 27 '14 at 15:37
  • $\begingroup$ just wondering, are you interested in generating a list of all numbers that satisfy this property, or are you just doing a check? If it's the former, there are much faster ways of doing this. $\endgroup$ – Red Alert Jan 27 '14 at 17:17
  • $\begingroup$ Hi @RedAlert. Thanks for caring. I'm basically interested in validating them rather than generating them from scratch, but thanks for asking! $\endgroup$ – stathisk Jan 29 '14 at 13:55

This is your idea with different functions:

FreeQ[Differences@IntegerDigits[n], _?Negative]



This is in case if sequence is non-descending instead of ascending but OP's functiong gives True for 133.

  • 1
    $\begingroup$ OrderedQ@IntegerDigits[n] wins for me :) Well done $\endgroup$ – Öskå Jan 27 '14 at 15:34
  • $\begingroup$ @Öskå I've only pressed F1 + couple of mouseclicks :P $\endgroup$ – Kuba Jan 27 '14 at 15:36
  • $\begingroup$ Well, one more proof that F1 is our friend! :D $\endgroup$ – Öskå Jan 27 '14 at 15:37
  • $\begingroup$ Wow! I should definitely try out ideas first... I thought of OrderedQ@IntegerDigits, but then I dismissed it because Tr and UnitStep etc. must be very fast, right? Right? Wrong! Lol! Nice :) $\endgroup$ – rm -rf Jan 27 '14 at 15:42
  • $\begingroup$ @rm-rf Thanks, I was quite surprised too :) $\endgroup$ – Kuba Jan 27 '14 at 15:51

I get a little more than a 3x increase with this, but it gives a 0/1 output which need to be converted to True/False (can be done at the end)

incQ2[n_] := Times @@ UnitStep@Differences@IntegerDigits[n]
res2 = Table[incQ2[x], {x, 10^5}] /. {1 -> True, 0 -> False}; // AbsoluteTiming
(* {0.550787, Null} *)

Boole@res1 == res2
(* True *)

For comparison:

res1 = Table[incQ[x], {x, 10^5}]; // AbsoluteTiming
(* {1.673954, Null} *)

A bit faster still, and gives a True/False output:

incQ3[n_] := Tr@UnitStep@Differences@IntegerDigits@n - IntegerLength@n + 1 === 0
res3 = Table[incQ3[x], {x, 10^5}]; // AbsoluteTiming
(* {0.478684, Null} *)

res1 == res3
(* True *)

Another simple variant, which is however slightly slower than the OrderedQ solution of Kuba:

LessEqual @@ IntegerDigits[n]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.