Middle three digits

From Rosetta Code
Revision as of 10:07, 3 February 2013 by rosettacode>Fwend (→‎{{header|D}}: don't need an exception actually)
Middle three digits is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

The task is to:

Write a function/procedure/subroutine that is called with an integer value and returns the middle three digits of the integer if possible or a clear indication of an error if this is not possible.

Your function should be tested with the following values; the first line should return valid answers, those of the second line should return clear indications of an error:

123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345
1, 2, -1, -10, 2002, -2002, 0

Show your output on this page.

D

<lang d>import std.stdio, std.traits, std.math, std.conv;

string middleThreeDigits(T)(in T n) if (isIntegral!T) {

   auto s = n.abs().text();
   auto len = s.length;
   if (len < 3 || len % 2 == 0)
       return "Need odd and >= 3 digits";
   auto mid = len / 2;
   return s[mid - 1 .. mid + 2];

}

void main() {

   immutable passing = [123, 12345, 1234567, 987654321, 10001, -10001,
           -123, -100, 100, -12345];
   immutable failing = [1, 2, -1, -10, 2002, -2002, 0];
   foreach (n; passing ~ failing)
       writefln("middleThreeDigits(%s): %s", n, middleThreeDigits(n));

}</lang>

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(1): Need odd and >= 3 digits
middleThreeDigits(2): Need odd and >= 3 digits
middleThreeDigits(-1): Need odd and >= 3 digits
middleThreeDigits(-10): Need odd and >= 3 digits
middleThreeDigits(2002): Need odd and >= 3 digits
middleThreeDigits(-2002): Need odd and >= 3 digits
middleThreeDigits(0): Need odd and >= 3 digits

OCaml

<lang ocaml>let even x = (x land 1) <> 1

let middle_three_digits x =

 let s = string_of_int (abs x) in
 let n = String.length s in
 if n < 3 then failwith "need >= 3 digits" else
 if even n then failwith "need odd number of digits" else
 String.sub s (n / 2 - 1) 3

let passing = [123; 12345; 1234567; 987654321; 10001; -10001; -123; -100; 100; -12345] let failing = [1; 2; -1; -10; 2002; -2002; 0]

let print x =

 let res =
   try (middle_three_digits x)
   with Failure e -> "failure: " ^ e
 in
 Printf.printf "%d: %s\n" x res

let () =

 print_endline "Should pass:";
 List.iter print passing;
 print_endline "Should fail:";
 List.iter print failing;
</lang>
Output:
Should pass:
123: 123
12345: 234
1234567: 345
987654321: 654
10001: 000
-10001: 000
-123: 123
-100: 100
100: 100
-12345: 234

Should fail:
1: failure: need >= 3 digits
2: failure: need >= 3 digits
-1: failure: need >= 3 digits
-10: failure: need >= 3 digits
2002: failure: need odd number of digits
-2002: failure: need odd number of digits
0: failure: need >= 3 digits

Perl 6

<lang Perl6>sub middle-three($n) {

   given $n.abs {
       when .chars < 3  { "$n is too short" }
       when .chars %% 2 { "$n has an even number of digits" }
       default          { "The three middle digits of $n are: ", .substr: (.chars - 3)/2, 3 }
   }

}

say middle-three($_) for <

   123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345
   1 2 -1 -10 2002 -2002 0

>;</lang>

Output:
The three middle digits of 123 are:  123
The three middle digits of 12345 are:  234
The three middle digits of 1234567 are:  345
The three middle digits of 987654321 are:  654
The three middle digits of 10001 are:  000
The three middle digits of -10001 are:  000
The three middle digits of -123 are:  123
The three middle digits of -100 are:  100
The three middle digits of 100 are:  100
The three middle digits of -12345 are:  234
1 is too short
2 is too short
-1 is too short
-10 is too short
2002 has an even number of digits
-2002 has an even number of digits
0 is too short

Python

<lang python>>>> def middle_three_digits(i): s = str(abs(i)) length = len(s) assert length >= 3 and length % 2 == 1, "Need odd and >= 3 digits" mid = length // 2 return s[mid-1:mid+2]

>>> passing = [123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345] >>> failing = [1, 2, -1, -10, 2002, -2002, 0] >>> for x in passing + failing: try: answer = middle_three_digits(x) except AssertionError as error: answer = error print("middle_three_digits(%s) returned: %r" % (x, answer))


middle_three_digits(123) returned: '123' middle_three_digits(12345) returned: '234' middle_three_digits(1234567) returned: '345' middle_three_digits(987654321) returned: '654' middle_three_digits(10001) returned: '000' middle_three_digits(-10001) returned: '000' middle_three_digits(-123) returned: '123' middle_three_digits(-100) returned: '100' middle_three_digits(100) returned: '100' middle_three_digits(-12345) returned: '234' middle_three_digits(1) returned: AssertionError('Need odd and >= 3 digits',) middle_three_digits(2) returned: AssertionError('Need odd and >= 3 digits',) middle_three_digits(-1) returned: AssertionError('Need odd and >= 3 digits',) middle_three_digits(-10) returned: AssertionError('Need odd and >= 3 digits',) middle_three_digits(2002) returned: AssertionError('Need odd and >= 3 digits',) middle_three_digits(-2002) returned: AssertionError('Need odd and >= 3 digits',) middle_three_digits(0) returned: AssertionError('Need odd and >= 3 digits',) >>> </lang>

XPL0

<lang XPL0>include c:\cxpl\stdlib;

func Mid3Digits(I); \Return the middle three digits of I int I; int Len, Mid; char S(10); [ItoA(abs(I), S); Len:= StrLen(S); if Len<3 or (Len&1)=0 then return "Must be 3, 5, 7 or 9 digits"; Mid:= Len/2; S:= S + Mid - 1; S(2):= S(2) ! $80; \terminate string return S; \WARNING: very temporary ];

int Passing, Failing, X; [Passing:= [123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345];

Failing:= [1, 2, -1, -10, 2002, -2002, 0];     \WARNING: nasty trick

for X:= 0 to 16 do

   [Text(0, "Middle three digits of ");  IntOut(0, Passing(X));
    Text(0, " returned: ");
    Text(0, Mid3Digits(Passing(X)));  CrLf(0);
   ];

]</lang>

Output:
Middle three digits of 123 returned: 123
Middle three digits of 12345 returned: 234
Middle three digits of 1234567 returned: 345
Middle three digits of 987654321 returned: 654
Middle three digits of 10001 returned: 000
Middle three digits of -10001 returned: 000
Middle three digits of -123 returned: 123
Middle three digits of -100 returned: 100
Middle three digits of 100 returned: 100
Middle three digits of -12345 returned: 234
Middle three digits of 1 returned: Must be 3, 5, 7 or 9 digits
Middle three digits of 2 returned: Must be 3, 5, 7 or 9 digits
Middle three digits of -1 returned: Must be 3, 5, 7 or 9 digits
Middle three digits of -10 returned: Must be 3, 5, 7 or 9 digits
Middle three digits of 2002 returned: Must be 3, 5, 7 or 9 digits
Middle three digits of -2002 returned: Must be 3, 5, 7 or 9 digits
Middle three digits of 0 returned: Must be 3, 5, 7 or 9 digits