Middle three digits: Difference between revisions
Content added Content deleted
(Vedit macro language added) |
(+ second D entry) |
||
Line 44: | Line 44: | ||
middleThreeDigits(-2002): Need odd and >= 3 digits |
middleThreeDigits(-2002): Need odd and >= 3 digits |
||
middleThreeDigits(0): Need odd and >= 3 digits</pre> |
middleThreeDigits(0): Need odd and >= 3 digits</pre> |
||
===Alternative Version=== |
|||
This longer version is more correct (works with T.min), gives a stronger typed output, and it tries to be faster avoiding conversions to string. |
|||
<lang d>import std.stdio, std.traits, std.math, std.variant; |
|||
/// Returns a string with the error, or the three digits. |
|||
Algebraic!(string, char[3]) middleThreeDigits(T)(in T n) |
|||
if (isIntegral!T) { |
|||
// Awkward code to face abs(T.min) when T is signed. |
|||
ulong ln; |
|||
static if (isSigned!T) { |
|||
if (n >= 0) { |
|||
ln = n; |
|||
} else { |
|||
if (n == T.min) { |
|||
ln = -(n + 1); |
|||
ln++; |
|||
} else { |
|||
ln = -n; |
|||
} |
|||
} |
|||
} else { |
|||
ln = n; |
|||
} |
|||
if (ln < 100) |
|||
return typeof(return)("n is too short."); |
|||
immutable uint digits = 1 + cast(uint)log10(ln); |
|||
if (digits % 2 == 0) |
|||
return typeof(return)("n must have an odd number of digits."); |
|||
// From the Reddit answer by "millstone". |
|||
int drop = (digits - 3) / 2; |
|||
while (drop-- > 0) |
|||
ln /= 10; |
|||
char[3] result = void; |
|||
result[2] = ln % 10 + '0'; |
|||
ln /= 10; |
|||
result[1] = ln % 10 + '0'; |
|||
ln /= 10; |
|||
result[0] = ln % 10 + '0'; |
|||
return typeof(return)(result); |
|||
} |
|||
void main() { |
|||
immutable passing = [123, 12345, 1234567, 987654321, 10001, |
|||
-10001, -123, -100, 100, -12345, -8765432]; |
|||
foreach (n; passing) { |
|||
auto mtd = middleThreeDigits(n); |
|||
// A string result means it didn't pass. |
|||
assert(!mtd.peek!string); |
|||
writefln("middleThreeDigits(%d): %s", n, mtd); |
|||
} |
|||
writeln(); |
|||
immutable failing = [1, 2, -1, -10, 2002, -2002, 0, |
|||
15, int.min, int.max]; |
|||
foreach (n; failing) { |
|||
auto mtd = middleThreeDigits(n); |
|||
assert(mtd.peek!string); |
|||
writefln("middleThreeDigits(%d): %s", n, mtd); |
|||
} |
|||
writeln(); |
|||
immutable long[] passingL = [123, 12345, 1234567, 987654321, 10001, |
|||
-10001, -123, -100, 100, -12345, |
|||
-8765432, long.min, long.max]; |
|||
foreach (n; passingL) { |
|||
auto mtd = middleThreeDigits(n); |
|||
assert(!mtd.peek!string); |
|||
writefln("middleThreeDigits(%d): %s", n, mtd); |
|||
} |
|||
writeln(); |
|||
immutable long[] failingL = [1, 2, -1, -10, 2002, -2002, 0, 15]; |
|||
foreach (n; failingL) { |
|||
auto mtd = middleThreeDigits(n); |
|||
assert(mtd.peek!string); |
|||
writefln("middleThreeDigits(%d): %s", n, mtd); |
|||
} |
|||
writeln(); |
|||
{ |
|||
immutable n = short.min; |
|||
auto mtd = middleThreeDigits(n); |
|||
assert(!mtd.peek!string); |
|||
writefln("middleThreeDigits(cast(short)%d): %s", n, mtd); |
|||
} |
|||
}</lang> |
|||
{{out}} |
|||
<pre>middleThreeDigits(123): 123 |
|||
middleThreeDigits(12345): 234 |
|||
middleThreeDigits(1234567): 345 |
|||
middleThreeDigits(987654321): 654 |
|||
middleThreeDigits(10001): 000 |
|||
middleThreeDigits(-10001): 000 |
|||
middleThreeDigits(-123): 123 |
|||
middleThreeDigits(-100): 100 |
|||
middleThreeDigits(100): 100 |
|||
middleThreeDigits(-12345): 234 |
|||
middleThreeDigits(-8765432): 654 |
|||
middleThreeDigits(1): n is too short. |
|||
middleThreeDigits(2): n is too short. |
|||
middleThreeDigits(-1): n is too short. |
|||
middleThreeDigits(-10): n is too short. |
|||
middleThreeDigits(2002): n must have an odd number of digits. |
|||
middleThreeDigits(-2002): n must have an odd number of digits. |
|||
middleThreeDigits(0): n is too short. |
|||
middleThreeDigits(15): n is too short. |
|||
middleThreeDigits(-2147483648): n must have an odd number of digits. |
|||
middleThreeDigits(2147483647): n must have an odd number of digits. |
|||
middleThreeDigits(123): 123 |
|||
middleThreeDigits(12345): 234 |
|||
middleThreeDigits(1234567): 345 |
|||
middleThreeDigits(987654321): 654 |
|||
middleThreeDigits(10001): 000 |
|||
middleThreeDigits(-10001): 000 |
|||
middleThreeDigits(-123): 123 |
|||
middleThreeDigits(-100): 100 |
|||
middleThreeDigits(100): 100 |
|||
middleThreeDigits(-12345): 234 |
|||
middleThreeDigits(-8765432): 654 |
|||
middleThreeDigits(-9223372036854775808): 368 |
|||
middleThreeDigits(9223372036854775807): 368 |
|||
middleThreeDigits(1): n is too short. |
|||
middleThreeDigits(2): n is too short. |
|||
middleThreeDigits(-1): n is too short. |
|||
middleThreeDigits(-10): n is too short. |
|||
middleThreeDigits(2002): n must have an odd number of digits. |
|||
middleThreeDigits(-2002): n must have an odd number of digits. |
|||
middleThreeDigits(0): n is too short. |
|||
middleThreeDigits(15): n is too short. |
|||
middleThreeDigits(cast(short)-32768): 276</pre> |
|||
=={{header|OCaml}}== |
=={{header|OCaml}}== |