Output the nth digits of an integer

Without using strings (except when necessary, such as with input or output) calculate the nth digit, from the left, of an integer (in base 10).

Input will be given in this format:

726433 5

Output should be:

3

as that is the fifth digit of "726433".

Input will not contain leading zeros, e.g. "00223".

Test cases / further examples:

9 1  ->  9
0 1  ->  0
444494 5  ->  9
800 2  ->  0

This is code golf; least amount of characters wins, but any built in functions such as "nthDigit(x,n)" are not acceptable.

Here's some pseudo-code to get you started:

x = number
n = index of the digit
digits = floor[log10[x]] + 1
dropRight = floor[x / 10^(digits - n)]
dropLeft = (dropRight / 10 - floor[dropRight / 10]) * 10
nthDigit = dropLeft

As you can see I'm new to code golf, and though I think it's a bit unfair that I ask a question before I've even answered one, I would really like to see what kind of responses this generates. :)

Edit: I was hoping for mathematical answers, so I cannot really accept answers that rely on converting strings to arrays or being able to access numbers as a list of digits.

We have a winner

Written in "dc", 12 bytes. By DigitalTrauma.

• Can this be just a function or must it need to handle I/O? If it does not need to handle I/O can it simply be a lambda instead of a function? Apr 9 '14 at 6:15
• Your edit leaves it unclear as to what exactly you don't like. In particular, with "being able to access numbers as a list of digits", is it the use of arrays in any form that you don't like, or just the existence of built-in base conversion routines? Apr 9 '14 at 8:44
• @PeterTaylor Arrays of digits are not OK, as one can easily just grab the nth item in the array. I am not sure how base-conversion works exactly, but it seems to easy. Apr 9 '14 at 15:45
• Why is it a problem to build a list of digits? That is highly mathematical - it represents the number as a polynomial. Apr 9 '14 at 16:03
• @2rs2ts If you can create a list of digits mathematically, i.e. without parsing a string into an array, then it could be acceptable. Apr 9 '14 at 16:10

GolfScript (10 bytes)

~(\10base=

This assumes input is as a string (e.g. via stdin). If it's as two integers on the stack, the initial ~ should be removed, saving 1 char.

If the base conversion is considered to fall foul of the built-in functions rule, I have a 16-char alternative:

~~)\{}{10/}/=10%
• Your first program with the base conversion outputs the first digit only if you enter "0" and the second if you enter "1". golfscript.apphb.com/?c=MjcwNiAxCgpcMTBiYXNlPQ%3D%3D Apr 8 '14 at 23:52
• @kukac67, fixed. Apr 9 '14 at 8:32

CJam - 7

