Middle three digits: Difference between revisions
Added Uiua solution |
|||
(94 intermediate revisions by 42 users not shown) | |||
Line 13: | Line 13: | ||
Show your output on this page. |
Show your output on this page. |
||
<br><br> |
<br><br> |
||
=={{header|11l}}== |
|||
{{trans|Python}} |
|||
<syntaxhighlight lang="11l">F middle_three_digits(i) |
|||
V s = String(abs(i)) |
|||
assert(s.len >= 3 & s.len % 2 == 1, ‘Need odd and >= 3 digits’) |
|||
R s[s.len I/ 2 - 1 .+ 3] |
|||
V passing = [123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345] |
|||
V failing = [1, 2, -1, -10, 2002, -2002, 0] |
|||
L(x) passing [+] failing |
|||
X.try |
|||
V answer = middle_three_digits(x) |
|||
print(‘middle_three_digits(#.) returned: #.’.format(x, answer)) |
|||
X.catch AssertionError error |
|||
print(‘middle_three_digits(#.) returned error: ’.format(x)‘’String(error))</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
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 error: Need odd and >= 3 digits |
|||
middle_three_digits(2) returned error: Need odd and >= 3 digits |
|||
middle_three_digits(-1) returned error: Need odd and >= 3 digits |
|||
middle_three_digits(-10) returned error: Need odd and >= 3 digits |
|||
middle_three_digits(2002) returned error: Need odd and >= 3 digits |
|||
middle_three_digits(-2002) returned error: Need odd and >= 3 digits |
|||
middle_three_digits(0) returned error: Need odd and >= 3 digits |
|||
</pre> |
|||
=={{header|Action!}}== |
|||
{{libheader|Action! Tool Kit}} |
|||
{{libheader|Action! Real Math}} |
|||
<syntaxhighlight lang="action!">INCLUDE "H6:REALMATH.ACT" |
|||
INCLUDE "D2:PRINTF.ACT" ;from the Action! Tool Kit |
|||
PROC MiddleThreeDigits(REAL POINTER n CHAR ARRAY res) |
|||
REAL r |
|||
CHAR ARRAY s(15) |
|||
BYTE i |
|||
RealAbs(n,r) |
|||
StrR(r,s) |
|||
i=s(0) |
|||
IF i<3 OR (i&1)=0 THEN |
|||
res(0)=0 |
|||
ELSE |
|||
i==RSH 1 |
|||
SCopyS(res,s,i,i+2) |
|||
FI |
|||
RETURN |
|||
PROC Test(CHAR ARRAY s) |
|||
REAL n |
|||
CHAR ARRAY res(4) |
|||
ValR(s,n) |
|||
MiddleThreeDigits(n,res) |
|||
IF res(0) THEN |
|||
PrintF("%9S -> %S%E",s,res) |
|||
ELSE |
|||
PrintF("%9S -> error!%E",s) |
|||
FI |
|||
RETURN |
|||
PROC Main() |
|||
Put(125) PutE() ;clear the screen |
|||
Test("123") Test("12345") |
|||
Test("1234567") Test("987654321") |
|||
Test("10001") Test("-10001") |
|||
Test("-123") Test("-100") |
|||
Test("100") Test("-12345") |
|||
Test("1") Test("2") |
|||
Test("-1") Test("-10") |
|||
Test("2002") Test("-2002") |
|||
Test("0") |
|||
RETURN</syntaxhighlight> |
|||
{{out}} |
|||
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Middle_three_digits.png Screenshot from Atari 8-bit computer] |
|||
<pre> |
|||
123 -> 123 |
|||
12345 -> 234 |
|||
1234567 -> 345 |
|||
987654321 -> 654 |
|||
10001 -> 000 |
|||
-10001 -> 000 |
|||
-123 -> 123 |
|||
-100 -> 100 |
|||
100 -> 100 |
|||
-12345 -> 234 |
|||
1 -> error! |
|||
2 -> error! |
|||
-1 -> error! |
|||
-10 -> error! |
|||
2002 -> error! |
|||
-2002 -> error! |
|||
0 -> error! |
|||
</pre> |
|||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
< |
<syntaxhighlight lang="ada">with Ada.Text_IO; |
||
procedure Middle_Three_Digits is |
procedure Middle_Three_Digits is |
||
Line 58: | Line 166: | ||
end loop; |
end loop; |
||
end Middle_Three_Digits;</ |
end Middle_Three_Digits;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 80: | Line 188: | ||
=={{header|Aime}}== |
=={{header|Aime}}== |
||
< |
<syntaxhighlight lang="aime">void |
||
m3(integer i) |
m3(integer i) |
||
{ |
{ |
||
Line 120: | Line 228: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> 123: 123 |
<pre> 123: 123 |
||
Line 142: | Line 250: | ||
=={{header|ALGOL 68}}== |
=={{header|ALGOL 68}}== |
||
{{works with|ALGOL 68G|Any - tested with release 2.6.win32}} |
{{works with|ALGOL 68G|Any - tested with release 2.6.win32}} |
||
< |
<syntaxhighlight lang="algol68"># we define a UNION MODE so that our middle 3 digits PROC can # |
||
# return either an integer on success or a error message if # |
# return either an integer on success or a error message if # |
||
# the middle 3 digits couldn't be extracted # |
# the middle 3 digits couldn't be extracted # |
||
Line 204: | Line 312: | ||
print( ( newline ) ) |
print( ( newline ) ) |
||
OD |
OD |
||
)</ |
)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 227: | Line 335: | ||
=={{header|ALGOL W}}== |
=={{header|ALGOL W}}== |
||
< |
<syntaxhighlight lang="algolw">begin |
||
% record structure that will be used to return the middle 3 digits of a number % |
% record structure that will be used to return the middle 3 digits of a number % |
||
% if the middle three digits can't be determined, isOk will be false and message % |
% if the middle three digits can't be determined, isOk will be false and message % |
||
Line 274: | Line 382: | ||
end for_n |
end for_n |
||
end.</ |
end.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 295: | Line 403: | ||
0: Number must have at least 3 digits |
0: Number must have at least 3 digits |
||
</pre> |
</pre> |
||
=={{header|Amazing Hopper}}== |
|||
<p>VERSION 1:</p> |
|||
<syntaxhighlight lang="c"> |
|||
#include <basico.h> |
|||
algoritmo |
|||
n=0, c="" |
|||
temp = 0, candidatos={} |
|||
'123, 12345, 1234567, 987654321, 10001, -10001,-123' |
|||
'-100, 100, -12345,1, 2, -1, -10, 2002, -2002, 0' |
|||
enlistar en 'candidatos' |
|||
decimales '0' |
|||
#basic{ |
|||
temp = string(candidatos * sign(candidatos)) |
|||
n = len( temp ) |
|||
c = replicate (temp, n>=3 && not(is even(n))) |
|||
toksep(NL) |
|||
print (cat( lpad(" ",11,string(candidatos)), cat(" : ", copy( 3, (n/2-1), c ))),NL) |
|||
} |
|||
terminar |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
123 : 123 |
|||
12345 : 234 |
|||
1234567 : 345 |
|||
987654321 : 654 |
|||
10001 : 000 |
|||
-10001 : 000 |
|||
-123 : 123 |
|||
-100 : 100 |
|||
100 : 100 |
|||
-12345 : 234 |
|||
1 : |
|||
2 : |
|||
-1 : |
|||
-10 : |
|||
2002 : |
|||
-2002 : |
|||
0 : |
|||
</pre> |
|||
<p>VERSION 2:</p> |
|||
<syntaxhighlight lang="c"> |
|||
#include <basico.h> |
|||
algoritmo |
|||
n=0, c="", |
|||
temp = 0, candidatos={} |
|||
'123, 12345, 1234567, 987654321, 10001, -10001,-123' |
|||
'-100, 100, -12345,1, 2, -1, -10, 2002, -2002, 0' |
|||
enlistar en 'candidatos' |
|||
decimales '0' |
|||
tomar 'candidatos', quitar el signo |
|||
convertir a cadena ---retener---, obtener largo, mover a 'n', |
|||
guardar en 'temp' |
|||
guardar ' replicar ( temp, #(n>=3 && not(is even(n))))' en 'c' |
|||
token.separador(NL) |
|||
justificar derecha(11,#(string(candidatos))), " : ", concatenar esto |
|||
#( copy( 3, (n/2-1), c ) ), unir esto |
|||
luego imprime |
|||
terminar |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
123 : 123 |
|||
12345 : 234 |
|||
1234567 : 345 |
|||
987654321 : 654 |
|||
10001 : 000 |
|||
-10001 : 000 |
|||
-123 : 123 |
|||
-100 : 100 |
|||
100 : 100 |
|||
-12345 : 234 |
|||
1 : |
|||
2 : |
|||
-1 : |
|||
-10 : |
|||
2002 : |
|||
-2002 : |
|||
0 : |
|||
</pre> |
|||
<p>VERSION 3:</p> |
|||
<syntaxhighlight lang="c"> |
|||
#include <basico.h> |
|||
algoritmo |
|||
n=0, c="", m=0, |
|||
candidatos={} |
|||
'123, 12345, 1234567, 987654321, 10001, -10001,-123' |
|||
'-100, 100, -12345,1, 2, -1, -10, 2002, -2002, 0' |
|||
enlistar en 'candidatos' |
|||
decimales '0' |
|||
para cada elemento (v,candidatos,17) |
|||
tomar'v' ---copiar en 'm'---, quitar el signo |
|||
guardar en 'v' |
|||
#(len( c:=(string(v)) ) ), mover a 'n' |
|||
"Num: ",justificar derecha(10,#(string(m))),"(",n,")\t" |
|||
si ' #( n>=3 && not(is even(n))) ' |
|||
" puede ser procesado : " |
|||
tomar si ( #(n==3), 'c', #( copy( 3, (n/2-1), c )) ), NL |
|||
sino |
|||
"no puede ser procesado\n" |
|||
fin si |
|||
luego imprime |
|||
siguiente |
|||
terminar |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Num: 123(3) puede ser procesado : 123 |
|||
Num: 12345(5) puede ser procesado : 234 |
|||
Num: 1234567(7) puede ser procesado : 345 |
|||
Num: 987654321(9) puede ser procesado : 654 |
|||
Num: 10001(5) puede ser procesado : 000 |
|||
Num: -10001(5) puede ser procesado : 000 |
|||
Num: -123(3) puede ser procesado : 123 |
|||
Num: -100(3) puede ser procesado : 100 |
|||
Num: 100(3) puede ser procesado : 100 |
|||
Num: -12345(5) puede ser procesado : 234 |
|||
Num: 1(1) no puede ser procesado |
|||
Num: 2(1) no puede ser procesado |
|||
Num: -1(1) no puede ser procesado |
|||
Num: -10(2) no puede ser procesado |
|||
Num: 2002(4) no puede ser procesado |
|||
Num: -2002(4) no puede ser procesado |
|||
Num: 0(1) no puede ser procesado |
|||
</pre> |
|||
=={{header|AppleScript}}== |
|||
===Procedural=== |
|||
987654321 is too large to be represented as an AppleScript integer, so "integer value" is taken here to refer to the numeric value rather than to the language class. AppleScript automatically coerces numeric text and single-item lists to appropriate number classes where necessary and possible, so these are acceptable as parameters too. |
|||
<syntaxhighlight lang="applescript">on middle3Digits(n) |
|||
try |
|||
n as number -- Errors if n isn't a number or coercible thereto. |
|||
set s to n as text -- Keep for the ouput string. |
|||
if (n mod 1 is not 0) then error (s & " isn't an integer value.") |
|||
if (n < 0) then set n to -n |
|||
if (n < 100) then error (s & " has fewer than three digits.") |
|||
-- Coercing large numbers to text may result in E notation, so extract the digit values individually. |
|||
set theDigits to {} |
|||
repeat until (n = 0) |
|||
set beginning of theDigits to n mod 10 as integer |
|||
set n to n div 10 |
|||
end repeat |
|||
set c to (count theDigits) |
|||
if (c mod 2 is 0) then error (s & " has an even number of digits.") |
|||
on error errMsg |
|||
return "middle3Digits handler got an error: " & errMsg |
|||
end try |
|||
set i to (c - 3) div 2 + 1 |
|||
set {x, y, z} to items i thru (i + 2) of theDigits |
|||
return "The middle three digits of " & s & " are " & ((x as text) & y & z & ".") |
|||
end middle3Digits |
|||
-- Test code: |
|||
set testNumbers to {123, 12345, 1234567, "987654321", "987654321" as number, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0} |
|||
set output to {} |
|||
repeat with thisNumber in testNumbers |
|||
set end of output to middle3Digits(thisNumber) |
|||
end repeat |
|||
set astid to AppleScript's text item delimiters |
|||
set AppleScript's text item delimiters to linefeed |
|||
set output to output as text |
|||
set AppleScript's text item delimiters to astid |
|||
return output</syntaxhighlight> |
|||
{{output}} |
|||
<syntaxhighlight lang="applescript">"The middle three digits of 123 are 123. |
|||
The middle three digits of 12345 are 234. |
|||
The middle three digits of 1234567 are 345. |
|||
The middle three digits of 987654321 are 654. |
|||
The middle three digits of 9.87654321E+8 are 654. |
|||
The middle three digits of 10001 are 000. |
|||
The middle three digits of -10001 are 000. |
|||
The middle three digits of -123 are 123. |
|||
The middle three digits of -100 are 100. |
|||
The middle three digits of 100 are 100. |
|||
The middle three digits of -12345 are 234. |
|||
middle3Digits handler got an error: 1 has fewer than three digits. |
|||
middle3Digits handler got an error: 2 has fewer than three digits. |
|||
middle3Digits handler got an error: -1 has fewer than three digits. |
|||
middle3Digits handler got an error: -10 has fewer than three digits. |
|||
middle3Digits handler got an error: 2002 has an even number of digits. |
|||
middle3Digits handler got an error: -2002 has an even number of digits. |
|||
middle3Digits handler got an error: 0 has fewer than three digits."</syntaxhighlight> |
|||
===Functional=== |
|||
<syntaxhighlight lang="applescript">-------------------- MID THREE DIGITS --------------------- |
|||
-- mid3digits :: Int -> Either String String |
|||
on mid3digits(n) |
|||
-- Either a message explaining why |
|||
-- no "mid 3 digits" are defined for n, |
|||
-- or the mid 3 digits themselves. |
|||
set m to abs(n) |
|||
if 100 > m then |
|||
|Left|("Less than 3 digits") |
|||
else if maxBound(1) < m then |
|||
|Left|("Out of AppleScript integer range") |
|||
else |
|||
set s to m as string |
|||
set intDigits to length of s |
|||
if even(intDigits) then |
|||
|Left|("Even digit count") |
|||
else |
|||
|Right|((items 1 thru 3 of ¬ |
|||
items (1 + ((intDigits - 3) div 2)) thru -1 of s) as string) |
|||
end if |
|||
end if |
|||
end mid3digits |
|||
-------------------------- TEST --------------------------- |
|||
on run |
|||
set ints to map(readInt, splitOn(", ", ¬ |
|||
"123, 12345, 1234567, 987654321, 10001, -10001, " & ¬ |
|||
"-123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0")) |
|||
script showResult |
|||
on |λ|(x) |
|||
either(my bracketed, my str, x) |
|||
end |λ| |
|||
end script |
|||
fTable("Mid three digits:", str, showResult, mid3digits, ints) |
|||
end run |
|||
------------------------ GENERICS ------------------------- |
|||
-- Left :: a -> Either a b |
|||
on |Left|(x) |
|||
{type:"Either", |Left|:x, |Right|:missing value} |
|||
end |Left| |
|||
-- Right :: b -> Either a b |
|||
on |Right|(x) |
|||
{type:"Either", |Left|:missing value, |Right|:x} |
|||
end |Right| |
|||
-- abs :: Num -> Num |
|||
on abs(x) |
|||
-- Absolute value. |
|||
if 0 > x then |
|||
-x |
|||
else |
|||
x |
|||
end if |
|||
end abs |
|||
-- even :: Int -> Bool |
|||
on even(x) |
|||
0 = x mod 2 |
|||
end even |
|||
-- maxBound :: a -> a |
|||
on maxBound(x) |
|||
set c to class of x |
|||
if text is c then |
|||
character id 65535 |
|||
else if integer is c then |
|||
(2 ^ 29 - 1) |
|||
else if real is c then |
|||
1.797693E+308 |
|||
else if boolean is c then |
|||
true |
|||
end if |
|||
end maxBound |
|||
-------------------- GENERICS FOR TEST AND DISPLAY --------------------- |
|||
-- bracketed :: String -> String |
|||
on bracketed(s) |
|||
"(" & s & ")" |
|||
end bracketed |
|||
-- compose (<<<) :: (b -> c) -> (a -> b) -> a -> c |
|||
on compose(f, g) |
|||
script |
|||
property mf : mReturn(f) |
|||
property mg : mReturn(g) |
|||
on |λ|(x) |
|||
mf's |λ|(mg's |λ|(x)) |
|||
end |λ| |
|||
end script |
|||
end compose |
|||
-- either :: (a -> c) -> (b -> c) -> Either a b -> c |
|||
on either(lf, rf, e) |
|||
if missing value is |Left| of e then |
|||
tell mReturn(rf) to |λ|(|Right| of e) |
|||
else |
|||
tell mReturn(lf) to |λ|(|Left| of e) |
|||
end if |
|||
end either |
|||
-- foldl :: (a -> b -> a) -> a -> [b] -> a |
|||
on foldl(f, startValue, xs) |
|||
tell mReturn(f) |
|||
set v to startValue |
|||
set lng to length of xs |
|||
repeat with i from 1 to lng |
|||
set v to |λ|(v, item i of xs, i, xs) |
|||
end repeat |
|||
return v |
|||
end tell |
|||
end foldl |
|||
-- fTable :: String -> (a -> String) -> (b -> String) -> (a -> b) -> [a] -> String |
|||
on fTable(s, xShow, fxShow, f, xs) |
|||
set ys to map(xShow, xs) |
|||
set w to maximum(map(my |length|, ys)) |
|||
script arrowed |
|||
on |λ|(a, b) |
|||
justifyRight(w, space, a) & " -> " & b |
|||
end |λ| |
|||
end script |
|||
s & linefeed & unlines(zipWith(arrowed, ¬ |
|||
ys, map(compose(fxShow, f), xs))) |
|||
end fTable |
|||
-- justifyRight :: Int -> Char -> String -> String |
|||
on justifyRight(n, cFiller, strText) |
|||
if n > length of strText then |
|||
text -n thru -1 of ((replicate(n, cFiller) as text) & strText) |
|||
else |
|||
strText |
|||
end if |
|||
end justifyRight |
|||
-- length :: [a] -> Int |
|||
on |length|(xs) |
|||
set c to class of xs |
|||
if list is c or string is c then |
|||
length of xs |
|||
else |
|||
(2 ^ 29 - 1) -- (maxInt - simple proxy for non-finite) |
|||
end if |
|||
end |length| |
|||
-- map :: (a -> b) -> [a] -> [b] |
|||
on map(f, xs) |
|||
-- The list obtained by applying f |
|||
-- to each element of xs. |
|||
tell mReturn(f) |
|||
set lng to length of xs |
|||
set lst to {} |
|||
repeat with i from 1 to lng |
|||
set end of lst to |λ|(item i of xs, i, xs) |
|||
end repeat |
|||
return lst |
|||
end tell |
|||
end map |
|||
-- maximum :: Ord a => [a] -> a |
|||
on maximum(xs) |
|||
script |
|||
on |λ|(a, b) |
|||
if a is missing value or b > a then |
|||
b |
|||
else |
|||
a |
|||
end if |
|||
end |λ| |
|||
end script |
|||
foldl(result, missing value, xs) |
|||
end maximum |
|||
-- min :: Ord a => a -> a -> a |
|||
on min(x, y) |
|||
if y < x then |
|||
y |
|||
else |
|||
x |
|||
end if |
|||
end min |
|||
-- mReturn :: First-class m => (a -> b) -> m (a -> b) |
|||
on mReturn(f) |
|||
-- 2nd class handler function lifted into 1st class script wrapper. |
|||
if script is class of f then |
|||
f |
|||
else |
|||
script |
|||
property |λ| : f |
|||
end script |
|||
end if |
|||
end mReturn |
|||
-- readInt :: String -> Int |
|||
on readInt(s) |
|||
s as integer |
|||
end readInt |
|||
-- Egyptian multiplication - progressively doubling a list, appending |
|||
-- stages of doubling to an accumulator where needed for binary |
|||
-- assembly of a target length |
|||
-- replicate :: Int -> a -> [a] |
|||
on replicate(n, a) |
|||
set out to {} |
|||
if 1 > n then return out |
|||
set dbl to {a} |
|||
repeat while (1 < n) |
|||
if 0 < (n mod 2) then set out to out & dbl |
|||
set n to (n div 2) |
|||
set dbl to (dbl & dbl) |
|||
end repeat |
|||
return out & dbl |
|||
end replicate |
|||
-- splitOn :: String -> String -> [String] |
|||
on splitOn(pat, src) |
|||
set {dlm, my text item delimiters} to ¬ |
|||
{my text item delimiters, pat} |
|||
set xs to text items of src |
|||
set my text item delimiters to dlm |
|||
return xs |
|||
end splitOn |
|||
-- str :: a -> String |
|||
on str(x) |
|||
x as string |
|||
end str |
|||
-- unlines :: [String] -> String |
|||
on unlines(xs) |
|||
-- A single string formed by the intercalation |
|||
-- of a list of strings with the newline character. |
|||
set {dlm, my text item delimiters} to ¬ |
|||
{my text item delimiters, linefeed} |
|||
set s to xs as text |
|||
set my text item delimiters to dlm |
|||
s |
|||
end unlines |
|||
-- zipWith :: (a -> b -> c) -> [a] -> [b] -> [c] |
|||
on zipWith(f, xs, ys) |
|||
set lng to min(length of xs, length of ys) |
|||
set lst to {} |
|||
if 1 > lng then |
|||
return {} |
|||
else |
|||
tell mReturn(f) |
|||
repeat with i from 1 to lng |
|||
set end of lst to |λ|(item i of xs, item i of ys) |
|||
end repeat |
|||
return lst |
|||
end tell |
|||
end if |
|||
end zipWith</syntaxhighlight> |
|||
{{Out}} |
|||
<pre>Mid three digits: |
|||
123 -> 123 |
|||
12345 -> 234 |
|||
1234567 -> 345 |
|||
9.87654321E+8 -> (Out of AppleScript integer range) |
|||
10001 -> 000 |
|||
-10001 -> 000 |
|||
-123 -> 123 |
|||
-100 -> 100 |
|||
100 -> 100 |
|||
-12345 -> 234 |
|||
1 -> (Less than 3 digits) |
|||
2 -> (Less than 3 digits) |
|||
-1 -> (Less than 3 digits) |
|||
-10 -> (Less than 3 digits) |
|||
2002 -> (Even digit count) |
|||
-2002 -> (Even digit count) |
|||
0 -> (Less than 3 digits)</pre> |
|||
=={{header|Arturo}}== |
|||
<syntaxhighlight lang="rebol">middleThree: function [num][ |
|||
n: to :string abs num |
|||
if 3 > size n -> return "Number must have at least three digits" |
|||
if even? size n -> return "Number must have an odd number of digits" |
|||
middle: ((size n)/2)- 1 |
|||
return slice n middle middle+2 |
|||
] |
|||
samples: @[ |
|||
123, 12345, 1234567, 987654321, 10001, neg 10001, neg 123, neg 100, 100, neg 12345, |
|||
1, 2, neg 1, neg 10, 2002, neg 2002, 0 |
|||
] |
|||
loop samples 's [ |
|||
print [pad to :string s 10 ":" middleThree s] |
|||
]</syntaxhighlight> |
|||
{{out}} |
|||
<pre> 123 : 123 |
|||
12345 : 234 |
|||
1234567 : 345 |
|||
987654321 : 654 |
|||
10001 : 000 |
|||
-10001 : 000 |
|||
-123 : 123 |
|||
-100 : 100 |
|||
100 : 100 |
|||
-12345 : 234 |
|||
1 : Number must have at least three digits |
|||
2 : Number must have at least three digits |
|||
-1 : Number must have at least three digits |
|||
-10 : Number must have at least three digits |
|||
2002 : Number must have an odd number of digits |
|||
-2002 : Number must have an odd number of digits |
|||
0 : Number must have at least three digits</pre> |
|||
=={{header|ATS}}== |
=={{header|ATS}}== |
||
<syntaxhighlight lang="ats"> |
|||
<lang ATS> |
|||
(* ****** ****** *) |
(* ****** ****** *) |
||
// |
// |
||
Line 418: | Line 1,088: | ||
(* ****** ****** *) |
(* ****** ****** *) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre>Middle-three-digits(123): 123 |
<pre>Middle-three-digits(123): 123 |
||
Line 439: | Line 1,109: | ||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
< |
<syntaxhighlight lang="autohotkey">Numbers:="123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345,1,2,-1,-10,2002,-2002,0" |
||
Loop, parse, Numbers, `, |
Loop, parse, Numbers, `, |
||
{ |
{ |
||
Line 451: | Line 1,121: | ||
log := log . A_LoopField . "`t: " . SubStr(n,((d-3)//2)+1,3) . "`n" |
log := log . A_LoopField . "`t: " . SubStr(n,((d-3)//2)+1,3) . "`n" |
||
} |
} |
||
MsgBox % log</ |
MsgBox % log</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>123 : 123 |
<pre>123 : 123 |
||
Line 472: | Line 1,142: | ||
=={{header|AWK}}== |
=={{header|AWK}}== |
||
< |
<syntaxhighlight lang="awk">#!/bin/awk -f |
||
# use as: awk -f middle_three_digits.awk |
# use as: awk -f middle_three_digits.awk |
||
Line 500: | Line 1,170: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 524: | Line 1,194: | ||
=={{header|BASIC}}== |
=={{header|BASIC}}== |
||
==={{header|Applesoft BASIC}}=== |
==={{header|Applesoft BASIC}}=== |
||
< |
<syntaxhighlight lang="applesoftbasic">100 DEF FN L(N) = LEN(STR$(INT(ABS(N)))) |
||
110 DEF FN N(N) = VAL(MID$(STR$(INT(ABS(N))),(FN L(N)-1)/2,3)) |
110 DEF FN N(N) = VAL(MID$(STR$(INT(ABS(N))),(FN L(N)-1)/2,3)) |
||
120 DEF FN EVEN(N) = INT(N/2) = N/2 |
120 DEF FN EVEN(N) = INT(N/2) = N/2 |
||
Line 546: | Line 1,216: | ||
300 DATA123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345 |
300 DATA123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345 |
||
310 DATA1,2,-1,-10,2002,-2002,0 |
310 DATA1,2,-1,-10,2002,-2002,0 |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 567: | Line 1,237: | ||
0: ?ONLY 1 DIGIT |
0: ?ONLY 1 DIGIT |
||
</pre> |
</pre> |
||
==={{header|BASIC256}}=== |
|||
<syntaxhighlight lang="vb">function middleThreeDigits(n) |
|||
if n < 0 then n = -n |
|||
if n < 100 then return "" ## error code |
|||
if n < 1000 then return string(n) |
|||
if n < 10000 then return "" |
|||
ns = string(n) |
|||
if length(ns) mod 2 = 0 then return "" ## need to have an odd number of digits for there to be 3 middle |
|||
return mid(ns, length(ns) \ 2, 3) |
|||
end function |
|||
dim a = {123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -123451, 2, -1, -10, 2002, -2002, 0} |
|||
print "The 3 middle digits of the following numbers are : " |
|||
print |
|||
for i = 0 to 15 |
|||
result = middleThreeDigits(a[i]) |
|||
print a[i]; chr(9); " => "; |
|||
if result <> "" then |
|||
print result |
|||
else |
|||
print "Error: does not have 3 middle digits" |
|||
end if |
|||
next</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Similar to FreeBASIC entry.</pre> |
|||
==={{header|BBC BASIC}}=== |
==={{header|BBC BASIC}}=== |
||
< |
<syntaxhighlight lang="bbcbasic">REM >midthree |
||
FOR i% = 1 TO 17 |
FOR i% = 1 TO 17 |
||
READ test% |
READ test% |
||
Line 589: | Line 1,286: | ||
OTHERWISE |
OTHERWISE |
||
= MID$(n$, LEN n$ / 2, 3) |
= MID$(n$, LEN n$ / 2, 3) |
||
ENDCASE</ |
ENDCASE</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> 123 -> 123 |
<pre> 123 -> 123 |
||
Line 610: | Line 1,307: | ||
==={{header|FBSL}}=== |
==={{header|FBSL}}=== |
||
< |
<syntaxhighlight lang="qbasic">#APPTYPE CONSOLE |
||
DIM numbers AS STRING = "123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345,1,2,-1,-10,2002,-2002,0" |
DIM numbers AS STRING = "123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345,1,2,-1,-10,2002,-2002,0" |
||
Line 654: | Line 1,351: | ||
RETURN m |
RETURN m |
||
END IF |
END IF |
||
END FUNCTION</ |
END FUNCTION</syntaxhighlight> |
||
Output |
Output |
||
<pre> 123 --> 123 |
<pre> 123 --> 123 |
||
Line 675: | Line 1,372: | ||
Press any key to continue...</pre> |
Press any key to continue...</pre> |
||
==={{header|IS-BASIC}}=== |
|||
<syntaxhighlight lang="is-basic">100 INPUT PROMPT "Number: ":N |
|||
120 PRINT MIDDLE$(N) |
|||
130 DEF MIDDLE$(N) |
|||
140 LET N$=STR$(ABS(N)) |
|||
150 IF LEN(N$)<3 THEN LET MIDDLE$="Not enough digits":EXIT DEF |
|||
160 IF MOD(LEN(N$),2)=0 THEN LET MIDDLE$="Even number of digits":EXIT DEF |
|||
170 LET P=(LEN(N$)-3)/2 |
|||
180 LET MIDDLE$=N$(P+1:P+3) |
|||
190 END DEF</syntaxhighlight> |
|||
==={{header|PureBasic}}=== |
==={{header|PureBasic}}=== |
||
< |
<syntaxhighlight lang="purebasic">Procedure.s middleThreeDigits(x.q) |
||
Protected x$, digitCount |
Protected x$, digitCount |
||
Line 704: | Line 1,413: | ||
Print(#crlf$ + #crlf$ + "Press ENTER to exit"): Input() |
Print(#crlf$ + #crlf$ + "Press ENTER to exit"): Input() |
||
CloseConsole() |
CloseConsole() |
||
EndIf</ |
EndIf</syntaxhighlight> |
||
Sample output: |
Sample output: |
||
<pre> 123 : 123 |
<pre> 123 : 123 |
||
Line 725: | Line 1,434: | ||
==={{header|Run BASIC}}=== |
==={{header|Run BASIC}}=== |
||
< |
<syntaxhighlight lang="runbasic">x$ = "123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0" |
||
while word$(x$,i+1,",") <> "" |
while word$(x$,i+1,",") <> "" |
||
Line 737: | Line 1,446: | ||
end if |
end if |
||
wend |
wend |
||
end</ |
end</syntaxhighlight> |
||
<pre>123 123 |
<pre>123 123 |
||
234 12345 |
234 12345 |
||
Line 755: | Line 1,464: | ||
-2002 length < 3 or is even |
-2002 length < 3 or is even |
||
0 length < 3 or is even</pre> |
0 length < 3 or is even</pre> |
||
==={{header|Yabasic}}=== |
|||
<syntaxhighlight lang="vb">sub middleThreeDigits$ (n) |
|||
if n < 0 n = -n |
|||
if n < 100 return "" // error code |
|||
if n < 1000 return str$(n) |
|||
if n < 10000 return "" |
|||
ns$ = str$(n) |
|||
if mod(len(ns$), 2) = 0 return "" // need to have an odd number of digits for there to be 3 middle |
|||
return mid$(ns$, len(ns$) / 2, 3) |
|||
end sub |
|||
dim a(16) |
|||
a(0) = 123 : a(1) = 12345 : a(2) = 1234567 |
|||
a(3) = 987654321 : a(4) = 10001 : a(5) = -10001 |
|||
a(6) = -123 : a(7) = -100 : a(8) = 100 |
|||
a(9) = -123451 |
|||
a(10) = 2 : a(11) = -1 : a(12) = -10 |
|||
a(13) = 2002 : a(14) = -2002 : a(15) = 0 |
|||
print "The 3 middle digits of the following numbers are : \n" |
|||
for i = 1 to 16 |
|||
result$ = middleThreeDigits$(a(i)) |
|||
print a(i), "\t => "; |
|||
if result$ <> "" then |
|||
print result$ |
|||
else |
|||
print "Error: does not have 3 middle digits" |
|||
fi |
|||
next</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Similar to FreeBASIC entry.</pre> |
|||
=={{header|Batch File}}== |
=={{header|Batch File}}== |
||
< |
<syntaxhighlight lang="dos">@echo off |
||
setlocal enabledelayedexpansion |
setlocal enabledelayedexpansion |
||
Line 802: | Line 1,544: | ||
) |
) |
||
goto :EOF |
goto :EOF |
||
%==/The Procedure ==%</ |
%==/The Procedure ==%</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>123: 123 |
<pre>123: 123 |
||
Line 823: | Line 1,565: | ||
Press any key to continue . . .</pre> |
Press any key to continue . . .</pre> |
||
=={{header|Befunge}}== |
=={{header|Befunge}}== |
||
Reads the integer value from stdin and writes the middle three digits (or an error message) to stdout. |
Reads the integer value from stdin and writes the middle three digits (or an error message) to stdout. |
||
< |
<syntaxhighlight lang="befunge">>&>:0`2*1-*0>v |
||
v+*86%+55:p00< |
v+*86%+55:p00< |
||
>\55+/:00g1+\| |
>\55+/:00g1+\| |
||
Line 835: | Line 1,576: | ||
2^,+55_,#!>#:< |
2^,+55_,#!>#:< |
||
>/>\#<$#-:#1_v |
>/>\#<$#-:#1_v |
||
>_@#<,+55,,,$<</ |
>_@#<,+55,,,$<</syntaxhighlight> |
||
{{out}} (multiple runs) |
{{out}} (multiple runs) |
||
Line 874: | Line 1,615: | ||
=={{header|Bracmat}}== |
=={{header|Bracmat}}== |
||
< |
<syntaxhighlight lang="bracmat">( ( middle3 |
||
= x p |
= x p |
||
. @(!arg:? [?p:? [(1/2*!p+-3/2) %?x [(1/2*!p+3/2) ?) |
. @(!arg:? [?p:? [(1/2*!p+-3/2) %?x [(1/2*!p+3/2) ?) |
||
Line 889: | Line 1,630: | ||
& |
& |
||
); |
); |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output: |
Output: |
||
<pre>123 |
<pre>123 |
||
Line 911: | Line 1,652: | ||
=={{header|Burlesque}}== |
=={{header|Burlesque}}== |
||
< |
<syntaxhighlight lang="blsq"> |
||
blsq ) {123 12345 1234567 987654321 -10001 -123}{XX{~-}{L[3.>}w!m]\[}m[uN |
blsq ) {123 12345 1234567 987654321 -10001 -123}{XX{~-}{L[3.>}w!m]\[}m[uN |
||
123 |
123 |
||
Line 919: | Line 1,660: | ||
000 |
000 |
||
123 |
123 |
||
</syntaxhighlight> |
|||
</lang> |
|||
<tt>m]\[</tt> and <tt>uN</tt> are just for displaying it nicely. |
<tt>m]\[</tt> and <tt>uN</tt> are just for displaying it nicely. |
||
Line 925: | Line 1,666: | ||
=={{header|C}}== |
=={{header|C}}== |
||
This code is followed by its output. |
This code is followed by its output. |
||
<syntaxhighlight lang="c"> |
|||
<lang c> |
|||
#include <stdio.h> |
#include <stdio.h> |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
Line 957: | Line 1,698: | ||
} |
} |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
<pre> |
<pre> |
||
Line 981: | Line 1,722: | ||
===Alternative Version=== |
===Alternative Version=== |
||
This code has been extensively rewritten. The original was purely interactive and had to be invoked each time from the console. It also did not produce the correct answer. |
This code has been extensively rewritten. The original was purely interactive and had to be invoked each time from the console. It also did not produce the correct answer. |
||
<syntaxhighlight lang="c"> |
|||
<lang c> |
|||
#include <stdio.h> |
#include <stdio.h> |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
Line 1,037: | Line 1,778: | ||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,061: | Line 1,802: | ||
Error, 0 is too short. |
Error, 0 is too short. |
||
The middle three digits of 1234567890 are 456. |
The middle three digits of 1234567890 are 456. |
||
</pre> |
|||
=={{header|C_sharp|C#}}== |
|||
<lang csharp>using System; |
|||
namespace RosettaCode |
|||
{ |
|||
class Program |
|||
{ |
|||
static void Main(string[] args) |
|||
{ |
|||
string text = Math.Abs(int.Parse(Console.ReadLine())).ToString(); |
|||
Console.WriteLine(text.Length < 2 || text.Length % 2 == 0 ? "Error" : text.Substring((text.Length - 3) / 2, 3)); |
|||
} |
|||
} |
|||
}</lang> |
|||
{{out}} |
|||
<pre>123:123 |
|||
12345:234 |
|||
1234567:345 |
|||
987654321:654 |
|||
10001:000 |
|||
-10001:000 |
|||
-123:123 |
|||
-100:100 |
|||
100:100 |
|||
-12345:234 |
|||
1:Error |
|||
2:Error |
|||
-1:Error |
|||
-10:Error |
|||
2002:Error |
|||
-2002:Error |
|||
0:Error |
|||
</pre> |
</pre> |
||
=={{header|C++}}== |
=={{header|C++}}== |
||
< |
<syntaxhighlight lang="cpp">#include <iostream> |
||
std::string middleThreeDigits(int n) |
std::string middleThreeDigits(int n) |
||
Line 1,126: | Line 1,832: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre>middleThreeDigits(123): 123 |
<pre>middleThreeDigits(123): 123 |
||
Line 1,145: | Line 1,851: | ||
middleThreeDigits(-2002): even number of digits |
middleThreeDigits(-2002): even number of digits |
||
middleThreeDigits(0): less than three digits</pre> |
middleThreeDigits(0): less than three digits</pre> |
||
=={{header|C_sharp|C#}}== |
|||
<syntaxhighlight lang="csharp">using System; |
|||
namespace RosettaCode |
|||
{ |
|||
class Program |
|||
{ |
|||
static void Main(string[] args) |
|||
{ |
|||
string text = Math.Abs(int.Parse(Console.ReadLine())).ToString(); |
|||
Console.WriteLine(text.Length < 2 || text.Length % 2 == 0 ? "Error" : text.Substring((text.Length - 3) / 2, 3)); |
|||
} |
|||
} |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>123:123 |
|||
12345:234 |
|||
1234567:345 |
|||
987654321:654 |
|||
10001:000 |
|||
-10001:000 |
|||
-123:123 |
|||
-100:100 |
|||
100:100 |
|||
-12345:234 |
|||
1:Error |
|||
2:Error |
|||
-1:Error |
|||
-10:Error |
|||
2002:Error |
|||
-2002:Error |
|||
0:Error |
|||
</pre> |
|||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
<syntaxhighlight lang="clojure">(defn middle3 |
|||
<lang Clojure> |
|||
[v] |
|||
(let [ |
(let [digit-str (str (Math/abs v)) |
||
len (count digit-str)] |
|||
len (count digits)] |
|||
(cond |
(cond |
||
(< len 3) : |
(< len 3) :too-short |
||
(even? len) : |
(even? len) :even-digit-count |
||
:else (let [ |
:else (let [half (/ len 2)] |
||
(subs digit-str (- half 1) (+ half 2)))))) |
|||
(apply str |
|||
(take 3 |
|||
(nthnext digits start))))))) |
|||
(clojure.pprint/print-table |
|||
(def passes '(123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345)) |
|||
(for [i [123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 |
|||
(def fails '(1 2 -1 -10 2002 -2002 0)) |
|||
1 2 -1 -10 2002 -2002 0]] |
|||
{:i i :middle-3 (middle3 i)})) |
|||
</lang> |
|||
</syntaxhighlight> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
| :i | :middle-3 | |
|||
user=> (map middle3 passes) |
|||
|-----------+-------------------| |
|||
("123" "234" "345" "654" "000" "000" "123" "100" "100" "234") |
|||
| 123 | 123 | |
|||
user=> (map middle3 fails) |
|||
| 12345 | 234 | |
|||
(:too_short :too_short :too_short :too_short :no_middle_in_even_no_of_digits :no_middle_in_even_no_of_digits :too_short) |
|||
| 1234567 | 345 | |
|||
| 987654321 | 654 | |
|||
| 10001 | 000 | |
|||
| -10001 | 000 | |
|||
| -123 | 123 | |
|||
| -100 | 100 | |
|||
| 100 | 100 | |
|||
| -12345 | 234 | |
|||
| 1 | :too-short | |
|||
| 2 | :too-short | |
|||
| -1 | :too-short | |
|||
| -10 | :too-short | |
|||
| 2002 | :even-digit-count | |
|||
| -2002 | :even-digit-count | |
|||
| 0 | :too-short | |
|||
</pre> |
</pre> |
||
=={{header|CLU}}== |
|||
<syntaxhighlight lang="clu">middle_three_digits = proc (n: int) returns (string) |
|||
signals (too_small, even_length) |
|||
s: string := int$unparse(int$abs(n)) |
|||
if string$size(s) < 3 then signal too_small end |
|||
if string$size(s) // 2 = 0 then signal even_length end |
|||
return(string$substr(s, string$size(s)/2, 3)) |
|||
end middle_three_digits |
|||
start_up = proc () |
|||
po: stream := stream$primary_output() |
|||
tests: sequence[int] := sequence[int]$ |
|||
[123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345, |
|||
1,2,-1,-10,2002,-2002,0] |
|||
for test: int in sequence[int]$elements(tests) do |
|||
stream$putright(po, int$unparse(test) || ": ", 11) |
|||
stream$putl(po, middle_three_digits(test)) |
|||
except |
|||
when too_small: stream$putl(po, "Too small") |
|||
when even_length: stream$putl(po, "Even length") |
|||
end |
|||
end |
|||
end start_up</syntaxhighlight> |
|||
{{out}} |
|||
<pre> 123: 123 |
|||
12345: 234 |
|||
1234567: 345 |
|||
987654321: 654 |
|||
10001: 000 |
|||
-10001: 000 |
|||
-123: 123 |
|||
-100: 100 |
|||
100: 100 |
|||
-12345: 234 |
|||
1: Too small |
|||
2: Too small |
|||
-1: Too small |
|||
-10: Too small |
|||
2002: Even length |
|||
-2002: Even length |
|||
0: Too small</pre> |
|||
=={{header|COBOL}}== |
=={{header|COBOL}}== |
||
< |
<syntaxhighlight lang="cobol">identification division. |
||
program-id. middle3. |
program-id. middle3. |
||
environment division. |
environment division. |
||
Line 1,265: | Line 2,062: | ||
add 1 to digit-counter |
add 1 to digit-counter |
||
end-perform. |
end-perform. |
||
exit paragraph.</ |
exit paragraph.</syntaxhighlight> |
||
Output |
Output |
||
<pre> 123 --> 123 |
<pre> 123 --> 123 |
||
Line 1,285: | Line 2,082: | ||
0 --> Number too small</pre> |
0 --> Number too small</pre> |
||
Optimised version |
Optimised version |
||
< |
<syntaxhighlight lang="cobol">identification division. |
||
program-id. middle3. |
program-id. middle3. |
||
environment division. |
environment division. |
||
Line 1,357: | Line 2,154: | ||
end-if. |
end-if. |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output |
Output |
||
<pre> 123 --> 123 |
<pre> 123 --> 123 |
||
Line 1,379: | Line 2,176: | ||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
===Solution #1=== |
|||
<lang lisp> |
|||
<syntaxhighlight lang="lisp"> |
|||
(defun mid3 (n) |
(defun mid3 (n) |
||
(let ((a (abs n)) |
(let ((a (abs n)) |
||
Line 1,392: | Line 2,190: | ||
((evenp hmd) (need "odd number of")) |
((evenp hmd) (need "odd number of")) |
||
(t (nbr (mod (truncate a (expt 10 (/ (- hmd 3) 2))) 1000))))))) |
(t (nbr (mod (truncate a (expt 10 (/ (- hmd 3) 2))) 1000))))))) |
||
</syntaxhighlight> |
|||
</lang> |
|||
Test code: |
Test code: |
||
< |
<syntaxhighlight lang="lisp"> |
||
(loop as n in '(123 12345 1234567 987654321 |
(loop as n in '(123 12345 1234567 987654321 |
||
10001 -10001 -123 -100 100 -12345 |
10001 -10001 -123 -100 100 -12345 |
||
1 2 -1 -10 2002 -2002 0) |
1 2 -1 -10 2002 -2002 0) |
||
do (format t "~d:~12t~a~%" n (mid3 n))) |
do (format t "~d:~12t~a~%" n (mid3 n))) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre>123: 123 |
<pre>123: 123 |
||
Line 1,420: | Line 2,218: | ||
-2002: Need odd number of digits, not 4. |
-2002: Need odd number of digits, not 4. |
||
0: Zero is 1 digit</pre> |
0: Zero is 1 digit</pre> |
||
===Solution #2=== |
|||
<syntaxhighlight lang="lisp"> |
|||
(defun mid3 (i) |
|||
(let ((ch-vec (coerce (format nil "~A" (abs i)) 'vector))) |
|||
(when (evenp (length ch-vec)) |
|||
(return-from mid3 |
|||
(format nil "Error: The number representation must have an odd ~ |
|||
number of digits."))) |
|||
(when (and (< i 100) |
|||
(> i -100)) |
|||
(return-from mid3 |
|||
(format nil "Error: Must be >= 100 or <= -100."))) |
|||
(let ((half (/ (1- (length ch-vec)) 2))) |
|||
(return-from mid3 (format nil "~A~A~A" |
|||
(elt ch-vec (1- half)) |
|||
(elt ch-vec half) |
|||
(elt ch-vec (1+ half)))) |
|||
))) |
|||
</syntaxhighlight> |
|||
Test code: |
|||
<syntaxhighlight lang="lisp"> |
|||
(defun test-mid3 () |
|||
(let ((test-lst (list 123 |
|||
12345 |
|||
1234567 |
|||
987654321 |
|||
10001 |
|||
-10001 |
|||
-123 |
|||
-100 |
|||
100 |
|||
-12345 |
|||
1 |
|||
2 |
|||
-1 |
|||
-10 |
|||
2002 |
|||
-2002 |
|||
0 |
|||
))) |
|||
(labels |
|||
((run-tests (lst) |
|||
(cond ((null lst) |
|||
nil) |
|||
(t |
|||
(format t "~A ~15T ~A~%" (first lst) (mid3 (first lst))) |
|||
(run-tests (rest lst)))))) |
|||
(run-tests test-lst))) |
|||
(values) |
|||
) |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
123 123 |
|||
12345 234 |
|||
1234567 345 |
|||
987654321 654 |
|||
10001 000 |
|||
-10001 000 |
|||
-123 123 |
|||
-100 100 |
|||
100 100 |
|||
-12345 234 |
|||
1 Error: Must be >= 100 or <= -100. |
|||
2 Error: Must be >= 100 or <= -100. |
|||
-1 Error: Must be >= 100 or <= -100. |
|||
-10 Error: The number representation must have an odd number of digits. |
|||
2002 Error: The number representation must have an odd number of digits. |
|||
-2002 Error: The number representation must have an odd number of digits. |
|||
0 Error: Must be >= 100 or <= -100. |
|||
</pre> |
|||
=={{header|D}}== |
=={{header|D}}== |
||
< |
<syntaxhighlight lang="d">import std.stdio, std.traits, std.conv; |
||
string middleThreeDigits(T)(in T n) pure nothrow if (isIntegral!T) { |
string middleThreeDigits(T)(in T n) pure nothrow if (isIntegral!T) { |
||
Line 1,442: | Line 2,317: | ||
foreach (immutable n; failing) |
foreach (immutable n; failing) |
||
writefln("middleThreeDigits(%s): %s", n, middleThreeDigits(n)); |
writefln("middleThreeDigits(%s): %s", n, middleThreeDigits(n)); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>middleThreeDigits(123): 123 |
<pre>middleThreeDigits(123): 123 |
||
Line 1,468: | Line 2,343: | ||
===Alternative Version=== |
===Alternative Version=== |
||
This longer version gives a stronger typed output, and it tries to be faster avoiding conversions to string. |
This longer version gives a stronger typed output, and it tries to be faster avoiding conversions to string. |
||
< |
<syntaxhighlight lang="d">import std.stdio, std.traits, std.math, std.variant; |
||
/// Returns a string with the error, or the three digits. |
/// Returns a string with the error, or the three digits. |
||
Line 1,554: | Line 2,429: | ||
writefln("middleThreeDigits(cast(short)%d): %s", n, mtd); |
writefln("middleThreeDigits(cast(short)%d): %s", n, mtd); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>middleThreeDigits(123): 123 |
<pre>middleThreeDigits(123): 123 |
||
Line 1,605: | Line 2,480: | ||
=={{header|Dart}}== |
=={{header|Dart}}== |
||
<lang> |
<syntaxhighlight lang="text"> |
||
import'dart:math'; |
import'dart:math'; |
||
int length(int x) |
int length(int x) |
||
Line 1,652: | Line 2,527: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|DCL}}== |
=={{header|DCL}}== |
||
<lang>$ list = "123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345,1,2,-1,-10,2002,-2002,0" |
<syntaxhighlight lang="text">$ list = "123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345,1,2,-1,-10,2002,-2002,0" |
||
$ i = 0 |
$ i = 0 |
||
$ loop: |
$ loop: |
||
Line 1,668: | Line 2,544: | ||
$ endif |
$ endif |
||
$ i = i + 1 |
$ i = i + 1 |
||
$ goto loop</ |
$ goto loop</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>$ @middle_three_digits |
<pre>$ @middle_three_digits |
||
Line 1,688: | Line 2,564: | ||
-2002: has no middle three |
-2002: has no middle three |
||
0: has no middle three</pre> |
0: has no middle three</pre> |
||
=={{header|Delphi}}== |
|||
See [https://rosettacode.org/wiki/Middle_three_digits#Pascal Pascal]. |
|||
=={{header|EasyLang}}== |
|||
<syntaxhighlight lang="easylang"> |
|||
func$ midThreeDigits num . |
|||
trueNumber$ = abs num |
|||
if (len trueNumber$ < 3) or (len trueNumber$ mod 2 = 0) |
|||
r$ = "error" |
|||
else |
|||
r$ = substr trueNumber$ ((len trueNumber$ - 3) / 2 + 1) 3 |
|||
. |
|||
return r$ |
|||
. |
|||
numbers[] = [ 123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 1 2 -1 -10 2002 -2002 0 ] |
|||
for i in numbers[] |
|||
print midThreeDigits i |
|||
. |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
123 |
|||
234 |
|||
345 |
|||
654 |
|||
000 |
|||
000 |
|||
123 |
|||
100 |
|||
100 |
|||
234 |
|||
error |
|||
error |
|||
error |
|||
error |
|||
error |
|||
error |
|||
error |
|||
</pre> |
|||
=={{header|Eiffel}}== |
=={{header|Eiffel}}== |
||
<syntaxhighlight lang="eiffel"> |
|||
<lang Eiffel> |
|||
class |
class |
||
APPLICATION |
APPLICATION |
||
Line 1,752: | Line 2,668: | ||
end |
end |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,774: | Line 2,690: | ||
</pre> |
</pre> |
||
=={{header|Elena}}== |
|||
ELENA 3.3 : |
|||
<lang elena>import system'routines. |
|||
import extensions. |
|||
=={{header|Elena}}== |
|||
middleThreeDigits = (:n)<int> |
|||
ELENA 6.x : |
|||
[ |
|||
<syntaxhighlight lang="elena">import system'routines; |
|||
literal s := n absolute; literal. |
|||
import extensions; |
|||
int len := s length. |
|||
middleThreeDigits(int n) |
|||
{ |
|||
string s := n.Absolute.toString(); |
|||
int len := s.Length; |
|||
if(len<3) |
if(len<3) |
||
{ |
|||
InvalidArgumentException |
InvalidArgumentException.new("n must have 3 digits or more").raise() |
||
} |
|||
if(len |
else if(len.isEven()) |
||
{ |
|||
InvalidArgumentException |
InvalidArgumentException.new("n must have an odd number of digits").raise() |
||
}; |
|||
int mid := len / 2 |
int mid := len / 2; |
||
^ s |
^ s.Substring(mid-1,3) |
||
} |
|||
]. |
|||
public program() |
|||
program = |
|||
{ |
|||
[ |
|||
new int[]{123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0} |
|||
forEach |
.forEach::(n) |
||
{ |
|||
console.printLine("middleThreeDigits(",n,"):",middleThreeDigits(n) \\ on::(e => e.Message)) |
|||
} |
|||
}</syntaxhighlight> |
|||
].</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,827: | Line 2,744: | ||
=={{header|Elixir}}== |
=={{header|Elixir}}== |
||
< |
<syntaxhighlight lang="elixir">defmodule Middle do |
||
def three(num) do |
def three(num) do |
||
n = num |> abs |> to_string |
n = num |> abs |> to_string |
||
Line 1,856: | Line 2,773: | ||
e -> IO.puts e.message |
e -> IO.puts e.message |
||
end |
end |
||
end)</ |
end)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,880: | Line 2,797: | ||
=={{header|Erlang}}== |
=={{header|Erlang}}== |
||
< |
<syntaxhighlight lang="erlang">% |
||
-module(middle_three_digits). |
-module(middle_three_digits). |
||
-export([main/0]). |
-export([main/0]). |
||
Line 1,919: | Line 2,836: | ||
loop(X,N) when X>0 -> |
loop(X,N) when X>0 -> |
||
loop(X-1, N div 10). |
loop(X-1, N div 10). |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre>123 |
<pre>123 |
||
Line 1,942: | Line 2,859: | ||
=={{header|ERRE}}== |
=={{header|ERRE}}== |
||
<syntaxhighlight lang="erre"> |
|||
<lang ERRE> |
|||
PROGRAM MIDDLE |
PROGRAM MIDDLE |
||
Line 1,987: | Line 2,904: | ||
END FOR |
END FOR |
||
END PROGRAM |
END PROGRAM |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,010: | Line 2,927: | ||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
<lang>USING: combinators formatting io kernel math math.parser |
<syntaxhighlight lang="text">USING: combinators formatting io kernel math math.parser |
||
sequences ; |
sequences ; |
||
IN: rosetta-code.middle-three-digits |
IN: rosetta-code.middle-three-digits |
||
CONSTANT: test-values { |
CONSTANT: test-values { |
||
123 12345 1234567 987654321 10001 -10001 |
|||
-123 -100 100 -12345 1 2 -1 -10 2002 -2002 0 |
|||
} |
|||
: middle-three ( str -- str' ) |
: (middle-three) ( str -- str' ) |
||
[ [ 1 - ] [ 2 + ] bi ] |
[ midpoint@ [ 1 - ] [ 2 + ] bi ] [ subseq ] bi ; |
||
: too-short ( -- ) |
: too-short ( -- ) |
||
print ; |
"Number must have at least three digits." print ; |
||
: number-even ( -- ) |
: number-even ( -- ) |
||
"Number must have an odd number of digits." print ; |
|||
print ; |
|||
: |
: middle-three ( n -- ) |
||
abs number>string { |
abs number>string { |
||
{ [ dup length 3 < ] [ drop too-short ] } |
{ [ dup length 3 < ] [ drop too-short ] } |
||
{ [ dup length even? ] [ drop number-even ] } |
{ [ dup length even? ] [ drop number-even ] } |
||
[ middle-three print ] |
[ (middle-three) print ] |
||
} cond ; |
} cond ; |
||
: main ( -- ) |
: main ( -- ) |
||
test-values [ dup "%9d : " printf middle-three ] each ; |
|||
MAIN: main</ |
MAIN: main</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,059: | Line 2,979: | ||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
This is a problem, which is easily solved in Forth. It converts the number to a string and checks it length. If the number does not represent a printable string, it returns an empty string. |
This is a problem, which is easily solved in Forth. It converts the number to a string and checks it length. If the number does not represent a printable string, it returns an empty string. |
||
< |
<syntaxhighlight lang="forth">: middle3 ( n1 -- a n2) |
||
abs s>d <# #s #> dup 2/ 0<> over 1 and 0<> and |
abs s>d <# #s #> dup 2/ 0<> over 1 and 0<> and |
||
if 2/ 1- chars + 3 else drop 0 then |
if 2/ 1- chars + 3 else drop 0 then |
||
;</ |
;</syntaxhighlight> |
||
=={{header|Fortran}}== |
=={{header|Fortran}}== |
||
Please find compilation instructions along with the output for the examples in the comments at the beginning of the file. This program was produced in an Ubuntu distribution of the GNU/linux system. |
Please find compilation instructions along with the output for the examples in the comments at the beginning of the file. This program was produced in an Ubuntu distribution of the GNU/linux system. |
||
<syntaxhighlight lang="fortran"> |
|||
<lang FORTRAN> |
|||
!-*- mode: compilation; default-directory: "/tmp/" -*- |
!-*- mode: compilation; default-directory: "/tmp/" -*- |
||
!Compilation started at Sat Jun 1 14:48:41 |
!Compilation started at Sat Jun 1 14:48:41 |
||
Line 2,139: | Line 3,060: | ||
end program MiddleMuddle |
end program MiddleMuddle |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
< |
<syntaxhighlight lang="freebasic">' FB 1.05.0 Win64 |
||
Function middleThreeDigits (n As Integer) As String |
Function middleThreeDigits (n As Integer) As String |
||
Line 2,173: | Line 3,094: | ||
Print |
Print |
||
Print "Press any key to quit" |
Print "Press any key to quit" |
||
Sleep</ |
Sleep</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,196: | Line 3,117: | ||
0 => Error: does not have 3 middle digits |
0 => Error: does not have 3 middle digits |
||
</pre> |
</pre> |
||
=={{header|FutureBasic}}== |
|||
<syntaxhighlight lang="futurebasic"> |
|||
local fn MiddleThreeDigits( n as NSInteger ) as CFStringRef |
|||
CFStringRef testStr, resultStr |
|||
NSInteger length, middle |
|||
testStr = fn StringWithFormat( @"%ld", n ) |
|||
testStr = fn StringByReplacingOccurrencesOfString( testStr, @"-", @"" ) |
|||
length = len(testStr) |
|||
if length < 3 then resultStr = fn StringWithFormat( @"%10ld -> Error: Less than three digits.", n ) : exit fn |
|||
if length == 3 then resultStr = fn StringWithFormat( @"%10ld -> %@", n, testStr ) : exit fn |
|||
length = len(testStr) |
|||
if ( length mod 2 == 0 ) |
|||
resultStr = fn StringWithFormat( @"%10ld -> Error: Even length; needs odd.", n ) |
|||
else |
|||
middle = length / 2 |
|||
resultStr = fn StringWithFormat( @"%10ld -> %@", n, mid( testStr, middle -1, 3 ) ) |
|||
end if |
|||
end fn = resultStr |
|||
window 1, @"Middle Three Digits", ( 0, 0, 400, 300 ) |
|||
NSUInteger i, count |
|||
CFArrayRef testArr |
|||
CFNumberRef tempNum |
|||
testArr = @[@123,@12345,@1234567,@987654321,@10001,@-10001,¬ |
|||
@-123,@-100,@100,@-12345,@1,@2,@-1,@-10,@2002,@-2002,@0] |
|||
count = fn ArrayCount( testArr ) |
|||
for i = 0 to count - 1 |
|||
print fn MiddleThreeDigits( fn NumberIntegerValue( testArr[i] ) ) |
|||
next |
|||
HandleEvents |
|||
</syntaxhighlight> |
|||
{{output}} |
|||
<pre style="font-size: 13px"> |
|||
123 -> 123 |
|||
12345 -> 234 |
|||
1234567 -> 345 |
|||
987654321 -> 654 |
|||
10001 -> 000 |
|||
-10001 -> 000 |
|||
-123 -> 123 |
|||
-100 -> 100 |
|||
100 -> 100 |
|||
-12345 -> 234 |
|||
1 -> Error: Less than three digits. |
|||
2 -> Error: Less than three digits. |
|||
-1 -> Error: Less than three digits. |
|||
-10 -> Error: Less than three digits. |
|||
2002 -> Error: Even length; needs odd. |
|||
-2002 -> Error: Even length; needs odd. |
|||
0 -> Error: Less than three digits. |
|||
</pre> |
|||
=={{header|Gambas}}== |
=={{header|Gambas}}== |
||
'''[https://gambas-playground.proko.eu/?gist=ed25e84978446d65895ccd909fc092fa Click this link to run this code]''' |
'''[https://gambas-playground.proko.eu/?gist=ed25e84978446d65895ccd909fc092fa Click this link to run this code]''' |
||
< |
<syntaxhighlight lang="gambas">Public Sub Main() |
||
Dim iList As Integer[] = [123, 12345, 1234567, 987654321, 10001, |
Dim iList As Integer[] = [123, 12345, 1234567, 987654321, 10001, |
||
-10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0] 'Array of integers to process |
-10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0] 'Array of integers to process |
||
Line 2,222: | Line 3,208: | ||
Next |
Next |
||
End</ |
End</syntaxhighlight> |
||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 2,247: | Line 3,233: | ||
File m3.go: |
File m3.go: |
||
< |
<syntaxhighlight lang="go">package m3 |
||
import ( |
import ( |
||
Line 2,272: | Line 3,258: | ||
m := len(s) / 2 |
m := len(s) / 2 |
||
return s[m-1 : m+2], nil |
return s[m-1 : m+2], nil |
||
}</ |
}</syntaxhighlight> |
||
File m3_test.go: |
File m3_test.go: |
||
< |
<syntaxhighlight lang="go">package m3_test |
||
import ( |
import ( |
||
Line 2,332: | Line 3,318: | ||
t.Logf("d(%d) returns %q", tc.i, err) |
t.Logf("d(%d) returns %q", tc.i, err) |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Output of go test is normally terse: |
Output of go test is normally terse: |
||
Line 2,365: | Line 3,351: | ||
=={{header|Gosu}}== |
=={{header|Gosu}}== |
||
< |
<syntaxhighlight lang="gosu">var valid = {123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345} |
||
valid.each(\ num ->print(middleThree(num))) |
valid.each(\ num ->print(middleThree(num))) |
||
Line 2,377: | Line 3,363: | ||
var start = (s.length / 2) - 1 |
var start = (s.length / 2) - 1 |
||
return s.substring(start, start + 3) |
return s.substring(start, start + 3) |
||
}</ |
}</syntaxhighlight> |
||
{{Output}} |
{{Output}} |
||
Line 2,400: | Line 3,386: | ||
=={{header|Groovy}}== |
=={{header|Groovy}}== |
||
< |
<syntaxhighlight lang="groovy">def middleThree(Number number) { |
||
def text = Math.abs(number) as String |
def text = Math.abs(number) as String |
||
assert text.size() >= 3 : "'$number' must be more than 3 numeric digits" |
assert text.size() >= 3 : "'$number' must be more than 3 numeric digits" |
||
Line 2,407: | Line 3,393: | ||
int start = text.size() / 2 - 1 |
int start = text.size() / 2 - 1 |
||
text[start..(start+2)] |
text[start..(start+2)] |
||
}</ |
}</syntaxhighlight> |
||
Test Code: |
Test Code: |
||
< |
<syntaxhighlight lang="groovy">[123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0].each { number -> |
||
def text = (number as String).padLeft(10) |
def text = (number as String).padLeft(10) |
||
try { |
try { |
||
Line 2,416: | Line 3,402: | ||
println "$text cannot be converted: $error.message" |
println "$text cannot be converted: $error.message" |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Output: |
Output: |
||
<pre> 123: 123 |
<pre> 123: 123 |
||
Line 2,437: | Line 3,423: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
<syntaxhighlight lang="haskell">------------------- MIDDLE THREE DIGITS ------------------ |
|||
<lang haskell>mid3 :: Int -> Either String String |
|||
mid3 :: Int -> Either String String |
|||
mid3 n |
mid3 n |
||
| m < 100 = Left " |
| m < 100 = Left "too small" |
||
| even |
| even lng = Left "even number of digits" |
||
| otherwise = Right . take 3 $ drop (( |
| otherwise = Right . take 3 $ drop ((lng - 3) `div` 2) s |
||
where |
where |
||
m = abs n |
m = abs n |
||
s = show m |
s = show m |
||
lng = length s |
|||
--------------------------- TEST ------------------------- |
|||
showMid3 :: Int -> String |
|||
main :: IO () |
|||
showMid3 n = show n ++ ": " ++ either id id (mid3 n) |
|||
main = do |
|||
let xs = |
|||
[ 123 |
|||
, 12345 |
|||
, 1234567 |
|||
, 987654321 |
|||
, 10001 |
|||
, -10001 |
|||
, -123 |
|||
, -100 |
|||
, 100 |
|||
, -12345 |
|||
, 1 |
|||
, 2 |
|||
, -1 |
|||
, -10 |
|||
, 2002 |
|||
, -2002 |
|||
, 0 |
|||
] |
|||
w = maximum $ length . show <$> xs |
|||
(putStrLn . unlines) $ |
|||
(\n -> |
|||
justifyRight w ' ' (show n) <> |
|||
" -> " <> either (concat . ("(" :) . (: [")"])) id (mid3 n)) <$> |
|||
xs |
|||
justifyRight :: Int -> Char -> String -> String |
|||
main :: IO () |
|||
justifyRight n c = (drop . length) <*> (replicate n c <>)</syntaxhighlight> |
|||
main = |
|||
mapM_ |
|||
(putStrLn . showMid3) |
|||
[ 123 |
|||
, 12345 |
|||
, 1234567 |
|||
, 987654321 |
|||
, 10001 |
|||
, -10001 |
|||
, -123 |
|||
, -100 |
|||
, 100 |
|||
, -12345 |
|||
, 1 |
|||
, 2 |
|||
, -1 |
|||
, -10 |
|||
, 2002 |
|||
, -2002 |
|||
, 0 |
|||
]</lang> |
|||
Output: |
Output: |
||
<pre>123 |
<pre> 123 -> 123 |
||
12345 |
12345 -> 234 |
||
1234567 |
1234567 -> 345 |
||
987654321 |
987654321 -> 654 |
||
10001 |
10001 -> 000 |
||
-10001 |
-10001 -> 000 |
||
-123 |
-123 -> 123 |
||
-100 |
-100 -> 100 |
||
100 |
100 -> 100 |
||
-12345 |
-12345 -> 234 |
||
1 |
1 -> (too small) |
||
2 |
2 -> (too small) |
||
-1 |
-1 -> (too small) |
||
-10 |
-10 -> (too small) |
||
2002 -> (even number of digits) |
|||
-2002 |
-2002 -> (even number of digits) |
||
0 |
0 -> (too small)</pre> |
||
=={{header|Icon}} and {{header|Unicon}}== |
=={{header|Icon}} and {{header|Unicon}}== |
||
Line 2,495: | Line 3,489: | ||
The following solution works in both languages. |
The following solution works in both languages. |
||
< |
<syntaxhighlight lang="unicon">procedure main(a) |
||
every n := !a do write(right(n,15)," -> ",midM(n)) |
every n := !a do write(right(n,15)," -> ",midM(n)) |
||
end |
end |
||
Line 2,506: | Line 3,500: | ||
else "wrong number of digits" |
else "wrong number of digits" |
||
else "too short" |
else "too short" |
||
end</ |
end</syntaxhighlight> |
||
with output: |
with output: |
||
Line 2,531: | Line 3,525: | ||
=={{header|J}}== |
=={{header|J}}== |
||
A key issue here is that some numbers do not have a "middle 3 digits" -- either because the number is too short, or because it has an even number of digits (or both, two digit numbers). |
|||
'''Solution:''' |
'''Solution:''' |
||
< |
<syntaxhighlight lang="j">asString=: ":"0 NB. convert vals to strings |
||
getPfxSize=: [: -:@| 3 -~ # NB. get size of prefix to drop before the 3 middle digits |
getPfxSize=: [: -:@| 3 -~ # NB. get size of prefix to drop before the 3 middle digits |
||
getMid3=: (3 {. getPfxSize }. ,&'err') :: ('err'"_) NB. get 3 middle digits or return 'err' |
getMid3=: (3 {. getPfxSize }. ,&'err') :: ('err'"_) NB. get 3 middle digits or return 'err' |
||
getMiddle3=: getMid3@asString@:|</ |
getMiddle3=: getMid3@asString@:|</syntaxhighlight> |
||
'''Example:''' |
'''Example:''' |
||
< |
<syntaxhighlight lang="j"> vals=: 123 12345 1234567 987654321 10001 _10001 _123 _100 100 _12345 1 2 _1 _10 2002 _2002 0 |
||
getMiddle3 vals |
getMiddle3 vals |
||
123 |
123 |
||
Line 2,555: | Line 3,552: | ||
err |
err |
||
err |
err |
||
err</ |
err</syntaxhighlight> |
||
Or, expressed more concisely:<syntaxhighlight lang="j"> ({~ 2 1 0 -~ -:@>:@#) ::('err'"_)@":@| vals |
|||
123 |
|||
234 |
|||
345 |
|||
654 |
|||
000 |
|||
000 |
|||
123 |
|||
100 |
|||
100 |
|||
234 |
|||
err |
|||
err |
|||
err |
|||
err |
|||
err |
|||
err |
|||
err</syntaxhighlight> |
|||
=={{header|Java}}== |
=={{header|Java}}== |
||
< |
<syntaxhighlight lang="java">public class MiddleThreeDigits { |
||
public static void main(String[] args) { |
public static void main(String[] args) { |
||
Line 2,584: | Line 3,600: | ||
return s.substring(mid - 1, mid + 2); |
return s.substring(mid - 1, mid + 2); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
<pre>middleThreeDigits(123): 123 |
<pre>middleThreeDigits(123): 123 |
||
middleThreeDigits(12345): 234 |
middleThreeDigits(12345): 234 |
||
Line 2,608: | Line 3,624: | ||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
< |
<syntaxhighlight lang="javascript">function middleThree(x){ |
||
var n=''+Math.abs(x); var l=n.length-1; |
var n=''+Math.abs(x); var l=n.length-1; |
||
if(l<2||l%2) throw new Error(x+': Invalid length '+(l+1)); |
if(l<2||l%2) throw new Error(x+': Invalid length '+(l+1)); |
||
Line 2,617: | Line 3,633: | ||
1, 2, -1, -10, 2002, -2002, 0].forEach(function(n){ |
1, 2, -1, -10, 2002, -2002, 0].forEach(function(n){ |
||
try{console.log(n,middleThree(n))}catch(e){console.error(e.message)} |
try{console.log(n,middleThree(n))}catch(e){console.error(e.message)} |
||
});</ |
});</syntaxhighlight> |
||
<pre>123 "123" |
<pre>123 "123" |
||
Line 2,636: | Line 3,652: | ||
-2002: Invalid length 4 |
-2002: Invalid length 4 |
||
0: Invalid length 1</pre> |
0: Invalid length 1</pre> |
||
Or, using an option type, composing a solution from existing generic primitives, and formatting the output a little: |
|||
{{Trans|Python}} |
|||
<syntaxhighlight lang="javascript">(() => { |
|||
'use strict'; |
|||
// mid3digits :: Int -> Either String String |
|||
const mid3digits = n => { |
|||
const |
|||
m = abs(n), |
|||
s = m.toString(); |
|||
return 100 > m ? ( |
|||
Left('Less than 3 digits') |
|||
) : even(length(s)) ? ( |
|||
Left('Even digit count') |
|||
) : Right(take(3, drop(quot(length(s) - 3, 2), s))); |
|||
}; |
|||
// TEST ----------------------------------------------- |
|||
const main = () => { |
|||
const |
|||
xs = [ |
|||
123, 12345, 1234567, 987654321, 10001, -10001, -123, |
|||
-100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0 |
|||
], |
|||
w = maximum(map(x => x.toString().length, xs)); |
|||
return ( |
|||
unlines(map( |
|||
n => justifyRight(w, ' ', n.toString()) + ' -> ' + |
|||
either( |
|||
s => '(' + s + ')', |
|||
id, |
|||
mid3digits(n) |
|||
), |
|||
xs |
|||
)) |
|||
); |
|||
}; |
|||
// GENERIC FUNCTIONS ---------------------------------- |
|||
// Left :: a -> Either a b |
|||
const Left = x => ({ |
|||
type: 'Either', |
|||
Left: x |
|||
}); |
|||
// Right :: b -> Either a b |
|||
const Right = x => ({ |
|||
type: 'Either', |
|||
Right: x |
|||
}); |
|||
// abs :: Num -> Num |
|||
const abs = Math.abs; |
|||
// drop :: Int -> [a] -> [a] |
|||
// drop :: Int -> Generator [a] -> Generator [a] |
|||
// drop :: Int -> String -> String |
|||
const drop = (n, xs) => |
|||
Infinity > length(xs) ? ( |
|||
xs.slice(n) |
|||
) : (take(n, xs), xs); |
|||
// either :: (a -> c) -> (b -> c) -> Either a b -> c |
|||
const either = (fl, fr, e) => |
|||
'Either' === e.type ? ( |
|||
undefined !== e.Left ? ( |
|||
fl(e.Left) |
|||
) : fr(e.Right) |
|||
) : undefined; |
|||
// even :: Int -> Bool |
|||
const even = n => 0 === n % 2; |
|||
// foldl1 :: (a -> a -> a) -> [a] -> a |
|||
const foldl1 = (f, xs) => |
|||
1 < xs.length ? xs.slice(1) |
|||
.reduce(f, xs[0]) : xs[0]; |
|||
// id :: a -> a |
|||
const id = x => x; |
|||
// justifyRight :: Int -> Char -> String -> String |
|||
const justifyRight = (n, cFiller, s) => |
|||
n > s.length ? ( |
|||
s.padStart(n, cFiller) |
|||
) : s; |
|||
// Returns Infinity over objects without finite length. |
|||
// This enables zip and zipWith to choose the shorter |
|||
// argument when one is non-finite, like cycle, repeat etc |
|||
// length :: [a] -> Int |
|||
const length = xs => |
|||
(Array.isArray(xs) || 'string' === typeof xs) ? ( |
|||
xs.length |
|||
) : Infinity; |
|||
// maximum :: Ord a => [a] -> a |
|||
const maximum = xs => |
|||
0 < xs.length ? ( |
|||
foldl1((a, x) => x > a ? x : a, xs) |
|||
) : undefined; |
|||
// map :: (a -> b) -> [a] -> [b] |
|||
const map = (f, xs) => xs.map(f); |
|||
// quot :: Int -> Int -> Int |
|||
const quot = (n, m) => Math.floor(n / m); |
|||
// take :: Int -> [a] -> [a] |
|||
// take :: Int -> String -> String |
|||
const take = (n, xs) => |
|||
'GeneratorFunction' !== xs.constructor.constructor.name ? ( |
|||
xs.slice(0, n) |
|||
) : [].concat.apply([], Array.from({ |
|||
length: n |
|||
}, () => { |
|||
const x = xs.next(); |
|||
return x.done ? [] : [x.value]; |
|||
})); |
|||
// unlines :: [String] -> String |
|||
const unlines = xs => xs.join('\n'); |
|||
// MAIN --- |
|||
return main(); |
|||
})();</syntaxhighlight> |
|||
{{Out}} |
|||
<pre> |
|||
123 -> 123 |
|||
12345 -> 234 |
|||
1234567 -> 345 |
|||
987654321 -> 654 |
|||
10001 -> 000 |
|||
-10001 -> 000 |
|||
-123 -> 123 |
|||
-100 -> 100 |
|||
100 -> 100 |
|||
-12345 -> 234 |
|||
1 -> (Less than 3 digits) |
|||
2 -> (Less than 3 digits) |
|||
-1 -> (Less than 3 digits) |
|||
-10 -> (Less than 3 digits) |
|||
2002 -> (Even digit count) |
|||
-2002 -> (Even digit count) |
|||
0 -> (Less than 3 digits)</pre> |
|||
=={{header|jq}}== |
=={{header|jq}}== |
||
< |
<syntaxhighlight lang="jq">def middle3: |
||
if . < 0 then -. else . end |
if . < 0 then -. else . end |
||
| tostring as $s |
| tostring as $s |
||
Line 2,647: | Line 3,812: | ||
(123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0) |
(123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0) |
||
| "\(.) => \( .|middle3 )"</ |
| "\(.) => \( .|middle3 )"</syntaxhighlight> |
||
Typescript:< |
Typescript:<syntaxhighlight lang="sh"> $ jq -r -n -f Middle_three_digits.jq |
||
123 => 123 |
123 => 123 |
||
12345 => 234 |
12345 => 234 |
||
Line 2,665: | Line 3,830: | ||
2002 => invalid length: 4 |
2002 => invalid length: 4 |
||
-2002 => invalid length: 4 |
-2002 => invalid length: 4 |
||
0 => invalid length: 1 </ |
0 => invalid length: 1 </syntaxhighlight> |
||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
{{works with|Julia|0. |
{{works with|Julia|1.0.3}} |
||
<syntaxhighlight lang="julia">using Printf |
|||
<lang julia>function middle3(n::Integer) |
|||
s = dec(abs(n)) |
|||
function middle3(n::Integer) |
|||
l = length(s) |
|||
l = ndigits(n) |
|||
iseven(l) && error("n must have an odd number of digits") |
|||
l < 3 && error("n must have 3 digits or more") |
|||
elseif l < 3 |
|||
throw(ArgumentError("n must have 3 digits or more")) |
|||
end |
|||
mid = (l + 1) ÷ 2 |
mid = (l + 1) ÷ 2 |
||
abs(n) ÷ 10^(mid-2) % 10^3 |
|||
end |
end |
||
Line 2,684: | Line 3,848: | ||
-100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0] |
-100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0] |
||
@printf("%10d -> %s\n", n, try middle3(n) catch e e.msg end) |
@printf("%10d -> %s\n", n, try middle3(n) catch e e.msg end) |
||
end</ |
end</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,704: | Line 3,868: | ||
-2002 -> n must have an odd number of digits |
-2002 -> n must have an odd number of digits |
||
0 -> n must have 3 digits or more</pre> |
0 -> n must have 3 digits or more</pre> |
||
=={{header|K}}== |
|||
<syntaxhighlight lang="k"> |
|||
/ Rosetta code - Middle three digits |
|||
/ mid3.k |
|||
mid3: {qs:$x;:[qs[0]="-";qs: 1 _ qs];:[(#qs)<3;:"small";(1+#qs)!2;:"even"];p:(-3+#qs)%2;:(|p _|p _ qs)} |
|||
</syntaxhighlight> |
|||
The output of the session: |
|||
{{out}} |
|||
<pre> |
|||
K Console - Enter \ for help |
|||
\l mid3 |
|||
mid3' 123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 1 2 -1 -10 |
|||
2002 -2002 0 |
|||
("123" |
|||
"234" |
|||
"345" |
|||
"654" |
|||
"000" |
|||
"000" |
|||
"123" |
|||
"100" |
|||
"100" |
|||
"234" |
|||
"small" |
|||
"small" |
|||
"small" |
|||
"small" |
|||
"even" |
|||
"even" |
|||
"small") |
|||
</pre> |
|||
=={{header|Klingphix}}== |
|||
<syntaxhighlight lang="klingphix">include ..\Utilitys.tlhy |
|||
( 123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 1 2 -1 -10 2002 -2002 0 ) |
|||
len [ |
|||
get ( dup " : " ) lprint |
|||
abs tostr len >ps |
|||
tps 3 < ( ["too short" ?] |
|||
[ tps 2 mod ( [tps 2 / 3 slice ?] ["is even" ?] ) if] |
|||
) if |
|||
ps> drop drop |
|||
] for |
|||
" " input |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre>123 : 123 |
|||
12345 : 234 |
|||
1234567 : 345 |
|||
987654321 : 654 |
|||
10001 : 000 |
|||
-10001 : 000 |
|||
-123 : 123 |
|||
-100 : 100 |
|||
100 : 100 |
|||
-12345 : 234 |
|||
1 : too short |
|||
2 : too short |
|||
-1 : too short |
|||
-10 : too short |
|||
2002 : is even |
|||
-2002 : is even |
|||
0 : too short</pre> |
|||
=={{header|Klong}}== |
=={{header|Klong}}== |
||
< |
<syntaxhighlight lang="k">items::[123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 1 2 -1 -10 2002 -2002 0] |
||
mid3::{[d k];:[3>k::#$#x;"small":|0=k!2;"even";(-d)_(d::_(k%2)-1)_$#x]} |
mid3::{[d k];:[3>k::#$#x;"small":|0=k!2;"even";(-d)_(d::_(k%2)-1)_$#x]} |
||
.p(mid3'items)</ |
.p(mid3'items)</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>[123 234 345 654 000 000 123 100 100 234 small small small small even even small]</pre> |
<pre>[123 234 345 654 000 000 123 100 100 234 small small small small even even small]</pre> |
||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
< |
<syntaxhighlight lang="scala">fun middleThree(x: Int): Int? { |
||
val s = Math.abs(x).toString() |
val s = Math.abs(x).toString() |
||
return when { |
return when { |
||
Line 2,729: | Line 3,962: | ||
println(middleThree(123))// 123 |
println(middleThree(123))// 123 |
||
println(middleThree(123555)) //null |
println(middleThree(123555)) //null |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Lambdatalk}}== |
|||
<syntaxhighlight lang="scheme"> |
|||
{def S 123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 |
|||
1 2 -1 -10 2002 -2002 0} |
|||
-> S |
|||
{def middle3digits |
|||
{lambda {:w} |
|||
{let { {:w {abs :w}} |
|||
{:l {W.length {abs :w}}} |
|||
} {if {= {% :l 2} 0} |
|||
then has an even number of digits |
|||
else {if {< :l 3} |
|||
then has not enough digits |
|||
else {W.get {- {/ :l 2} 1} :w} |
|||
{W.get {/ :l 2} :w} |
|||
{W.get {+ {/ :l 2} 1} :w} }}}}} |
|||
-> middle3digits |
|||
{table |
|||
{S.map {lambda {:i} |
|||
{tr {td {@ style="text-align:right;"}:i:} |
|||
{td {middle3digits :i}}}} |
|||
{S}} } |
|||
-> |
|||
123: 123 |
|||
12345: 234 |
|||
1234567: 345 |
|||
987654321: 654 |
|||
10001: 000 |
|||
-10001: 000 |
|||
-123: 123 |
|||
-100: 100 |
|||
100: 100 |
|||
-12345: 234 |
|||
1: has not enough digits |
|||
2: has not enough digits |
|||
-1: has not enough digits |
|||
-10: has an even number of digits |
|||
2002: has an even number of digits |
|||
-2002: has an even number of digits |
|||
0: has not enough digits |
|||
</syntaxhighlight> |
|||
=={{header|Lasso}}== |
=={{header|Lasso}}== |
||
< |
<syntaxhighlight lang="lasso">define middlethree(value::integer) => { |
||
local( |
local( |
||
pos_value = math_abs(#value), |
pos_value = math_abs(#value), |
||
Line 2,753: | Line 4,031: | ||
'<br />' |
'<br />' |
||
^} |
^} |
||
'</pre>'</ |
'</pre>'</syntaxhighlight> |
||
'''Output''' |
'''Output''' |
||
<pre> 123: 123 |
<pre> 123: 123 |
||
Line 2,774: | Line 4,052: | ||
=={{header|Logo}}== |
=={{header|Logo}}== |
||
< |
<syntaxhighlight lang="logo">to middle3digits :n |
||
if [less? :n 0] [make "n minus :n] |
if [less? :n 0] [make "n minus :n] |
||
local "len make "len count :n |
local "len make "len count :n |
||
Line 2,792: | Line 4,070: | ||
] |
] |
||
bye</ |
bye</syntaxhighlight> |
||
{{Output}} |
{{Output}} |
||
Line 2,814: | Line 4,092: | ||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
< |
<syntaxhighlight lang="lua">function middle_three(n) |
||
if n < 0 then |
if n < 0 then |
||
n = -n |
n = -n |
||
Line 2,839: | Line 4,117: | ||
print(n, middle_three(n)) |
print(n, middle_three(n)) |
||
end |
end |
||
end</ |
end</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,861: | Line 4,139: | ||
=={{header|Maple}}== |
=={{header|Maple}}== |
||
< |
<syntaxhighlight lang="maple">middleDigits := proc(n) |
||
local nList, start; |
local nList, start; |
||
nList := [seq(parse(i), i in convert (abs(n), string))]; |
nList := [seq(parse(i), i in convert (abs(n), string))]; |
||
Line 2,879: | Line 4,157: | ||
middleDigits(i); |
middleDigits(i); |
||
printf("\n"); |
printf("\n"); |
||
end do;</ |
end do;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,901: | Line 4,179: | ||
</pre> |
</pre> |
||
=={{header|Mathematica}}== |
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
||
< |
<syntaxhighlight lang="mathematica">middleThree[n_Integer] := |
||
Block[{digits = IntegerDigits[n], len}, |
Block[{digits = IntegerDigits[n], len}, |
||
len = Length[digits]; |
len = Length[digits]; |
||
Line 2,912: | Line 4,190: | ||
100, -12345, 1, 2, -1, -10, 2002, -2002, 0}; |
100, -12345, 1, 2, -1, -10, 2002, -2002, 0}; |
||
Column[middleThree /@ testData]</ |
Column[middleThree /@ testData]</syntaxhighlight> |
||
{{out}}<pre> |
{{out}}<pre>123 |
||
123 |
|||
234 |
234 |
||
345 |
345 |
||
Line 2,930: | Line 4,207: | ||
err: even number of digits |
err: even number of digits |
||
err: even number of digits |
err: even number of digits |
||
err: n too small |
err: n too small</pre> |
||
</pre> |
|||
=={{header|MATLAB}} / {{header|Octave}}== |
=={{header|MATLAB}} / {{header|Octave}}== |
||
< |
<syntaxhighlight lang="matlab">function s=middle_three_digits(a) |
||
% http://rosettacode.org/wiki/Middle_three_digits |
% http://rosettacode.org/wiki/Middle_three_digits |
||
Line 2,948: | Line 4,224: | ||
end; |
end; |
||
s = s((length(s)+1)/2+[-1:1]);</ |
s = s((length(s)+1)/2+[-1:1]);</syntaxhighlight> |
||
Test with |
Test with |
||
< |
<syntaxhighlight lang="matlab"> x=[123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0]; |
||
for k=1:length(x); fprintf(1,'%9i:%s\n',x(k),middle_three_digits(x(k)));end;</ |
for k=1:length(x); fprintf(1,'%9i:%s\n',x(k),middle_three_digits(x(k)));end;</syntaxhighlight> |
||
Result |
Result |
||
<pre> |
<pre> |
||
Line 2,972: | Line 4,248: | ||
0:*** error: number of digits must not be smaller than 3 *** |
0:*** error: number of digits must not be smaller than 3 *** |
||
</pre> |
</pre> |
||
=={{header|MiniScript}}== |
|||
<syntaxhighlight lang="miniscript">middle3 = function(num) |
|||
if num < 0 then num = -num |
|||
s = str(num) |
|||
if s.len < 3 then return "Input too short" |
|||
if s.len % 2 == 0 then return "Input length not odd" |
|||
mid = (s.len + 1) / 2 - 1 |
|||
return s[mid-1:mid+2] |
|||
end function |
|||
for test in [123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, |
|||
100, -12345, 1, 2, -1, -10, 2002, -2002, 0] |
|||
print test + " --> " + middle3(test) |
|||
end for</syntaxhighlight> |
|||
{{out}} |
|||
<pre>123 --> 123 |
|||
12345 --> 234 |
|||
1234567 --> 345 |
|||
987654321 --> 654 |
|||
10001 --> 000 |
|||
-10001 --> 000 |
|||
-123 --> 123 |
|||
-100 --> 100 |
|||
100 --> 100 |
|||
-12345 --> 234 |
|||
1 --> Input too short |
|||
2 --> Input too short |
|||
-1 --> Input too short |
|||
-10 --> Input too short |
|||
2002 --> Input length not odd |
|||
-2002 --> Input length not odd |
|||
0 --> Input too short</pre> |
|||
=={{header|МК-61/52}}== |
=={{header|МК-61/52}}== |
||
<lang>П0 lg [x] 3 - x>=0 23 ИП0 1 0 |
<syntaxhighlight lang="text">П0 lg [x] 3 - x>=0 23 ИП0 1 0 |
||
/ [x] ^ lg [x] 10^x П1 / {x} ИП1 |
/ [x] ^ lg [x] 10^x П1 / {x} ИП1 |
||
* БП 00 1 + x=0 29 ИП0 С/П 0 |
* БП 00 1 + x=0 29 ИП0 С/П 0 |
||
/</ |
/</syntaxhighlight> |
||
''Instruction:'' enter the number in the РX (on display), the result after the execution of the same. In the case of an even or less than 3 number of digits the indicator displays an error message. |
''Instruction:'' enter the number in the РX (on display), the result after the execution of the same. In the case of an even or less than 3 number of digits the indicator displays an error message. |
||
Line 2,983: | Line 4,292: | ||
=={{header|ML}}== |
=={{header|ML}}== |
||
==={{header|mLite}}=== |
==={{header|mLite}}=== |
||
< |
<syntaxhighlight lang="ocaml"> |
||
val test_array = ["123","12345","1234567","987654321","10001","~10001","~123","~100","100","~12345","1","2","~1","~10","2002","~2002","0"]; |
val test_array = ["123","12345","1234567","987654321","10001","~10001","~123","~100","100","~12345","1","2","~1","~10","2002","~2002","0"]; |
||
Line 3,008: | Line 4,317: | ||
; |
; |
||
map (println o middleThreeDigits) test_array;</ |
map (println o middleThreeDigits) test_array;</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>123 --> 123 |
<pre>123 --> 123 |
||
Line 3,030: | Line 4,339: | ||
=={{header|MUMPS}}== |
=={{header|MUMPS}}== |
||
This sample shows the MUMPS code required to pass the specification. |
This sample shows the MUMPS code required to pass the specification. |
||
< |
<syntaxhighlight lang="mumps">/* MUMPS */ |
||
MID3(N) ; |
MID3(N) ; |
||
N LEN,N2 |
N LEN,N2 |
||
Line 3,040: | Line 4,349: | ||
F I=123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345,1,2,-1,-10,2002,-2002,0 W !,$J(I,10),": ",$$MID3^MID3(I) |
F I=123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345,1,2,-1,-10,2002,-2002,0 W !,$J(I,10),": ",$$MID3^MID3(I) |
||
</syntaxhighlight> |
|||
</lang> |
|||
'''Output:''' |
'''Output:''' |
||
<pre> |
<pre> |
||
Line 3,064: | Line 4,373: | ||
=={{header|NetRexx}}== |
=={{header|NetRexx}}== |
||
This sample goes the extra mile and provides a method that can display the middle N digits from the input value. To satisfy the requirements of this task, a static invocation of this general method is also provided with the value '''<tt>3</tt>''' hard coded as the digit count. |
This sample goes the extra mile and provides a method that can display the middle N digits from the input value. To satisfy the requirements of this task, a static invocation of this general method is also provided with the value '''<tt>3</tt>''' hard coded as the digit count. |
||
< |
<syntaxhighlight lang="netrexx">/* NetRexx */ |
||
options replace format comments java crossref symbols nobinary |
options replace format comments java crossref symbols nobinary |
||
Line 3,110: | Line 4,419: | ||
end |
end |
||
return text |
return text |
||
</syntaxhighlight> |
|||
</lang> |
|||
'''Output:''' |
'''Output:''' |
||
<pre> |
<pre> |
||
Line 3,140: | Line 4,449: | ||
=={{header|NewLISP}}== |
=={{header|NewLISP}}== |
||
<syntaxhighlight lang="newlisp"> |
|||
<lang NewLISP> |
|||
(define (middle3 x) |
(define (middle3 x) |
||
(if (even? (length x)) |
(if (even? (length x)) |
||
Line 3,152: | Line 4,461: | ||
(map middle3 lst) |
(map middle3 lst) |
||
</syntaxhighlight> |
|||
</lang> |
|||
'''Output:''' |
'''Output:''' |
||
<pre> |
<pre> |
||
Line 3,175: | Line 4,484: | ||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
<syntaxhighlight lang="nim">proc middleThreeDigits(i: int): string = |
|||
<lang nim>import math |
|||
proc middleThreeDigits(i): auto = |
|||
var s = $abs(i) |
var s = $abs(i) |
||
if s.len < 3 or s.len mod 2 == 0: |
if s.len < 3 or s.len mod 2 == 0: |
||
Line 3,183: | Line 4,490: | ||
let mid = s.len div 2 |
let mid = s.len div 2 |
||
return s[mid-1..mid+1] |
return s[mid-1..mid+1] |
||
const passing = @[123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345] |
const passing = @[123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345] |
||
const failing = @[1, 2, -1, -10, 2002, -2002, 0] |
const failing = @[1, 2, -1, -10, 2002, -2002, 0] |
||
for i in passing & failing: |
for i in passing & failing: |
||
var answer = try: middleThreeDigits(i) |
var answer = try: middleThreeDigits(i) |
||
except ValueError: getCurrentExceptionMsg() |
except ValueError: getCurrentExceptionMsg() |
||
echo "middleThreeDigits(",i,") returned: ",answer</ |
echo "middleThreeDigits(", i, ") returned: ", answer</syntaxhighlight> |
||
Output: |
|||
{{out}} |
|||
<pre>middleThreeDigits(123) returned: 123 |
<pre>middleThreeDigits(123) returned: 123 |
||
middleThreeDigits(12345) returned: 234 |
middleThreeDigits(12345) returned: 234 |
||
Line 3,211: | Line 4,519: | ||
=={{header|Objeck}}== |
=={{header|Objeck}}== |
||
< |
<syntaxhighlight lang="objeck"> |
||
class Test { |
class Test { |
||
function : Main(args : String[]) ~ Nil { |
function : Main(args : String[]) ~ Nil { |
||
Line 3,224: | Line 4,532: | ||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
<pre> |
<pre> |
||
Line 3,248: | Line 4,556: | ||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
< |
<syntaxhighlight lang="ocaml">let even x = (x land 1) <> 1 |
||
let middle_three_digits x = |
let middle_three_digits x = |
||
Line 3,272: | Line 4,580: | ||
print_endline "Should fail:"; |
print_endline "Should fail:"; |
||
List.iter print failing; |
List.iter print failing; |
||
;;</ |
;;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,300: | Line 4,608: | ||
=={{header|Oforth}}== |
=={{header|Oforth}}== |
||
< |
<syntaxhighlight lang="oforth">: middle3 |
||
| s sz | |
| s sz | |
||
abs asString dup ->s size ->sz |
abs asString dup ->s size ->sz |
||
sz 3 < ifTrue: [ "Too short" println return ] |
sz 3 < ifTrue: [ "Too short" println return ] |
||
sz isEven ifTrue: [ "Not odd number of digits" println return ] |
sz isEven ifTrue: [ "Not odd number of digits" println return ] |
||
sz 3 - 2 / 1+ dup 2 + s extract ;</ |
sz 3 - 2 / 1+ dup 2 + s extract ;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,324: | Line 4,632: | ||
=={{header|PARI/GP}}== |
=={{header|PARI/GP}}== |
||
{{works with|PARI/GP|2.6.0}} |
{{works with|PARI/GP|2.6.0}} |
||
< |
<syntaxhighlight lang="parigp">middle(n)=my(v=digits(n));if(#v>2&&#v%2,100*v[#v\2]+10*v[#v\2+1]+v[#v\2+2],"no middle 3 digits"); |
||
apply(middle,[123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0])</ |
apply(middle,[123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0])</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>%1 = [123, 234, 345, 654, 0, 0, 123, 100, 100, 234, "no middle 3 digits", "no middle 3 digits", "no middle 3 digits", "no middle 3 digits", "no middle 3 digits", "no middle 3 digits", "no middle 3 digits"]</pre> |
<pre>%1 = [123, 234, 345, 654, 0, 0, 123, 100, 100, 234, "no middle 3 digits", "no middle 3 digits", "no middle 3 digits", "no middle 3 digits", "no middle 3 digits", "no middle 3 digits", "no middle 3 digits"]</pre> |
||
If for some reason you want to see the leading digits, you can run |
If for some reason you want to see the leading digits, you can run |
||
< |
<syntaxhighlight lang="parigp">apply(n-> Strprintf("%03d", n), %)</syntaxhighlight> |
||
For earlier versions <code>digits</code> can be defined as |
For earlier versions <code>digits</code> can be defined as |
||
< |
<syntaxhighlight lang="parigp">digits(n)=eval(Vec(Str(n)))</syntaxhighlight> |
||
or more efficiently as |
or more efficiently as |
||
< |
<syntaxhighlight lang="parigp">digits(n)=Vec(apply(n->n-48,Vectorsmall(Str(n))))</syntaxhighlight> |
||
=={{header|Pascal}}== |
=={{header|Pascal}}== |
||
{{works with|Free Pascal}} |
{{works with|Free Pascal}} |
||
< |
<syntaxhighlight lang="pascal">program Midl3dig; |
||
{$IFDEF FPC} |
{$IFDEF FPC} |
||
{$MODE Delphi} //result /integer => Int32 aka longInt etc.. |
{$MODE Delphi} //result /integer => Int32 aka longInt etc.. |
||
Line 3,374: | Line 4,683: | ||
writeln(n:9,': ',GetMid3dig(Test[i])); |
writeln(n:9,': ',GetMid3dig(Test[i])); |
||
end; |
end; |
||
end.</ |
end.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> 123: 123 |
<pre> 123: 123 |
||
Line 3,394: | Line 4,703: | ||
0: got too few digits |
0: got too few digits |
||
</pre> |
</pre> |
||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
< |
<syntaxhighlight lang="perl">#!/usr/bin/perl |
||
use strict ; |
use strict ; |
||
use warnings ; |
use warnings ; |
||
Line 3,420: | Line 4,730: | ||
1, 2, -1, -10, 2002, -2002, 0 ) ; |
1, 2, -1, -10, 2002, -2002, 0 ) ; |
||
map { middlethree( $_ ) } @numbers ; |
map { middlethree( $_ ) } @numbers ; |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre>Middle 3 digits of 123 : 123 ! |
<pre>Middle 3 digits of 123 : 123 ! |
||
Line 3,440: | Line 4,750: | ||
Middle 3 digits can't be shown : 0 too short! |
Middle 3 digits can't be shown : 0 too short! |
||
</pre> |
</pre> |
||
=={{header|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> |
|||
{{out}} |
|||
<pre>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</pre> |
|||
It is also possible to write a regular expression with a code assertion: |
|||
<lang perl6>for [\~] ^10 { say "$_ => $()" if m/^^(\d+) <(\d**3)> (\d+) $$ <?{ $0.chars == $1.chars}> / }</lang> |
|||
{{out}} |
|||
<pre>01234 => 123 |
|||
0123456 => 234 |
|||
012345678 => 345</pre> |
|||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
<!--<syntaxhighlight lang="phix">(phixonline)--> |
|||
<lang Phix>procedure mid3(integer i) |
|||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">mid3</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">)</span> |
|||
string s = sprintf("%d",abs(i)) |
|||
<span style="color: #004080;">string</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%d"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">))</span> |
|||
integer k = length(s)-3 |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">3</span> |
|||
printf(1,"%10d: %s\n",{i,iff(k<0 or and_bits(k,1)?"error":s[k/2+1..k/2+3])}) |
|||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%10d: %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">k</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">or</span> <span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">k</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)?</span><span style="color: #008000;">"error"</span><span style="color: #0000FF;">:</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">k</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">+</span><span style="color: #000000;">3</span><span style="color: #0000FF;">])})</span> |
|||
end procedure |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span> |
|||
constant tests = {123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345, |
|||
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">123</span><span style="color: #0000FF;">,</span><span style="color: #000000;">12345</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1234567</span><span style="color: #0000FF;">,</span><span style="color: #000000;">987654321</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10001</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">10001</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">123</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">100</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">12345</span><span style="color: #0000FF;">,</span> |
|||
1,2,-1,-10,2002,-2002,0} |
|||
<span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2002</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">2002</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">}</span> |
|||
for i=1 to length(tests) do |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
mid3(tests[i]) |
|||
<span style="color: #000000;">mid3</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span> |
|||
end for</lang> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<!--</syntaxhighlight>--> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,514: | Line 4,787: | ||
=={{header|PHP}}== |
=={{header|PHP}}== |
||
< |
<syntaxhighlight lang="php">// 32-bit builds of PHP: Integers can be from -2147483648 to 2147483647 |
||
// 64-bit builds of PHP: Integers can be from -9223372036854775808 to 9223372036854775807 |
// 64-bit builds of PHP: Integers can be from -9223372036854775808 to 9223372036854775807 |
||
Line 3,552: | Line 4,825: | ||
{ |
{ |
||
echo $nums.' : '.middlethree($nums). '<br>'; |
echo $nums.' : '.middlethree($nums). '<br>'; |
||
}</ |
}</syntaxhighlight> |
||
Output: |
Output: |
||
<pre>123 : 123 |
<pre>123 : 123 |
||
Line 3,571: | Line 4,844: | ||
-2002 : The value must contain an odd amount of digits... |
-2002 : The value must contain an odd amount of digits... |
||
0 : The value must contain at least three digits...</pre> |
0 : The value must contain at least three digits...</pre> |
||
=={{header|Picat}}== |
|||
===Prolog-style=== |
|||
{{trans|Prolog}} |
|||
<syntaxhighlight lang="picat">get_middle_f1(Str) = [X,Y,Z] => |
|||
append(Pre,[X,Y,Z],Post,Str), |
|||
length(Pre) = length(Post).</syntaxhighlight> |
|||
===List slice=== |
|||
<syntaxhighlight lang="picat">get_middle_f2(Str) = Str[Mid-1..Mid+1] => |
|||
Mid = 1 + Str.len div 2.</syntaxhighlight> |
|||
===Test=== |
|||
<syntaxhighlight lang="picat">go => |
|||
Success = [123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345], |
|||
Fail = [1, 2, -1, -10, 2002, -2002, 0], |
|||
All = Success ++ Fail, |
|||
test(All, get_middle_f1), |
|||
test(All, get_middle_f2). |
|||
% Test and check for exceptions |
|||
test(List,F) => |
|||
printf("\nTesting %w:\n", F), |
|||
foreach(N in List) |
|||
catch(Middle=apply(get_middle,N,F), E, printf("%d = exception %w\n",N,E)), |
|||
if E.var() then |
|||
println([n=N,middle=Middle]) |
|||
end |
|||
end, |
|||
nl. |
|||
% Check with the get_middle funcion F |
|||
get_middle(N,F) = apply(F,Str) => |
|||
Str = N.abs().to_string(), |
|||
Len = length(Str), |
|||
if Len mod 2 = 0 then throw $not_odd_length(N) |
|||
elseif Len < 3 then throw $number_too_small(N) |
|||
end.</syntaxhighlight> |
|||
{{out}} |
|||
<pre>[n = 123,middle = 123] |
|||
[n = 12345,middle = 234] |
|||
[n = 1234567,middle = 345] |
|||
[n = 987654321,middle = 654] |
|||
[n = 10001,middle = 000] |
|||
[n = -10001,middle = 000] |
|||
[n = -123,middle = 123] |
|||
[n = -100,middle = 100] |
|||
[n = 100,middle = 100] |
|||
[n = -12345,middle = 234] |
|||
[n = 1,exception = number_too_small(1)] |
|||
[n = 2,exception = number_too_small(2)] |
|||
[n = -1,exception = number_too_small(-1)] |
|||
[n = -10,exception = not_odd_length(-10)] |
|||
[n = 2002,exception = not_odd_length(2002)] |
|||
[n = -2002,exception = not_odd_length(-2002)] |
|||
[n = 0,exception = number_too_small(0)]</pre> |
|||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
< |
<syntaxhighlight lang="picolisp">(de middle3digits (N) |
||
(let (Lst (chop (abs N)) Len (length Lst)) |
(let (Lst (chop (abs N)) Len (length Lst)) |
||
(tab (10 -2 -30) |
(tab (10 -2 -30) |
||
Line 3,582: | Line 4,913: | ||
((bit? 1 Len) |
((bit? 1 Len) |
||
(head 3 (nth Lst (/ Len 2))) ) |
(head 3 (nth Lst (/ Len 2))) ) |
||
(T "even number of digits") ) ) ) )</ |
(T "even number of digits") ) ) ) )</syntaxhighlight> |
||
Test: |
Test: |
||
< |
<syntaxhighlight lang="picolisp">(mapc middle3digits |
||
(123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 |
(123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 |
||
1 2 -1 -10 2002 -2002 0 ) )</ |
1 2 -1 -10 2002 -2002 0 ) )</syntaxhighlight> |
||
Output: |
Output: |
||
<pre> 123: 123 |
<pre> 123: 123 |
||
Line 3,605: | Line 4,936: | ||
-2002: even number of digits |
-2002: even number of digits |
||
0: not enough digits</pre> |
0: not enough digits</pre> |
||
=={{header|Pike}}== |
|||
{{trans|PHP}} |
|||
<syntaxhighlight lang="pike">string middlethree(int i) { |
|||
i = abs(i); |
|||
int length = sizeof((string)i); |
|||
if(length >= 3) { |
|||
if(length % 2 == 1) { |
|||
int middle = (int)floor(length / 2) - 1; |
|||
return(((string)i)[middle..middle+2]); |
|||
} |
|||
else { |
|||
return "The value must contain an odd amount of digits..."; |
|||
} |
|||
} |
|||
else { |
|||
return "The value must contain at least three digits..."; |
|||
} |
|||
} |
|||
int main() { |
|||
array(int) numbers = ({123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0}); |
|||
foreach(numbers, int nums) { |
|||
write((string)nums + " : " + middlethree(nums) + "\n"); |
|||
} |
|||
return 0; |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>123 : 123 |
|||
12345 : 234 |
|||
1234567 : 345 |
|||
987654321 : 654 |
|||
10001 : 000 |
|||
-10001 : 000 |
|||
-123 : 123 |
|||
-100 : 100 |
|||
100 : 100 |
|||
-12345 : 234 |
|||
1 : The value must contain at least three digits... |
|||
2 : The value must contain at least three digits... |
|||
-1 : The value must contain at least three digits... |
|||
-10 : The value must contain at least three digits... |
|||
2002 : The value must contain an odd amount of digits... |
|||
-2002 : The value must contain an odd amount of digits... |
|||
0 : The value must contain at least three digits...</pre> |
|||
=={{header|PL/I}}== |
=={{header|PL/I}}== |
||
<syntaxhighlight lang="pl/i"> |
|||
<lang PL/I> |
|||
middle: procedure options (main); /* 29 October 2013 */ |
middle: procedure options (main); /* 29 October 2013 */ |
||
declare n fixed (15); |
declare n fixed (15); |
||
Line 3,632: | Line 5,011: | ||
end middle; |
end middle; |
||
</syntaxhighlight> |
|||
</lang> |
|||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 3,651: | Line 5,030: | ||
-2002 not possible |
-2002 not possible |
||
0 not possible |
0 not possible |
||
</pre> |
|||
=={{header|Plain English}}== |
|||
<syntaxhighlight lang="plainenglish">To run: |
|||
Start up. |
|||
Test 123. |
|||
Test 12345. |
|||
Test 1234567. |
|||
Test 987654321. |
|||
Test 10001. |
|||
Test -10001. |
|||
Test -123. |
|||
Test -100. |
|||
Test 100. |
|||
Test -12345. |
|||
Test 1. |
|||
Test 2. |
|||
Test -1. |
|||
Test -10. |
|||
Test 2002. |
|||
Test -2002. |
|||
Test 0. |
|||
Wait for the escape key. |
|||
Shut down. |
|||
To get the middle three digits of a number giving a string: |
|||
Privatize the number. |
|||
De-sign the number. |
|||
Convert the number to the string. |
|||
If the string's length is less than 3, put "Number has fewer than three digits" into the string; exit. |
|||
If the string's length is even, put "Number has no middle" into the string; exit. |
|||
Put the string's length divided by 2 into a midpoint number. |
|||
Slap a substring on the string. |
|||
Put the substring's first plus the midpoint minus 1 into the substring's first. |
|||
Put the substring's first plus 2 into the substring's last. |
|||
Put the substring into the string. |
|||
To test a number: |
|||
Get the middle three digits of the number giving a string. |
|||
Write "" then the number then " -> " then the string on the console.</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
123 -> 123 |
|||
12345 -> 234 |
|||
1234567 -> 345 |
|||
987654321 -> 654 |
|||
10001 -> 000 |
|||
-10001 -> 000 |
|||
-123 -> 123 |
|||
-100 -> 100 |
|||
100 -> 100 |
|||
-12345 -> 234 |
|||
1 -> Number has fewer than three digits |
|||
2 -> Number has fewer than three digits |
|||
-1 -> Number has fewer than three digits |
|||
-10 -> Number has fewer than three digits |
|||
2002 -> Number has no middle |
|||
-2002 -> Number has no middle |
|||
0 -> Number has fewer than three digits |
|||
</pre> |
</pre> |
||
=={{header|PowerShell}}== |
=={{header|PowerShell}}== |
||
< |
<syntaxhighlight lang="powershell">function middle3($inp){ |
||
$str = [Math]::abs($inp) |
$str = [Math]::abs($inp) |
||
Line 3,677: | Line 5,115: | ||
$sample = 123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0 |
$sample = 123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0 |
||
foreach ($x in $sample){middle3 $x}</ |
foreach ($x in $sample){middle3 $x}</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>123: 123 |
<pre>123: 123 |
||
Line 3,696: | Line 5,134: | ||
-2002: [ERROR] even number of digits. |
-2002: [ERROR] even number of digits. |
||
0: [ERROR] too short.</pre> |
0: [ERROR] too short.</pre> |
||
=={{header|Prolog}}== |
=={{header|Prolog}}== |
||
{{works with|SWI-Prolog|6}} |
{{works with|SWI-Prolog|6}} |
||
< |
<syntaxhighlight lang="prolog"> |
||
middle_3_digits(Number, [D1,D2,D3]) :- |
middle_3_digits(Number, [D1,D2,D3]) :- |
||
verify_middle_3_able(Number, Digits), |
verify_middle_3_able(Number, Digits), |
||
Line 3,716: | Line 5,153: | ||
; true |
; true |
||
). |
). |
||
</syntaxhighlight> |
|||
</lang> |
|||
Test code: |
Test code: |
||
< |
<syntaxhighlight lang="prolog"> |
||
test_correct :- |
test_correct :- |
||
TestCases = [123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345], |
TestCases = [123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345], |
||
Line 3,728: | Line 5,165: | ||
format('Middle 3 digits of ~w ~30|: ~w~n', [TestCase, Result]) |
format('Middle 3 digits of ~w ~30|: ~w~n', [TestCase, Result]) |
||
). |
). |
||
</syntaxhighlight> |
|||
</lang> |
|||
Line 3,767: | Line 5,204: | ||
=={{header|Python}}== |
=={{header|Python}}== |
||
===Procedural=== |
|||
<lang python>>>> def middle_three_digits(i): |
|||
<syntaxhighlight lang="python">>>> def middle_three_digits(i): |
|||
s = str(abs(i)) |
s = str(abs(i)) |
||
length = len(s) |
length = len(s) |
||
Line 3,801: | Line 5,239: | ||
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',) |
middle_three_digits(0) returned: AssertionError('Need odd and >= 3 digits',) |
||
>>> </ |
>>> </syntaxhighlight> |
||
===Composition of pure functions=== |
|||
Using a composable option type as an alternative to error handling: |
|||
{{Trans|Haskell}} |
|||
<syntaxhighlight lang="python">'''Middle 3 digits''' |
|||
# mid3digits :: Int -> Either String String |
|||
def mid3digits(n): |
|||
'''Either the middle three digits, |
|||
or an explanatory string.''' |
|||
m = abs(n) |
|||
s = str(m) |
|||
return Left('Less than 3 digits') if (100 > m) else ( |
|||
Left('Even digit count') if even(len(s)) else Right( |
|||
s[(len(s) - 3) // 2:][0:3] |
|||
) |
|||
) |
|||
# TEST ---------------------------------------------------- |
|||
def main(): |
|||
'''Test''' |
|||
def bracketed(x): |
|||
return '(' + str(x) + ')' |
|||
print( |
|||
tabulated('Middle three digits, where defined:\n')(str)( |
|||
either(bracketed)(str) |
|||
)(mid3digits)([ |
|||
123, 12345, 1234567, 987654321, 10001, -10001, -123, |
|||
-100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0 |
|||
]) |
|||
) |
|||
# GENERIC ------------------------------------------------- |
|||
# Left :: a -> Either a b |
|||
def Left(x): |
|||
'''Constructor for an empty Either (option type) value |
|||
with an associated string.''' |
|||
return {'type': 'Either', 'Right': None, 'Left': x} |
|||
# Right :: b -> Either a b |
|||
def Right(x): |
|||
'''Constructor for a populated Either (option type) value''' |
|||
return {'type': 'Either', 'Left': None, 'Right': x} |
|||
# compose (<<<) :: (b -> c) -> (a -> b) -> a -> c |
|||
def compose(g): |
|||
'''Function composition.''' |
|||
return lambda f: lambda x: g(f(x)) |
|||
# either :: (a -> c) -> (b -> c) -> Either a b -> c |
|||
def either(fl): |
|||
'''The application of fl to e if e is a Left value, |
|||
or the application of fr to e if e is a Right value.''' |
|||
return lambda fr: lambda e: fl(e['Left']) if ( |
|||
None is e['Right'] |
|||
) else fr(e['Right']) |
|||
# even :: Int -> Bool |
|||
def even(x): |
|||
'''Is x even ?''' |
|||
return 0 == x % 2 |
|||
# tabulated :: String -> (b -> String) -> (a -> b) -> [a] -> String |
|||
def tabulated(s): |
|||
'''Heading -> x display function -> fx display function -> |
|||
f -> value list -> tabular string.''' |
|||
def go(xShow, fxShow, f, xs): |
|||
w = max(map(compose(len)(str), xs)) |
|||
return s + '\n' + '\n'.join( |
|||
xShow(x).rjust(w, ' ') + ' -> ' + fxShow(f(x)) for x in xs |
|||
) |
|||
return lambda xShow: lambda fxShow: lambda f: lambda xs: go( |
|||
xShow, fxShow, f, xs |
|||
) |
|||
if __name__ == '__main__': |
|||
main()</syntaxhighlight> |
|||
{{Out}} |
|||
<pre>Middle three digits, where defined: |
|||
123 -> 123 |
|||
12345 -> 234 |
|||
1234567 -> 345 |
|||
987654321 -> 654 |
|||
10001 -> 000 |
|||
-10001 -> 000 |
|||
-123 -> 123 |
|||
-100 -> 100 |
|||
100 -> 100 |
|||
-12345 -> 234 |
|||
1 -> (Less than 3 digits) |
|||
2 -> (Less than 3 digits) |
|||
-1 -> (Less than 3 digits) |
|||
-10 -> (Less than 3 digits) |
|||
2002 -> (Even digit count) |
|||
-2002 -> (Even digit count) |
|||
0 -> (Less than 3 digits)</pre> |
|||
=={{header|Quackery}}== |
|||
<syntaxhighlight lang="quackery"> [ 1 & not ] is even ( n --> b ) |
|||
[ over size - |
|||
space swap of |
|||
swap join ] is justify ( $ n --> $ ) |
|||
[ abs number$ |
|||
dup size dup 3 < iff |
|||
[ 2drop $ "too few digits" ] |
|||
done |
|||
dup even iff |
|||
[ 2drop $ "even digit count" ] |
|||
done |
|||
dup 3 = iff |
|||
drop done |
|||
3 - 2 / |
|||
tuck split nip |
|||
swap negate split drop ] is middle3 ( n --> $ ) |
|||
' [ 123 12345 1234567 |
|||
987654321 10001 -10001 |
|||
-123 -100 100 -12345 1 |
|||
2 -1 -10 2002 -2002 0 ] |
|||
witheach |
|||
[ dup number$ 9 justify echo$ |
|||
say " --> " |
|||
middle3 echo$ cr ]</syntaxhighlight> |
|||
{{out}} |
|||
<pre> 123 --> 123 |
|||
12345 --> 234 |
|||
1234567 --> 345 |
|||
987654321 --> 654 |
|||
10001 --> 000 |
|||
-10001 --> 000 |
|||
-123 --> 123 |
|||
-100 --> 100 |
|||
100 --> 100 |
|||
-12345 --> 234 |
|||
1 --> too few digits |
|||
2 --> too few digits |
|||
-1 --> too few digits |
|||
-10 --> too few digits |
|||
2002 --> even digit count |
|||
-2002 --> even digit count |
|||
0 --> too few digits</pre> |
|||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
< |
<syntaxhighlight lang="scheme">#lang racket |
||
(define (middle x) |
(define (middle x) |
||
(cond |
(cond |
||
Line 3,817: | Line 5,416: | ||
(map middle (list 123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345)) |
(map middle (list 123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345)) |
||
(map middle (list 1 2 -1 -10 2002 -2002 0))</ |
(map middle (list 1 2 -1 -10 2002 -2002 0))</syntaxhighlight> |
||
The output: |
The output: |
||
< |
<syntaxhighlight lang="scheme">'("123" "234" "345" "654" "000" "000" "123" "100" "100" "234") |
||
'("error: number too small" "error: number too small" "error: number too small" "error: number too small" |
'("error: number too small" "error: number too small" "error: number too small" "error: number too small" |
||
"error: number has even length" "error: number has even length" "error: number too small")</ |
"error: number has even length" "error: number has even length" "error: number too small")</syntaxhighlight> |
||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
<syntaxhighlight lang="raku" line>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 |
|||
>;</syntaxhighlight> |
|||
{{out}} |
|||
<pre>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</pre> |
|||
It is also possible to write a regular expression with a code assertion: |
|||
<syntaxhighlight lang="raku" line>for [\~] ^10 { say "$_ => $()" if m/^^(\d+) <(\d**3)> (\d+) $$ <?{ $0.chars == $1.chars}> / }</syntaxhighlight> |
|||
{{out}} |
|||
<pre>01234 => 123 |
|||
0123456 => 234 |
|||
012345678 => 345</pre> |
|||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
===version 1=== |
===version 1=== |
||
< |
<syntaxhighlight lang="rexx">/* REXX *************************************************************** |
||
* 03.02.2013 Walter Pachl |
* 03.02.2013 Walter Pachl |
||
* 19.04.2013 mid 3 is now a function returning the middle 3 digits |
* 19.04.2013 mid 3 is now a function returning the middle 3 digits |
||
Line 3,852: | Line 5,491: | ||
End |
End |
||
End |
End |
||
Return res</ |
Return res</syntaxhighlight> |
||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 3,880: | Line 5,519: | ||
<br>So is the value of a '''googol''' and a '''googolplex'''. |
<br>So is the value of a '''googol''' and a '''googolplex'''. |
||
<br><br>This REXX version is limited to numbers whose length is <big>≤</big> 100,000 decimal digits. |
<br><br>This REXX version is limited to numbers whose length is <big>≤</big> 100,000 decimal digits. |
||
<br>(The decimal digits limit is defined via the '''numeric digits''' statement |
<br>(The decimal digits limit is defined via the '''numeric digits''' statement in the first line of the subroutine/procedure.) |
||
< |
<syntaxhighlight lang="rexx">/*REXX program returns the three middle digits of a decimal number (or an error msg).*/ |
||
n= '123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345', |
n= '123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345', |
||
'+123 0123 2 -1 -10 2002 -2002 0 abc 1e3 -17e-3 1234567.', |
'+123 0123 2 -1 -10 2002 -2002 0 abc 1e3 -17e-3 1234567.', |
||
Line 3,896: | Line 5,535: | ||
if L<3 then return er "argument is less than three digits." |
if L<3 then return er "argument is less than three digits." |
||
if L//2==0 then return er "argument isn't an odd number of digits." |
if L//2==0 then return er "argument isn't an odd number of digits." |
||
return substr(x, (L-3)%2+1, 3)</ |
return substr(x, (L-3)%2+1, 3)</syntaxhighlight> |
||
'''output''' |
'''output''' |
||
<pre> |
<pre> |
||
Line 3,926: | Line 5,565: | ||
=={{header|Ring}}== |
=={{header|Ring}}== |
||
< |
<syntaxhighlight lang="ring"> |
||
n = 1234567 |
n = 1234567 |
||
middle(n) |
middle(n) |
||
Line 3,937: | Line 5,576: | ||
but lennr%2=0 see "Number must have an odd number of digits" |
but lennr%2=0 see "Number must have an odd number of digits" |
||
else cnr = substr(string(nr),mnr,3) see cnr + nl ok |
else cnr = substr(string(nr),mnr,3) see cnr + nl ok |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|RPL}}== |
|||
Staying in the real world: no number/string conversion, -1 is returned if input is invalid. |
|||
{{works with|Halcyon Calc|4.2.7}} |
|||
≪ ABS DUP XPON |
|||
'''IF''' DUP 2 < OVER 2 MOD OR |
|||
'''THEN''' DROP2 -1 |
|||
'''ELSE''' 2 / 1 - ALOG / IP 1000 MOD |
|||
'''END''' |
|||
≫ '<span style="color:blue">→M3D</span>' STO |
|||
≪ { 123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 -10 2002} |
|||
→ tl |
|||
≪ { } |
|||
1 tl SIZE '''FOR''' j |
|||
tl j GET <span style="color:blue">→M3D</span> + |
|||
'''NEXT''' |
|||
≫ ≫ EVAL |
|||
{{out}} |
|||
<pre> |
|||
1: { 123 234 345 654 0 0 123 100 100 234 -1 -1 } |
|||
</pre> |
|||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
< |
<syntaxhighlight lang="ruby">def middle_three_digits(num) |
||
# minus sign doesn't factor into digit count, |
# minus sign doesn't factor into digit count, |
||
# and calling #abs acts as a duck-type assertion |
# and calling #abs acts as a duck-type assertion |
||
Line 3,954: | Line 5,615: | ||
return str[length/2 - 1, 3].to_i |
return str[length/2 - 1, 3].to_i |
||
end</ |
end</syntaxhighlight> |
||
Testing program: |
Testing program: |
||
< |
<syntaxhighlight lang="ruby">samples = [ |
||
123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, |
123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, |
||
1, 2, -1, -10, 2002, -2002, 0 |
1, 2, -1, -10, 2002, -2002, 0 |
||
Line 3,971: | Line 5,632: | ||
puts e |
puts e |
||
end |
end |
||
end</ |
end</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,994: | Line 5,655: | ||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
< |
<syntaxhighlight lang="rust">fn middle_three_digits(x: i32) -> Result<String, String> { |
||
let s: String = x.abs().to_string(); |
let s: String = x.abs().to_string(); |
||
let len = s.len(); |
let len = s.len(); |
||
Line 4,023: | Line 5,684: | ||
print_result(*i); |
print_result(*i); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
Line 4,059: | Line 5,720: | ||
course just list the numbers backwards. |
course just list the numbers backwards. |
||
</pre> |
</pre> |
||
< |
<syntaxhighlight lang="s-lang"> |
||
define m3(i) |
define m3(i) |
||
{ |
{ |
||
Line 4,089: | Line 5,750: | ||
#endif |
#endif |
||
1, 2, -1, -10, 2002, -2002, 0 } ); |
1, 2, -1, -10, 2002, -2002, 0 } ); |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}}<pre> |
{{out}}<pre> |
||
" 123: 123" |
" 123: 123" |
||
Line 4,113: | Line 5,774: | ||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
< |
<syntaxhighlight lang="scala">/** |
||
* Optionally return the middle three digits of an integer. |
* Optionally return the middle three digits of an integer. |
||
* |
* |
||
Line 4,134: | Line 5,795: | ||
case Some(v) => "%03d".format(v) // Format the value, force leading zeroes |
case Some(v) => "%03d".format(v) // Format the value, force leading zeroes |
||
} mkString("\n") |
} mkString("\n") |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre>123 |
<pre>123 |
||
Line 4,153: | Line 5,814: | ||
No middle three |
No middle three |
||
No middle three |
No middle three |
||
</pre> |
|||
=={{header|sed}}== |
|||
<syntaxhighlight lang="sed">h |
|||
s/^[-+]\{0,1\}0*\([1-9]\([0-9][0-9]\)\{1,\}\)$/\1/ |
|||
t l |
|||
s/$/ -> error!/ |
|||
b |
|||
:l |
|||
s/.\(.\{3,\}\)./\1/ |
|||
t l |
|||
x |
|||
G |
|||
s/\n/ -> /</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
$ printf "%s\n" -12345 -10001 -2002 -123 -100 -10 -1 0 1 2 100 123 2002 10001 12345 1234567 987654321 | sed -f middle_three_digits.sed |
|||
-12345 -> 234 |
|||
-10001 -> 000 |
|||
-2002 -> error! |
|||
-123 -> 123 |
|||
-100 -> 100 |
|||
-10 -> error! |
|||
-1 -> error! |
|||
0 -> error! |
|||
1 -> error! |
|||
2 -> error! |
|||
100 -> 100 |
|||
123 -> 123 |
|||
2002 -> error! |
|||
10001 -> 000 |
|||
12345 -> 234 |
|||
1234567 -> 345 |
|||
987654321 -> 654 |
|||
</pre> |
</pre> |
||
=={{header|Seed7}}== |
=={{header|Seed7}}== |
||
< |
<syntaxhighlight lang="seed7">$include "seed7_05.s7i"; |
||
const func string: middle3 (in integer: number) is func |
const func string: middle3 (in integer: number) is func |
||
Line 4,179: | Line 5,874: | ||
writeln(number <& ": " <& middle3(number)); |
writeln(number <& ": " <& middle3(number)); |
||
end for; |
end for; |
||
end func;</ |
end func;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 4,200: | Line 5,895: | ||
-2002: error |
-2002: error |
||
0: error |
0: error |
||
</pre> |
|||
=={{header|SenseTalk}}== |
|||
As a People Oriented Programming language, SenseTalk treats values in a fluid fashion. So although the calls to the middle3Digits handler pass an integer as the parameter, the handler itself treats the value as text, looking for occurrences of the text pattern <digit> in it. Similarly, the variable 'output' is initially set to a number, then becomes a text value when the middle digits are put into it at character position 15. |
|||
<syntaxhighlight lang="sensetalk">set inputs to [123, 12345, 1234567, 987654321, |
|||
10001, -10001, -123, -100, 100, -12345, |
|||
1, 2, -1, -10, 2002, -2002, 0] |
|||
repeat with each num in inputs |
|||
put num into output |
|||
put middle3digits of num into character 15 of output -- will autofill with "."s |
|||
put output |
|||
end repeat |
|||
to handle middle3digits of number |
|||
put every occurrence of <digit> in number into digits |
|||
if the number of items in digits is less than 3 then return "Error: too few digits" |
|||
if the number of items in digits is an even number then return "Error: even number of digits" |
|||
repeat while the number of items in digits is greater than 3 |
|||
delete the first item of digits |
|||
delete the last item of digits |
|||
end repeat |
|||
return digits joined by empty |
|||
end middle3digits |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
123...........123 |
|||
12345.........234 |
|||
1234567.......345 |
|||
987654321.....654 |
|||
10001.........000 |
|||
-10001........000 |
|||
-123..........123 |
|||
-100..........100 |
|||
100...........100 |
|||
-12345........234 |
|||
1.............Error: too few digits |
|||
2.............Error: too few digits |
|||
-1............Error: too few digits |
|||
-10...........Error: too few digits |
|||
2002..........Error: even number of digits |
|||
-2002.........Error: even number of digits |
|||
0.............Error: too few digits |
|||
</pre> |
</pre> |
||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
{{trans| |
{{trans|Raku}} |
||
< |
<syntaxhighlight lang="ruby">func middle_three(n) { |
||
var l = n.len |
var l = n.len |
||
if (l < 3) { |
if (l < 3) { |
||
"#{n} is too short" |
"#{n} is too short" |
||
Line 4,211: | Line 5,950: | ||
"#{n} has an even number of digits" |
"#{n} has an even number of digits" |
||
} else { |
} else { |
||
"The three middle digits of #{n} are: " + n.digits. |
"The three middle digits of #{n} are: " + n.digits.slice((l-3)/2).first(3).flip.join |
||
} |
} |
||
} |
} |
||
Line 4,218: | Line 5,957: | ||
123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 |
123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 |
||
1 2 -1 -10 2002 -2002 0 |
1 2 -1 -10 2002 -2002 0 |
||
) |
) |
||
nums.each { say middle_three(_) } |
nums.each { say middle_three(_) }</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 4,242: | Line 5,981: | ||
=={{header|SQL}}== |
=={{header|SQL}}== |
||
< |
<syntaxhighlight lang="sql">;WITH DATA |
||
AS (SELECT CAST(ABS(NUMBER) AS NVARCHAR(MAX)) charNum, |
AS (SELECT CAST(ABS(NUMBER) AS NVARCHAR(MAX)) charNum, |
||
NUMBER, |
NUMBER, |
||
Line 4,253: | Line 5,992: | ||
END Output, |
END Output, |
||
NUMBER Input |
NUMBER Input |
||
FROM DATA </ |
FROM DATA </syntaxhighlight> |
||
<pre> |
<pre> |
||
Line 4,282: | Line 6,021: | ||
</pre> |
</pre> |
||
=={{header|Swift}}== |
=={{header|Swift}}== |
||
< |
<syntaxhighlight lang="swift">var num:Int = \\enter your number here |
||
if num<0{num = -num} |
if num<0{num = -num} |
||
var numArray:[Int]=[] |
var numArray:[Int]=[] |
||
Line 4,298: | Line 6,038: | ||
i=i/2 |
i=i/2 |
||
print("\(numArray[i+1]),\(numArray[i]),\(numArray[i-1])") |
print("\(numArray[i+1]),\(numArray[i]),\(numArray[i-1])") |
||
}</ |
}</syntaxhighlight> |
||
<pre> |
<pre> |
||
123: 123 |
123: 123 |
||
Line 4,318: | Line 6,058: | ||
0: Invalid Input |
0: Invalid Input |
||
</pre> |
</pre> |
||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
< |
<syntaxhighlight lang="tcl">proc middleThree n { |
||
if {$n < 0} { |
if {$n < 0} { |
||
set n [expr {-$n}] |
set n [expr {-$n}] |
||
Line 4,334: | Line 6,073: | ||
set idx [expr {$idx / 2}] |
set idx [expr {$idx / 2}] |
||
string range $n $idx [expr {$idx+2}] |
string range $n $idx [expr {$idx+2}] |
||
}</ |
}</syntaxhighlight> |
||
Demonstrating: |
Demonstrating: |
||
< |
<syntaxhighlight lang="tcl">foreach n { |
||
123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 |
123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 |
||
1 2 -1 -10 2002 -2002 0 |
1 2 -1 -10 2002 -2002 0 |
||
Line 4,347: | Line 6,086: | ||
puts "found for ${n}: $mid" |
puts "found for ${n}: $mid" |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 4,369: | Line 6,108: | ||
</pre> |
</pre> |
||
=={{header|TI SR-56}}== |
|||
{| class="wikitable" |
|||
|+ Texas Instruments SR-56 Program Listing for "Middle three digits" |
|||
|- |
|||
! Display !! Key !! Display !! Key !! Display !! Key !! Display !! Key |
|||
|- |
|||
| 00 28 || <nowiki>*|x|</nowiki> || 25 54 || / || 50 || || 75 || |
|||
|- |
|||
| 01 33 || STO || 26 02 || 2 || 51 || || 76 || |
|||
|- |
|||
| 02 01 || 1 || 27 74 || - || 52 || || 77 || |
|||
|- |
|||
| 03 18 || *log || 28 01 || 1 || 53 || || 78 || |
|||
|- |
|||
| 04 29 || *Int || 29 53 || ) || 54 || || 79 || |
|||
|- |
|||
| 05 20 || *1/x || 30 19 || *10^x || 55 || || 80 || |
|||
|- |
|||
| 06 20 || *1/x || 31 94 || = || 56 || || 81 || |
|||
|- |
|||
| 07 33 || STO || 32 29 || *Int || 57 || || 82 || |
|||
|- |
|||
| 08 02 || 2 || 33 54 || / || 58 || || 83 || |
|||
|- |
|||
| 09 54 || / || 34 01 || 1 || 59 || || 84 || |
|||
|- |
|||
| 10 02 || 2 || 35 00 || 0 || 60 || || 85 || |
|||
|- |
|||
| 11 94 || = || 36 00 || 0 || 61 || || 86 || |
|||
|- |
|||
| 12 12 || INV || 37 00 || 0 || 62 || || 87 || |
|||
|- |
|||
| 13 29 || *Int || 38 94 || = || 63 || || 88 || |
|||
|- |
|||
| 14 74 || - || 39 12 || INV || 64 || || 89 || |
|||
|- |
|||
| 15 92 || . || 40 29 || *Int || 65 || || 90 || |
|||
|- |
|||
| 16 05 || 5 || 41 64 || * || 66 || || 91 || |
|||
|- |
|||
| 17 94 || = || 42 01 || 1 || 67 || || 92 || |
|||
|- |
|||
| 18 20 || *1/x || 43 00 || 0 || 68 || || 93 || |
|||
|- |
|||
| 19 34 || RCL || 44 00 || 0 || 69 || || 94 || |
|||
|- |
|||
| 20 01 || 1 || 45 00 || 0 || 70 || || 95 || |
|||
|- |
|||
| 21 54 || / || 46 94 || = || 71 || || 96 || |
|||
|- |
|||
| 22 52 || ( || 47 41 || R/S || 72 || || 97 || |
|||
|- |
|||
| 23 34 || RCL || 48 || || 73 || || 98 || |
|||
|- |
|||
| 24 02 || 2 || 49 || || 74 || || 99 || |
|||
|} |
|||
Asterisk denotes 2nd function key. |
|||
{| class="wikitable" |
|||
|+ Register allocation |
|||
|- |
|||
| 0: Unused || 1: Number || 2: Log || 3: Unused || 4: Unused |
|||
|- |
|||
| 5: Unused || 6: Unused || 7: Unused || 8: Unused || 9: Unused |
|||
|} |
|||
Annotated listing: |
|||
<syntaxhighlight lang="text"> |
|||
*|x| STO 1 // Number := |input| |
|||
*log *Int // #Digits - 1 |
|||
*1/x *1/x // Divide by zero if 1-digit number |
|||
STO 2 // Log := #Digits - 1 |
|||
/ 2 = INV *Int - . 5 = *1/x // Divide by zero if #Digits is even |
|||
RCL 1 / ( RCL 2 / 2 - 1 ) *10^x = // Shift appropriately |
|||
*Int / 1 0 0 0 = INV *Int * 1 0 0 0 = // Take the middle 3 digits |
|||
R/S // End |
|||
</syntaxhighlight> |
|||
'''Usage:''' |
|||
Enter the number and then press RST R/S. A flashing number indicates an error. |
|||
{{in}} |
|||
987654321 RST R/S |
|||
{{out}} |
|||
After about two seconds, '''654''' will appear on the screen. |
|||
{{in}} |
|||
12345 +/- RST R/S |
|||
{{out}} |
|||
After about two seconds, '''234''' will appear on the screen. |
|||
{{in}} |
|||
5 RST R/S |
|||
{{out}} |
|||
A flashing 9.999999999 99 appears on the screen indicating an error. |
|||
=={{header|Uiua}}== |
|||
{{Works with |Uiua|0.12.0-dev.1}} |
|||
Uses `assert` and `try` to handle the exceptions. |
|||
<syntaxhighlight lang="uiua"> |
|||
[123 12345 1234567 987654321 10001 ¯10001 ¯123 ¯100 100 ¯12345 |
|||
1 2 ¯1 ¯10 2002 ¯2002 0] |
|||
Mid ← ( |
|||
⍤("too short")≥3.⧻.°□°⋕⌵ |
|||
⍤("even length")≠0◿2. |
|||
↘¯⟜↘⌊÷2-3 |
|||
) |
|||
⍉⊟⟜≡⍚⍣(Mid|⊂"Error: "◌) # Convert each |
|||
≡(&p$"_\t->\t_"°⊟) # Display |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
123 -> 123 |
|||
12345 -> 234 |
|||
1234567 -> 345 |
|||
987654321 -> 654 |
|||
10001 -> 000 |
|||
-10001 -> 000 |
|||
-123 -> 123 |
|||
-100 -> 100 |
|||
100 -> 100 |
|||
-12345 -> 234 |
|||
1 -> Error: too short |
|||
2 -> Error: too short |
|||
-1 -> Error: too short |
|||
-10 -> Error: too short |
|||
2002 -> Error: even length |
|||
-2002 -> Error: even length |
|||
0 -> Error: too short |
|||
</pre> |
|||
=={{header|UNIX Shell}}== |
=={{header|UNIX Shell}}== |
||
{{works with|Bourne Again Shell}} |
{{works with|Bourne Again Shell}} |
||
Line 4,374: | Line 6,254: | ||
{{works with|Z Shell}} |
{{works with|Z Shell}} |
||
< |
<syntaxhighlight lang="bash">function middle3digits |
||
{ |
{ |
||
typeset -i n="${1#-}" |
typeset -i n="${1#-}" |
||
Line 4,396: | Line 6,276: | ||
printf "%10d: " $n |
printf "%10d: " $n |
||
middle3digits "$n" |
middle3digits "$n" |
||
done</ |
done</syntaxhighlight> |
||
Output: <pre> 123: 123 |
Output: <pre> 123: 123 |
||
Line 4,418: | Line 6,298: | ||
=={{header|VBA}}== |
=={{header|VBA}}== |
||
<syntaxhighlight lang="vb"> |
|||
<lang vb> |
|||
Option Explicit |
Option Explicit |
||
Line 4,440: | Line 6,320: | ||
End If |
End If |
||
End Function |
End Function |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre>123 Return : 123 |
<pre>123 Return : 123 |
||
Line 4,461: | Line 6,341: | ||
=={{header|VBScript}}== |
=={{header|VBScript}}== |
||
< |
<syntaxhighlight lang="vb">'http://rosettacode.org/wiki/Middle_three_digits |
||
Function mid3n(n) |
Function mid3n(n) |
||
Line 4,481: | Line 6,361: | ||
WScript.StdOut.Write n & ": " & mid3n(n) |
WScript.StdOut.Write n & ": " & mid3n(n) |
||
WScript.StdOut.WriteLine |
WScript.StdOut.WriteLine |
||
Next</ |
Next</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre> |
<pre> |
||
Line 4,504: | Line 6,384: | ||
=={{header|Vedit macro language}}== |
=={{header|Vedit macro language}}== |
||
< |
<syntaxhighlight lang="vedit">do { |
||
#1 = Get_Num("Enter a number, or 0 to stop: ", STATLINE) |
#1 = Get_Num("Enter a number, or 0 to stop: ", STATLINE) |
||
Ins_Text("Input: ") Num_Ins(#1, COUNT, 10) |
Ins_Text("Input: ") Num_Ins(#1, COUNT, 10) |
||
Line 4,532: | Line 6,412: | ||
} |
} |
||
Buf_Quit(OK) |
Buf_Quit(OK) |
||
Return </ |
Return </syntaxhighlight> |
||
Output: |
Output: |
||
Line 4,552: | Line 6,432: | ||
Input: -2002 Result: Not odd number of digits! |
Input: -2002 Result: Not odd number of digits! |
||
Input: 0 Result: Too few digits! </pre> |
Input: 0 Result: Too few digits! </pre> |
||
=={{header|V (Vlang)}}== |
|||
<syntaxhighlight lang="v (vlang)">import math |
|||
const |
|||
( |
|||
valid = [123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345] |
|||
invalid = [1, 2, -1, -10, 2002, -2002, 0] |
|||
) |
|||
fn main() { |
|||
for elem in valid {println(middle(elem))} |
|||
for elem in invalid {println(middle(elem))} |
|||
} |
|||
fn middle(num int) string { |
|||
mut strip := math.abs(num).str() |
|||
if strip.len < 3 {return 'Error: $num has less than 3 digits'} |
|||
if strip.len % 2 == 0 {return 'Error: $num has an even number of digits'} |
|||
start := (strip.len / 2) - 1 |
|||
return strip.substr(start, start + 3) |
|||
} |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
123 |
|||
234 |
|||
345 |
|||
654 |
|||
000 |
|||
000 |
|||
123 |
|||
100 |
|||
100 |
|||
234 |
|||
Error: 1 has less than 3 digits |
|||
Error: 2 has less than 3 digits |
|||
Error: -1 has less than 3 digits |
|||
Error: -10 has less than 3 digits |
|||
Error: 2002 has an even number of digits |
|||
Error: -2002 has an even number of digits |
|||
Error: 0 has less than 3 digits |
|||
</pre> |
|||
=={{header|Wart}}== |
=={{header|Wart}}== |
||
< |
<syntaxhighlight lang="wart">def (mid3 n) |
||
withs (digits (with outstring # itoa |
withs (digits (with outstring # itoa |
||
(pr abs.n)) |
(pr abs.n)) |
||
Line 4,561: | Line 6,486: | ||
mid (int max/2)) |
mid (int max/2)) |
||
if (and odd?.max (max >= 3)) |
if (and odd?.max (max >= 3)) |
||
(digits mid-1 mid+2)</ |
(digits mid-1 mid+2)</syntaxhighlight> |
||
'''Output''' |
'''Output''' |
||
Line 4,600: | Line 6,525: | ||
(mid3 0) |
(mid3 0) |
||
=> nil</pre> |
=> nil</pre> |
||
=={{header|Wren}}== |
|||
{{libheader|Wren-fmt}} |
|||
<syntaxhighlight lang="wren">import "./fmt" for Fmt |
|||
var middle3 = Fn.new { |n| |
|||
if (n < 0) n = -n |
|||
var s = "%(n)" |
|||
var c = s.count |
|||
if (c < 3) return "Minimum is 3 digits, only has %(c)." |
|||
if (c%2 == 0) return "Number of digits must be odd, %(c) is even." |
|||
if (c == 3) return s |
|||
var d = (c - 3)/2 |
|||
return s[d..d+2] |
|||
} |
|||
var a = [123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, |
|||
1, 2, -1, -10, 2002, -2002, 0] |
|||
for (e in a) { |
|||
Fmt.print("$9d -> $n", e, middle3.call(e)) |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
123 -> 123 |
|||
12345 -> 234 |
|||
1234567 -> 345 |
|||
987654321 -> 654 |
|||
10001 -> 000 |
|||
-10001 -> 000 |
|||
-123 -> 123 |
|||
-100 -> 100 |
|||
100 -> 100 |
|||
-12345 -> 234 |
|||
1 -> Minimum is 3 digits, only has 1. |
|||
2 -> Minimum is 3 digits, only has 1. |
|||
-1 -> Minimum is 3 digits, only has 1. |
|||
-10 -> Minimum is 3 digits, only has 2. |
|||
2002 -> Number of digits must be odd, 4 is even. |
|||
-2002 -> Number of digits must be odd, 4 is even. |
|||
0 -> Minimum is 3 digits, only has 1. |
|||
</pre> |
|||
=={{header|XPL0}}== |
=={{header|XPL0}}== |
||
< |
<syntaxhighlight lang="xpl0">include c:\cxpl\stdlib; |
||
func Mid3Digits(I); \Return the middle three digits of I |
func Mid3Digits(I); \Return the middle three digits of I |
||
Line 4,625: | Line 6,593: | ||
Text(0, Mid3Digits(Passing(X))); CrLf(0); |
Text(0, Mid3Digits(Passing(X))); CrLf(0); |
||
]; |
]; |
||
]</ |
]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 4,649: | Line 6,617: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
< |
<syntaxhighlight lang="zkl">fcn middle(ns){ |
||
ns.apply("toString").apply('-("-")) |
ns.apply("toString").apply('-("-")) |
||
.apply(fcn(n){nl:=n.len(); |
.apply(fcn(n){nl:=n.len(); |
||
Line 4,657: | Line 6,625: | ||
} |
} |
||
middle(T(123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345)).println() |
middle(T(123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345)).println() |
||
middle(T(1, 2, -1, -10, 2002, -2002, 0)).println();</ |
middle(T(1, 2, -1, -10, 2002, -2002, 0)).println();</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
Latest revision as of 19:03, 24 June 2024
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
- Task
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.
Note: The order of the middle digits should be preserved.
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.
11l
F middle_three_digits(i)
V s = String(abs(i))
assert(s.len >= 3 & s.len % 2 == 1, ‘Need odd and >= 3 digits’)
R s[s.len I/ 2 - 1 .+ 3]
V passing = [123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345]
V failing = [1, 2, -1, -10, 2002, -2002, 0]
L(x) passing [+] failing
X.try
V answer = middle_three_digits(x)
print(‘middle_three_digits(#.) returned: #.’.format(x, answer))
X.catch AssertionError error
print(‘middle_three_digits(#.) returned error: ’.format(x)‘’String(error))
- Output:
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 error: Need odd and >= 3 digits middle_three_digits(2) returned error: Need odd and >= 3 digits middle_three_digits(-1) returned error: Need odd and >= 3 digits middle_three_digits(-10) returned error: Need odd and >= 3 digits middle_three_digits(2002) returned error: Need odd and >= 3 digits middle_three_digits(-2002) returned error: Need odd and >= 3 digits middle_three_digits(0) returned error: Need odd and >= 3 digits
Action!
INCLUDE "H6:REALMATH.ACT"
INCLUDE "D2:PRINTF.ACT" ;from the Action! Tool Kit
PROC MiddleThreeDigits(REAL POINTER n CHAR ARRAY res)
REAL r
CHAR ARRAY s(15)
BYTE i
RealAbs(n,r)
StrR(r,s)
i=s(0)
IF i<3 OR (i&1)=0 THEN
res(0)=0
ELSE
i==RSH 1
SCopyS(res,s,i,i+2)
FI
RETURN
PROC Test(CHAR ARRAY s)
REAL n
CHAR ARRAY res(4)
ValR(s,n)
MiddleThreeDigits(n,res)
IF res(0) THEN
PrintF("%9S -> %S%E",s,res)
ELSE
PrintF("%9S -> error!%E",s)
FI
RETURN
PROC Main()
Put(125) PutE() ;clear the screen
Test("123") Test("12345")
Test("1234567") Test("987654321")
Test("10001") Test("-10001")
Test("-123") Test("-100")
Test("100") Test("-12345")
Test("1") Test("2")
Test("-1") Test("-10")
Test("2002") Test("-2002")
Test("0")
RETURN
- Output:
Screenshot from Atari 8-bit computer
123 -> 123 12345 -> 234 1234567 -> 345 987654321 -> 654 10001 -> 000 -10001 -> 000 -123 -> 123 -100 -> 100 100 -> 100 -12345 -> 234 1 -> error! 2 -> error! -1 -> error! -10 -> error! 2002 -> error! -2002 -> error! 0 -> error!
Ada
with Ada.Text_IO;
procedure Middle_Three_Digits is
Impossible: exception;
function Middle_String(I: Integer; Middle_Size: Positive) return String is
S: constant String := Integer'Image(I);
First: Natural := S'First;
Full_Size, Border: Natural;
begin
while S(First) not in '0' .. '9' loop -- skip leading blanks and minus
First := First + 1;
end loop;
Full_Size := S'Last-First+1;
if (Full_Size < Middle_Size) or (Full_Size mod 2 = 0) then
raise Impossible;
else
Border := (Full_Size - Middle_Size)/2;
return S(First+Border .. First+Border+Middle_Size-1);
end if;
end Middle_String;
Inputs: array(Positive range <>) of Integer :=
(123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345,
1, 2, -1, -10, 2002, -2002, 0);
Error_Message: constant String := "number of digits must be >= 3 and odd";
package IIO is new Ada.Text_IO.Integer_IO(Integer);
begin
for I in Inputs'Range loop
IIO.Put(Inputs(I), Width => 9);
Ada.Text_IO.Put(": ");
begin
Ada.Text_IO.Put(Middle_String(Inputs(I), 3));
exception
when Impossible => Ada.Text_IO.Put("****" & Error_Message & "****");
end;
Ada.Text_IO.New_Line;
end loop;
end Middle_Three_Digits;
- Output:
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: ****number of digits must be >= 3 and odd**** 2: ****number of digits must be >= 3 and odd**** -1: ****number of digits must be >= 3 and odd**** -10: ****number of digits must be >= 3 and odd**** 2002: ****number of digits must be >= 3 and odd**** -2002: ****number of digits must be >= 3 and odd**** 0: ****number of digits must be >= 3 and odd****
Aime
void
m3(integer i)
{
text s;
s = itoa(i);
if (s[0] == '-') {
s = delete(s, 0);
}
if (~s < 3) {
v_integer(i);
v_text(" has not enough digits\n");
} elif (~s & 1) {
o_form("/w9/: ~\n", i, cut(s, ~s - 3 >> 1, 3));
} else {
v_integer(i);
v_text(" has an even number of digits\n");
}
}
void
middle_3(...)
{
integer i;
i = 0;
while (i < count()) {
m3($i);
i += 1;
}
}
integer
main(void)
{
middle_3(123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100,
-12345, 1, 2, -1, -10, 2002, -2002, 0);
return 0;
}
- Output:
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1 has not enough digits 2 has not enough digits -1 has not enough digits -10 has not enough digits 2002 has an even number of digits -2002 has an even number of digits 0 has not enough digits
ALGOL 68
# we define a UNION MODE so that our middle 3 digits PROC can #
# return either an integer on success or a error message if #
# the middle 3 digits couldn't be extracted #
MODE EINT = UNION( INT # success value #, STRING # error message # );
# PROC to return the middle 3 digits of an integer. #
# if this is not possible, an error message is returned #
# instead #
PROC middle 3 digits = ( INT number ) EINT:
BEGIN
# convert the absolute value of the number to a string with the #
# minumum possible number characters #
STRING digits = whole( ABS number, 0 );
INT len = UPB digits;
IF len < 3
THEN
# number has less than 3 digits #
# return an error message #
"number must have at least three digits"
ELIF ( len MOD 2 ) = 0
THEN
# the number has an even number of digits #
# return an error message #
"number must have an odd number of digits"
ELSE
# the number is suitable for extraction of the middle 3 digits #
INT first digit pos = 1 + ( ( len - 3 ) OVER 2 );
# the result is the integer value of the three digits #
( ( ( ABS digits[ first digit pos ] - ABS "0" ) * 100 )
+ ( ( ABS digits[ first digit pos + 1 ] - ABS "0" ) * 10 )
+ ( ( ABS digits[ first digit pos + 2 ] - ABS "0" ) )
)
FI
END; # middle 3 digits #
main: (
# test the middle 3 digits PROC #
[]INT test values = ( 123, 12345, 1234567, 987654321
, 10001, -10001, -123, -100
, 100, -12345
# the following values should fail #
, 1, 2, -1, -10, 2002, -2002, 0
);
FOR test number FROM LWB test values TO UPB test values
DO
CASE middle 3 digits( test values[ test number ] )
IN
( INT success value ): # got the middle 3 digits #
printf( ( $ 11z-d, " : ", 3d $
, test values[ test number ]
, success value
)
)
,
( STRING error message ): # got an error message #
printf( ( $ 11z-d, " : ", n( UPB error message )a $
, test values[ test number ]
, error message
)
)
ESAC;
print( ( newline ) )
OD
)
- Output:
123 : 123 12345 : 234 1234567 : 345 987654321 : 654 10001 : 000 -10001 : 000 -123 : 123 -100 : 100 100 : 100 -12345 : 234 1 : number must have at least three digits 2 : number must have at least three digits -1 : number must have at least three digits -10 : number must have at least three digits 2002 : number must have an odd number of digits -2002 : number must have an odd number of digits 0 : number must have at least three digits
ALGOL W
begin
% record structure that will be used to return the middle 3 digits of a number %
% if the middle three digits can't be determined, isOk will be false and message %
% will contain an error message %
% if the middle 3 digts can be determined, middle3 will contain the middle 3 %
% digits and isOk will be true %
record MiddleThreeDigits ( integer middle3; logical isOk; string(80) message );
% finds the middle3 digits of a number or describes why they can't be found %
reference(MiddleThreeDigits) procedure findMiddleThreeDigits ( integer value number ) ;
begin
integer n, digitCount, d;
n := abs( number );
% count the number of digits the number has %
digitCount := if n = 0 then 1 else 0;
d := n;
while d > 0 do begin
digitCount := digitCount + 1;
d := d div 10
end while_d_gt_0 ;
if digitCount < 3 then MiddleThreeDigits( 0, false, "Number must have at least 3 digits" )
else if not odd( digitCount ) then MiddleThreeDigits( 0, false, "Number must have an odd number of digits" )
else begin
% can find the middle three digits %
integer m3;
m3 := n;
for d := 1 until ( digitCount - 3 ) div 2 do m3 := m3 div 10;
MiddleThreeDigits( m3 rem 1000, true, "" )
end
end findMiddleThreeDigits ;
% test the findMiddleThreeDigits procedure %
for n := 123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0 do begin
reference(MiddleThreeDigits) m3;
i_w := 10; s_w := 0; % set output formating %
m3 := findMiddleThreeDigits( n );
write( n, ": " );
if not isOk(m3) then writeon( message(m3) )
else begin
% as we return the middle three digits as an integer, we must manually 0 pad %
if middle3(m3) < 100 then writeon( "0" );
if middle3(m3) < 10 then writeon( "0" );
writeon( i_w := 1, middle3(m3) )
end
end for_n
end.
- Output:
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: Number must have at least 3 digits 2: Number must have at least 3 digits -1: Number must have at least 3 digits -10: Number must have at least 3 digits 2002: Number must have an odd number of digits -2002: Number must have an odd number of digits 0: Number must have at least 3 digits
Amazing Hopper
VERSION 1:
#include <basico.h>
algoritmo
n=0, c=""
temp = 0, candidatos={}
'123, 12345, 1234567, 987654321, 10001, -10001,-123'
'-100, 100, -12345,1, 2, -1, -10, 2002, -2002, 0'
enlistar en 'candidatos'
decimales '0'
#basic{
temp = string(candidatos * sign(candidatos))
n = len( temp )
c = replicate (temp, n>=3 && not(is even(n)))
toksep(NL)
print (cat( lpad(" ",11,string(candidatos)), cat(" : ", copy( 3, (n/2-1), c ))),NL)
}
terminar
- Output:
123 : 123 12345 : 234 1234567 : 345 987654321 : 654 10001 : 000 -10001 : 000 -123 : 123 -100 : 100 100 : 100 -12345 : 234 1 : 2 : -1 : -10 : 2002 : -2002 : 0 :
VERSION 2:
#include <basico.h>
algoritmo
n=0, c="",
temp = 0, candidatos={}
'123, 12345, 1234567, 987654321, 10001, -10001,-123'
'-100, 100, -12345,1, 2, -1, -10, 2002, -2002, 0'
enlistar en 'candidatos'
decimales '0'
tomar 'candidatos', quitar el signo
convertir a cadena ---retener---, obtener largo, mover a 'n',
guardar en 'temp'
guardar ' replicar ( temp, #(n>=3 && not(is even(n))))' en 'c'
token.separador(NL)
justificar derecha(11,#(string(candidatos))), " : ", concatenar esto
#( copy( 3, (n/2-1), c ) ), unir esto
luego imprime
terminar
- Output:
123 : 123 12345 : 234 1234567 : 345 987654321 : 654 10001 : 000 -10001 : 000 -123 : 123 -100 : 100 100 : 100 -12345 : 234 1 : 2 : -1 : -10 : 2002 : -2002 : 0 :
VERSION 3:
#include <basico.h>
algoritmo
n=0, c="", m=0,
candidatos={}
'123, 12345, 1234567, 987654321, 10001, -10001,-123'
'-100, 100, -12345,1, 2, -1, -10, 2002, -2002, 0'
enlistar en 'candidatos'
decimales '0'
para cada elemento (v,candidatos,17)
tomar'v' ---copiar en 'm'---, quitar el signo
guardar en 'v'
#(len( c:=(string(v)) ) ), mover a 'n'
"Num: ",justificar derecha(10,#(string(m))),"(",n,")\t"
si ' #( n>=3 && not(is even(n))) '
" puede ser procesado : "
tomar si ( #(n==3), 'c', #( copy( 3, (n/2-1), c )) ), NL
sino
"no puede ser procesado\n"
fin si
luego imprime
siguiente
terminar
- Output:
Num: 123(3) puede ser procesado : 123 Num: 12345(5) puede ser procesado : 234 Num: 1234567(7) puede ser procesado : 345 Num: 987654321(9) puede ser procesado : 654 Num: 10001(5) puede ser procesado : 000 Num: -10001(5) puede ser procesado : 000 Num: -123(3) puede ser procesado : 123 Num: -100(3) puede ser procesado : 100 Num: 100(3) puede ser procesado : 100 Num: -12345(5) puede ser procesado : 234 Num: 1(1) no puede ser procesado Num: 2(1) no puede ser procesado Num: -1(1) no puede ser procesado Num: -10(2) no puede ser procesado Num: 2002(4) no puede ser procesado Num: -2002(4) no puede ser procesado Num: 0(1) no puede ser procesado
AppleScript
Procedural
987654321 is too large to be represented as an AppleScript integer, so "integer value" is taken here to refer to the numeric value rather than to the language class. AppleScript automatically coerces numeric text and single-item lists to appropriate number classes where necessary and possible, so these are acceptable as parameters too.
on middle3Digits(n)
try
n as number -- Errors if n isn't a number or coercible thereto.
set s to n as text -- Keep for the ouput string.
if (n mod 1 is not 0) then error (s & " isn't an integer value.")
if (n < 0) then set n to -n
if (n < 100) then error (s & " has fewer than three digits.")
-- Coercing large numbers to text may result in E notation, so extract the digit values individually.
set theDigits to {}
repeat until (n = 0)
set beginning of theDigits to n mod 10 as integer
set n to n div 10
end repeat
set c to (count theDigits)
if (c mod 2 is 0) then error (s & " has an even number of digits.")
on error errMsg
return "middle3Digits handler got an error: " & errMsg
end try
set i to (c - 3) div 2 + 1
set {x, y, z} to items i thru (i + 2) of theDigits
return "The middle three digits of " & s & " are " & ((x as text) & y & z & ".")
end middle3Digits
-- Test code:
set testNumbers to {123, 12345, 1234567, "987654321", "987654321" as number, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0}
set output to {}
repeat with thisNumber in testNumbers
set end of output to middle3Digits(thisNumber)
end repeat
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to linefeed
set output to output as text
set AppleScript's text item delimiters to astid
return output
- Output:
"The middle three digits of 123 are 123.
The middle three digits of 12345 are 234.
The middle three digits of 1234567 are 345.
The middle three digits of 987654321 are 654.
The middle three digits of 9.87654321E+8 are 654.
The middle three digits of 10001 are 000.
The middle three digits of -10001 are 000.
The middle three digits of -123 are 123.
The middle three digits of -100 are 100.
The middle three digits of 100 are 100.
The middle three digits of -12345 are 234.
middle3Digits handler got an error: 1 has fewer than three digits.
middle3Digits handler got an error: 2 has fewer than three digits.
middle3Digits handler got an error: -1 has fewer than three digits.
middle3Digits handler got an error: -10 has fewer than three digits.
middle3Digits handler got an error: 2002 has an even number of digits.
middle3Digits handler got an error: -2002 has an even number of digits.
middle3Digits handler got an error: 0 has fewer than three digits."
Functional
-------------------- MID THREE DIGITS ---------------------
-- mid3digits :: Int -> Either String String
on mid3digits(n)
-- Either a message explaining why
-- no "mid 3 digits" are defined for n,
-- or the mid 3 digits themselves.
set m to abs(n)
if 100 > m then
|Left|("Less than 3 digits")
else if maxBound(1) < m then
|Left|("Out of AppleScript integer range")
else
set s to m as string
set intDigits to length of s
if even(intDigits) then
|Left|("Even digit count")
else
|Right|((items 1 thru 3 of ¬
items (1 + ((intDigits - 3) div 2)) thru -1 of s) as string)
end if
end if
end mid3digits
-------------------------- TEST ---------------------------
on run
set ints to map(readInt, splitOn(", ", ¬
"123, 12345, 1234567, 987654321, 10001, -10001, " & ¬
"-123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0"))
script showResult
on |λ|(x)
either(my bracketed, my str, x)
end |λ|
end script
fTable("Mid three digits:", str, showResult, mid3digits, ints)
end run
------------------------ GENERICS -------------------------
-- Left :: a -> Either a b
on |Left|(x)
{type:"Either", |Left|:x, |Right|:missing value}
end |Left|
-- Right :: b -> Either a b
on |Right|(x)
{type:"Either", |Left|:missing value, |Right|:x}
end |Right|
-- abs :: Num -> Num
on abs(x)
-- Absolute value.
if 0 > x then
-x
else
x
end if
end abs
-- even :: Int -> Bool
on even(x)
0 = x mod 2
end even
-- maxBound :: a -> a
on maxBound(x)
set c to class of x
if text is c then
character id 65535
else if integer is c then
(2 ^ 29 - 1)
else if real is c then
1.797693E+308
else if boolean is c then
true
end if
end maxBound
-------------------- GENERICS FOR TEST AND DISPLAY ---------------------
-- bracketed :: String -> String
on bracketed(s)
"(" & s & ")"
end bracketed
-- compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
on compose(f, g)
script
property mf : mReturn(f)
property mg : mReturn(g)
on |λ|(x)
mf's |λ|(mg's |λ|(x))
end |λ|
end script
end compose
-- either :: (a -> c) -> (b -> c) -> Either a b -> c
on either(lf, rf, e)
if missing value is |Left| of e then
tell mReturn(rf) to |λ|(|Right| of e)
else
tell mReturn(lf) to |λ|(|Left| of e)
end if
end either
-- foldl :: (a -> b -> a) -> a -> [b] -> a
on foldl(f, startValue, xs)
tell mReturn(f)
set v to startValue
set lng to length of xs
repeat with i from 1 to lng
set v to |λ|(v, item i of xs, i, xs)
end repeat
return v
end tell
end foldl
-- fTable :: String -> (a -> String) -> (b -> String) -> (a -> b) -> [a] -> String
on fTable(s, xShow, fxShow, f, xs)
set ys to map(xShow, xs)
set w to maximum(map(my |length|, ys))
script arrowed
on |λ|(a, b)
justifyRight(w, space, a) & " -> " & b
end |λ|
end script
s & linefeed & unlines(zipWith(arrowed, ¬
ys, map(compose(fxShow, f), xs)))
end fTable
-- justifyRight :: Int -> Char -> String -> String
on justifyRight(n, cFiller, strText)
if n > length of strText then
text -n thru -1 of ((replicate(n, cFiller) as text) & strText)
else
strText
end if
end justifyRight
-- length :: [a] -> Int
on |length|(xs)
set c to class of xs
if list is c or string is c then
length of xs
else
(2 ^ 29 - 1) -- (maxInt - simple proxy for non-finite)
end if
end |length|
-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
-- The list obtained by applying f
-- to each element of xs.
tell mReturn(f)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, i, xs)
end repeat
return lst
end tell
end map
-- maximum :: Ord a => [a] -> a
on maximum(xs)
script
on |λ|(a, b)
if a is missing value or b > a then
b
else
a
end if
end |λ|
end script
foldl(result, missing value, xs)
end maximum
-- min :: Ord a => a -> a -> a
on min(x, y)
if y < x then
y
else
x
end if
end min
-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
-- 2nd class handler function lifted into 1st class script wrapper.
if script is class of f then
f
else
script
property |λ| : f
end script
end if
end mReturn
-- readInt :: String -> Int
on readInt(s)
s as integer
end readInt
-- Egyptian multiplication - progressively doubling a list, appending
-- stages of doubling to an accumulator where needed for binary
-- assembly of a target length
-- replicate :: Int -> a -> [a]
on replicate(n, a)
set out to {}
if 1 > n then return out
set dbl to {a}
repeat while (1 < n)
if 0 < (n mod 2) then set out to out & dbl
set n to (n div 2)
set dbl to (dbl & dbl)
end repeat
return out & dbl
end replicate
-- splitOn :: String -> String -> [String]
on splitOn(pat, src)
set {dlm, my text item delimiters} to ¬
{my text item delimiters, pat}
set xs to text items of src
set my text item delimiters to dlm
return xs
end splitOn
-- str :: a -> String
on str(x)
x as string
end str
-- unlines :: [String] -> String
on unlines(xs)
-- A single string formed by the intercalation
-- of a list of strings with the newline character.
set {dlm, my text item delimiters} to ¬
{my text item delimiters, linefeed}
set s to xs as text
set my text item delimiters to dlm
s
end unlines
-- zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
on zipWith(f, xs, ys)
set lng to min(length of xs, length of ys)
set lst to {}
if 1 > lng then
return {}
else
tell mReturn(f)
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, item i of ys)
end repeat
return lst
end tell
end if
end zipWith
- Output:
Mid three digits: 123 -> 123 12345 -> 234 1234567 -> 345 9.87654321E+8 -> (Out of AppleScript integer range) 10001 -> 000 -10001 -> 000 -123 -> 123 -100 -> 100 100 -> 100 -12345 -> 234 1 -> (Less than 3 digits) 2 -> (Less than 3 digits) -1 -> (Less than 3 digits) -10 -> (Less than 3 digits) 2002 -> (Even digit count) -2002 -> (Even digit count) 0 -> (Less than 3 digits)
Arturo
middleThree: function [num][
n: to :string abs num
if 3 > size n -> return "Number must have at least three digits"
if even? size n -> return "Number must have an odd number of digits"
middle: ((size n)/2)- 1
return slice n middle middle+2
]
samples: @[
123, 12345, 1234567, 987654321, 10001, neg 10001, neg 123, neg 100, 100, neg 12345,
1, 2, neg 1, neg 10, 2002, neg 2002, 0
]
loop samples 's [
print [pad to :string s 10 ":" middleThree s]
]
- Output:
123 : 123 12345 : 234 1234567 : 345 987654321 : 654 10001 : 000 -10001 : 000 -123 : 123 -100 : 100 100 : 100 -12345 : 234 1 : Number must have at least three digits 2 : Number must have at least three digits -1 : Number must have at least three digits -10 : Number must have at least three digits 2002 : Number must have an odd number of digits -2002 : Number must have an odd number of digits 0 : Number must have at least three digits
ATS
(* ****** ****** *)
//
#include
"share/atspre_staload.hats"
#include
"share/HATS/atspre_staload_libats_ML.hats"
//
(* ****** ****** *)
//
extern
fun
int2digits(x: int): list0(int)
//
(* ****** ****** *)
implement
int2digits(x) =
loop(x, list0_nil) where
{
//
fun
loop
(
x: int, res: list0(int)
) : list0(int) =
if x > 0 then loop(x/10, list0_cons(x%10, res)) else res
//
} (* end of [int2digits] *)
(* ****** ****** *)
extern
fun
Middle_three_digits(x: int): void
(* ****** ****** *)
implement
Middle_three_digits
(x0) = let
//
val x1 =
(
if x0 >= 0 then x0 else ~x0
) : int
//
fun
skip
(
ds: list0(int), k: int
) : list0(int) =
if k > 0 then skip(ds.tail(), k-1) else ds
//
val ds =
int2digits(x1)
//
val n0 = length(ds)
//
in
//
if
(n0 <= 2)
then
(
println! ("Middle-three-digits(", x0, "): Too small!")
)
else
(
if
(n0 % 2 = 0)
then
(
println!
(
"Middle-three-digits(", x0, "): Even number of digits!"
)
)
else let
val ds =
skip(ds, (n0-3)/2)
val-list0_cons(d1, ds) = ds
val-list0_cons(d2, ds) = ds
val-list0_cons(d3, ds) = ds
in
println! ("Middle-three-digits(", x0, "): ", d1, d2, d3)
end // end of [else]
)
//
end // end of [Middle_three_digits]
(* ****** ****** *)
implement
main0() =
{
//
val
thePassing =
g0ofg1
(
$list{int}
(
123
, 12345
, 1234567
, 987654321
, 10001, ~10001
, ~123, ~100, 100, ~12345
)
)
val
theFailing =
g0ofg1($list{int}(1, 2, ~1, ~10, 2002, ~2002, 0))
//
val () = thePassing.foreach()(lam x => Middle_three_digits(x))
val () = theFailing.foreach()(lam x => Middle_three_digits(x))
//
} (* end of [main0] *)
(* ****** ****** *)
- Output:
Middle-three-digits(123): 123 Middle-three-digits(12345): 234 Middle-three-digits(1234567): 345 Middle-three-digits(987654321): 654 Middle-three-digits(10001): 000 Middle-three-digits(-10001): 000 Middle-three-digits(-123): 123 Middle-three-digits(-100): 100 Middle-three-digits(100): 100 Middle-three-digits(-12345): 234 Middle-three-digits(1): Too small! Middle-three-digits(2): Too small! Middle-three-digits(-1): Too small! Middle-three-digits(-10): Too small! Middle-three-digits(2002): Even number of digits! Middle-three-digits(-2002): Even number of digits! Middle-three-digits(0): Too small!
AutoHotkey
Numbers:="123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345,1,2,-1,-10,2002,-2002,0"
Loop, parse, Numbers, `,
{
if A_LoopField is not number
log := log . A_LoopField . "`t: Not a valid number`n"
else if((d:=StrLen(n:=RegExReplace(A_LoopField,"\D")))<3)
log := log . A_LoopField . "`t: Too short`n"
else if(!Mod(d,2))
log := log . A_LoopField . "`t: Not an odd number of digits`n"
else
log := log . A_LoopField . "`t: " . SubStr(n,((d-3)//2)+1,3) . "`n"
}
MsgBox % log
- Output:
123 : 123 12345 : 234 1234567 : 345 987654321 : 654 10001 : 000 -10001 : 000 -123 : 123 -100 : 100 100 : 100 -12345 : 234 1 : Too short 2 : Too short -1 : Too short -10 : Too short 2002 : Not an odd number of digits -2002 : Not an odd number of digits 0 : Too short
AWK
#!/bin/awk -f
# use as: awk -f middle_three_digits.awk
BEGIN {
n = split("123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 1 2 -1 -10 2002 -2002 0", arr)
for (i=1; i<=n; i++) {
if (arr[i] !~ /^-?[0-9]+$/) {
printf("%10s : invalid input: not a number\n", arr[i])
continue
}
num = arr[i]<0 ? -arr[i]:arr[i]
len = length(num)
if (len < 3) {
printf("%10s : invalid input: too few digits\n", arr[i])
continue
}
if (len % 2 == 0) {
printf("%10s : invalid input: even number of digits\n", arr[i])
continue
}
printf("%10s : %s\n", arr[i], substr(num, len/2, 3))
}
}
- Output:
123 : 123 12345 : 234 1234567 : 345 987654321 : 654 10001 : 000 -10001 : 000 -123 : 123 -100 : 100 100 : 100 -12345 : 234 1 : invalid input: too few digits 2 : invalid input: too few digits -1 : invalid input: too few digits -10 : invalid input: too few digits 2002 : invalid input: even number of digits -2002 : invalid input: even number of digits 0 : invalid input: too few digits
BASIC
Applesoft BASIC
100 DEF FN L(N) = LEN(STR$(INT(ABS(N))))
110 DEF FN N(N) = VAL(MID$(STR$(INT(ABS(N))),(FN L(N)-1)/2,3))
120 DEF FN EVEN(N) = INT(N/2) = N/2
130 FOR I = 1 TO 20
140 READ N
150 PRINT N":",
160 GOSUB 100"MIDDLE THREE DIGITS
170 PRINT R$
180 NEXT
190 END
200 R$ = ""
210 IF FN EVEN(FN L(N)) THEN R$ = "?EVEN,"
220 IF FN L(N) < 3 THEN R$ = R$ + "ONLY " + STR$(FN L(N)) + " DIGIT" + MID$("S",FN L(N) - 1, 1)
230 IF RIGHT$(R$, 1) = "," THEN R$ = LEFT$(R$, LEN(R$) - 1) : RETURN
240 IF LEFT$(R$, 1) = "?" THEN RETURN
250 IF R$ <> "" THEN R$ = "?" + R$ : RETURN
260 R$ = STR$(FN N(N))
270 IF LEN(R$) = 1 THEN R$ = "00" + R$
280 IF LEN(R$) = 2 THEN R$ = "0" + R$
290 RETURN
300 DATA123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345
310 DATA1,2,-1,-10,2002,-2002,0
- Output:
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: ?ONLY 1 DIGIT 2: ?ONLY 1 DIGIT -1: ?ONLY 1 DIGIT -10: ?EVEN,ONLY 2 DIGITS 2002: ?EVEN -2002: ?EVEN 0: ?ONLY 1 DIGIT
BASIC256
function middleThreeDigits(n)
if n < 0 then n = -n
if n < 100 then return "" ## error code
if n < 1000 then return string(n)
if n < 10000 then return ""
ns = string(n)
if length(ns) mod 2 = 0 then return "" ## need to have an odd number of digits for there to be 3 middle
return mid(ns, length(ns) \ 2, 3)
end function
dim a = {123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -123451, 2, -1, -10, 2002, -2002, 0}
print "The 3 middle digits of the following numbers are : "
print
for i = 0 to 15
result = middleThreeDigits(a[i])
print a[i]; chr(9); " => ";
if result <> "" then
print result
else
print "Error: does not have 3 middle digits"
end if
next
- Output:
Similar to FreeBASIC entry.
BBC BASIC
REM >midthree
FOR i% = 1 TO 17
READ test%
PRINT test%; " -> "; FN_middle_three(test%)
NEXT
END
:
DATA 123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345
DATA 1, 2, -1, -10, 2002, -2002, 0
:
DEF FN_middle_three(n%)
LOCAL n$
n$ = STR$ ABS n%
CASE TRUE OF
WHEN LEN n$ < 3
= "Not enough digits"
WHEN LEN n$ MOD 2 = 0
= "Even number of digits"
OTHERWISE
= MID$(n$, LEN n$ / 2, 3)
ENDCASE
- Output:
123 -> 123 12345 -> 234 1234567 -> 345 987654321 -> 654 10001 -> 000 -10001 -> 000 -123 -> 123 -100 -> 100 100 -> 100 -12345 -> 234 1 -> Not enough digits 2 -> Not enough digits -1 -> Not enough digits -10 -> Not enough digits 2002 -> Even number of digits -2002 -> Even number of digits 0 -> Not enough digits
FBSL
#APPTYPE CONSOLE
DIM numbers AS STRING = "123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345,1,2,-1,-10,2002,-2002,0"
DIM dict[] = Split(numbers, ",")
DIM num AS INTEGER
DIM num2 AS INTEGER
DIM powered AS INTEGER
FOR DIM i = 0 TO COUNT(dict) - 1
num2 = dict[i]
num = ABS(num2)
IF num < 100 THEN
display(num2, "is too small")
ELSE
FOR DIM j = 9 DOWNTO 1
powered = 10 ^ j
IF num >= powered THEN
IF j MOD 2 = 1 THEN
display(num2, "has even number of digits")
ELSE
display(num2, middle3(num, j))
END IF
EXIT FOR
END IF
NEXT
END IF
NEXT
PAUSE
FUNCTION display(num, msg)
PRINT LPAD(num, 11, " "), " --> ", msg
END FUNCTION
FUNCTION middle3(n, pwr)
DIM power AS INTEGER = (pwr \ 2) - 1
DIM m AS INTEGER = n
m = m \ (10 ^ power)
m = m MOD 1000
IF m = 0 THEN
RETURN "000"
ELSE
RETURN m
END IF
END FUNCTION
Output
123 --> 123 12345 --> 234 1234567 --> 345 987654321 --> 654 10001 --> 000 -10001 --> 000 -123 --> 123 -100 --> 100 100 --> 100 -12345 --> 234 1 --> is too small 2 --> is too small -1 --> is too small -10 --> is too small 2002 --> has even number of digits -2002 --> has even number of digits 0 --> is too small Press any key to continue...
IS-BASIC
100 INPUT PROMPT "Number: ":N
120 PRINT MIDDLE$(N)
130 DEF MIDDLE$(N)
140 LET N$=STR$(ABS(N))
150 IF LEN(N$)<3 THEN LET MIDDLE$="Not enough digits":EXIT DEF
160 IF MOD(LEN(N$),2)=0 THEN LET MIDDLE$="Even number of digits":EXIT DEF
170 LET P=(LEN(N$)-3)/2
180 LET MIDDLE$=N$(P+1:P+3)
190 END DEF
PureBasic
Procedure.s middleThreeDigits(x.q)
Protected x$, digitCount
If x < 0: x = -x: EndIf
x$ = Str(x)
digitCount = Len(x$)
If digitCount < 3
ProcedureReturn "invalid input: too few digits"
ElseIf digitCount % 2 = 0
ProcedureReturn "invalid input: even number of digits"
EndIf
ProcedureReturn Mid(x$,digitCount / 2, 3)
EndProcedure
If OpenConsole()
Define testValues$ = "123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 1 2 -1 -10 2002 -2002 0"
Define i, value.q, numTests = CountString(testValues$, " ") + 1
For i = 1 To numTests
value = Val(StringField(testValues$, i, " "))
PrintN(RSet(Str(value), 12, " ") + " : " + middleThreeDigits(value))
Next
Print(#crlf$ + #crlf$ + "Press ENTER to exit"): Input()
CloseConsole()
EndIf
Sample output:
123 : 123 12345 : 234 1234567 : 345 987654321 : 654 10001 : 000 -10001 : 000 -123 : 123 -100 : 100 100 : 100 -12345 : 234 1 : invalid input: too few digits 2 : invalid input: too few digits -1 : invalid input: too few digits -10 : invalid input: too few digits 2002 : invalid input: even number of digits -2002 : invalid input: even number of digits 0 : invalid input: too few digits
Run BASIC
x$ = "123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0"
while word$(x$,i+1,",") <> ""
i = i + 1
a1$ = trim$(word$(x$,i,","))
if left$(a1$,1) = "-" then a$ = mid$(a1$,2) else a$ = a1$
if (len(a$) and 1) = 0 or len(a$) < 3 then
print a1$;chr$(9);" length < 3 or is even"
else
print mid$(a$,((len(a$)-3)/2)+1,3);" ";a1$
end if
wend
end
123 123 234 12345 345 1234567 654 987654321 000 10001 000 -10001 123 -123 100 -100 100 100 234 -12345 1 length < 3 or is even 2 length < 3 or is even -1 length < 3 or is even -10 length < 3 or is even 2002 length < 3 or is even -2002 length < 3 or is even 0 length < 3 or is even
Yabasic
sub middleThreeDigits$ (n)
if n < 0 n = -n
if n < 100 return "" // error code
if n < 1000 return str$(n)
if n < 10000 return ""
ns$ = str$(n)
if mod(len(ns$), 2) = 0 return "" // need to have an odd number of digits for there to be 3 middle
return mid$(ns$, len(ns$) / 2, 3)
end sub
dim a(16)
a(0) = 123 : a(1) = 12345 : a(2) = 1234567
a(3) = 987654321 : a(4) = 10001 : a(5) = -10001
a(6) = -123 : a(7) = -100 : a(8) = 100
a(9) = -123451
a(10) = 2 : a(11) = -1 : a(12) = -10
a(13) = 2002 : a(14) = -2002 : a(15) = 0
print "The 3 middle digits of the following numbers are : \n"
for i = 1 to 16
result$ = middleThreeDigits$(a(i))
print a(i), "\t => ";
if result$ <> "" then
print result$
else
print "Error: does not have 3 middle digits"
fi
next
- Output:
Similar to FreeBASIC entry.
Batch File
@echo off
setlocal enabledelayedexpansion
%== Initialization ==%
set "numbers=123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0"
%== The Main Thing ==%
for %%N in (%numbers%) do (
call :middle3 %%N
)
echo.
pause
exit /b 0
%==/The Main Thing ==%
%== The Procedure ==%
:middle3
set str=%1
%== Making sure that str is positive ==%
if !str! lss 0 set /a str*=-1
%== Alternative for finding the string length ==%
%== But this has a limit of 1000 characters ==%
set leng=0&if not "!str!"=="" for /l %%. in (0,1,1000) do if not "!str:~%%.,1!"=="" set /a leng+=1
if !leng! lss 3 (
echo.%~1: [ERROR] Input too small.
goto :EOF
)
set /a "test2=leng %% 2,trimmer=(leng - 3) / 2"
if !test2! equ 0 (
echo.%~1: [ERROR] Even number of digits.
goto :EOF
)
%== Passed the tests. Now, really find the middle 3 digits... ==%
if !trimmer! equ 0 (
echo.%~1: !str!
) else (
echo.%~1: !str:~%trimmer%,-%trimmer%!
)
goto :EOF
%==/The Procedure ==%
- Output:
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: [ERROR] Input too small. 2: [ERROR] Input too small. -1: [ERROR] Input too small. -10: [ERROR] Input too small. 2002: [ERROR] Even number of digits. -2002: [ERROR] Even number of digits. 0: [ERROR] Input too small. Press any key to continue . . .
Befunge
Reads the integer value from stdin and writes the middle three digits (or an error message) to stdout.
>&>:0`2*1-*0>v
v+*86%+55:p00<
>\55+/:00g1+\|
v3_v#*%2\`2::<
->@>0".rorrE"v
2^,+55_,#!>#:<
>/>\#<$#-:#1_v
>_@#<,+55,,,$<
- Output:
(multiple runs)
123 123 12345 234 1234567 345 987654321 654 10001 000 -10001 000 -123 123 -100 100 100 100 -12345 234 1 Error. 2 Error. -1 Error. -10 Error. 2002 Error. -2002 Error. 0 Error.
Bracmat
( ( middle3
= x p
. @(!arg:? [?p:? [(1/2*!p+-3/2) %?x [(1/2*!p+3/2) ?)
& !x
| !arg
( !p:<3&"is too small"
| "has even number of digits"
)
)
& 123 12345 1234567 987654321 10001 -10001 -123 -100 100
-12345 1 2 -1 -10 2002 -2002 0
: ?L
& whl'(!L:%?e ?L&out$(middle3$!e))
&
);
Output:
123 234 345 654 000 000 123 100 100 234 1 is too small 2 is too small -1 is too small -10 is too small 2002 has even number of digits -2002 has even number of digits 0 is too small
Burlesque
blsq ) {123 12345 1234567 987654321 -10001 -123}{XX{~-}{L[3.>}w!m]\[}m[uN
123
234
345
654
000
123
m]\[ and uN are just for displaying it nicely.
C
This code is followed by its output.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// we return a static buffer; caller wants it, caller copies it
char * mid3(int n)
{
static char buf[32];
int l;
sprintf(buf, "%d", n > 0 ? n : -n);
l = strlen(buf);
if (l < 3 || !(l & 1)) return 0;
l = l / 2 - 1;
buf[l + 3] = 0;
return buf + l;
}
int main(void)
{
int x[] = {123, 12345, 1234567, 987654321, 10001, -10001,
-123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0,
1234567890};
int i;
char *m;
for (i = 0; i < sizeof(x)/sizeof(x[0]); i++) {
if (!(m = mid3(x[i])))
m = "error";
printf("%d: %s\n", x[i], m);
}
return 0;
}
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: error 2: error -1: error -10: error 2002: error -2002: error 0: error 1234567890: error
Alternative Version
This code has been extensively rewritten. The original was purely interactive and had to be invoked each time from the console. It also did not produce the correct answer.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void midThree(char arg[])
{
char output[4];
int midPoint;
arg[0]=='-'?midPoint = ((strlen(arg) + 1) / 2):midPoint = ((strlen(arg) + 1) / 2) - 1;
if(strlen(arg) < 3)
{
printf("Error, %d is too short.\n",atoi(arg));
return ;
}
else if(strlen(arg) == 4 || strlen(arg) == 3)
{
printf("Error, %d has %d digits, no 3 middle digits.\n",atoi(arg),arg[0]=='-'?strlen(arg)-1:strlen(arg));
return ;
}
else{
for(int i=0; i<3; i++)
{
output[i] = arg[(midPoint-1) + i];
}
output[3] = '\0';
printf("The middle three digits of %s are %s.\n",arg,output);
}}
int main(int argc, char * argv[])
{
char input[50];
int x[] = {123, 12345, 1234567, 987654321, 10001, -10001,
-123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0,
1234567890},i;
if(argc < 2)
{
printf("Usage: %s <integer>\n",argv[0]);
printf("Examples with preloaded data shown below :\n");
for(i=0;i<18;i++)
{
midThree(itoa(x[i],argv[0],10));
}
return 1;
}
else
{
sprintf(input,"%d",atoi(argv[1]));
midThree(argv[1]);
return 0;
}
}
- Output:
Usage: C:\TurboC++\Disk\TurboC3\BIN\rosmid3_2.exe <integer> Examples with preloaded data shown below : Error, 123 has 3 digits, no 3 middle digits. The middle three digits of 12345 are 234. The middle three digits of 1234567 are 345. The middle three digits of 987654321 are 654. The middle three digits of 10001 are 000. The middle three digits of -10001 are 000. Error, -123 has 3 digits, no 3 middle digits. Error, -100 has 3 digits, no 3 middle digits. Error, 100 has 3 digits, no 3 middle digits. The middle three digits of -12345 are 234. Error, 1 is too short. Error, 2 is too short. Error, -1 is too short. Error, -10 has 2 digits, no 3 middle digits. Error, 2002 has 4 digits, no 3 middle digits. Error, -2002 has 4 digits, no 3 middle digits. Error, 0 is too short. The middle three digits of 1234567890 are 456.
C++
#include <iostream>
std::string middleThreeDigits(int n)
{
auto number = std::to_string(std::abs(n));
auto length = number.size();
if (length < 3) {
return "less than three digits";
} else if (length % 2 == 0) {
return "even number of digits";
} else {
return number.substr(length / 2 - 1, 3);
}
}
int main()
{
auto values {123, 12345, 1234567, 987654321, 10001,
-10001, -123, -100, 100, -12345,
1, 2, -1, -10, 2002, -2002, 0};
for (auto&& v : values) {
std::cout << "middleThreeDigits(" << v << "): " <<
middleThreeDigits(v) << "\n";
}
}
- Output:
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): less than three digits middleThreeDigits(2): less than three digits middleThreeDigits(-1): less than three digits middleThreeDigits(-10): less than three digits middleThreeDigits(2002): even number of digits middleThreeDigits(-2002): even number of digits middleThreeDigits(0): less than three digits
C_sharp
using System;
namespace RosettaCode
{
class Program
{
static void Main(string[] args)
{
string text = Math.Abs(int.Parse(Console.ReadLine())).ToString();
Console.WriteLine(text.Length < 2 || text.Length % 2 == 0 ? "Error" : text.Substring((text.Length - 3) / 2, 3));
}
}
}
- Output:
123:123 12345:234 1234567:345 987654321:654 10001:000 -10001:000 -123:123 -100:100 100:100 -12345:234 1:Error 2:Error -1:Error -10:Error 2002:Error -2002:Error 0:Error
Clojure
(defn middle3
[v]
(let [digit-str (str (Math/abs v))
len (count digit-str)]
(cond
(< len 3) :too-short
(even? len) :even-digit-count
:else (let [half (/ len 2)]
(subs digit-str (- half 1) (+ half 2))))))
(clojure.pprint/print-table
(for [i [123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345
1 2 -1 -10 2002 -2002 0]]
{:i i :middle-3 (middle3 i)}))
- Output:
| :i | :middle-3 | |-----------+-------------------| | 123 | 123 | | 12345 | 234 | | 1234567 | 345 | | 987654321 | 654 | | 10001 | 000 | | -10001 | 000 | | -123 | 123 | | -100 | 100 | | 100 | 100 | | -12345 | 234 | | 1 | :too-short | | 2 | :too-short | | -1 | :too-short | | -10 | :too-short | | 2002 | :even-digit-count | | -2002 | :even-digit-count | | 0 | :too-short |
CLU
middle_three_digits = proc (n: int) returns (string)
signals (too_small, even_length)
s: string := int$unparse(int$abs(n))
if string$size(s) < 3 then signal too_small end
if string$size(s) // 2 = 0 then signal even_length end
return(string$substr(s, string$size(s)/2, 3))
end middle_three_digits
start_up = proc ()
po: stream := stream$primary_output()
tests: sequence[int] := sequence[int]$
[123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345,
1,2,-1,-10,2002,-2002,0]
for test: int in sequence[int]$elements(tests) do
stream$putright(po, int$unparse(test) || ": ", 11)
stream$putl(po, middle_three_digits(test))
except
when too_small: stream$putl(po, "Too small")
when even_length: stream$putl(po, "Even length")
end
end
end start_up
- Output:
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: Too small 2: Too small -1: Too small -10: Too small 2002: Even length -2002: Even length 0: Too small
COBOL
identification division.
program-id. middle3.
environment division.
data division.
working-storage section.
01 num pic 9(9).
88 num-too-small values are -99 thru 99.
01 num-disp pic ---------9.
01 div pic 9(9).
01 mod pic 9(9).
01 mod-disp pic 9(3).
01 digit-counter pic 999.
01 digit-div pic 9(9).
88 no-more-digits value 0.
01 digit-mod pic 9(9).
88 is-even value 0.
01 multiplier pic 9(9).
01 value-items.
05 filler pic s9(9) value 123.
05 filler pic s9(9) value 12345.
05 filler pic s9(9) value 1234567.
05 filler pic s9(9) value 987654321.
05 filler pic s9(9) value 10001.
05 filler pic s9(9) value -10001.
05 filler pic s9(9) value -123.
05 filler pic s9(9) value -100.
05 filler pic s9(9) value 100.
05 filler pic s9(9) value -12345.
05 filler pic s9(9) value 1.
05 filler pic s9(9) value 2.
05 filler pic s9(9) value -1.
05 filler pic s9(9) value -10.
05 filler pic s9(9) value 2002.
05 filler pic s9(9) value -2002.
05 filler pic s9(9) value 0.
01 value-array redefines value-items.
05 items pic s9(9) occurs 17 times indexed by item.
01 result pic x(20).
procedure division.
10-main.
perform with test after varying item from 1 by 1 until items(item) = 0
move items(item) to num
move items(item) to num-disp
perform 20-check
display num-disp " --> " result
end-perform.
stop run.
20-check.
if num-too-small
move "Number too small" to result
exit paragraph
end-if.
perform 30-count-digits.
divide digit-counter by 2 giving digit-div remainder digit-mod.
if is-even
move "Even number of digits" to result
exit paragraph
end-if.
*> if digit-counter is 5, mul by 10
*> if digit-counter is 7, mul by 100
*> if digit-counter is 9, mul by 1000
if digit-counter > 3
compute multiplier rounded = 10 ** (((digit-counter - 5) / 2) + 1)
divide num by multiplier giving num
divide num by 1000 giving div remainder mod
move mod to mod-disp
else
move num to mod-disp
end-if.
move mod-disp to result.
exit paragraph.
30-count-digits.
move zeroes to digit-counter.
move num to digit-div.
perform with test before until no-more-digits
divide digit-div by 10 giving digit-div remainder digit-mod
add 1 to digit-counter
end-perform.
exit paragraph.
Output
123 --> 123 12345 --> 234 1234567 --> 345 987654321 --> 654 10001 --> 000 -10001 --> 000 -123 --> 123 -100 --> 100 100 --> 100 -12345 --> 234 1 --> Number too small 2 --> Number too small -1 --> Number too small -10 --> Number too small 2002 --> Even number of digit -2002 --> Even number of digit 0 --> Number too small
Optimised version
identification division.
program-id. middle3.
environment division.
data division.
working-storage section.
01 value-items.
05 filler pic s9(9) value 123.
05 filler pic s9(9) value 12345.
05 filler pic s9(9) value 1234567.
05 filler pic s9(9) value 987654321.
05 filler pic s9(9) value 10001.
05 filler pic s9(9) value -10001.
05 filler pic s9(9) value -123.
05 filler pic s9(9) value -100.
05 filler pic s9(9) value 100.
05 filler pic s9(9) value -12345.
05 filler pic s9(9) value 1.
05 filler pic s9(9) value 2.
05 filler pic s9(9) value -1.
05 filler pic s9(9) value -10.
05 filler pic s9(9) value 2002.
05 filler pic s9(9) value -2002.
05 filler pic s9(9) value 0.
01 value-array redefines value-items.
05 items pic s9(9) occurs 17 times indexed by item.
01 num pic 9(9).
01 num-disp pic ---------9.
01 num2 pic 9(9).
01 power pic 9.
01 power10 pic 9(16).
01 three-digits pic 999.
01 result pic X(20).
01 flag pic 9.
88 done value 1.
procedure division.
01-setup.
perform 02-outer with test after varying item from 1 by 1 until items(item) = 0.
stop run.
02-outer.
move items(item) to num.
move items(item) to num-disp.
if num less than 100
move "too small" to result
else
perform 03-inner with test after varying power from 9 by -1 until power = 1 or done
end-if.
display num-disp " --> " result.
exit paragraph.
03-inner.
move 0 to flag.
compute power10 = 10 ** power.
if num >= power10
move 1 to flag
if function mod(power,2) = 1
move "even number digits" to result
else
move num to num2
compute num2 = num2 / ( 10 ** (( power / 2 ) - 1 ))
move function mod(num2,1000) to three-digits
move three-digits to result
end-if
end-if.
Output
123 --> 123 12345 --> 234 1234567 --> 345 987654321 --> 654 10001 --> 000 -10001 --> 000 -123 --> 123 -100 --> 100 100 --> 100 -12345 --> 234 1 --> too small 2 --> too small -1 --> too small -10 --> too small 2002 --> even number digits -2002 --> even number digits 0 --> too small
Common Lisp
Solution #1
(defun mid3 (n)
(let ((a (abs n))
(hmd)) ; how many digits
(labels ((give (fmt &optional x y) (return-from mid3 (format nil fmt x y)))
(need (x) (give "Need ~a digits, not ~d." x hmd))
(nbr (n) (give "~3,'0d" n)))
(when (zerop n) (give "Zero is 1 digit"))
(setq hmd (truncate (1+ (log a 10))))
(cond ((< hmd 3) (need "3+"))
((= hmd 3) (nbr a))
((evenp hmd) (need "odd number of"))
(t (nbr (mod (truncate a (expt 10 (/ (- hmd 3) 2))) 1000)))))))
Test code:
(loop as n in '(123 12345 1234567 987654321
10001 -10001 -123 -100 100 -12345
1 2 -1 -10 2002 -2002 0)
do (format t "~d:~12t~a~%" n (mid3 n)))
- Output:
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: Need 3+ digits, not 1. 2: Need 3+ digits, not 1. -1: Need 3+ digits, not 1. -10: Need 3+ digits, not 2. 2002: Need odd number of digits, not 4. -2002: Need odd number of digits, not 4. 0: Zero is 1 digit
Solution #2
(defun mid3 (i)
(let ((ch-vec (coerce (format nil "~A" (abs i)) 'vector)))
(when (evenp (length ch-vec))
(return-from mid3
(format nil "Error: The number representation must have an odd ~
number of digits.")))
(when (and (< i 100)
(> i -100))
(return-from mid3
(format nil "Error: Must be >= 100 or <= -100.")))
(let ((half (/ (1- (length ch-vec)) 2)))
(return-from mid3 (format nil "~A~A~A"
(elt ch-vec (1- half))
(elt ch-vec half)
(elt ch-vec (1+ half))))
)))
Test code:
(defun test-mid3 ()
(let ((test-lst (list 123
12345
1234567
987654321
10001
-10001
-123
-100
100
-12345
1
2
-1
-10
2002
-2002
0
)))
(labels
((run-tests (lst)
(cond ((null lst)
nil)
(t
(format t "~A ~15T ~A~%" (first lst) (mid3 (first lst)))
(run-tests (rest lst))))))
(run-tests test-lst)))
(values)
)
- Output:
123 123 12345 234 1234567 345 987654321 654 10001 000 -10001 000 -123 123 -100 100 100 100 -12345 234 1 Error: Must be >= 100 or <= -100. 2 Error: Must be >= 100 or <= -100. -1 Error: Must be >= 100 or <= -100. -10 Error: The number representation must have an odd number of digits. 2002 Error: The number representation must have an odd number of digits. -2002 Error: The number representation must have an odd number of digits. 0 Error: Must be >= 100 or <= -100.
D
import std.stdio, std.traits, std.conv;
string middleThreeDigits(T)(in T n) pure nothrow if (isIntegral!T) {
auto s = n < 0 ? n.text[1 .. $] : n.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, long.min, long.max];
foreach (immutable n; passing)
writefln("middleThreeDigits(%s): %s", n, middleThreeDigits(n));
immutable failing = [1, 2, -1, -10, 2002, -2002, 0,int.min,int.max];
foreach (immutable n; failing)
writefln("middleThreeDigits(%s): %s", n, middleThreeDigits(n));
}
- Output:
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(-9223372036854775808): 368 middleThreeDigits(9223372036854775807): 368 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 middleThreeDigits(-2147483648): Need odd and >= 3 digits middleThreeDigits(2147483647): Need odd and >= 3 digits
Alternative Version
This longer version gives a stronger typed output, and it tries to be faster avoiding conversions to string.
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);
}
}
- Output:
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
Dart
import'dart:math';
int length(int x)
{
int i,y;
for(i=0;;i++)
{
y=pow(10,i);
if(x%y==x)
break;
}
return i;
}
int middle(int x,int l)
{
int a=(x/10)-((x%10)/10);
int b=a%(pow(10,l-2));
int l2=length(b);
if(l2==3)
{
return b;
}
if(l2!=3)
{
return middle(b,l2);
}
return 0;
}
main()
{
int x=-100,y;
if(x<0)
x=-x;
int l=length(x);
if(l.isEven||x<100)
{print('error');}
if(l==3)
{print('$x');}
if(l.isOdd&& x>100)
{
y=middle(x,l);
print('$y');
}
}
DCL
$ list = "123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345,1,2,-1,-10,2002,-2002,0"
$ i = 0
$ loop:
$ number = f$element( i, ",", list )
$ if number .eqs. "," then $ exit
$ abs_number = number - "-"
$ len = f$length( abs_number )
$ if len .lt. 3 .or. .not. len
$ then
$ write sys$output f$fao( "!9SL: ", f$integer( number )), "has no middle three"
$ else
$ write sys$output f$fao( "!9SL: ", f$integer( number )), f$extract( ( len - 3 ) / 2, 3, abs_number )
$ endif
$ i = i + 1
$ goto loop
- Output:
$ @middle_three_digits 123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: has no middle three 2: has no middle three -1: has no middle three -10: has no middle three 2002: has no middle three -2002: has no middle three 0: has no middle three
Delphi
See Pascal.
EasyLang
func$ midThreeDigits num .
trueNumber$ = abs num
if (len trueNumber$ < 3) or (len trueNumber$ mod 2 = 0)
r$ = "error"
else
r$ = substr trueNumber$ ((len trueNumber$ - 3) / 2 + 1) 3
.
return r$
.
numbers[] = [ 123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 1 2 -1 -10 2002 -2002 0 ]
for i in numbers[]
print midThreeDigits i
.
- Output:
123 234 345 654 000 000 123 100 100 234 error error error error error error error
Eiffel
class
APPLICATION
create
make
feature
make
-- Test of middle_three_digits.
local
test_1, test_2: ARRAY [INTEGER]
do
test_1 := <<123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345>>
test_2 := <<1, 2, -1, -10, 2002, -2002, 0>>
across
test_1 as t
loop
io.put_string ("The middle three digits of " + t.item.out + " are: %T ")
io.put_string (middle_three_digits (t.item) + "%N")
end
across
test_2 as t
loop
io.put_string ("The middle three digits of " + t.item.out + " are: %T")
io.put_string (middle_three_digits (t.item) + "%N")
end
end
middle_three_digits (n: INTEGER): STRING
-- The middle three digits of 'n'.
local
k, i: INTEGER
in: STRING
do
create in.make_empty
in := n.out
if n < 0 then
in.prune ('-')
end
create Result.make_empty
if in.count < 3 then
io.put_string (" Not enough digits. ")
elseif in.count \\ 2 = 0 then
io.put_string (" Even number of digits. ")
else
i := (in.count - 3) // 2
from
k := i + 1
until
k > i + 3
loop
Result.extend (in.at (k))
k := k + 1
end
end
ensure
length_is_three: Result.count = 3 or Result.count = 0
end
end
- Output:
The middle three digits of 123 are: 123 The middle three digits of 12345 are: 234 The middle three digits of 1234567 are: 345 The middle three digits of 987654321 are: 654 The middle three digits of 10001 are: 000 The middle three digits of -10001 are: 000 The middle three digits of -123 are: 123 The middle three digits of -100 are: 100 The middle three digits of 100 are: 100 The middle three digits of -12345 are: 234 The middle three digits of 1 are: Not enough digits. The middle three digits of 2 are: Not enough digits. The middle three digits of -1 are: Not enough digits. The middle three digits of -10 are: Not enough digits. The middle three digits of 2002 are: Even number of digits. The middle three digits of -2002 are: Even number of digits. The middle three digits of 0 are: Not enough digits.
Elena
ELENA 6.x :
import system'routines;
import extensions;
middleThreeDigits(int n)
{
string s := n.Absolute.toString();
int len := s.Length;
if(len<3)
{
InvalidArgumentException.new("n must have 3 digits or more").raise()
}
else if(len.isEven())
{
InvalidArgumentException.new("n must have an odd number of digits").raise()
};
int mid := len / 2;
^ s.Substring(mid-1,3)
}
public program()
{
new int[]{123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0}
.forEach::(n)
{
console.printLine("middleThreeDigits(",n,"):",middleThreeDigits(n) \\ on::(e => e.Message))
}
}
- Output:
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):n must have 3 digits or more middleThreeDigits(2):n must have 3 digits or more middleThreeDigits(-1):n must have 3 digits or more middleThreeDigits(-10):n must have 3 digits or more middleThreeDigits(2002):n must have an odd number of digits middleThreeDigits(-2002):n must have an odd number of digits middleThreeDigits(0):n must have 3 digits or more
Elixir
defmodule Middle do
def three(num) do
n = num |> abs |> to_string
case {n,String.length(n) > 2,even?(n)} do
{n, true, false} ->
cut(n)
{_, false, _} ->
raise "Number must have at least three digits"
{_, _, true} ->
raise "Number must have an odd number of digits"
end
end
defp even?(n), do: rem(String.length(n),2) == 0
defp cut(n), do: String.slice(n,(div(String.length(n),2) - 1),3)
end
valids = [123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345]
Enum.each(valids, fn n -> :io.format "~10w : ~s~n", [n, Middle.three(n)] end)
errors = [1, 2, -1, -10, 2002, -2002, 0]
Enum.each(errors, fn n ->
:io.format "~10w : ", [n]
try do
IO.puts Middle.three(n)
rescue
e -> IO.puts e.message
end
end)
- Output:
123 : 123 12345 : 234 1234567 : 345 987654321 : 654 10001 : 000 -10001 : 000 -123 : 123 -100 : 100 100 : 100 -12345 : 234 1 : Number must have at least three digits 2 : Number must have at least three digits -1 : Number must have at least three digits -10 : Number must have at least three digits 2002 : Number must have an odd number of digits -2002 : Number must have an odd number of digits 0 : Number must have at least three digits
Erlang
%
-module(middle_three_digits).
-export([main/0]).
main() ->
digits(123),
digits(12345),
digits(1234567),
digits(987654321),
digits(10001),
digits(-10001),
digits(-123),
digits(-100),
digits(100),
digits(-12345),
digits(1),
digits(2),
digits(-1),
digits(-10),
digits(2002),
digits(-2002),
digits(0).
digits(N) when N < 0 ->
digits(-N);
digits(N) when (N div 100) =:= 0 ->
io:format("too small\n");
digits(N) ->
K=length(integer_to_list(N)),
if (K rem 2) =:= 0 ->
io:format("even number of digits\n");
true ->
loop((K-3) div 2 , N)
end.
loop(0, N) ->
io:format("~3..0B~n",[N rem 1000]);
loop(X,N) when X>0 ->
loop(X-1, N div 10).
- Output:
123 234 345 654 000 000 123 100 100 234 too small too small too small too small even number of digits even number of digits too small ok
ERRE
PROGRAM MIDDLE
!$DOUBLE
FUNCTION LUNG(N)
LUNG=LEN(STR$(INT(ABS(N))))+1
END FUNCTION
FUNCTION NCNT(N)
NCNT=VAL(MID$(STR$(INT(ABS(N))),(LUNG(N)-1)/2,3))
END FUNCTION
FUNCTION EVEN(N)
EVEN=INT(N/2)=N/2
END FUNCTION
PROCEDURE NUMBER_EXAM(N->R$)
R$="" LG%=LUNG(N)-2
IF EVEN(LG%) THEN R$="?EVEN," END IF
IF LG%<3 THEN
R$=R$+"ONLY"+STR$(LG%)+" DIGIT"
IF LG%=1 THEN
R$=R$+"S"
END IF
END IF
IF RIGHT$(R$,1)="," THEN R$=LEFT$(R$,LEN(R$)-1) EXIT PROCEDURE END IF
IF LEFT$(R$,1)="?" THEN EXIT PROCEDURE END IF
IF R$<>"" THEN R$="?"+R$ EXIT PROCEDURE END IF
R$=STR$(NCNT(N))
IF LEFT$(R$,1)=" " THEN R$=MID$(R$,2) END IF
IF LEN(R$)=1 THEN R$="00"+R$ END IF
IF LEN(R$)=2 THEN R$="0"+R$ END IF
END PROCEDURE
BEGIN
DATA(123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345)
DATA(1,2,-1,-10,2002,-2002,0)
FOR I%=1 TO 17 DO
READ(N)
PRINT(N;" ",)
NUMBER_EXAM(N->R$)
PRINT(R$)
END FOR
END PROGRAM
- Output:
123 123 12345 234 1234567 345 987654321 654 10001 000 -10001 000 -123 123 -100 100 100 100 -12345 234 1 ?ONLY 1 DIGITS 2 ?ONLY 1 DIGITS -1 ?ONLY 1 DIGITS -10 ?EVEN,ONLY 2 DIGIT 2002 ?EVEN -2002 ?EVEN 0 ?ONLY 1 DIGITS
Factor
USING: combinators formatting io kernel math math.parser
sequences ;
IN: rosetta-code.middle-three-digits
CONSTANT: test-values {
123 12345 1234567 987654321 10001 -10001
-123 -100 100 -12345 1 2 -1 -10 2002 -2002 0
}
: (middle-three) ( str -- str' )
[ midpoint@ [ 1 - ] [ 2 + ] bi ] [ subseq ] bi ;
: too-short ( -- )
"Number must have at least three digits." print ;
: number-even ( -- )
"Number must have an odd number of digits." print ;
: middle-three ( n -- )
abs number>string {
{ [ dup length 3 < ] [ drop too-short ] }
{ [ dup length even? ] [ drop number-even ] }
[ (middle-three) print ]
} cond ;
: main ( -- )
test-values [ dup "%9d : " printf middle-three ] each ;
MAIN: main
- Output:
123 : 123 12345 : 234 1234567 : 345 987654321 : 654 10001 : 000 -10001 : 000 -123 : 123 -100 : 100 100 : 100 -12345 : 234 1 : Number must have at least three digits. 2 : Number must have at least three digits. -1 : Number must have at least three digits. -10 : Number must have at least three digits. 2002 : Number must have an odd number of digits. -2002 : Number must have an odd number of digits. 0 : Number must have at least three digits.
Forth
This is a problem, which is easily solved in Forth. It converts the number to a string and checks it length. If the number does not represent a printable string, it returns an empty string.
: middle3 ( n1 -- a n2)
abs s>d <# #s #> dup 2/ 0<> over 1 and 0<> and
if 2/ 1- chars + 3 else drop 0 then
;
Fortran
Please find compilation instructions along with the output for the examples in the comments at the beginning of the file. This program was produced in an Ubuntu distribution of the GNU/linux system.
!-*- mode: compilation; default-directory: "/tmp/" -*-
!Compilation started at Sat Jun 1 14:48:41
!
!a=./f && make $a && OMP_NUM_THREADS=2 $a < unixdict.txt # some of the compilation options and redirection from unixdict.txt are vestigial.
!gfortran -std=f2008 -Wall -fopenmp -ffree-form -fall-intrinsics -fimplicit-none f.f08 -o f
! 123 123
! 12345 234
! 1234567 345
! 987654321 654
! 10001 000
! -10001 000
! -123 123
! -100 100
! 100 100
! -12345 234
! 1 Too short
! 2 Too short
! -1 Too short
! -10 Too short
! 2002 Digit count too even
! -2002 Digit count too even
! 0 Too short
!
!Compilation finished at Sat Jun 1 14:48:41
program MiddleMuddle
integer, dimension(17) :: itest, idigits
integer :: i, n
data itest/123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345,1,2,-1,-10,2002,-2002,0/
do i = 1, size(itest)
call antibase(10, abs(itest(i)), idigits, n)
write(6,'(i20,2x,a20)') itest(i), classifym3(idigits, n)
if (0 .eq. itest(i)) exit
end do
contains
logical function even(n)
integer, intent(in) :: n
even = 0 .eq. iand(n,1)
end function even
function classifym3(iarray, n) result(s)
integer, dimension(:), intent(in) :: iarray
integer, intent(in) :: n
character(len=20) :: s
integer :: i,m
if (n < 3) then
s = 'Too short'
else if (even(n)) then
s = 'Digit count too even'
else
m = (n+1)/2
write(s,'(3i1)')(iarray(i), i=m+1,m-1,-1)
end if
end function classifym3
subroutine antibase(base, m, digits, n) ! digits ordered by increasing significance
integer, intent(in) :: base, m
integer, intent(out) :: n ! the number of digits
integer, dimension(:), intent(out) :: digits
integer :: em
em = m
do n=1, size(digits)
digits(n) = mod(em, base)
em = em / base
if (0 .eq. em) return
end do
stop 'antibase ran out of space to store result'
end subroutine antibase
end program MiddleMuddle
FreeBASIC
' FB 1.05.0 Win64
Function middleThreeDigits (n As Integer) As String
If n < 0 Then n = -n
If n < 100 Then Return "" '' error code
If n < 1000 Then Return Str(n)
If n < 10000 Then Return ""
Dim ns As String = Str(n)
If Len(ns) Mod 2 = 0 Then Return "" '' need to have an odd number of digits for there to be 3 middle
Return Mid(ns, Len(ns) \ 2, 3)
End Function
Dim a(1 To 16) As Integer => _
{123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -123451, 2, -1, -10, 2002, -2002, 0}
Dim As Integer i
Dim As String result
Print "The 3 middle digits of the following numbers are : "
Print
For i = 1 To 16
result = middleThreeDigits(a(i))
Print a(i), " => ";
If result <> "" Then
Print result
Else
Print "Error: does not have 3 middle digits"
End If
Next
Print
Print "Press any key to quit"
Sleep
- Output:
The 3 middle digits of the following numbers are : 123 => 123 12345 => 234 1234567 => 345 987654321 => 654 10001 => 000 -10001 => 000 -123 => 123 -100 => 100 100 => 100 -123451 => Error: does not have 3 middle digits 2 => Error: does not have 3 middle digits -1 => Error: does not have 3 middle digits -10 => Error: does not have 3 middle digits 2002 => Error: does not have 3 middle digits -2002 => Error: does not have 3 middle digits 0 => Error: does not have 3 middle digits
FutureBasic
local fn MiddleThreeDigits( n as NSInteger ) as CFStringRef
CFStringRef testStr, resultStr
NSInteger length, middle
testStr = fn StringWithFormat( @"%ld", n )
testStr = fn StringByReplacingOccurrencesOfString( testStr, @"-", @"" )
length = len(testStr)
if length < 3 then resultStr = fn StringWithFormat( @"%10ld -> Error: Less than three digits.", n ) : exit fn
if length == 3 then resultStr = fn StringWithFormat( @"%10ld -> %@", n, testStr ) : exit fn
length = len(testStr)
if ( length mod 2 == 0 )
resultStr = fn StringWithFormat( @"%10ld -> Error: Even length; needs odd.", n )
else
middle = length / 2
resultStr = fn StringWithFormat( @"%10ld -> %@", n, mid( testStr, middle -1, 3 ) )
end if
end fn = resultStr
window 1, @"Middle Three Digits", ( 0, 0, 400, 300 )
NSUInteger i, count
CFArrayRef testArr
CFNumberRef tempNum
testArr = @[@123,@12345,@1234567,@987654321,@10001,@-10001,¬
@-123,@-100,@100,@-12345,@1,@2,@-1,@-10,@2002,@-2002,@0]
count = fn ArrayCount( testArr )
for i = 0 to count - 1
print fn MiddleThreeDigits( fn NumberIntegerValue( testArr[i] ) )
next
HandleEvents
- Output:
123 -> 123 12345 -> 234 1234567 -> 345 987654321 -> 654 10001 -> 000 -10001 -> 000 -123 -> 123 -100 -> 100 100 -> 100 -12345 -> 234 1 -> Error: Less than three digits. 2 -> Error: Less than three digits. -1 -> Error: Less than three digits. -10 -> Error: Less than three digits. 2002 -> Error: Even length; needs odd. -2002 -> Error: Even length; needs odd. 0 -> Error: Less than three digits.
Gambas
Click this link to run this code
Public Sub Main()
Dim iList As Integer[] = [123, 12345, 1234567, 987654321, 10001,
-10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0] 'Array of integers to process
Dim sTemp As String 'Temp string
Dim siCount As Short 'Counter
Dim sAnswer As New String[] 'Array, resons for failure or 'middle three digits'
For siCount = 0 To iList.Max 'Loop through the integers
sTemp = Str(Abs(iList[siCount])) 'Convert integer to positive and place in sTemp as a string
If Len(sTemp) < 3 Then 'If sTemp has less than 3 characters then..
sAnswer.Add("This integer has less than 3 characters") 'Place text in sAnswers
Else If Even(Len(sTemp)) Then 'Else If sTemp is of even length then
sAnswer.Add("This integer has an even length") 'Place text in sAnswers
Else 'Else..
sAnswer.Add(Mid(sTemp, Int(Len(sTemp) / 2), 3)) 'Place the middle 3 digits in sAnswer
Endif
Next
For siCount = 0 To iList.Max 'Loop through the integers
Print Space$(10 - Len(Str(iList[siCount]))) &
iList[siCount] & " : " & sAnswer[siCount] 'Print out results
Next
End
Output:
12345 : 234 1234567 : 345 987654321 : 654 10001 : 000 -10001 : 000 -123 : 123 -100 : 100 100 : 100 -12345 : 234 1 : This integer has less than 3 characters 2 : This integer has less than 3 characters -1 : This integer has less than 3 characters -10 : This integer has less than 3 characters 2002 : This integer has an even length -2002 : This integer has an even length 0 : This integer has less than 3 characters
Go
Unlike most Go examples on RC, this is written as a package to show operation of the go test tool.
File m3.go:
package m3
import (
"errors"
"strconv"
)
var (
ErrorLT3 = errors.New("N of at least three digits required.")
ErrorEven = errors.New("N with odd number of digits required.")
)
func Digits(i int) (string, error) {
if i < 0 {
i = -i
}
if i < 100 {
return "", ErrorLT3
}
s := strconv.Itoa(i)
if len(s)%2 == 0 {
return "", ErrorEven
}
m := len(s) / 2
return s[m-1 : m+2], nil
}
File m3_test.go:
package m3_test
import (
"testing"
"m3"
)
func TestPassing(t *testing.T) {
type s struct {
i int
m string
}
tcs := []s{
{123, "123"},
{12345, "234"},
{1234567, "345"},
{987654321, "654"},
{10001, "000"},
{-10001, "000"},
}
for _, tc := range tcs {
m, err := m3.Digits(tc.i)
if err != nil {
t.Fatalf("d(%d) returned %q.", tc.i, err)
}
if m != tc.m {
t.Fatalf("d(%d) expected %q, got %q.", tc.i, tc.m, m)
}
t.Logf("d(%d) = %q.", tc.i, m)
}
}
func TestFailing(t *testing.T) {
type s struct {
i int
err error
}
tcs := []s{
{1, m3.ErrorLT3},
{2, m3.ErrorLT3},
{-1, m3.ErrorLT3},
{-10, m3.ErrorLT3},
{2002, m3.ErrorEven},
{-2002, m3.ErrorEven},
{0, m3.ErrorLT3},
}
for _, tc := range tcs {
m, err := m3.Digits(tc.i)
if err == nil {
t.Fatal("d(%d) expected error %q, got non-error %q.",
tc.i, tc.err, m)
}
if err != tc.err {
t.Fatal("d(d) expected error %q, got %q", tc.i, tc.err, err)
}
t.Logf("d(%d) returns %q", tc.i, err)
}
}
- Output:
Output of go test is normally terse:
> go test PASS ok m3 0.008s
With -v (for verbose):
> go test -v === RUN TestPassing-4 --- PASS: TestPassing-4 (0.00 seconds) m3_test.go:30: d(123) = "123". m3_test.go:30: d(12345) = "234". m3_test.go:30: d(1234567) = "345". m3_test.go:30: d(987654321) = "654". m3_test.go:30: d(10001) = "000". m3_test.go:30: d(-10001) = "000". === RUN TestFailing-4 --- PASS: TestFailing-4 (0.00 seconds) m3_test.go:57: d(1) returns "N of at least three digits required." m3_test.go:57: d(2) returns "N of at least three digits required." m3_test.go:57: d(-1) returns "N of at least three digits required." m3_test.go:57: d(-10) returns "N of at least three digits required." m3_test.go:57: d(2002) returns "N with odd number of digits required." m3_test.go:57: d(-2002) returns "N with odd number of digits required." m3_test.go:57: d(0) returns "N of at least three digits required." PASS ok m3 0.008s
Gosu
var valid = {123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345}
valid.each(\ num ->print(middleThree(num)))
var errant = {1, 2, -1, -10, 2002, -2002, 0}
errant.each(\ num ->print(middleThree(num)))
function middleThree(x: int) : String {
var s = Math.abs(x) as String
if(s.length < 3) return "Error: ${x} has less than 3 digits"
if(s.length % 2 == 0) return "Error: ${x} has an even number of digits"
var start = (s.length / 2) - 1
return s.substring(start, start + 3)
}
- Output:
123 234 345 654 000 000 123 100 100 234 Error: 1 has less than 3 digits Error: 2 has less than 3 digits Error: -1 has less than 3 digits Error: -10 has less than 3 digits Error: 2002 has an even number of digits Error: -2002 has an even number of digits Error: 0 has less than 3 digits
Groovy
def middleThree(Number number) {
def text = Math.abs(number) as String
assert text.size() >= 3 : "'$number' must be more than 3 numeric digits"
assert text.size() % 2 == 1 : "'$number' must have an odd number of digits"
int start = text.size() / 2 - 1
text[start..(start+2)]
}
Test Code:
[123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0].each { number ->
def text = (number as String).padLeft(10)
try {
println "$text: ${middleThree(number)}"
} catch(AssertionError error) {
println "$text cannot be converted: $error.message"
}
}
Output:
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1 cannot be converted: '1' must be more than 3 numeric digits. Expression: (text.size() >= 3) 2 cannot be converted: '2' must be more than 3 numeric digits. Expression: (text.size() >= 3) -1 cannot be converted: '-1' must be more than 3 numeric digits. Expression: (text.size() >= 3) -10 cannot be converted: '-10' must be more than 3 numeric digits. Expression: (text.size() >= 3) 2002 cannot be converted: '2002' must have an odd number of digits. Expression: ((text.size() % 2) == 1) -2002 cannot be converted: '-2002' must have an odd number of digits. Expression: ((text.size() % 2) == 1) 0 cannot be converted: '0' must be more than 3 numeric digits. Expression: (text.size() >= 3)
Haskell
------------------- MIDDLE THREE DIGITS ------------------
mid3 :: Int -> Either String String
mid3 n
| m < 100 = Left "too small"
| even lng = Left "even number of digits"
| otherwise = Right . take 3 $ drop ((lng - 3) `div` 2) s
where
m = abs n
s = show m
lng = length s
--------------------------- TEST -------------------------
main :: IO ()
main = do
let xs =
[ 123
, 12345
, 1234567
, 987654321
, 10001
, -10001
, -123
, -100
, 100
, -12345
, 1
, 2
, -1
, -10
, 2002
, -2002
, 0
]
w = maximum $ length . show <$> xs
(putStrLn . unlines) $
(\n ->
justifyRight w ' ' (show n) <>
" -> " <> either (concat . ("(" :) . (: [")"])) id (mid3 n)) <$>
xs
justifyRight :: Int -> Char -> String -> String
justifyRight n c = (drop . length) <*> (replicate n c <>)
Output:
123 -> 123 12345 -> 234 1234567 -> 345 987654321 -> 654 10001 -> 000 -10001 -> 000 -123 -> 123 -100 -> 100 100 -> 100 -12345 -> 234 1 -> (too small) 2 -> (too small) -1 -> (too small) -10 -> (too small) 2002 -> (even number of digits) -2002 -> (even number of digits) 0 -> (too small)
Icon and Unicon
The following solution works in both languages.
procedure main(a)
every n := !a do write(right(n,15)," -> ",midM(n))
end
procedure midM(n,m)
/m := 3
n := abs(n)
return n ? if (*n >= m) then
if (((*n-m) % 2) = 0) then (move((*n - m)/2),move(m))
else "wrong number of digits"
else "too short"
end
with output:
->m3d 123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 1 2 -1 -10 2002 -2002 0 123 -> 123 12345 -> 234 1234567 -> 345 987654321 -> 654 10001 -> 000 -10001 -> 000 -123 -> 123 -100 -> 100 100 -> 100 -12345 -> 234 1 -> too short 2 -> too short -1 -> too short -10 -> too short 2002 -> wrong number of digits -2002 -> wrong number of digits 0 -> too short ->
J
A key issue here is that some numbers do not have a "middle 3 digits" -- either because the number is too short, or because it has an even number of digits (or both, two digit numbers).
Solution:
asString=: ":"0 NB. convert vals to strings
getPfxSize=: [: -:@| 3 -~ # NB. get size of prefix to drop before the 3 middle digits
getMid3=: (3 {. getPfxSize }. ,&'err') :: ('err'"_) NB. get 3 middle digits or return 'err'
getMiddle3=: getMid3@asString@:|
Example:
vals=: 123 12345 1234567 987654321 10001 _10001 _123 _100 100 _12345 1 2 _1 _10 2002 _2002 0
getMiddle3 vals
123
234
345
654
000
000
123
100
100
234
err
err
err
err
err
err
err
Or, expressed more concisely:
({~ 2 1 0 -~ -:@>:@#) ::('err'"_)@":@| vals
123
234
345
654
000
000
123
100
100
234
err
err
err
err
err
err
err
Java
public class MiddleThreeDigits {
public static void main(String[] args) {
final long[] passing = {123, 12345, 1234567, 987654321, 10001, -10001,
-123, -100, 100, -12345, Long.MIN_VALUE, Long.MAX_VALUE};
final int[] failing = {1, 2, -1, -10, 2002, -2002, 0, Integer.MIN_VALUE,
Integer.MAX_VALUE};
for (long n : passing)
System.out.printf("middleThreeDigits(%s): %s\n", n, middleThreeDigits(n));
for (int n : failing)
System.out.printf("middleThreeDigits(%s): %s\n", n, middleThreeDigits(n));
}
public static <T> String middleThreeDigits(T n) {
String s = String.valueOf(n);
if (s.charAt(0) == '-')
s = s.substring(1);
int len = s.length();
if (len < 3 || len % 2 == 0)
return "Need odd and >= 3 digits";
int mid = len / 2;
return s.substring(mid - 1, mid + 2);
}
}
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(-9223372036854775808): 368 middleThreeDigits(9223372036854775807): 368 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 middleThreeDigits(-2147483648): Need odd and >= 3 digits middleThreeDigits(2147483647): Need odd and >= 3 digits
JavaScript
function middleThree(x){
var n=''+Math.abs(x); var l=n.length-1;
if(l<2||l%2) throw new Error(x+': Invalid length '+(l+1));
return n.slice(l/2-1,l/2+2);
}
[123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345,
1, 2, -1, -10, 2002, -2002, 0].forEach(function(n){
try{console.log(n,middleThree(n))}catch(e){console.error(e.message)}
});
123 "123" 12345 "234" 1234567 "345" 987654321 "654" 10001 "000" -10001 "000" -123 "123" -100 "100" 100 "100" -12345 "234" 1: Invalid length 1 2: Invalid length 1 -1: Invalid length 1 -10: Invalid length 2 2002: Invalid length 4 -2002: Invalid length 4 0: Invalid length 1
Or, using an option type, composing a solution from existing generic primitives, and formatting the output a little:
(() => {
'use strict';
// mid3digits :: Int -> Either String String
const mid3digits = n => {
const
m = abs(n),
s = m.toString();
return 100 > m ? (
Left('Less than 3 digits')
) : even(length(s)) ? (
Left('Even digit count')
) : Right(take(3, drop(quot(length(s) - 3, 2), s)));
};
// TEST -----------------------------------------------
const main = () => {
const
xs = [
123, 12345, 1234567, 987654321, 10001, -10001, -123,
-100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0
],
w = maximum(map(x => x.toString().length, xs));
return (
unlines(map(
n => justifyRight(w, ' ', n.toString()) + ' -> ' +
either(
s => '(' + s + ')',
id,
mid3digits(n)
),
xs
))
);
};
// GENERIC FUNCTIONS ----------------------------------
// Left :: a -> Either a b
const Left = x => ({
type: 'Either',
Left: x
});
// Right :: b -> Either a b
const Right = x => ({
type: 'Either',
Right: x
});
// abs :: Num -> Num
const abs = Math.abs;
// drop :: Int -> [a] -> [a]
// drop :: Int -> Generator [a] -> Generator [a]
// drop :: Int -> String -> String
const drop = (n, xs) =>
Infinity > length(xs) ? (
xs.slice(n)
) : (take(n, xs), xs);
// either :: (a -> c) -> (b -> c) -> Either a b -> c
const either = (fl, fr, e) =>
'Either' === e.type ? (
undefined !== e.Left ? (
fl(e.Left)
) : fr(e.Right)
) : undefined;
// even :: Int -> Bool
const even = n => 0 === n % 2;
// foldl1 :: (a -> a -> a) -> [a] -> a
const foldl1 = (f, xs) =>
1 < xs.length ? xs.slice(1)
.reduce(f, xs[0]) : xs[0];
// id :: a -> a
const id = x => x;
// justifyRight :: Int -> Char -> String -> String
const justifyRight = (n, cFiller, s) =>
n > s.length ? (
s.padStart(n, cFiller)
) : s;
// Returns Infinity over objects without finite length.
// This enables zip and zipWith to choose the shorter
// argument when one is non-finite, like cycle, repeat etc
// length :: [a] -> Int
const length = xs =>
(Array.isArray(xs) || 'string' === typeof xs) ? (
xs.length
) : Infinity;
// maximum :: Ord a => [a] -> a
const maximum = xs =>
0 < xs.length ? (
foldl1((a, x) => x > a ? x : a, xs)
) : undefined;
// map :: (a -> b) -> [a] -> [b]
const map = (f, xs) => xs.map(f);
// quot :: Int -> Int -> Int
const quot = (n, m) => Math.floor(n / m);
// take :: Int -> [a] -> [a]
// take :: Int -> String -> String
const take = (n, xs) =>
'GeneratorFunction' !== xs.constructor.constructor.name ? (
xs.slice(0, n)
) : [].concat.apply([], Array.from({
length: n
}, () => {
const x = xs.next();
return x.done ? [] : [x.value];
}));
// unlines :: [String] -> String
const unlines = xs => xs.join('\n');
// MAIN ---
return main();
})();
- Output:
123 -> 123 12345 -> 234 1234567 -> 345 987654321 -> 654 10001 -> 000 -10001 -> 000 -123 -> 123 -100 -> 100 100 -> 100 -12345 -> 234 1 -> (Less than 3 digits) 2 -> (Less than 3 digits) -1 -> (Less than 3 digits) -10 -> (Less than 3 digits) 2002 -> (Even digit count) -2002 -> (Even digit count) 0 -> (Less than 3 digits)
jq
def middle3:
if . < 0 then -. else . end
| tostring as $s
| ($s | length) as $n
| if $n<3 or ($n % 2) == 0 then "invalid length: \($n)"
else (($n - 1) / 2) as $n | $s[$n - 1 : $n + 2]
end ;
(123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0)
| "\(.) => \( .|middle3 )"
Typescript:
$ jq -r -n -f Middle_three_digits.jq
123 => 123
12345 => 234
1234567 => 345
987654321 => 654
10001 => 000
-10001 => 000
-123 => 123
-100 => 100
100 => 100
-12345 => 234
1 => invalid length: 1
2 => invalid length: 1
-1 => invalid length: 1
-10 => invalid length: 2
2002 => invalid length: 4
-2002 => invalid length: 4
0 => invalid length: 1
Julia
using Printf
function middle3(n::Integer)
l = ndigits(n)
iseven(l) && error("n must have an odd number of digits")
l < 3 && error("n must have 3 digits or more")
mid = (l + 1) ÷ 2
abs(n) ÷ 10^(mid-2) % 10^3
end
for n = [123, 12345, 1234567, 987654321, 10001, -10001, -123,
-100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0]
@printf("%10d -> %s\n", n, try middle3(n) catch e e.msg end)
end
- Output:
123 -> 123 12345 -> 234 1234567 -> 345 987654321 -> 654 10001 -> 000 -10001 -> 000 -123 -> 123 -100 -> 100 100 -> 100 -12345 -> 234 1 -> n must have 3 digits or more 2 -> n must have 3 digits or more -1 -> n must have 3 digits or more -10 -> n must have an odd number of digits 2002 -> n must have an odd number of digits -2002 -> n must have an odd number of digits 0 -> n must have 3 digits or more
K
/ Rosetta code - Middle three digits
/ mid3.k
mid3: {qs:$x;:[qs[0]="-";qs: 1 _ qs];:[(#qs)<3;:"small";(1+#qs)!2;:"even"];p:(-3+#qs)%2;:(|p _|p _ qs)}
The output of the session:
- Output:
K Console - Enter \ for help \l mid3 mid3' 123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 1 2 -1 -10 2002 -2002 0 ("123" "234" "345" "654" "000" "000" "123" "100" "100" "234" "small" "small" "small" "small" "even" "even" "small")
Klingphix
include ..\Utilitys.tlhy
( 123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 1 2 -1 -10 2002 -2002 0 )
len [
get ( dup " : " ) lprint
abs tostr len >ps
tps 3 < ( ["too short" ?]
[ tps 2 mod ( [tps 2 / 3 slice ?] ["is even" ?] ) if]
) if
ps> drop drop
] for
" " input
- Output:
123 : 123 12345 : 234 1234567 : 345 987654321 : 654 10001 : 000 -10001 : 000 -123 : 123 -100 : 100 100 : 100 -12345 : 234 1 : too short 2 : too short -1 : too short -10 : too short 2002 : is even -2002 : is even 0 : too short
Klong
items::[123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 1 2 -1 -10 2002 -2002 0]
mid3::{[d k];:[3>k::#$#x;"small":|0=k!2;"even";(-d)_(d::_(k%2)-1)_$#x]}
.p(mid3'items)
Output:
[123 234 345 654 000 000 123 100 100 234 small small small small even even small]
Kotlin
fun middleThree(x: Int): Int? {
val s = Math.abs(x).toString()
return when {
s.length < 3 -> null // throw Exception("too short!")
s.length % 2 == 0 -> null // throw Exception("even number of digits")
else -> ((s.length / 2) - 1).let { s.substring(it, it + 3) }.toInt()
}
}
fun main(args: Array<String>) {
println(middleThree(12345)) // 234
println(middleThree(1234)) // null
println(middleThree(1234567)) // 345
println(middleThree(123))// 123
println(middleThree(123555)) //null
}
Lambdatalk
{def S 123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345
1 2 -1 -10 2002 -2002 0}
-> S
{def middle3digits
{lambda {:w}
{let { {:w {abs :w}}
{:l {W.length {abs :w}}}
} {if {= {% :l 2} 0}
then has an even number of digits
else {if {< :l 3}
then has not enough digits
else {W.get {- {/ :l 2} 1} :w}
{W.get {/ :l 2} :w}
{W.get {+ {/ :l 2} 1} :w} }}}}}
-> middle3digits
{table
{S.map {lambda {:i}
{tr {td {@ style="text-align:right;"}:i:}
{td {middle3digits :i}}}}
{S}} }
->
123: 123
12345: 234
1234567: 345
987654321: 654
10001: 000
-10001: 000
-123: 123
-100: 100
100: 100
-12345: 234
1: has not enough digits
2: has not enough digits
-1: has not enough digits
-10: has an even number of digits
2002: has an even number of digits
-2002: has an even number of digits
0: has not enough digits
Lasso
define middlethree(value::integer) => {
local(
pos_value = math_abs(#value),
stringvalue = #pos_value -> asstring,
intlength = #stringvalue -> size,
middle = integer((#intlength + 1) / 2),
prefix = string(#value) -> padleading(15)& + ': '
)
#intlength < 3 ? return #prefix + 'Error: too few digits'
not(#intlength % 2) ? return #prefix + 'Error: even number of digits'
return #prefix + #stringvalue -> sub(#middle -1, 3)
}
'<pre>'
with number in array(123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0) do {^
middlethree(#number)
'<br />'
^}
'</pre>'
Output
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: Error: too few digits 2: Error: too few digits -1: Error: too few digits -10: Error: too few digits 2002: Error: even number of digits -2002: Error: even number of digits 0: Error: too few digits
Logo
to middle3digits :n
if [less? :n 0] [make "n minus :n]
local "len make "len count :n
if [less? :len 3] [(throw "error [Number must have at least 3 digits])]
if [equal? 0 modulo :len 2] [(throw "error [Number must have odd number of digits])]
while [greater? count :n 3] [
make "n butlast butfirst :n
]
output :n
end
foreach [123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345
1 2 -1 -10 2002 -2002 0] [
type sentence (word ? ": char 9) runresult [if [less? count ? 7] [char 9]]
make "mid runresult [catch "error [middle3digits ?]]
print ifelse [empty? :mid] [item 2 error] [:mid]
]
bye
- Output:
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: Number must have at least 3 digits 2: Number must have at least 3 digits -1: Number must have at least 3 digits -10: Number must have at least 3 digits 2002: Number must have odd number of digits -2002: Number must have odd number of digits 0: Number must have at least 3 digits
Lua
function middle_three(n)
if n < 0 then
n = -n
end
n = tostring(n)
if #n % 2 == 0 then
return "Error: the number of digits is even."
elseif #n < 3 then
return "Error: the number has less than 3 digits."
end
local l = math.floor(#n/2)
return n:sub(l, l+2)
end
-- test
do
local t = {123, 12345, 1234567, 987654321,
10001, -10001, -123, -100, 100, -12345, 1,
2, -1, -10, 2002, -2002, 0}
for _,n in pairs(t) do
print(n, middle_three(n))
end
end
- Output:
123 123 12345 234 1234567 345 987654321 654 10001 000 -10001 000 -123 123 -100 100 100 100 -12345 234 1 Error: the number has less than 3 digits. 2 Error: the number has less than 3 digits. -1 Error: the number has less than 3 digits. -10 Error: the number is even. 2002 Error: the number is even. -2002 Error: the number is even. 0 Error: the number has less than 3 digits.
Maple
middleDigits := proc(n)
local nList, start;
nList := [seq(parse(i), i in convert (abs(n), string))];
if numelems(nList) < 3 then
printf ("%9a: Error: Not enough digits.", n);
elif numelems(nList) mod 2 = 0 then
printf ("%9a: Error: Even number of digits.", n);
else
start := (numelems(nList)-1)/2;
printf("%9a: %a%a%a", n, op(nList[start..start+2]));
end if;
end proc:
a := [123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345,
1, 2, -1, -10, 2002, -2002, 0]:
for i in a do
middleDigits(i);
printf("\n");
end do;
- Output:
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: Error: Not enough digits. 2: Error: Not enough digits. -1: Error: Not enough digits. -10: Error: Not enough digits. 2002: Error: Even number of digits. -2002: Error: Even number of digits. 0: Error: Not enough digits.
Mathematica /Wolfram Language
middleThree[n_Integer] :=
Block[{digits = IntegerDigits[n], len},
len = Length[digits];
If[len < 3 || EvenQ[len], "number digits odd or less than 3",
len = Ceiling[len/2];
StringJoin @@ (ToString /@ digits[[len - 1 ;; len + 1]])]]
testData = {123, 12345, 1234567, 987654321, 10001, -10001, -123, -100,
100, -12345, 1, 2, -1, -10, 2002, -2002, 0};
Column[middleThree /@ testData]
- Output:
123234 345 654 000 000 123 100 100 234 err: n too small err: n too small err: n too small err: n too small err: even number of digits err: even number of digits
err: n too small
MATLAB / Octave
function s=middle_three_digits(a)
% http://rosettacode.org/wiki/Middle_three_digits
s=num2str(abs(a));
if ~mod(length(s),2)
s='*** error: number of digits must be odd ***';
return;
end;
if length(s)<3,
s='*** error: number of digits must not be smaller than 3 ***';
return;
end;
s = s((length(s)+1)/2+[-1:1]);
Test with
x=[123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0];
for k=1:length(x); fprintf(1,'%9i:%s\n',x(k),middle_three_digits(x(k)));end;
Result
123:123 12345:234 1234567:457 987654321:654 10001:000 -10001:000 -123:123 -100:100 100:100 -12345:234 1:*** error: number of digits must not be smaller than 3 *** 2:*** error: number of digits must not be smaller than 3 *** -1:*** error: number of digits must not be smaller than 3 *** -10:*** error: number of digits must be odd *** 2002:*** error: number of digits must be odd *** -2002:*** error: number of digits must be odd *** 0:*** error: number of digits must not be smaller than 3 ***
MiniScript
middle3 = function(num)
if num < 0 then num = -num
s = str(num)
if s.len < 3 then return "Input too short"
if s.len % 2 == 0 then return "Input length not odd"
mid = (s.len + 1) / 2 - 1
return s[mid-1:mid+2]
end function
for test in [123, 12345, 1234567, 987654321, 10001, -10001, -123, -100,
100, -12345, 1, 2, -1, -10, 2002, -2002, 0]
print test + " --> " + middle3(test)
end for
- Output:
123 --> 123 12345 --> 234 1234567 --> 345 987654321 --> 654 10001 --> 000 -10001 --> 000 -123 --> 123 -100 --> 100 100 --> 100 -12345 --> 234 1 --> Input too short 2 --> Input too short -1 --> Input too short -10 --> Input too short 2002 --> Input length not odd -2002 --> Input length not odd 0 --> Input too short
МК-61/52
П0 lg [x] 3 - x>=0 23 ИП0 1 0
/ [x] ^ lg [x] 10^x П1 / {x} ИП1
* БП 00 1 + x=0 29 ИП0 С/П 0
/
Instruction: enter the number in the РX (on display), the result after the execution of the same. In the case of an even or less than 3 number of digits the indicator displays an error message.
ML
mLite
val test_array = ["123","12345","1234567","987654321","10001","~10001","~123","~100","100","~12345","1","2","~1","~10","2002","~2002","0"];
fun even (x rem 2 = 0) = true | _ = false;
fun middleThreeDigits
(h :: t, s, 1 ) = s @ " --> too small"
| (h :: t, s, 2 ) = s @ " --> has even digits"
| (h :: t, s, 3 ) where (len (h :: t) = 3) = s @ " --> " @ (implode (h :: t))
| (h :: t, s, 3 ) = (middleThreeDigits ( sub (t, 0, (len t)-1), s, 3))
| (h :: t, s, m) = if len (h :: t) < 3 then
middleThreeDigits (h :: t, s, 1)
else
if even ` len (h :: t) then
middleThreeDigits (h :: t, s, 2)
else
middleThreeDigits (h :: t, s, 3)
| s = if sub (s, 0, 1) = "~" then
middleThreeDigits (sub (explode s, 1, len s), s, 0)
else
middleThreeDigits (explode s, s, 0)
;
map (println o middleThreeDigits) test_array;
Output:
123 --> 123 12345 --> 234 1234567 --> 345 987654321 --> 654 10001 --> 000 ~10001 --> 000 ~123 --> 123 ~100 --> 100 100 --> 100 ~12345 --> 234 1 --> too small 2 --> too small ~1 --> too small ~10 --> too small 2002 --> has even digits ~2002 --> has even digits 0 --> too small
MUMPS
This sample shows the MUMPS code required to pass the specification.
/* MUMPS */
MID3(N) ;
N LEN,N2
S N2=$S(N<0:-N,1:N)
I N2<100 Q "NUMBER TOO SMALL"
S LEN=$L(N2)
I LEN#2=0 Q "EVEN NUMBER OF DIGITS"
Q $E(N2,LEN\2,LEN\2+2)
F I=123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345,1,2,-1,-10,2002,-2002,0 W !,$J(I,10),": ",$$MID3^MID3(I)
Output:
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: NUMBER TOO SMALL 2: NUMBER TOO SMALL -1: NUMBER TOO SMALL -10: NUMBER TOO SMALL 2002: EVEN NUMBER OF DIGITS -2002: EVEN NUMBER OF DIGITS 0: NUMBER TOO SMALL
NetRexx
This sample goes the extra mile and provides a method that can display the middle N digits from the input value. To satisfy the requirements of this task, a static invocation of this general method is also provided with the value 3 hard coded as the digit count.
/* NetRexx */
options replace format comments java crossref symbols nobinary
sl = '123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345' -
'1 2 -1 -10 2002 -2002 0' -
'abc 1e3 -17e-3 4004.5 12345678 9876543210' -- extras
parse arg digsL digsR .
if \digsL.datatype('w') then digsL = 3
if \digsR.datatype('w') then digsR = digsL
if digsL > digsR then digsR = digsL
loop dc = digsL to digsR
say 'Middle' dc 'characters'
loop nn = 1 to sl.words()
val = sl.word(nn)
say middleDigits(dc, val)
end nn
say
end dc
return
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method middle3Digits(val) constant
return middleDigits(3, val)
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method middleDigits(digitCt, val) constant
text = val.right(15)':'
even = digitCt // 2 == 0 -- odd or even?
select
when digitCt <= 0 then text = 'digit selection size must be >= 1'
when \val.datatype('w') then text = text 'is not a whole number'
when val.abs().length < digitCt then text = text 'has less than' digitCt 'digits'
when \even & val.abs().length // 2 == 0 then text = text 'does not have an odd number of digits'
when even & val.abs().length // 2 \= 0 then text = text 'does not have an even number of digits'
otherwise do
val = val.abs()
valL = val.length
cutP = (valL - digitCt) % 2
text = text val.substr(cutP + 1, digitCt)
end
catch NumberFormatException
text = val 'is not numeric'
end
return text
Output:
Middle 3 characters 123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: has less than 3 digits 2: has less than 3 digits -1: has less than 3 digits -10: has less than 3 digits 2002: does not have an odd number of digits -2002: does not have an odd number of digits 0: has less than 3 digits abc: is not a whole number 1e3: is not a whole number -17e-3: is not a whole number 4004.5: is not a whole number 12345678: does not have an odd number of digits 9876543210: does not have an odd number of digits
NewLISP
(define (middle3 x)
(if (even? (length x))
(println "You entered " x ". I need an odd number of digits, not " (length x) ".")
(if (< (length x) 3)
(println "You entered " x ". Sorry, but I need 3 or more digits.")
(println "The middle 3 digits of " x " are " ((- (/ (- (length x) 1) 2) 1) 3 (string (abs x))) ".")
)
)
)
(map middle3 lst)
Output:
The middle 3 digits of 123 are 123. The middle 3 digits of 12345 are 234. The middle 3 digits of 1234567 are 345. The middle 3 digits of 987654321 are 654. The middle 3 digits of 10001 are 000. The middle 3 digits of -10001 are 000. The middle 3 digits of -123 are 123. The middle 3 digits of -100 are 100. The middle 3 digits of 100 are 100. The middle 3 digits of -12345 are 234. You entered 1. Sorry, but I need 3 or more digits. You entered 2. Sorry, but I need 3 or more digits. You entered -1. Sorry, but I need 3 or more digits. You entered 10. I need an odd number of digits, not 2. You entered 2002. I need an odd number of digits, not 4. You entered -2002. I need an odd number of digits, not 4. You entered 0. Sorry, but I need 3 or more digits.
Nim
proc middleThreeDigits(i: int): string =
var s = $abs(i)
if s.len < 3 or s.len mod 2 == 0:
raise newException(ValueError, "Need odd and >= 3 digits")
let mid = s.len div 2
return s[mid-1..mid+1]
const passing = @[123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345]
const failing = @[1, 2, -1, -10, 2002, -2002, 0]
for i in passing & failing:
var answer = try: middleThreeDigits(i)
except ValueError: getCurrentExceptionMsg()
echo "middleThreeDigits(", i, ") returned: ", answer
- Output:
middleThreeDigits(123) returned: 123 middleThreeDigits(12345) returned: 234 middleThreeDigits(1234567) returned: 345 middleThreeDigits(987654321) returned: 654 middleThreeDigits(10001) returned: 000 middleThreeDigits(-10001) returned: 000 middleThreeDigits(-123) returned: 123 middleThreeDigits(-100) returned: 100 middleThreeDigits(100) returned: 100 middleThreeDigits(-12345) returned: 234 middleThreeDigits(1) returned: Need odd and >= 3 digits middleThreeDigits(2) returned: Need odd and >= 3 digits middleThreeDigits(-1) returned: Need odd and >= 3 digits middleThreeDigits(-10) returned: Need odd and >= 3 digits middleThreeDigits(2002) returned: Need odd and >= 3 digits middleThreeDigits(-2002) returned: Need odd and >= 3 digits middleThreeDigits(0) returned: Need odd and >= 3 digits
Objeck
class Test {
function : Main(args : String[]) ~ Nil {
text := "123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0";
ins := text->Split(",");
each(i : ins) {
in := ins[i]->Trim();
IO.Console->Print(in)->Print(": ");
in := (in->Size() > 0 & in->Get(0) = '-') ? in->SubString(1, in->Size() - 1) : in;
IO.Console->PrintLine((in->Size() < 2 | in->Size() % 2 = 0) ? "Error" : in->SubString((in->Size() - 3) / 2, 3));
};
}
}
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: Error 2: Error -1: Error -10: Error 2002: Error -2002: Error 0: Error
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;
;;
- 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
Oforth
: middle3
| s sz |
abs asString dup ->s size ->sz
sz 3 < ifTrue: [ "Too short" println return ]
sz isEven ifTrue: [ "Not odd number of digits" println return ]
sz 3 - 2 / 1+ dup 2 + s extract ;
- Output:
[ 123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345] map(#middle3) println [123, 234, 345, 654, 000, 000, 123, 100, 100, 234] [ 1, 2, -1, -10, 2002, -2002, 0 ] apply(#middle3) Too short Too short Too short Too short Not odd number of digits Not odd number of digits Too short
PARI/GP
middle(n)=my(v=digits(n));if(#v>2&&#v%2,100*v[#v\2]+10*v[#v\2+1]+v[#v\2+2],"no middle 3 digits");
apply(middle,[123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0])
Output:
%1 = [123, 234, 345, 654, 0, 0, 123, 100, 100, 234, "no middle 3 digits", "no middle 3 digits", "no middle 3 digits", "no middle 3 digits", "no middle 3 digits", "no middle 3 digits", "no middle 3 digits"]
If for some reason you want to see the leading digits, you can run
apply(n-> Strprintf("%03d", n), %)
For earlier versions digits
can be defined as
digits(n)=eval(Vec(Str(n)))
or more efficiently as
digits(n)=Vec(apply(n->n-48,Vectorsmall(Str(n))))
Pascal
program Midl3dig;
{$IFDEF FPC}
{$MODE Delphi} //result /integer => Int32 aka longInt etc..
{$ELSE}
{$APPTYPE console} // Delphi
{$ENDIF}
uses
sysutils; //IntToStr
function GetMid3dig(i:NativeInt):Ansistring;
var
n,l: NativeInt;
Begin
setlength(result,0);
//n = |i| jumpless abs
n := i-((ORD(i>0)-1)AND (2*i));
//calculate digitcount
IF n > 0 then
l := trunc(ln(n)/ln(10))+1
else
l := 1;
if l<3 then Begin write('got too few digits'); EXIT; end;
If Not(ODD(l)) then Begin write('got even number of digits'); EXIT; end;
result:= copy(IntToStr(n),l DIV 2,3);
end;
const
Test : array [0..16] of NativeInt =
( 123,12345,1234567,987654321,10001,-10001,
-123,-100,100,-12345,1,2,-1,-10,2002,-2002,0);
var
i,n : NativeInt;
Begin
For i := low(Test) to High(Test) do
Begin
n := Test[i];
writeln(n:9,': ',GetMid3dig(Test[i]));
end;
end.
- Output:
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: got too few digits 2: got too few digits -1: got too few digits -10: got too few digits 2002: got even number of digits -2002: got even number of digits 0: got too few digits
Perl
#!/usr/bin/perl
use strict ;
use warnings ;
sub middlethree {
my $number = shift ;
my $testnumber = abs $number ;
my $error = "Middle 3 digits can't be shown" ;
my $numberlength = length $testnumber ;
if ( $numberlength < 3 ) {
print "$error : $number too short!\n" ;
return ;
}
if ( $numberlength % 2 == 0 ) {
print "$error : even number of digits in $number!\n" ;
return ;
}
my $middle = int ( $numberlength / 2 ) ;
print "Middle 3 digits of $number : " . substr( $testnumber , $middle - 1 , 3 ) . " !\n" ;
return ;
}
my @numbers = ( 123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345 ,
1, 2, -1, -10, 2002, -2002, 0 ) ;
map { middlethree( $_ ) } @numbers ;
- Output:
Middle 3 digits of 123 : 123 ! Middle 3 digits of 12345 : 234 ! Middle 3 digits of 1234567 : 345 ! Middle 3 digits of 987654321 : 654 ! Middle 3 digits of 10001 : 000 ! Middle 3 digits of -10001 : 000 ! Middle 3 digits of -123 : 123 ! Middle 3 digits of -100 : 100 ! Middle 3 digits of 100 : 100 ! Middle 3 digits of -12345 : 234 ! Middle 3 digits can't be shown : 1 too short! Middle 3 digits can't be shown : 2 too short! Middle 3 digits can't be shown : -1 too short! Middle 3 digits can't be shown : -10 too short! Middle 3 digits can't be shown : even number of digits in 2002! Middle 3 digits can't be shown : even number of digits in -2002! Middle 3 digits can't be shown : 0 too short!
Phix
procedure mid3(integer i) string s = sprintf("%d",abs(i)) integer k = length(s)-3 printf(1,"%10d: %s\n",{i,iff(k<0 or and_bits(k,1)?"error":s[k/2+1..k/2+3])}) end procedure constant tests = {123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345, 1,2,-1,-10,2002,-2002,0} for i=1 to length(tests) do mid3(tests[i]) end for
- Output:
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: error 2: error -1: error -10: error 2002: error -2002: error 0: error
PHP
// 32-bit builds of PHP: Integers can be from -2147483648 to 2147483647
// 64-bit builds of PHP: Integers can be from -9223372036854775808 to 9223372036854775807
function middlethree($integer)
{
$int = (int)str_replace('-','',$integer);
$length = strlen($int);
if(is_int($int))
{
if($length >= 3)
{
if($length % 2 == 1)
{
$middle = floor($length / 2) - 1;
return substr($int,$middle, 3);
}
else
{
return 'The value must contain an odd amount of digits...';
}
}
else
{
return 'The value must contain at least three digits...';
}
}
else
{
return 'The value does not appear to be an integer...';
}
}
$numbers = array(123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0);
foreach($numbers as $nums)
{
echo $nums.' : '.middlethree($nums). '<br>';
}
Output:
123 : 123 12345 : 234 1234567 : 345 987654321 : 654 10001 : 000 -10001 : 000 -123 : 123 -100 : 100 100 : 100 -12345 : 234 1 : The value must contain at least three digits... 2 : The value must contain at least three digits... -1 : The value must contain at least three digits... -10 : The value must contain at least three digits... 2002 : The value must contain an odd amount of digits... -2002 : The value must contain an odd amount of digits... 0 : The value must contain at least three digits...
Picat
Prolog-style
get_middle_f1(Str) = [X,Y,Z] =>
append(Pre,[X,Y,Z],Post,Str),
length(Pre) = length(Post).
List slice
get_middle_f2(Str) = Str[Mid-1..Mid+1] =>
Mid = 1 + Str.len div 2.
Test
go =>
Success = [123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345],
Fail = [1, 2, -1, -10, 2002, -2002, 0],
All = Success ++ Fail,
test(All, get_middle_f1),
test(All, get_middle_f2).
% Test and check for exceptions
test(List,F) =>
printf("\nTesting %w:\n", F),
foreach(N in List)
catch(Middle=apply(get_middle,N,F), E, printf("%d = exception %w\n",N,E)),
if E.var() then
println([n=N,middle=Middle])
end
end,
nl.
% Check with the get_middle funcion F
get_middle(N,F) = apply(F,Str) =>
Str = N.abs().to_string(),
Len = length(Str),
if Len mod 2 = 0 then throw $not_odd_length(N)
elseif Len < 3 then throw $number_too_small(N)
end.
- Output:
[n = 123,middle = 123] [n = 12345,middle = 234] [n = 1234567,middle = 345] [n = 987654321,middle = 654] [n = 10001,middle = 000] [n = -10001,middle = 000] [n = -123,middle = 123] [n = -100,middle = 100] [n = 100,middle = 100] [n = -12345,middle = 234] [n = 1,exception = number_too_small(1)] [n = 2,exception = number_too_small(2)] [n = -1,exception = number_too_small(-1)] [n = -10,exception = not_odd_length(-10)] [n = 2002,exception = not_odd_length(2002)] [n = -2002,exception = not_odd_length(-2002)] [n = 0,exception = number_too_small(0)]
PicoLisp
(de middle3digits (N)
(let (Lst (chop (abs N)) Len (length Lst))
(tab (10 -2 -30)
N
":"
(cond
((> 3 Len) "not enough digits")
((bit? 1 Len)
(head 3 (nth Lst (/ Len 2))) )
(T "even number of digits") ) ) ) )
Test:
(mapc middle3digits
(123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345
1 2 -1 -10 2002 -2002 0 ) )
Output:
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: not enough digits 2: not enough digits -1: not enough digits -10: not enough digits 2002: even number of digits -2002: even number of digits 0: not enough digits
Pike
string middlethree(int i) {
i = abs(i);
int length = sizeof((string)i);
if(length >= 3) {
if(length % 2 == 1) {
int middle = (int)floor(length / 2) - 1;
return(((string)i)[middle..middle+2]);
}
else {
return "The value must contain an odd amount of digits...";
}
}
else {
return "The value must contain at least three digits...";
}
}
int main() {
array(int) numbers = ({123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0});
foreach(numbers, int nums) {
write((string)nums + " : " + middlethree(nums) + "\n");
}
return 0;
}
- Output:
123 : 123 12345 : 234 1234567 : 345 987654321 : 654 10001 : 000 -10001 : 000 -123 : 123 -100 : 100 100 : 100 -12345 : 234 1 : The value must contain at least three digits... 2 : The value must contain at least three digits... -1 : The value must contain at least three digits... -10 : The value must contain at least three digits... 2002 : The value must contain an odd amount of digits... -2002 : The value must contain an odd amount of digits... 0 : The value must contain at least three digits...
PL/I
middle: procedure options (main); /* 29 October 2013 */
declare n fixed (15);
declare s character (25) varying;
declare in file input;
open file (in) title ('/MIDDLE.DAT,type(text),recsize(100)');
on endfile (in) stop;
do forever;
get file (in) list (n); put skip list (n);
n = abs(n);
s = trim(n);
if length(s) < 3 then put list ('not possible');
else if mod(length(s), 2) = 0 then put list ('not possible');
else
do;
do while (length(s) > 3);
s = substr(s, 2, length(s)-2);
end;
put list ('The middle three digits are: ' || s);
end;
end;
end middle;
Output:
123 The middle three digits are: 123 12345 The middle three digits are: 234 1234567 The middle three digits are: 345 987654321 The middle three digits are: 654 10001 The middle three digits are: 000 -10001 The middle three digits are: 000 -123 The middle three digits are: 123 -100 The middle three digits are: 100 100 The middle three digits are: 100 -123451 not possible 2 not possible -1 not possible -10 not possible 2002 not possible -2002 not possible 0 not possible
Plain English
To run:
Start up.
Test 123.
Test 12345.
Test 1234567.
Test 987654321.
Test 10001.
Test -10001.
Test -123.
Test -100.
Test 100.
Test -12345.
Test 1.
Test 2.
Test -1.
Test -10.
Test 2002.
Test -2002.
Test 0.
Wait for the escape key.
Shut down.
To get the middle three digits of a number giving a string:
Privatize the number.
De-sign the number.
Convert the number to the string.
If the string's length is less than 3, put "Number has fewer than three digits" into the string; exit.
If the string's length is even, put "Number has no middle" into the string; exit.
Put the string's length divided by 2 into a midpoint number.
Slap a substring on the string.
Put the substring's first plus the midpoint minus 1 into the substring's first.
Put the substring's first plus 2 into the substring's last.
Put the substring into the string.
To test a number:
Get the middle three digits of the number giving a string.
Write "" then the number then " -> " then the string on the console.
- Output:
123 -> 123 12345 -> 234 1234567 -> 345 987654321 -> 654 10001 -> 000 -10001 -> 000 -123 -> 123 -100 -> 100 100 -> 100 -12345 -> 234 1 -> Number has fewer than three digits 2 -> Number has fewer than three digits -1 -> Number has fewer than three digits -10 -> Number has fewer than three digits 2002 -> Number has no middle -2002 -> Number has no middle 0 -> Number has fewer than three digits
PowerShell
function middle3($inp){
$str = [Math]::abs($inp)
$leng = "$str".length
if ($leng -lt 3){
Write-host $inp": [ERROR] too short."
Return
}
if (($leng % 2) -eq 0){
Write-host $inp": [ERROR] even number of digits."
} else {
$trimmer = ($leng - 3) / 2
$ans = "$str".subString($trimmer,3)
Write-host $inp": $ans"
}
Return
}
$sample = 123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0
foreach ($x in $sample){middle3 $x}
- Output:
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: [ERROR] too short. 2: [ERROR] too short. -1: [ERROR] too short. -10: [ERROR] too short. 2002: [ERROR] even number of digits. -2002: [ERROR] even number of digits. 0: [ERROR] too short.
Prolog
middle_3_digits(Number, [D1,D2,D3]) :-
verify_middle_3_able(Number, Digits),
append(FrontDigits, [D1,D2,D3| BackDigits], Digits),
same_length(FrontDigits, BackDigits).
verify_middle_3_able(Number, Digits) :-
must_be(number, Number),
AbsNumber is abs(Number),
number_chars(AbsNumber, Digits),
length(Digits, NumDigits),
( 3 > NumDigits -> domain_error('at least 3 digits', Number)
; 0 is NumDigits mod 2 -> domain_error('odd number of digits', Number)
; true
).
Test code:
test_correct :-
TestCases = [123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345],
foreach( ( member(TestCase, TestCases),
middle_3_digits(TestCase, Result) ),
format('Middle 3 digits of ~w ~30|: ~w~n', [TestCase, Result])
).
Testing correct inputs:
?- test_correct. Middle 3 digits of 123 : [1,2,3] Middle 3 digits of 12345 : [2,3,4] Middle 3 digits of 1234567 : [3,4,5] Middle 3 digits of 987654321 : [6,5,4] Middle 3 digits of 10001 : [0,0,0] Middle 3 digits of -10001 : [0,0,0] Middle 3 digits of -123 : [1,2,3] Middle 3 digits of -100 : [1,0,0] Middle 3 digits of 100 : [1,0,0] Middle 3 digits of -12345 : [2,3,4] true.
Errors
?- middle_3_digits(1, S). ERROR: Domain error: `at least 3 digits' expected, found `1' ?- middle_3_digits(2, S). ERROR: Domain error: `at least 3 digits' expected, found `2' ?- middle_3_digits(-1, S). ERROR: Domain error: `at least 3 digits' expected, found `-1' ?- middle_3_digits(-10, S). ERROR: Domain error: `at least 3 digits' expected, found `-10' ?- middle_3_digits(2002, S). ERROR: Domain error: `odd number of digits' expected, found `2002' ?- middle_3_digits(-2002, S). ERROR: Domain error: `odd number of digits' expected, found `-2002' ?- middle_3_digits(0, S). ERROR: Domain error: `at least 3 digits' expected, found `0'
Python
Procedural
>>> 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',)
>>>
Composition of pure functions
Using a composable option type as an alternative to error handling:
'''Middle 3 digits'''
# mid3digits :: Int -> Either String String
def mid3digits(n):
'''Either the middle three digits,
or an explanatory string.'''
m = abs(n)
s = str(m)
return Left('Less than 3 digits') if (100 > m) else (
Left('Even digit count') if even(len(s)) else Right(
s[(len(s) - 3) // 2:][0:3]
)
)
# TEST ----------------------------------------------------
def main():
'''Test'''
def bracketed(x):
return '(' + str(x) + ')'
print(
tabulated('Middle three digits, where defined:\n')(str)(
either(bracketed)(str)
)(mid3digits)([
123, 12345, 1234567, 987654321, 10001, -10001, -123,
-100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0
])
)
# GENERIC -------------------------------------------------
# Left :: a -> Either a b
def Left(x):
'''Constructor for an empty Either (option type) value
with an associated string.'''
return {'type': 'Either', 'Right': None, 'Left': x}
# Right :: b -> Either a b
def Right(x):
'''Constructor for a populated Either (option type) value'''
return {'type': 'Either', 'Left': None, 'Right': x}
# compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
def compose(g):
'''Function composition.'''
return lambda f: lambda x: g(f(x))
# either :: (a -> c) -> (b -> c) -> Either a b -> c
def either(fl):
'''The application of fl to e if e is a Left value,
or the application of fr to e if e is a Right value.'''
return lambda fr: lambda e: fl(e['Left']) if (
None is e['Right']
) else fr(e['Right'])
# even :: Int -> Bool
def even(x):
'''Is x even ?'''
return 0 == x % 2
# tabulated :: String -> (b -> String) -> (a -> b) -> [a] -> String
def tabulated(s):
'''Heading -> x display function -> fx display function ->
f -> value list -> tabular string.'''
def go(xShow, fxShow, f, xs):
w = max(map(compose(len)(str), xs))
return s + '\n' + '\n'.join(
xShow(x).rjust(w, ' ') + ' -> ' + fxShow(f(x)) for x in xs
)
return lambda xShow: lambda fxShow: lambda f: lambda xs: go(
xShow, fxShow, f, xs
)
if __name__ == '__main__':
main()
- Output:
Middle three digits, where defined: 123 -> 123 12345 -> 234 1234567 -> 345 987654321 -> 654 10001 -> 000 -10001 -> 000 -123 -> 123 -100 -> 100 100 -> 100 -12345 -> 234 1 -> (Less than 3 digits) 2 -> (Less than 3 digits) -1 -> (Less than 3 digits) -10 -> (Less than 3 digits) 2002 -> (Even digit count) -2002 -> (Even digit count) 0 -> (Less than 3 digits)
Quackery
[ 1 & not ] is even ( n --> b )
[ over size -
space swap of
swap join ] is justify ( $ n --> $ )
[ abs number$
dup size dup 3 < iff
[ 2drop $ "too few digits" ]
done
dup even iff
[ 2drop $ "even digit count" ]
done
dup 3 = iff
drop done
3 - 2 /
tuck split nip
swap negate split drop ] is middle3 ( n --> $ )
' [ 123 12345 1234567
987654321 10001 -10001
-123 -100 100 -12345 1
2 -1 -10 2002 -2002 0 ]
witheach
[ dup number$ 9 justify echo$
say " --> "
middle3 echo$ cr ]
- Output:
123 --> 123 12345 --> 234 1234567 --> 345 987654321 --> 654 10001 --> 000 -10001 --> 000 -123 --> 123 -100 --> 100 100 --> 100 -12345 --> 234 1 --> too few digits 2 --> too few digits -1 --> too few digits -10 --> too few digits 2002 --> even digit count -2002 --> even digit count 0 --> too few digits
Racket
#lang racket
(define (middle x)
(cond
[(negative? x) (middle (- x))]
[(< x 100) "error: number too small"]
[else
(define s (number->string x))
(define l (string-length s))
(cond [(even? l) "error: number has even length"]
[else (define i (quotient l 2))
(substring s (- i 1) (+ i 2))])]))
(map middle (list 123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345))
(map middle (list 1 2 -1 -10 2002 -2002 0))
The output:
'("123" "234" "345" "654" "000" "000" "123" "100" "100" "234")
'("error: number too small" "error: number too small" "error: number too small" "error: number too small"
"error: number has even length" "error: number has even length" "error: number too small")
Raku
(formerly Perl 6)
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
>;
- 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
It is also possible to write a regular expression with a code assertion:
for [\~] ^10 { say "$_ => $()" if m/^^(\d+) <(\d**3)> (\d+) $$ <?{ $0.chars == $1.chars}> / }
- Output:
01234 => 123 0123456 => 234 012345678 => 345
REXX
version 1
/* REXX ***************************************************************
* 03.02.2013 Walter Pachl
* 19.04.2013 mid 3 is now a function returning the middle 3 digits
* or an error indication
**********************************************************************/
sl='123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345',
'2 -1 -10 2002 -2002 0 abc 1e3 -17e-3'
Do While sl<>'' /* loop through test values */
Parse Var sl s sl /* pick next value */
Say left(s,12) '->' mid3(s) /* test it */
End
Exit
mid3: Procedure
Parse arg d /* take the argument */
Select /* first test for valid input */
When datatype(d)<>'NUM' Then Return 'not a number'
When pos('E',translate(d))>0 Then Return 'not just digits'
When length(abs(d))<3 Then Return 'less than 3 digits'
When length(abs(d))//2<>1 Then Return 'not an odd number of digits'
Otherwise Do /* input is ok */
dx=abs(d) /* get rid of optional sign */
ld=length(dx) /* length of digit string */
z=(ld-3)/2 /* number of digits to cut */
res=substr(dx,z+1,3) /* get middle 3 digits */
End
End
Return res
Output:
123 -> 123 12345 -> 234 1234567 -> 345 987654321 -> 654 10001 -> 000 -10001 -> 000 -123 -> 123 -100 -> 100 100 -> 100 -12345 -> 234 2 -> less than 3 digits -1 -> less than 3 digits -10 -> less than 3 digits 2002 -> not an odd number of digits -2002 -> not an odd number of digits 0 -> less than 3 digits abc -> not a number 1e3 -> not just digits -17e-3 -> not just digits
version 2
A premise: 12.3e2 is an integer (regardless of how it's displayed).
So is the value of a googol and a googolplex.
This REXX version is limited to numbers whose length is ≤ 100,000 decimal digits.
(The decimal digits limit is defined via the numeric digits statement in the first line of the subroutine/procedure.)
/*REXX program returns the three middle digits of a decimal number (or an error msg).*/
n= '123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345',
'+123 0123 2 -1 -10 2002 -2002 0 abc 1e3 -17e-3 1234567.',
1237654.00 1234567890123456789012345678901234567890123456789012345678901234567
do j=1 for words(n); #=word(n,j) /* [↓] format number for pretty output*/
say 'middle 3 digits of' right(#, max(15, length(#) ) ) "──►" middle3(#)
end /*j*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
middle3: procedure; parse arg x; numeric digits 1e6; er=' ***error*** '
if datatype(x,'N') then x=abs(x)/1; L=length(x) /*use abs value; get length*/
if \datatype(x,'W') then return er "argument isn't an integer."
if L<3 then return er "argument is less than three digits."
if L//2==0 then return er "argument isn't an odd number of digits."
return substr(x, (L-3)%2+1, 3)
output
middle 3 digits of 123 ──► 123 middle 3 digits of 12345 ──► 234 middle 3 digits of 1234567 ──► 345 middle 3 digits of 987654321 ──► 654 middle 3 digits of 10001 ──► 000 middle 3 digits of -10001 ──► 000 middle 3 digits of -123 ──► 123 middle 3 digits of -100 ──► 100 middle 3 digits of 100 ──► 100 middle 3 digits of -12345 ──► 234 middle 3 digits of +123 ──► 123 middle 3 digits of 0123 ──► 123 middle 3 digits of 2 ──► ***error*** argument is less than three digits. middle 3 digits of -1 ──► ***error*** argument is less than three digits. middle 3 digits of -10 ──► ***error*** argument is less than three digits. middle 3 digits of 2002 ──► ***error*** argument isn't an odd number of digits. middle 3 digits of -2002 ──► ***error*** argument isn't an odd number of digits. middle 3 digits of 0 ──► ***error*** argument is less than three digits. middle 3 digits of abc ──► ***error*** argument isn't an integer. middle 3 digits of 1e3 ──► ***error*** argument isn't an odd number of digits. middle 3 digits of -17e-3 ──► ***error*** argument isn't an integer. middle 3 digits of 1234567. ──► 345 middle 3 digits of 1237654.00 ──► 376 middle 3 digits of 1234567890123456789012345678901234567890123456789012345678901234567 ──► 345
Ring
n = 1234567
middle(n)
func middle nr
mnr = floor(len(string(nr))/2)
lennr = len(string(nr))
if lennr = 3 see "" + nr + nl
but lennr < 3 see "Number must have at least three digits"
but lennr%2=0 see "Number must have an odd number of digits"
else cnr = substr(string(nr),mnr,3) see cnr + nl ok
RPL
Staying in the real world: no number/string conversion, -1 is returned if input is invalid.
≪ ABS DUP XPON
IF DUP 2 < OVER 2 MOD OR
THEN DROP2 -1
ELSE 2 / 1 - ALOG / IP 1000 MOD
END
≫ '→M3D' STO
≪ { 123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 -10 2002}
→ tl
≪ { }
1 tl SIZE FOR j
tl j GET →M3D +
NEXT
≫ ≫ EVAL
- Output:
1: { 123 234 345 654 0 0 123 100 100 234 -1 -1 }
Ruby
def middle_three_digits(num)
# minus sign doesn't factor into digit count,
# and calling #abs acts as a duck-type assertion
num = num.abs
# convert to string and find length
length = (str = num.to_s).length
# check validity
raise ArgumentError, "Number must have at least three digits" if length < 3
raise ArgumentError, "Number must have an odd number of digits" if length.even?
return str[length/2 - 1, 3].to_i
end
Testing program:
samples = [
123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345,
1, 2, -1, -10, 2002, -2002, 0
]
left_column_width = samples.map { |n| n.to_s.length }.max
samples.each do |n|
print "%#{left_column_width}d: " % n
begin
puts "%03d" % middle_three_digits(n)
rescue ArgumentError => e
puts e
end
end
- Output:
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: Number must have at least three digits 2: Number must have at least three digits -1: Number must have at least three digits -10: Number must have at least three digits 2002: Number must have an odd number of digits -2002: Number must have an odd number of digits 0: Number must have at least three digits
Rust
fn middle_three_digits(x: i32) -> Result<String, String> {
let s: String = x.abs().to_string();
let len = s.len();
if len < 3 {
Err("Too short".into())
} else if len % 2 == 0 {
Err("Even number of digits".into())
} else {
Ok(s[len/2 - 1 .. len/2 + 2].to_owned())
}
}
fn print_result(x: i32) {
print!("middle_three_digits({}) returned: ", x);
match middle_three_digits(x) {
Ok(s) => println!("Success, {}", s),
Err(s) => println!("Failure, {}", s)
}
}
fn main() {
let passing = [123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345];
let failing = [1, 2, -1, -10, 2002, -2002, 0];
for i in passing.iter() {
print_result(*i);
}
for i in failing.iter() {
print_result(*i);
}
}
- Output:
middle_three_digits(123) returned: Success, 123 middle_three_digits(12345) returned: Success, 234 middle_three_digits(1234567) returned: Success, 345 middle_three_digits(987654321) returned: Success, 654 middle_three_digits(10001) returned: Success, 000 middle_three_digits(-10001) returned: Success, 000 middle_three_digits(-123) returned: Success, 123 middle_three_digits(-100) returned: Success, 100 middle_three_digits(100) returned: Success, 100 middle_three_digits(-12345) returned: Success, 234 middle_three_digits(1) returned: Failure, Too short middle_three_digits(2) returned: Failure, Too short middle_three_digits(-1) returned: Failure, Too short middle_three_digits(-10) returned: Failure, Too short middle_three_digits(2002) returned: Failure, Even number of digits middle_three_digits(-2002) returned: Failure, Even number of digits middle_three_digits(0) returned: Failure, Too short
S-lang
Educational Notes: 1) Array-style string manipulations (e.g. as = as[[1:]] ) always use bytes, not UTF-8 characters. As digits and '-' are all ASCII, all is copacetic. 2) The task doesn't require 64-bit integer support, but I added it, dependant on whether the S-Lang library compile supports them, which it generally does. [Main exception would be the current downloadable/installable MS-Win version of the Jed editor.] 3) S-Lang functions peel arguments off right-to-left, opposite of many languages. To align the order with other solutions, I enclosed the parameters in a list. One alternative would have been for m3() to call _stk_reverse(_NARGS), then pop each arg directly off the stack. Or of course just list the numbers backwards.
define m3(i)
{
variable s = string(i), sabs = s, l;
if (sabs[0] == '-')
sabs = sabs[[1:]];
l = strlen(sabs);
if (l < 3)
print(sprintf("%s doesn't have enough digits", s));
else if (l & 1) {
variable st = (l-3) >> 1;
print(sprintf("%13s: %s", s, sabs[[st:st+2]]));
}
else
print(sprintf("%s has an even number of digits", s));
}
define middle_3(lst)
{
foreach (lst)
m3( () );
}
middle_3( { 123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345,
#ifexists Int64_Type
6644221335577ll, -11122588999ll,
#endif
1, 2, -1, -10, 2002, -2002, 0 } );
- Output:
" 123: 123" " 12345: 234" " 1234567: 345" " 987654321: 654" " 10001: 000" " -10001: 000" " -123: 123" " -100: 100" " 100: 100" " -12345: 234" "6644221335577: 213" " -11122588999: 258" "1 doesn't have enough digits" "2 doesn't have enough digits" "-1 doesn't have enough digits" "-10 doesn't have enough digits" "2002 has an even number of digits" "-2002 has an even number of digits" "0 doesn't have enough digits"
Scala
/**
* Optionally return the middle three digits of an integer.
*
* @example List(123,12345,-789,1234,12) flatMap (middleThree(_)), returns: List(123, 234, 789)
*/
def middleThree( s:Int ) : Option[Int] = s.abs.toString match {
case v if v.length % 2 == 0 => None // Middle three is undefined for even lengths
case v if v.length < 3 => None
case v =>
val i = (v.length / 2) - 1
Some( v.substring(i,i+3).toInt )
}
// A little test...
val intVals = List(123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345,1,2,-1,-10,2002,-2002,0)
intVals map (middleThree(_)) map {
case None => "No middle three"
case Some(v) => "%03d".format(v) // Format the value, force leading zeroes
} mkString("\n")
- Output:
123 234 345 654 000 000 123 100 100 234 No middle three No middle three No middle three No middle three No middle three No middle three No middle three
sed
h
s/^[-+]\{0,1\}0*\([1-9]\([0-9][0-9]\)\{1,\}\)$/\1/
t l
s/$/ -> error!/
b
:l
s/.\(.\{3,\}\)./\1/
t l
x
G
s/\n/ -> /
- Output:
$ printf "%s\n" -12345 -10001 -2002 -123 -100 -10 -1 0 1 2 100 123 2002 10001 12345 1234567 987654321 | sed -f middle_three_digits.sed -12345 -> 234 -10001 -> 000 -2002 -> error! -123 -> 123 -100 -> 100 -10 -> error! -1 -> error! 0 -> error! 1 -> error! 2 -> error! 100 -> 100 123 -> 123 2002 -> error! 10001 -> 000 12345 -> 234 1234567 -> 345 987654321 -> 654
Seed7
$include "seed7_05.s7i";
const func string: middle3 (in integer: number) is func
result
var string: middle3 is "";
begin
middle3 := str(abs(number));
if not odd(length(middle3)) or length(middle3) < 3 then
middle3 := "error";
else
middle3 := middle3[succ((length(middle3) - 3) div 2) len 3];
end if;
end func;
const proc: main is func
local
var integer: number is 0;
var string: mid3 is "";
begin
for number range [] (123, 12345, 1234567, 987654321, 10001, -10001, -123,
-100, 100, -12345, 1, 2, -1, -10, 2002, -2002, 0) do
writeln(number <& ": " <& middle3(number));
end for;
end func;
- Output:
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: error 2: error -1: error -10: error 2002: error -2002: error 0: error
SenseTalk
As a People Oriented Programming language, SenseTalk treats values in a fluid fashion. So although the calls to the middle3Digits handler pass an integer as the parameter, the handler itself treats the value as text, looking for occurrences of the text pattern <digit> in it. Similarly, the variable 'output' is initially set to a number, then becomes a text value when the middle digits are put into it at character position 15.
set inputs to [123, 12345, 1234567, 987654321,
10001, -10001, -123, -100, 100, -12345,
1, 2, -1, -10, 2002, -2002, 0]
repeat with each num in inputs
put num into output
put middle3digits of num into character 15 of output -- will autofill with "."s
put output
end repeat
to handle middle3digits of number
put every occurrence of <digit> in number into digits
if the number of items in digits is less than 3 then return "Error: too few digits"
if the number of items in digits is an even number then return "Error: even number of digits"
repeat while the number of items in digits is greater than 3
delete the first item of digits
delete the last item of digits
end repeat
return digits joined by empty
end middle3digits
- Output:
123...........123 12345.........234 1234567.......345 987654321.....654 10001.........000 -10001........000 -123..........123 -100..........100 100...........100 -12345........234 1.............Error: too few digits 2.............Error: too few digits -1............Error: too few digits -10...........Error: too few digits 2002..........Error: even number of digits -2002.........Error: even number of digits 0.............Error: too few digits
Sidef
func middle_three(n) {
var l = n.len
if (l < 3) {
"#{n} is too short"
} elsif (l.is_even) {
"#{n} has an even number of digits"
} else {
"The three middle digits of #{n} are: " + n.digits.slice((l-3)/2).first(3).flip.join
}
}
var nums = %n(
123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345
1 2 -1 -10 2002 -2002 0
)
nums.each { say middle_three(_) }
- 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
SQL
;WITH DATA
AS (SELECT CAST(ABS(NUMBER) AS NVARCHAR(MAX)) charNum,
NUMBER,
LEN(CAST(ABS(NUMBER) AS NVARCHAR(MAX))) LcharNum
FROM TABLE1)
SELECT CASE
WHEN ( LCHARNUM >= 3
AND LCHARNUM % 2 = 1 ) THEN SUBSTRING(CHARNUM, LCHARNUM / 2, 3)
ELSE 'Error!'
END Output,
NUMBER Input
FROM DATA
| OUTPUT | INPUT | |--------|-----------| | 123 | 123 | | 234 | 12345 | | 345 | 1234567 | | 654 | 987654321 | | 000 | 10001 | | 000 | -10001 | | 123 | -123 | | 100 | -100 | | 100 | 100 | | 234 | -12345 |
| OUTPUT | INPUT | |--------|-------| | Error! | 1 | | Error! | 2 | | Error! | -1 | | Error! | -10 | | Error! | 2002 | | Error! | -2002 | | Error! | 0 |
Swift
var num:Int = \\enter your number here
if num<0{num = -num}
var numArray:[Int]=[]
while num>0{
var temp:Int=num%10
numArray.append(temp)
num=num/10
}
var i:Int=numArray.count
if i<3||i%2==0{
print("Invalid Input")
}
else{
i=i/2
print("\(numArray[i+1]),\(numArray[i]),\(numArray[i-1])")
}
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: Invalid Input 2: Invalid Input -1: Invalid Input -10: Invalid Input 2002: Invalid Input -2002: Invalid Input 0: Invalid Input
Tcl
proc middleThree n {
if {$n < 0} {
set n [expr {-$n}]
}
set idx [expr {[string length $n] - 2}]
if {$idx % 2 == 0} {
error "no middle three digits: input is of even length"
}
if {$idx < 1} {
error "no middle three digits: insufficient digits"
}
set idx [expr {$idx / 2}]
string range $n $idx [expr {$idx+2}]
}
Demonstrating:
foreach n {
123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345
1 2 -1 -10 2002 -2002 0
} {
if {[catch {
set mid [middleThree $n]
} msg]} then {
puts "error for ${n}: $msg"
} else {
puts "found for ${n}: $mid"
}
}
- Output:
found for 123: 123 found for 12345: 234 found for 1234567: 345 found for 987654321: 654 found for 10001: 000 found for -10001: 000 found for -123: 123 found for -100: 100 found for 100: 100 found for -12345: 234 error for 1: no middle three digits: insufficient digits error for 2: no middle three digits: insufficient digits error for -1: no middle three digits: insufficient digits error for -10: no middle three digits: input is of even length error for 2002: no middle three digits: input is of even length error for -2002: no middle three digits: input is of even length error for 0: no middle three digits: insufficient digits
TI SR-56
Display | Key | Display | Key | Display | Key | Display | Key |
---|---|---|---|---|---|---|---|
00 28 | *|x| | 25 54 | / | 50 | 75 | ||
01 33 | STO | 26 02 | 2 | 51 | 76 | ||
02 01 | 1 | 27 74 | - | 52 | 77 | ||
03 18 | *log | 28 01 | 1 | 53 | 78 | ||
04 29 | *Int | 29 53 | ) | 54 | 79 | ||
05 20 | *1/x | 30 19 | *10^x | 55 | 80 | ||
06 20 | *1/x | 31 94 | = | 56 | 81 | ||
07 33 | STO | 32 29 | *Int | 57 | 82 | ||
08 02 | 2 | 33 54 | / | 58 | 83 | ||
09 54 | / | 34 01 | 1 | 59 | 84 | ||
10 02 | 2 | 35 00 | 0 | 60 | 85 | ||
11 94 | = | 36 00 | 0 | 61 | 86 | ||
12 12 | INV | 37 00 | 0 | 62 | 87 | ||
13 29 | *Int | 38 94 | = | 63 | 88 | ||
14 74 | - | 39 12 | INV | 64 | 89 | ||
15 92 | . | 40 29 | *Int | 65 | 90 | ||
16 05 | 5 | 41 64 | * | 66 | 91 | ||
17 94 | = | 42 01 | 1 | 67 | 92 | ||
18 20 | *1/x | 43 00 | 0 | 68 | 93 | ||
19 34 | RCL | 44 00 | 0 | 69 | 94 | ||
20 01 | 1 | 45 00 | 0 | 70 | 95 | ||
21 54 | / | 46 94 | = | 71 | 96 | ||
22 52 | ( | 47 41 | R/S | 72 | 97 | ||
23 34 | RCL | 48 | 73 | 98 | |||
24 02 | 2 | 49 | 74 | 99 |
Asterisk denotes 2nd function key.
0: Unused | 1: Number | 2: Log | 3: Unused | 4: Unused |
5: Unused | 6: Unused | 7: Unused | 8: Unused | 9: Unused |
Annotated listing:
*|x| STO 1 // Number := |input|
*log *Int // #Digits - 1
*1/x *1/x // Divide by zero if 1-digit number
STO 2 // Log := #Digits - 1
/ 2 = INV *Int - . 5 = *1/x // Divide by zero if #Digits is even
RCL 1 / ( RCL 2 / 2 - 1 ) *10^x = // Shift appropriately
*Int / 1 0 0 0 = INV *Int * 1 0 0 0 = // Take the middle 3 digits
R/S // End
Usage:
Enter the number and then press RST R/S. A flashing number indicates an error.
- Input:
987654321 RST R/S
- Output:
After about two seconds, 654 will appear on the screen.
- Input:
12345 +/- RST R/S
- Output:
After about two seconds, 234 will appear on the screen.
- Input:
5 RST R/S
- Output:
A flashing 9.999999999 99 appears on the screen indicating an error.
Uiua
Uses `assert` and `try` to handle the exceptions.
[123 12345 1234567 987654321 10001 ¯10001 ¯123 ¯100 100 ¯12345
1 2 ¯1 ¯10 2002 ¯2002 0]
Mid ← (
⍤("too short")≥3.⧻.°□°⋕⌵
⍤("even length")≠0◿2.
↘¯⟜↘⌊÷2-3
)
⍉⊟⟜≡⍚⍣(Mid|⊂"Error: "◌) # Convert each
≡(&p$"_\t->\t_"°⊟) # Display
- Output:
123 -> 123 12345 -> 234 1234567 -> 345 987654321 -> 654 10001 -> 000 -10001 -> 000 -123 -> 123 -100 -> 100 100 -> 100 -12345 -> 234 1 -> Error: too short 2 -> Error: too short -1 -> Error: too short -10 -> Error: too short 2002 -> Error: even length -2002 -> Error: even length 0 -> Error: too short
UNIX Shell
function middle3digits
{
typeset -i n="${1#-}"
typeset -i l=${#n}
if (( l < 3 )); then
echo >&2 "$1 has less than 3 digits"
return 1
elif (( l % 2 == 0 )); then
echo >&2 "$1 has an even number of digits"
return 1
else
echo ${n:$((l/2-1)):3}
return 0
fi
}
# test
testdata=(123 12345 1234567 987654321 10001 -10001 -123 -100 100 -12345 1 2 -1
-10 2002 -2002 0)
for n in ${testdata[@]}; do
printf "%10d: " $n
middle3digits "$n"
done
Output:
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: 1 has less than 3 digits 2: 2 has less than 3 digits -1: -1 has less than 3 digits -10: -10 has less than 3 digits 2002: 2002 has an even number of digits -2002: -2002 has an even number of digits 0: 0 has less than 3 digits
VBA
Option Explicit
Sub Main_Middle_three_digits()
Dim Numbers, i&
Numbers = Array(123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, _
100, -12345, 1, 2, -1, -10, 2002, -2002, 0)
For i = 0 To 16
Debug.Print Numbers(i) & " Return : " & Middle3digits(CStr(Numbers(i)))
Next
End Sub
Function Middle3digits(strNb As String) As String
If Left(strNb, 1) = "-" Then strNb = Right(strNb, Len(strNb) - 1)
If Len(strNb) < 3 Then
Middle3digits = "Error ! Number of digits must be >= 3"
ElseIf Len(strNb) Mod 2 = 0 Then
Middle3digits = "Error ! Number of digits must be odd"
Else
Middle3digits = Mid(strNb, 1 + (Len(strNb) - 3) / 2, 3)
End If
End Function
- Output:
123 Return : 123 12345 Return : 234 1234567 Return : 345 987654321 Return : 654 10001 Return : 000 -10001 Return : 000 -123 Return : 123 -100 Return : 100 100 Return : 100 -12345 Return : 234 1 Return : Error ! Number of digits must be >= 3 2 Return : Error ! Number of digits must be >= 3 -1 Return : Error ! Number of digits must be >= 3 -10 Return : Error ! Number of digits must be >= 3 2002 Return : Error ! Number of digits must be odd -2002 Return : Error ! Number of digits must be odd 0 Return : Error ! Number of digits must be >= 3
VBScript
'http://rosettacode.org/wiki/Middle_three_digits
Function mid3n(n)
'Remove the number's sign.
n = CStr(Abs(n))
If Len(n) < 3 Or Len(n) Mod 2 = 0 Then
mid3n = "Invalid: Either the length of n < 3 or an even number."
ElseIf Round(Len(n)/2) > Len(n)/2 Then
mid3n = Mid(n,Round(Len(n)/2)-1,3)
Else
mid3n = Mid(n,Round(Len(n)/2),3)
End If
End Function
'Calling the function.
arrn = Array(123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345,_
1,2,-1,-10,2002,-2002,0)
For Each n In arrn
WScript.StdOut.Write n & ": " & mid3n(n)
WScript.StdOut.WriteLine
Next
- Output:
123: 123 12345: 234 1234567: 345 987654321: 654 10001: 000 -10001: 000 -123: 123 -100: 100 100: 100 -12345: 234 1: Invalid: Either the length of n < 3 or an even number. 2: Invalid: Either the length of n < 3 or an even number. -1: Invalid: Either the length of n < 3 or an even number. -10: Invalid: Either the length of n < 3 or an even number. 2002: Invalid: Either the length of n < 3 or an even number. -2002: Invalid: Either the length of n < 3 or an even number. 0: Invalid: Either the length of n < 3 or an even number.
Vedit macro language
do {
#1 = Get_Num("Enter a number, or 0 to stop: ", STATLINE)
Ins_Text("Input: ") Num_Ins(#1, COUNT, 10)
Call("MIDDLE_3_DIGITS")
Ins_Text(" Result: ") Reg_Ins(10) Ins_Newline
Update()
} while (#1);
Return
// Find middle 3 digits of a number
// in: #1 = numeric value
// out: @10 = the result, or error text
//
:MIDDLE_3_DIGITS:
Buf_Switch(Buf_Free)
Num_Ins(abs(#1), LEFT+NOCR) // the input value as string
#2 = Cur_Col-1 // #2 = number of digits
if (#2 < 3) {
Reg_Set(10, "Too few digits!")
} else {
if ((#2 & 1) == 0) {
Reg_Set(10, "Not odd number of digits!")
} else {
Goto_Pos((#2-3)/2)
Reg_Copy_Block(10, Cur_Pos, Cur_Pos+3)
}
}
Buf_Quit(OK)
Return
Output:
Input: 123 Result: 123 Input: 12345 Result: 234 Input: 1234567 Result: 345 Input: 987654321 Result: 654 Input: 10001 Result: 000 Input: -10001 Result: 000 Input: -123 Result: 123 Input: -100 Result: 100 Input: 100 Result: 100 Input: -12345 Result: 234 Input: 1 Result: Too few digits! Input: 2 Result: Too few digits! Input: -1 Result: Too few digits! Input: -10 Result: Too few digits! Input: 2002 Result: Not odd number of digits! Input: -2002 Result: Not odd number of digits! Input: 0 Result: Too few digits!
V (Vlang)
import math
const
(
valid = [123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345]
invalid = [1, 2, -1, -10, 2002, -2002, 0]
)
fn main() {
for elem in valid {println(middle(elem))}
for elem in invalid {println(middle(elem))}
}
fn middle(num int) string {
mut strip := math.abs(num).str()
if strip.len < 3 {return 'Error: $num has less than 3 digits'}
if strip.len % 2 == 0 {return 'Error: $num has an even number of digits'}
start := (strip.len / 2) - 1
return strip.substr(start, start + 3)
}
- Output:
123 234 345 654 000 000 123 100 100 234 Error: 1 has less than 3 digits Error: 2 has less than 3 digits Error: -1 has less than 3 digits Error: -10 has less than 3 digits Error: 2002 has an even number of digits Error: -2002 has an even number of digits Error: 0 has less than 3 digits
Wart
def (mid3 n)
withs (digits (with outstring # itoa
(pr abs.n))
max len.digits
mid (int max/2))
if (and odd?.max (max >= 3))
(digits mid-1 mid+2)
Output
mid3.123 => 123 mid3.12345 => 234 mid3.1234567 => 345 mid3.987654321 => 654 mid3.10001 => 000 mid3 -10001 => 000 (mid3 -123) => 123 (mid3 -100) => 100 (mid3 100) => 100 (mid3 -12345) => 234 # Errors mid3.1 => nil mid3.2 => nil mid3 -1 => nil mid3 -10 => nil mid3 2002 => nil mid3 -2002 => nil (mid3 0) => nil
Wren
import "./fmt" for Fmt
var middle3 = Fn.new { |n|
if (n < 0) n = -n
var s = "%(n)"
var c = s.count
if (c < 3) return "Minimum is 3 digits, only has %(c)."
if (c%2 == 0) return "Number of digits must be odd, %(c) is even."
if (c == 3) return s
var d = (c - 3)/2
return s[d..d+2]
}
var a = [123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345,
1, 2, -1, -10, 2002, -2002, 0]
for (e in a) {
Fmt.print("$9d -> $n", e, middle3.call(e))
}
- Output:
123 -> 123 12345 -> 234 1234567 -> 345 987654321 -> 654 10001 -> 000 -10001 -> 000 -123 -> 123 -100 -> 100 100 -> 100 -12345 -> 234 1 -> Minimum is 3 digits, only has 1. 2 -> Minimum is 3 digits, only has 1. -1 -> Minimum is 3 digits, only has 1. -10 -> Minimum is 3 digits, only has 2. 2002 -> Number of digits must be odd, 4 is even. -2002 -> Number of digits must be odd, 4 is even. 0 -> Minimum is 3 digits, only has 1.
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);
];
]
- 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
zkl
fcn middle(ns){
ns.apply("toString").apply('-("-"))
.apply(fcn(n){nl:=n.len();
if(nl<3 or nl.isEven) return(False);
n[(nl-3)/2,3] : "%03d".fmt(_)
})
}
middle(T(123,12345,1234567,987654321,10001,-10001,-123,-100,100,-12345)).println()
middle(T(1, 2, -1, -10, 2002, -2002, 0)).println();
- Output:
L("123","234","345","654","000","000","123","100","100","234") L(False,False,False,False,False,False,False)
Algorithm is convert each number into a string, remove any "-", reject strings less than 3 characters or are even in length, return middle three characters of remainder.
- Programming Tasks
- Solutions by Programming Task
- 11l
- Action!
- Action! Tool Kit
- Action! Real Math
- Ada
- Aime
- ALGOL 68
- ALGOL W
- Amazing Hopper
- AppleScript
- Arturo
- ATS
- AutoHotkey
- AWK
- BASIC
- Applesoft BASIC
- BASIC256
- BBC BASIC
- FBSL
- IS-BASIC
- PureBasic
- Run BASIC
- Yabasic
- Batch File
- Befunge
- Bracmat
- Burlesque
- C
- C++
- C sharp
- Clojure
- CLU
- COBOL
- Common Lisp
- D
- Dart
- DCL
- Delphi
- EasyLang
- Eiffel
- Elena
- Elixir
- Erlang
- ERRE
- Factor
- Forth
- Fortran
- FreeBASIC
- FutureBasic
- Gambas
- Go
- Gosu
- Groovy
- Haskell
- Icon
- Unicon
- J
- Java
- JavaScript
- Jq
- Julia
- K
- Klingphix
- Klong
- Kotlin
- Lambdatalk
- Lasso
- Logo
- Lua
- Maple
- Mathematica
- Wolfram Language
- MATLAB
- Octave
- MiniScript
- МК-61/52
- ML
- MLite
- MUMPS
- NetRexx
- NewLISP
- Nim
- Objeck
- OCaml
- Oforth
- PARI/GP
- Pascal
- Perl
- Phix
- PHP
- Picat
- PicoLisp
- Pike
- PL/I
- Plain English
- PowerShell
- Prolog
- Python
- Quackery
- Racket
- Raku
- REXX
- Ring
- RPL
- Ruby
- Rust
- S-lang
- Scala
- Sed
- Seed7
- SenseTalk
- Sidef
- SQL
- Swift
- Tcl
- TI SR-56
- Uiua
- UNIX Shell
- VBA
- VBScript
- Vedit macro language
- V (Vlang)
- Wart
- Wren
- Wren-fmt
- XPL0
- Zkl
- GUISS/Omit
- Pages with too many expensive parser function calls