输出整数的第n个数字


13

如果不使用字符串(除了在必要时,如与输入或输出)计算第n个位,从左侧,一个的整数(在基体10)。

输入将以以下格式给出:

726433 5

输出应为:

3

因为那是“ 726433”的第五位数字。

输入将包含前导零,例如“ 00223”。

测试案例/更多示例:

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

这是代码高尔夫;最少的字符获胜,但是任何内置函数(例如“ nthDigit(x,n)”)都不可接受

以下是一些伪代码,可以帮助您入门:

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

如您所见,我是打高尔夫球的新手,尽管我认为在回答一个问题之前先问一个问题有点不公平,但我真的很想看看这会产生什么样的反应。:)

编辑:我希望数学答案,所以我不能真正接受依赖于将字符串转换为数组或能够访问数字作为数字列表的答案。

我们有一个赢家

用“ dc”表示,12个字节。通过DigitalTrauma


这可以仅仅是一个功能,还是必须处理I / O?如果它不需要处理I / O,是否可以只是lambda而不是函数?
slebetman'4

您所做的编辑不清楚您到底不喜欢什么。特别是,“能够以数字列表形式访问数字”,是使用您不喜欢的任何形式的数组,还是仅存在内置的基本转换例程?
彼得·泰勒

@PeterTaylor数字数组不正确,因为您可以轻松地抓住数组中的第n个项目。我不确定基本转换是如何工作的,但这似乎很容易。
kukac67

为什么建立数字列表是一个问题?这是高度数学的-将数字表示为多项式。
2rs2ts 2014年

@ 2rs2ts如果可以数学方式创建数字列表,即无需将字符串解析为数组,则可以接受。
kukac67'4

Answers:


2

dc,12个字节

?dZ?-Ar^/A%p

这是一个数学答案。运作方式如下:

  • ? 读取输入数字并压入堆栈
  • d 堆栈顶部重复
  • Z 从堆栈中弹出值,计算并压入位数
  • ? 读取数字索引并压入堆栈
  • - 从数字计数中减去数字索引
  • A 将10推入堆栈
  • r 交换堆栈上的前2个值
  • ^ 取10 ^(数字计数-数字索引)
  • / 将数字除以求幂的结果
  • A 将10推入堆栈
  • % 计算数字mod 10以获取最后一位并推入堆栈顶部
  • p 弹出并打印堆栈顶部

实际上:

$ {echo 987654321; 回声1; } | 直流ndigit.dc
9
$ {echo 987654321; 回声2; } | 直流ndigit.dc
8
$ {echo 987654321; 回声8; } | 直流ndigit.dc
2
$ {echo 987654321; 回声9; } | 直流ndigit.dc
1个
$ 

1
我认为你是赢家。这是第三最短的代码,但使用的最短的2 base conversion -> arrays
kukac67

5

GolfScript(10个字节)

~(\10base=

假定输入为字符串(例如,通过stdin)。如果它是堆栈上的两个整数,~则应删除首字母,节省1个字符。

如果基本转换被认为不符合内置函数规则,则我有16个字符的替代方法:

~~)\{}{10/}/=10%

具有基本转换的第一个程序仅在输入“ 0”时输出第一个数字,而在输入“ 1”时输出第二个数字。golfscript.apphb.com/?c=MjcwNiAxCgpcMTBiYXNlPQ%3D%3D
kukac67 2014年

@ kukac67,已修复。
彼得·泰勒

4

果酱-7