l~(\Ab=

CJam is a new language I am developing, similar to GolfScript - http://sf.net/p/cjam. Here is the explanation:

l reads a line from the input
~ evaluates the string (thus getting the two numbers)
( decrements the second number
\ swaps the numbers
A is a variable preinitialized to 10
b does a base conversion, making an array with the base-10 digits of the first number
= gets the desired element of the array

The program is basically a translation of Peter Taylor's solution.

• I would argue putting base 10 digits into an array is more of a string operation than a mathematical one. Apr 12 '14 at 21:08

nth x n
| x < (10^n) = mod x 10
| True = nth (div x 10) n

no strings involved!

*Main> nth 1234567 4
4
• This can be golfed down to 36 Aug 16 '17 at 11:20
• Wow you fought for every byte. 1<2" instead of "true" - cute. Aug 17 '17 at 21:08
• It's what we do around here... Aug 18 '17 at 6:08

J - 15 24 char

(10|[<.@*10^]-10>.@^.[)/

Same results as below, but is endowed with the mystical quality of being mathematical.

The short version, using base-10 expansion.

({0,10&#.inv)~/

We prepend a 0 to adjust for 1-based indexing.

Usage:

({0,10&#.inv)~/ 1234567 3
3
({0,10&#.inv)~/ 444494 5
9
• Strings are not allowed. Apr 8 '14 at 23:27

dc, 12 bytes

?dZ?-Ar^/A%p

This is a mathematical answer. Here's how it works:

• ? read input number and push to stack
• d duplicate top of stack
• Z Pops value off the stack, calculates and pushes the number of digits
• ? read digit index and push to stack
• - subtract digit index from digit count
• A push 10 to the stack
• r swap top 2 values on stack
• ^ exponentiate 10 ^ (digit count - digit index)
• / divide number by result of exponentiation
• A push 10 to the stack
• % calculate the number mod 10 to get the last digit and push to top of stack
• p pop and print the top of stack

In action:

${ echo 987654321; echo 1; } | dc ndigit.dc 9$ { echo 987654321; echo 2; } | dc ndigit.dc
8
${ echo 987654321; echo 8; } | dc ndigit.dc 2$ { echo 987654321; echo 9; } | dc ndigit.dc
1
$• I think you're the winner. This is the third shortest code, but the shortest 2 used base conversion -> arrays. Apr 13 '14 at 19:23 Python 127 def f(i,n): b=10;j=i/b;k=1;d=i-j*b while j>0: k+=1;j/=b if n>k: return -1 while k>n: k-=1;j/=b;i/=b;d=i-j*b return d • You don't need to define it as a fn: def f(i,n): ... return d – smci Apr 9 '14 at 10:44 • You don't need to sanity-check the if n>k: return -1 case. – smci Apr 9 '14 at 10:45 • ...and you certainly don't need to make a first-pass just to count k (the number of digits in i), in order to sanity-compare it to n. – smci Apr 9 '14 at 10:52 C, 50 This uses arrays. main(int c,char**a){putchar(a[atoi(a)-1]);} Just ignore all the warnings. And yes, in C, strings are really just arrays, so this is sort of cheap. More Mathematical: C, 83 main(int c,char**a){printf("%d",(atoi(a)/pow(10,strlen(a)-atoi(a)))%10);} • isn't it using string/array functions? – V-X Apr 10 '14 at 5:20 • First one does, like it says ;) The second one obviously doesn't, apart from the strlen, which I chose simply because it's shorter than using log. If that's a problem it's an easy fix, I can add it when I get home. – SBI Apr 10 '14 at 6:46 • There we go, added the purely mathematical version. – SBI Apr 11 '14 at 8:56 • Math - not even once! Apr 11 '14 at 8:59 bc (driven by bash), 41 29 I think this is the first answer to do this mathematically and not with strings: bc<<<"$1/A^(length($1)-$2)%A"

The use of length() perhaps seems a bit stringy, but the bc man page talks about number of digits and not length of string:

length ( expression )
The value of the length function is the  number  of  significant
digits in the expression.

Output:

$./ndigits.bc.sh 726433 5 3$ ./ndigits.bc.sh 9 1
9
$./ndigits.bc.sh 0 1 0$ ./ndigits.bc.sh 444494 5
9
$./ndigits.bc.sh 800 2 0$
• @kukac67 I appreciate the acceptance vote! But I think it is customary for code-golf questions to be left open more than 2 hours to encourage more answers. Perhaps a week or so. I won't be offended if you de-accept this answer :) Apr 9 '14 at 1:38
• ok. I will de-accept then. Hope you don't win! :P Apr 9 '14 at 2:59

Mathematica - 24 23

This one is kind of obvious :)

IntegerDigits[#][[#2]]&

Example:

IntegerDigits[#][[#2]]& [726433, 5]

Output:

3

You can get it shorter by hard-coding two integers, e.g.

IntegerDigits[n][[m]]

but then you first have to write n = 726433; m = 5;. The function call felt more similar to a program.

• You can drop the number 1. Apr 9 '14 at 13:53
• Now this is cheating.. :D Apr 9 '14 at 15:46

C 145

Program finds distance from end of integer and divides until index is reached then uses modulus 10 to get the last digit.

int main()
{
int i,a,b,d,n;
scanf("%d %d",&i,&a);
d=(int)(log(i)/log(10))+1;
n=d-a;
while(n--){i=(int)(i/10);}
b=i%10;
printf("%d",b);
}
• This can be golfed significantly. Start with these tips Apr 9 '14 at 23:20
• For a start, the (int) casts and associated parens are unnecessary Apr 9 '14 at 23:36
• I couldn't resist. I golfed it down to 87 chars: i,a;main(){scanf("%d%d",&i,&a);for(a=log(i)/log(10)+1-a;a--;)i/=10;printf("%d",i%10);}. Apr 9 '14 at 23:37

Wolfram Alpha - between 40 and 43

Of course, I can totally defend that using IntegerDigits is a trick that does not fall under

any built in functions such as "nthDigit(x,n)"

But because my previous answer still felt like cheating a little bit, here's an alternative. Unfortunately it's quite a bit longer, but I didn't see how to shorten it any more than I did.

Counting in a similar way as before (with the ampersand, without passing in any arguments),

Mod[Trunc[#/10^(Trunc[Log10[#]]-#2+1)],10]&

has 43 characters. By negating the exponent and shuffling the terms around, I can lose one arithmetic operator (10^(...)x will be interpreted as multiplication)

Mod[Trunc[10^(#2-Trunc[Log10[#]]-1)#],10]&

I don't have Mathematica at hand to test, I doubt that it will beAs I suspected (and as was kindly verified by kukac67) in Mathematica this is not accepted, but it runs in WolframAlpha.

I am in doubt about the use of RealDigits, because I restricted myself from using IntegerDigits for this answer and they are quite similar. However, if I allow myself to include it (after all, it doesn't return the integers directly, just how many of them there are), I can slash off another two characters:

Mod[Trunc[10^(#2-RealDigits[#]-1)#],10]&
• I tried it in Mathematica, it doesn't output a value. The 43 character one ouputs this: Mod[Trunc[57 2^(3 - Trunc[Log/Log])5^Trunc[Log/Log]], 10] Apr 9 '14 at 16:26
• Yeah, I figured as much. Wolfram Alpha is a bit more lenient in interpreting input. Luckily I gave it the correct header ;) Apr 9 '14 at 16:29
• But I see it does work on WolframAlpha. Apr 9 '14 at 16:30
• {edit} Although I see the link is broken... apparently doesn't like [ characters even when they are encoded. I'll pull it through an URL shortener. {edit2} Apparently W.Alpha has one - changed the link. Apr 9 '14 at 16:30

puts [expr [lindex $argv 0]/10**int(log10([lindex$argv 0])+1-[lindex $argv 1])%10] • How does this work? Apr 9 '14 at 16:08 • Added explanation. It's just the most obvious way to do it mathematically. How you'd do it on paper. Apr 9 '14 at 17:11 • I think you're counting from the wrong end. Apr 9 '14 at 17:18 • Hmm.. yeah. Looks like it. I'll revise it to count form the left. Apr 9 '14 at 17:20 • I'll accept the 31 bytes. Though how can the lambda be run? Does Tcl have an interpreter which can use it? Or only as part of a program which defines the arguments? Apr 9 '14 at 17:32 R (60) Solved the problem using log10 to calculate the number of digits. The special case x==0 costs 13 character, sigh. f=function(x,n)if(x)x%/%10^(trunc(log10(x))-n+1)%%10 else 0 Ungolfed: f=function(x,n) if(x) x %/% 10^(trunc(log10(x)) - n + 1) %% 10 else 0 Usage > f(898,2)  9 Scala (133 99 bytes): Works for all positive inputs. Divides by 10 to the power of the digit looked for from the right, then takes it modulo 10. def k(i:Array[String])={val m=i(0).toInt (m*Math.pow(10,i(1).toInt-1-Math.log10(m)toInt)).toInt%10} Thank you for noticing the bug in the previous formula. This one is shorter. • I like it! :) Up-voted Apr 9 '14 at 16:01 • Tested the solution: k(Array("1234", "7")) which gives 9. Does it not work for n > #digits(x) ? Apr 9 '14 at 20:48 • It's because 10^-1 is not exact in this notation, so there is a rounding error when you take 10%pow(10,-1) which should have given zero but gave 0.0999 instead. Corrected my answer to accomodate this side-effect. Apr 10 '14 at 6:04 Haskell, 142 I'm not sure I understood the question correctly, but this is what I think you wanted: read stdin (string), make the two numbers int (not string), do some algorithmic things, and then output the result (string). I crammed it into 142 chars, which is way too much: import System.Environment a%b|a>9=div a 10%(b+1)|1<2=b x#n=xdiv10^(x%1-n)mod10 u[a,b]=read a#read b main=fmap(u.words)getContents>>=print example usage: > echo 96594 4 | getIndex 9 JavaScript - 84 p=prompt,x=+p(),m=Math;r=~~(x/m.pow(10,~~(m.log(x)/m.LN10)+1-+p()));p(r-~~(r/10)*10) Purely mathematical, no strings, none of them. Takes the first number in the first prompt and the second number in the second prompt. Test Case: Input: 97654 5 Output: 4 Input: 224658 3 Output: 4 Ungolfed Code: p = prompt, x = +p(), // or parseInt(prompt()) m = Math; r = m.floor( x / m.pow(10, m.floor(m.log(x) / m.LN10) + 1 - +p()) ) // ^-- log(10) ^-- this is n p(r - ~~(r / 10) * 10) // show output perl, 38, 36 no 30 characters (not counting the linefeed) This is arguably cheating due to the command switch, but thanks for letting me play :-) ~/$ cat ndigits.pl
say((split//,$ARGV)[$ARGV-1]);
~/$tr -cd "[:print:]" < ndigits.pl |wc -m 36 ~/$ perl -M5.010 ndigits.pl 726433 5
3

edit:

Was able to remove 2 characters:

say for(split//,$ARGV)[$ARGV-1];
say((split//,$ARGV)[$ARGV-1]);

... then 6 more:

say((split//,shift)[pop()-1]);

How

We split the input of the first argument to the script $ARGV by character (split//) creating an zero indexed array; adding one to the second argument$ARGV to the script then corresponds to the element at that position in the string or first argument. We then hold the expression inside () as a one element list which say will iterate through. For the shorter short version we just shift in the first argument and use the remaining part of @ARGV to use for the index - once shifted only the second argument remains so we pop() it and subtract 1.

Is this supposed to be a math exercise? I just realized I'm indexing a string read from input, so ... I guess I lose?? Mark me up if I make sense in parallel golf course and I will try again - more mathematically - in a separate answer.

cheers,

• Yup, sorry, Without using strings. Welcome to PPCG anyway! Apr 12 '14 at 2:47
• OK sorry 'bout that ... so far my mathematical approaches are not very golf-worthy :-) Apr 12 '14 at 14:08

PHP, 58

Using math only

<?$n=$argv;while($n>pow(10,$argv))$n/=10;echo$n%10;

• Doesn't this find from the right? Apr 9 '14 at 14:58
• You can save 1 char by changing it to echo$n%10. Apr 9 '14 at 19:41 • @Trimsty no, it actually loops until entered number is no longer bigger than 10^x, x being the digit number. So, for example, if you enter 3457 as a number and 2 as a digit, it will take away the last digit until the number becomes smaller than 100 (10^2). That means it will take away 5 and 7, because then 34 remains and it is not bigger than 100. Then it just outputs the last digit (4). Apr 9 '14 at 19:44 • But it is true that if the second number is bigger than the number of digits, you output 9 and not zero Apr 10 '14 at 6:26 • I see, it outputs last digit if the number if bigger than the number of digits. If you enter 1234 and 5th digit, you will get 4 since 1234 i already less than 10^5. Apr 10 '14 at 6:53 ~-~! - 94 93 Bends the rules a bit - it's a function that takes n as input and assumes the number to find digit n of is stored in ''''' - and ~-~! doesn't support floats. '=~~~~~,~~:''=|*==~[']<''&*-~>,'|:'''=|*==%[%]~+*/~~~~/~~|:''''=|'''''/''&<<'''&'''''>-*-~>|: '''''=~~~~,~~,~~,~~,~~,~~:''''''=''''&~: will result in '''''' being ~~ (2) (''''' = 128). • Hm... Yet another esoteric language? Apr 9 '14 at 14:33 • @VisioN it isn't really esoteric, just that the only native data type is a number and it can't interact with the os/internet. esolangs.org/wiki/No_Comment Apr 9 '14 at 14:34 • Well, to me every syntax that can't be easily read by a human being is esoteric. And yes, Perl is also esoteric according to this theory :) Apr 9 '14 at 14:38 • @VisioN It gets easy to read after a while. :P Apr 9 '14 at 14:45 Python 2.7 (89 bytes) I transform the integer into a "polynomial" by using a list of digits. I know you say you can't accept that, but I don't see why not since it uses the mathematical concept of numbers being represented as polynomials of their bases. It will only fail when the integer passed in is 0, but you said no padded zeroes ;) import sys;v=sys.argv;p,x,n=[],int(v),int(v) while x:p=[x%10]+p;x//=10 print p[n-1] Run as test.py:$ python test.py 726489 5
8

I assume you wanted shell input and that I couldn't make use of the fact that the input would be strings. Skipping shell input it's just 43 bytes, with:

p=[]
while x:p=[x%10]+p;x//=10
print p[n-1]

Although I use some unnecessary iteration, I save some bytes by not adding an additional decrement on n.

Extended BrainFuck: 49

+[>>,32-]<<-[<<-],49-[->>>[>>]+[<<]<]>>>[>>]<33+.

Usage:

% bf ebf.bf < nth-digit.ebf > nth-digit.bf
% echo "112234567 7" | bf nth-digit.bf
5

I'm not ectually using any special features of EBF except the multiplication operator (eg. 10+ => ++++++++++). Other than that it's mostly pure BrainFuck

How it works:

+                ; Make a 1 in the first cell
[>>,32-]         ; while cell is not zero: read byte 2 to the right and reduce by 32 (space)
<<-[<<-]         ; move back to the first cell by reducing every cell with 1
,49-             ; read index, reduce by 49 so that ascii 1 becomes 0
[->>>[>>]+[<<]<] ; use that to fill a trail of breadcrumbs to the desired number
<33+.            ; go to value part, increase by 33 (32 + 1 which we substracted) and print

Scheme (R6RS): 100 (without unnecessary whitespace)

(exact(div(mod x(* e 10))e)))

awk - 53

{for(d=10^9;!int($1/d)||--$2;d/=10);$0=int($1/d)%10}1
1. trim digits by division, starting with max possible for 32 bit unsigned int
2. when we hit the left side of the integer, int($1 / d) returns non-zero 3. continue n ($2) digits past that

Ungolfed:

{
for(d = 1000000000; int($1 / d) != 0 || --$2; d /= 10);
print int($1 / d) % 10; } Scala (83) Does not use any Scala special features. Rather the standard solution. def f(x:Int,n:Int)=if(x==0)0 else x/(math.pow(10,math.log10(x).toInt-n+1)).toInt%10 Ungolfed: def f(x:Int,n:Int) = if(x==0) 0 else x / (math.pow(10, math.log10(x).toInt - n + 1)).toInt % 10 C, 94 main(x,y,z,n){scanf("%d%d",&x,&y);for(z=x,n=1-y;z/=10;n++);for(;n--;x/=10);printf("%d",x%10);} C, 91, invalid because of using arrays. main(x,y,z){int w;scanf("%d%d",&x,&y);for(z=0;x;x/=10)w[z++]=x%10;printf("%d",w[z-y]);} • I disallowed arrays in a edit (before you posted this)... But I like how you did this. :) Apr 9 '14 at 15:52 • OK, I wasn't looking properly. I've added a solution avoiding arrays. – V-X Apr 10 '14 at 5:18 Julia 37 d(x,y)=div(x,10^int(log10(x)-y+1))%10 Owing to the builtin ^ operator. Arbitrary precision arithmetic allows for any size int. Sample julia> d(1231198713987192871,10) 3 perl (slightly more mathy/not very golfy) - 99 chars ~/$ cat ndigits2.pl
($n,$i)=@ARGV;
$r=floor($n/10**(floor(log($n)/log(10)+1)-$i));
print int(.5+($r/10-floor($r/10))*10);

Run it as:

perl -M5.010 -MPOSIX=floor ndigits.pl 726433 1

Perl6 - 85 chars

my ($n,$i)=@*ARGS;
my$r=$n/10**(log10($n).round-$i);
say (($r/10-floor($r/10))*10).Int;

Smalltalk, 44

Although dc is unbeatable, here is a Smalltalk solution:

arguments, n number; d digit-nr to extract:

[:n :d|(n//(10**((n log:10)ceiling-d)))\\10]