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...
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. See also http://rosettacode.org/wiki/Kaprekar_numbers
Feb 11 2012
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
H. S. Teoh: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, bearophilebool 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?
Feb 11 2012
On Sat, Feb 11, 2012 at 10:47:01AM -0500, bearophile wrote:H. S. Teoh:[...] 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.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 :-)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?
Feb 11 2012
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. TIn 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
On 11-2-2012 16:30, H. S. Teoh wrote:On Sat, Feb 11, 2012 at 12:20:22PM +0100, Jos van Uden wrote: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; }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?
Feb 11 2012