l~(\Ab=

CJam是我正在开发的一种新语言,类似于GolfScript- http: //sf.net/p/cjam 。这里是解释:

l从输入中读取一行,
~计算字符串(从而获得两个数字),然后
(递减第二个数字
\交换数字
A是一个预初始化为10的变量
b进行基数转换,使第一个数字的基数为10的数组
=得到所需的值数组元素

该程序基本上是Peter Taylor解决方案的翻译。


我会说将以10为基数的数字放入数组中比算术运算更多的是字符串运算。
Digital Trauma 2014年


3

J- 15 24个字符

一个足够的“数学答案”。

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

得出以下相同的结果,但具有数学上的神秘特质。


简短版本,使用base-10扩展。

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

我们将0前置以调整基于1的索引。

用法:

   ({0,10&#.inv)~/ 1234567 3
3
   ({0,10&#.inv)~/ 444494 5
9

2
不允许使用字符串。
0xcaff 2014年

2

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

您无需将其定义为fn:def f(i,n): ... return d
smci 2014年

您无需理智检查if n>k: return -1案件。
smci 2014年

...而且您当然不需要进行首次遍历即可计算k(i中的位数),以便将其理智比较为n。
smci 2014年

2

C,50

这使用数组。

main(int c,char**a){putchar(a[1][atoi(a[2])-1]);}

只需忽略所有警告即可。

是的,在C语言中,字符串实际上只是数组,因此这很便宜。


更多数学:

C,83

main(int c,char**a){printf("%d",(atoi(a[1])/pow(10,strlen(a[1])-atoi(a[2])))%10);}

它不是使用字符串/数组函数吗?
VX

第一个确实如此,就像它说的;)第二个显然没有,除了strlen之外,我之所以选择它只是因为它比使用log短。如果有问题,这很容易解决,我可以在回家时添加它。
SBI

到这里,添加纯数学版本。
SBI

2
数学-一次都没有!
Potzblitz 2014年

2

bc(由bash驱动),41 29

我认为这是数学上而不是使用字符串的第一个答案:

bc<<<"$1/A^(length($1)-$2)%A"

的使用length()似乎有点严格,但是bc手册页谈论的是位数而不是字符串的长度:

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

输出:

$ ./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
$ 

1
@ kukac67我感谢接受投票!但是我认为习惯将代码高尔夫球问题开放两个小时以上以鼓励更多答案。大概一个星期左右。如果您不接受此答案,我不会感到冒犯:)
Digital Trauma 2014年

1
好。那我会拒绝的。希望你不会赢!:P
kukac67

1

Mathematica- 24 23

这很明显:)

IntegerDigits[#][[#2]]&

例:

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

输出:

3

您可以通过硬编码两个整数来缩短它,例如

IntegerDigits[n][[m]]

但是然后你首先要写信n = 726433; m = 5;。函数调用感觉更类似于程序。


1
您可以删除号码1
DavidC 2014年

现在这是作弊..:D
kukac67

1

C 145

程序查找到整数末尾的距离并除以直到达到索引,然后使用模数10获得最后一位。

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);
}

这可以打很多球。 从这些技巧开始
Digital Trauma

首先,不需要(int)强制转换和相关的括号
Digital Trauma

1
我无法抗拒。我将其打低至87个字符:i,a;main(){scanf("%d%d",&i,&a);for(a=log(i)/log(10)+1-a;a--;)i/=10;printf("%d",i%10);}
Digital Trauma 2014年

1

Wolfram Alpha-40至43之间

当然,我可以完全辩护说使用IntegerDigits是一个绝不落伍的技巧

任何内置函数,例如“ nthDigit(x,n)”

但是因为我以前的回答仍然有点像作弊,所以这是另一种选择。不幸的是,它的时间更长了,但是我没有看到如何比我缩短它的时间了。

以与以前相似的方式进行计数(使用&号,不传递任何参数),

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

有43个字符。通过否定指数并改组术语,我可以失去一个算术运算符(10^(...)x将被解释为乘法)

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

我没有手头的Mathematica进行测试,我怀疑它是否会像我怀疑的那样(并已由kukac67进行了验证)在Mathematica中不被接受,但它在WolframAlpha中运行

我对的使用感到怀疑RealDigits,因为我限制自己不能使用IntegerDigits此答案,而且它们非常相似。但是,如果我允许自己包括它(毕竟,它并不直接返回整数,是多么许多人也有),我可以另外两个字符斜线关:

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

我在Mathematica中尝试过,它没有输出值。一个43字符的输出:Mod[Trunc[57 2^(3 - Trunc[Log[456]/Log[10]])5^Trunc[Log[456]/Log[10]]], 10]
kukac67

是的,我想了很多。Wolfram Alpha在解释输入时更为宽大。幸运的是,我给了它正确的标题;)
CompuChip 2014年

但是我看到它确实可以在WolframAlpha上运行。
kukac67'4

{edit}尽管我看到链接断开了……显然,[即使对字符进行编码,他们也不喜欢它们。我将通过URL缩短器将其拉出。{edit2}显然W.Alpha有一个-更改了链接。
CompuChip 2014年

1

Tcl(42字节,lambda):

{{x y} {expr $x/10**int(log10($x)+1-$y)%10}}

(49个字节,功能):

proc f {x y} {expr $x/10**int(log10($x)+1-$y)%10}

(83个字节,如果我们需要接受来自shell的输入):

puts [expr [lindex $argv 0]/10**int(log10([lindex $argv 0])+1-[lindex $argv 1])%10]

这是如何运作的?
kukac67'4

添加了解释。这只是数学上最明显的方法。您如何在纸上做。
slebetman

我认为您是从错误的角度进行计数。
彼得·泰勒

嗯..是的。看起来像。我将其修改为左侧的计数。
slebetman 2014年

我接受31个字节。虽然lambda如何运行?Tcl是否有可以使用它的解释器?还是仅作为定义参数的程序的一部分?
kukac67

1

R(60)

解决了使用log10计算位数的问题。特殊情况x == 0需花费13个字符。

f=function(x,n)if(x)x%/%10^(trunc(log10(x))-n+1)%%10 else 0

取消高尔夫:

f=function(x,n)
  if(x) 
    x %/% 10^(trunc(log10(x)) - n + 1) %% 10
  else
    0

用法

> f(898,2)
[1] 9

1

Scala(133 99字节):

适用于所有正输入。用10除以从右边寻找的数字的幂,然后取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}

感谢您注意到上一个公式中的错误。这个比较短。


我喜欢!:)投票
kukac67'4

