# 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? Commented Apr 9, 2014 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? Commented Apr 9, 2014 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. Commented Apr 9, 2014 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. Commented Apr 9, 2014 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. Commented Apr 9, 2014 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 Commented Apr 8, 2014 at 23:52
• @kukac67, fixed. Commented Apr 9, 2014 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. Commented Apr 12, 2014 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 Commented Aug 16, 2017 at 11:20
• Wow you fought for every byte. 1<2" instead of "true" - cute. Commented Aug 17, 2017 at 21:08
• It's what we do around here... Commented Aug 18, 2017 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. Commented Apr 8, 2014 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. Commented Apr 13, 2014 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 Commented Apr 9, 2014 at 10:44 • You don't need to sanity-check the if n>k: return -1 case. – smci Commented Apr 9, 2014 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 Commented Apr 9, 2014 at 10:52 # C, 50 This uses arrays. main(int c,char**a){putchar(a[1][atoi(a[2])-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[1])/pow(10,strlen(a[1])-atoi(a[2])))%10);} • isn't it using string/array functions? – V-X Commented Apr 10, 2014 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 Commented Apr 10, 2014 at 6:46 • There we go, added the purely mathematical version. – SBI Commented Apr 11, 2014 at 8:56 • Math - not even once! Commented Apr 11, 2014 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 :) Commented Apr 9, 2014 at 1:38
• ok. I will de-accept then. Hope you don't win! :P Commented Apr 9, 2014 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. Commented Apr 9, 2014 at 13:53
• Now this is cheating.. :D Commented Apr 9, 2014 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 Commented Apr 9, 2014 at 23:20
• For a start, the (int) casts and associated parens are unnecessary Commented Apr 9, 2014 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);}. Commented Apr 9, 2014 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[456]/Log[10]])5^Trunc[Log[456]/Log[10]]], 10] Commented Apr 9, 2014 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 ;) Commented Apr 9, 2014 at 16:29
• But I see it does work on WolframAlpha. Commented Apr 9, 2014 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. Commented Apr 9, 2014 at 16:30

puts [expr [lindex $argv 0]/10**int(log10([lindex$argv 0])+1-[lindex $argv 1])%10] • How does this work? Commented Apr 9, 2014 at 16:08 • Added explanation. It's just the most obvious way to do it mathematically. How you'd do it on paper. Commented Apr 9, 2014 at 17:11 • I think you're counting from the wrong end. Commented Apr 9, 2014 at 17:18 • Hmm.. yeah. Looks like it. I'll revise it to count form the left. Commented Apr 9, 2014 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? Commented Apr 9, 2014 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) [1] 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 Commented Apr 9, 2014 at 16:01 • Tested the solution: k(Array("1234", "7")) which gives 9. Does it not work for n > #digits(x) ? Commented Apr 9, 2014 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. Commented Apr 10, 2014 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[0])[$ARGV[1]-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[0])[$ARGV[1]-1];
say((split//,$ARGV[0])[$ARGV[1]-1]);

... then 6 more:

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

How

We split the input of the first argument to the script $ARGV[0] by character (split//) creating an zero indexed array; adding one to the second argument$ARGV[1] 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! Commented Apr 12, 2014 at 2:47
• OK sorry 'bout that ... so far my mathematical approaches are not very golf-worthy :-) Commented Apr 12, 2014 at 14:08

# PHP, 58

Using math only

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

• Doesn't this find from the right? Commented Apr 9, 2014 at 14:58
• You can save 1 char by changing it to echo$n%10. Commented Apr 9, 2014 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). Commented Apr 9, 2014 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 Commented Apr 10, 2014 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. Commented Apr 10, 2014 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? Commented Apr 9, 2014 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 Commented Apr 9, 2014 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 :) Commented Apr 9, 2014 at 14:38 • @VisioN It gets easy to read after a while. :P Commented Apr 9, 2014 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[1]),int(v[2]) 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[99];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. :) Commented Apr 9, 2014 at 15:52 • OK, I wasn't looking properly. I've added a solution avoiding arrays. – V-X Commented Apr 10, 2014 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]