Middle three digits

From Rosetta Code
Revision as of 12:51, 3 February 2013 by rosettacode>Paddy3118 (Promote to full task from draft.)
Task
Middle three digits
You are encouraged to solve this task according to the task description, using any language you may know.

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