测试了解决方案:k(Array(“ 1234”,“ 7”))得到9。它不适用于n> #digits(x)吗?
lambruscoAcido 2014年

这是因为10 ^ -1在此表示法中并不精确,因此当您采用10%pow(10,-1)时会出现舍入误差,该值应给定为零但给定为0.0999。更正了我的答案以适应这种副作用。
麦克尔迈耶

1

哈斯克尔(142)

我不确定我是否正确理解了这个问题,但这就是我想要的:读取stdin(字符串),将两个数字设置为int(而不是字符串),做一些算法上的事情,然后输出结果(字符串)。我将其塞入142个字符,这太多了:

import System.Environment
a%b|a>9=div a 10%(b+1)|1<2=b
x#n=x`div`10^(x%1-n)`mod`10
u[a,b]=read a#read b
main=fmap(u.words)getContents>>=print

用法示例:

> echo 96594 4 | getIndex
9

1

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)

纯粹是数学上的,没有字符串,也没有。在第一个提示中输入第一个数字,在第二个提示中输入第二个数字。

测试用例

Input: 97654 5
Output: 4

Input: 224658 3
Output: 4

非高尔夫代码:

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

1

Perl中,38,36   没有30个字符

(不包括换行符)

可以说这是由于命令开关而作弊,但感谢您让我玩:-)

~/$ 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

编辑

能够删除2个字符:

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

...再加6:

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

怎么样

我们将第一个参数的输入$ARGV[0]按字符(split//)分割为脚本,从而创建零索引数组;$ARGV[1]在脚本的第二个参数中添加一个,然后对应于字符串或第一个参数中该位置的元素。然后,将表达式()作为一个元素列表保存在其中,该列表say将进行迭代。对于较短的简短版本,我们只shift在第一个参数中使用@ARGV的其余部分用于索引-一次shifted仅保留第二个参数,因此我们将pop()其减去1。

这应该是数学练习吗?我只是意识到我正在索引从输入读取的字符串,所以...我想我输了?如果我在平行高尔夫球场上有意义,请给我评分,然后我将在另一个答案中-从数学上再试一次。

干杯,


是的,很抱歉,没有使用string。欢迎使用PPCG!
Digital Trauma 2014年

好吧,抱歉,……到目前为止,我的数学方法还不是很值得高尔夫:-)
G. Cito 2014年

0

PHP,58

仅使用数学

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


1
这不是从右边找到的吗?
cjfaure 2014年

2
您可以将1个字符更改为来保存echo$n%10
Amal Murali 2014年

@Trimsty不,它实际上一直循环直到输入的数字不再大于10 ^ x,x是数字。因此,例如,如果您输入3457作为数字,并输入2作为数字,它将带走最后一位数字,直到该数字小于100(10 ^ 2)。这意味着它将带走5和7,因为那时剩下34,并且不大于100。然后它仅输出最后一位(4)。
dkasipovic 2014年

