This commit is contained in:
Ingy döt Net 2013-04-10 21:29:02 -07:00
parent 764da6cbbb
commit db842d013d
19005 changed files with 197040 additions and 7 deletions

View file

@ -0,0 +1,7 @@
The task is to:
:“''Write a function/procedure/subroutine that is called with an integer value and returns the middle three digits of the integer if possible or a clear indication of an error if this is not possible.''”
:<small>''Note: The order of the middle digits should be preserved''.</small>
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:
<pre>123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345
1, 2, -1, -10, 2002, -2002, 0</pre>
Show your output on this page.

View file

@ -0,0 +1,43 @@
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;

View file

@ -0,0 +1,84 @@
#include <iostream>
#include <sstream>
#include <string>
// @author Martin Ettl
// @date 2013-02-04
/**
* Convert variables of type T to std::string
*
*
* @param d --> digit of type T
*
* @return <-- the corresponding string value
*/
template <typename T> const std::string toString(const T &d)
{
std::ostringstream result;
result << d;
return result.str();
}
/**
* Determine the middle n digits of the integer. If it is not possible to determine the
* the middle n digits, an empty string is provided.
*
* @param iDigit --> The digit to test
* @param n --> The number of digits inbetween
*
* @return <-- the middle three digits
*/
std::string strMiddleNDigits(int iDigit, const int &n)
{
// is negative: --> convert to a positive number
if(iDigit<0)
{
iDigit*=-1;
}
// convert to string
std::string strNumber (toString(iDigit));
size_t len(strNumber.length());
if( (len < n) || (len % 2 == 0) )
{
return "";
}
size_t mid(len/2);
return strNumber.substr(mid-n/2, n);
}
/**
* Determine the middle three digits of the integer. If it is not possible to determine the
* the middle three digits, an empty string is provided.
*
* @param iDigit --> The digit to test
*
* @return <-- the middle three digits
*/
std::string strMiddleThreeDigits(int iDigit)
{
return strMiddleNDigits(iDigit,3);
}
int main()
{
const int iPassing[] = {123, 12345, 1234567, 987654321, 10001, -10001,
-123, -100, 100, -12345
};
for(unsigned int ui = 0; ui < 10; ++ui)
{
std::cout << "strMiddleThreeDigits("<< iPassing[ui] <<"): "
<< strMiddleThreeDigits(iPassing[ui])<< "\n";
}
const int iFailing[] = {1, 2, -1, -10, 2002, -2002, 0};
for(unsigned int ui = 0; ui < 7; ++ui)
{
std::string strResult = strMiddleThreeDigits(iFailing[ui]);
std::cout << "strMiddleThreeDigits("<< iFailing[ui] <<"): "
<< (strResult.empty()?"Need odd and >= 3 digits":strResult)
<< "\n";
}
return 0;
}

View file

@ -0,0 +1,47 @@
#include <stdio.h>
#define E_SMALL 1
#define E_EVEN 2
static const char *errors[] = {"too small", "even length"};
int mid3(int num, char *buf)
{
int i, mag = 1;
int tmp = num = num < 0 ? -num : num; /* Discard sign. */
/* A number's magnitude can be used to determine both
* its length and, in this case, the oddness thereof. */
while (tmp /= 10) mag *= 10;
if (mag < 100) return E_SMALL;
if (mag & 128) return E_EVEN;
while (num > 1000) {
num -= num / mag * mag; /* Chop left digit. */
num /= 10; /* Now the right. */
mag /= 100;
}
/* Populate a character buffer to handle zeroes. */
for (i = 2; i >= 0; num /= 10, --i)
buf[i] = num % 10 + '0';
return 0;
}
int main(void)
{
int num;
char buf[4] = "";
while (scanf("%d", &num) != EOF) {
printf("%d: ", num);
if ((num = mid3(num, buf)) == 0)
printf("%s\n", buf);
else
puts(errors[--num]);
}
return 0;
}

View file

@ -0,0 +1,21 @@
import std.stdio, std.traits, std.conv;
string middleThreeDigits(T)(in T n) 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 (n; passing)
writefln("middleThreeDigits(%s): %s", n, middleThreeDigits(n));
immutable failing = [1, 2, -1, -10, 2002, -2002, 0,int.min,int.max];
foreach (n; failing)
writefln("middleThreeDigits(%s): %s", n, middleThreeDigits(n));
}

View file

@ -0,0 +1,87 @@
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);
}
}

View file

@ -0,0 +1,17 @@
import Numeric
mid3 :: Integral a => a -> Either String String
mid3 n | m < 100 = Left "is too small"
| even l = Left "has an even number of digits"
| otherwise = Right . take 3 $ drop ((l-3) `div` 2) s
where m = abs n
s = showInt m ""
l = length s
showMid3 :: Integer -> String
showMid3 n = show n ++ ": " ++ either id id (mid3 n)
main :: IO ()
main = mapM_ (putStrLn . showMid3) [
123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345,
1, 2, -1, -10, 2002, -2002, 0]

View file

@ -0,0 +1,4 @@
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@:|

View file

@ -0,0 +1,19 @@
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

View file

@ -0,0 +1,27 @@
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);
}
}

View file

@ -0,0 +1,10 @@
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)}
});

View file

@ -0,0 +1,16 @@
function middle(s)
s = string(abs(s))
len = length(s)
assert(len >= 3 && len % 2 == 1, "Number of digits must be odd and >= 3")
mid = ifloor(len/2)
return s[mid:mid+2]
end
passing = [123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345]
failing = [1, 2, -1, -10, 2002, -2002, 0]
for i in [passing,failing]
try
println("Number: $i ", "Answer: ",middle(i))
catch e
println("Number: $i ", "Answer: ",e)
end
end

View file

@ -0,0 +1,26 @@
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

View file

@ -0,0 +1,11 @@
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]

View file

@ -0,0 +1,25 @@
#!/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 ;

View file

@ -0,0 +1,35 @@
>>> 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',)
>>>

View file

@ -0,0 +1,28 @@
/* REXX ***************************************************************
* 03.02.2013 Walter Pachl
**********************************************************************/
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 */
Call 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 Call error 'not a number'
When pos('E',translate(d))>0 Then Call error 'not just digits'
When length(abs(d))<3 Then Call error 'less than 3 digits'
When length(abs(d))//2<>1 Then Call error '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 */
Say left(d,12) '->' substr(dx,z+1,3) /* show middle 3 digits */
End
End
Return
error:
Say left(d,12) '->' arg(1) /* tell about the problem */
Return

View file

@ -0,0 +1,14 @@
#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))

View file

@ -0,0 +1,3 @@
'("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")

View file

@ -0,0 +1,30 @@
def middle_three_digits(n)
# minus sign doesn't factor into digit count,
# and calling #abs acts as a duck-type assertion
n = n.abs
# convert to string and find length
l = (s = n.to_s).length
# check validity
raise ArgumentError, "Number must have at least three digits" if l < 3
raise ArgumentError, "Number must have an odd number of digits" if l % 2 == 0
return s[l/2-1,3].to_i
end
samples = [
123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345,
1, 2, -1, -10, 2002, -2002, 0
]
width = samples.map { |n| n.to_s.length }.max
samples.each do |n|
print "%#{width}d: " % n
begin
puts "%03d" % middle_three_digits(n)
rescue ArgumentError => e
puts e.to_s
end
end

View file

@ -0,0 +1,21 @@
/**
* 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")

View file

@ -0,0 +1,14 @@
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}]
}

View file

@ -0,0 +1,12 @@
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"
}
}