## digitalmars.D - [your code here]

• Jos van Uden (26/26) Feb 11 2012 bool isKaprekar(in long n) pure nothrow
• H. S. Teoh (7/12) Feb 11 2012 [...]
• bearophile (6/15) Feb 11 2012 In this case the answer is probably positive.
• H. S. Teoh (11/33) Feb 11 2012 [...]
• Kapps (4/8) Feb 11 2012 In this case, you're actually not changing the domain of the function.
• Jos van Uden (19/28) Feb 11 2012 Good question. I'm not sure which is better. My personal preference goes...
Jos van Uden <user domain.invalid> writes:
```bool isKaprekar(in long n) pure nothrow
in {
assert(n > 0, "isKaprekar(n): n must be > 0");
assert(n <= uint.max, "isKaprekar(n): n must be <= uint.max");
} body {
ulong powr = n ^^ 2UL;
ulong tens = 10, r, l;
while (r < n) {
r = powr % tens;
l = powr / tens;
if (r && l + r == n)
return true;
tens *= 10;
}
return false;
}

--

A positive integer is a Kaprekar number if:

-It is 1
-The decimal representation of its square may be split once into two
parts consisting of positive integers which sum to the original number.
Note that a split resulting in a part consisting purely of 0s is not
valid, as 0 is not considered positive.

Example: 2223 is a Kaprekar number, as 2223 * 2223 = 4941729, 4941729
may be split to 494 and 1729, and 494 + 1729 = 2223.

```
Feb 11 2012
"H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
```On Sat, Feb 11, 2012 at 12:20:22PM +0100, Jos van Uden wrote:
bool isKaprekar(in long n) pure nothrow
in {
assert(n > 0, "isKaprekar(n): n must be > 0");
assert(n <= uint.max, "isKaprekar(n): n must be <= uint.max");
} body {

[...]

Shouldn't you just use "in ulong n" as parameter instead of long with a
contract?

T

--
The richest man is not he who has the most, but he who needs the least.
```
Feb 11 2012
bearophile <bearophileHUGS lycos.com> writes:
```H. S. Teoh:

bool isKaprekar(in long n) pure nothrow
in {
assert(n > 0, "isKaprekar(n): n must be > 0");
assert(n <= uint.max, "isKaprekar(n): n must be <= uint.max");
} body {

[...]

Shouldn't you just use "in ulong n" as parameter instead of long with a
contract?

In this case the answer is probably positive.

But in general it's better to accept a signed number and then refuse the
negative values in the pre-condition, otherwise if you give by mistake a
negative number to the function it's not caught.

Such work-arounds are less needed in saner languages, where the ranges of
integral values are verified, at compile time where possible, and at run-time
otherwise. Unwanted wrap-arounds and undetected overflows in integral values
are so '70 :-)

Bye,
bearophile
```
Feb 11 2012
"H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
```On Sat, Feb 11, 2012 at 10:47:01AM -0500, bearophile wrote:
H. S. Teoh:

bool isKaprekar(in long n) pure nothrow
in {
assert(n > 0, "isKaprekar(n): n must be > 0");
assert(n <= uint.max, "isKaprekar(n): n must be <= uint.max");
} body {

[...]

Shouldn't you just use "in ulong n" as parameter instead of long with a
contract?

In this case the answer is probably positive.

But in general it's better to accept a signed number and then refuse
the negative values in the pre-condition, otherwise if you give by
mistake a negative number to the function it's not caught.

Such work-arounds are less needed in saner languages, where the ranges
of integral values are verified, at compile time where possible, and
at run-time otherwise. Unwanted wrap-arounds and undetected overflows
in integral values are so '70 :-)

[...]

Hmph. I was under the impression that D was clever enough to be able to
detect overflow problems when dealing with signed->unsigned conversion.

The bad thing about taking signed long as parameter and then restrict it
to 0..uint.max means that you're unnecessarily constraining the domain
of the function.

T

--
Being able to learn is a great learning; being able to unlearn is a
greater learning.
```
Feb 11 2012
Kapps <Kapps NotValidEmail.com> writes:
```On 11/02/2012 9:55 AM, H. S. Teoh wrote:
The bad thing about taking signed long as parameter and then restrict it
to 0..uint.max means that you're unnecessarily constraining the domain
of the function.

T

In this case, you're actually not changing the domain of the function.
The domain was (0, sqrt(0 .. ulong.max)], which is smaller than long.max
anyways.
```
Feb 11 2012
Jos van Uden <user domain.invalid> writes:
```On 11-2-2012 16:30, H. S. Teoh wrote:
On Sat, Feb 11, 2012 at 12:20:22PM +0100, Jos van Uden wrote:
bool isKaprekar(in long n) pure nothrow
in {
assert(n>  0, "isKaprekar(n): n must be>  0");
assert(n<= uint.max, "isKaprekar(n): n must be<= uint.max");
} body {

[...]

Shouldn't you just use "in ulong n" as parameter instead of long with a
contract?

Good question. I'm not sure which is better. My personal preference goes
to (in uint n) and rely on the (self) documentation. But this is demo
code and I wanted to show Ds support for contracts. Also, the contract
version will at least give you a warning in debug mode. By
the way, if you use (in ulong n) you could still get in trouble
because the code only handles upto uint.max correctly due to the pow.

bool isKaprekar(in uint n) pure nothrow {
ulong powr = n ^^ 2UL;
ulong tens = 10, r, l;
while (r < n) {
r = powr % tens;
l = powr / tens;
if (r && l + r == n)
return true;
tens *= 10;
}
return false;
}
```
Feb 11 2012