但是,这是事实,如果第二个数字是比数字的数量越大,你输出9和不为零
麦克尔迈耶

我看到,如果数字大于位数,则输出最后一位数字。如果输入1234和第5个数字,则自1234开始,您将得到4,而我已经小于10 ^ 5。
dkasipovic 2014年

0

〜-〜!- 94 93

弯曲规则-这是一个将n作为输入并假定要查找数字n的数字存储在'''''-和〜-〜中的函数!不支持浮点数。

'=~~~~~,~~:''=|*==~[']<''&*-~>,'|:'''=|*==%[%]~+*/~~~~/~~|:''''=|'''''/''&<<'''&'''''>-*-~>|:

'''''=~~~~,~~,~~,~~,~~,~~:''''''=''''&~:将导致''''''~~(2)('''''= 128)。


嗯...另一种深奥的语言?
2014年

@VisioN并不是很深奥,只是唯一的本机数据类型是数字,并且它不能与os / internet交互。esolangs.org/wiki/No_Comment
cjfaure

1
好吧,对我而言,人类无法轻易理解的每一种语法都是深奥的。是的,根据该理论,Perl也是深奥的:)
VisioN 2014年

@VisioN一段时间后,它很容易阅读。:P
cjfaure 2014年

0

Python 2.7(89字节)

我通过使用数字列表将整数转换为“多项式”。我知道您说您不能接受,但我不明白为什么不这样做,因为它使用数字的数学概念表示为基数的多项式。它只会在传入的整数为时失败0,但是您说没有填充零;)

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]

运行方式test.py

$ python test.py 726489 5
8

我假设您需要shell输入,但我无法利用输入将是字符串这一事实。跳过shell输入只有43个字节,其中包括:

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

尽管我使用了不必要的迭代,但是通过不对添加额外的减量来节省一些字节n


0

扩展的BrainFuck:49

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

用法:

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

除了乘法运算符(例如10+ => ++++++++++)之外,我并未真正使用EBF的任何特殊功能。除此之外,大部分都是纯BrainFuck

怎么运行的:

+                ; 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
>>>[>>]          ; follow the breadcrumbs
<33+.            ; go to value part, increase by 33 (32 + 1 which we substracted) and print

方案(R6RS):100(没有不必要的空格)

(let*((x(read))(n(read))(e(expt 10(-(floor(+(/(log x)(log 10))1))n))))
  (exact(div(mod x(* e 10))e)))

0

awk-53

{for(d=10^9;!int($1/d)||--$2;d/=10);$0=int($1/d)%10}1
  1. 按除法修剪数字,最大可能为32位unsigned int
  2. 当我们击中整数的左侧时,int($ 1 / d)返回非零
  3. 继续超过该位数的n($ 2)位数字

取消高尔夫:

{
    for(d = 1000000000; int($1 / d) != 0 || --$2; d /= 10);
    print int($1 / d) % 10;
}

0

斯卡拉(83)

不使用任何Scala特殊功能。而是标准解决方案。

def f(x:Int,n:Int)=if(x==0)0 else x/(math.pow(10,math.log10(x).toInt-n+1)).toInt%10

取消高尔夫:

def f(x:Int,n:Int) = 
  if(x==0)
    0
  else
    x / (math.pow(10, math.log10(x).toInt - n + 1)).toInt % 10 

0

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,由于使用数组而无效。

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]);}

我不允许在编辑中使用数组(在发布之前)...但是我喜欢您的操作方式。:)
kukac67

好吧,我看起来不太正常。我添加了避免数组的解决方案。
VX

0

朱莉娅37

d(x,y)=div(x,10^int(log10(x)-y+1))%10

由于内置的​​^运算符。任意精度的算术允许int的任何大小。

样品

julia> d(1231198713987192871,10)
3

0

perl(有点数学/不是很高尔夫)-99个字符

 ~/$ 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);

运行为:

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

0

Perl6-85个字符

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

0

Smalltalk,44岁

尽管dc无与伦比,但这是Smalltalk解决方案:

参数,n个数字;d digit-nr提取:

[:n :d|(n//(10**((n log:10)ceiling-d)))\\10]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.