整数のn桁目を出力します


13

文字列を使用せずに(入力や出力などの必要な場合を除き)、整数の(10を底とする)左から n番目の桁を計算します。

入力は次の形式で提供されます。

726433 5

出力は次のとおりです。

3

それは「726433」の5桁目です。

入力に、先行するゼロ含まれません(例: "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を処理する必要がない場合、関数ではなくラムダにすることはできますか?
スリーブマン14

あなたの編集は、あなたが本当に好きではないものについては不明確なままにします。特に、「数字のリストとして数字にアクセスできる」ということで、好きではない任意の形式の配列を使用するのでしょうか、それとも組み込みの基本変換ルーチンが存在するのでしょうか?
ピーターテイラー14

@PeterTaylor配列のn番目の項目を簡単に取得できるため、数字の配列は問題ありません。基本変換が正確にどのように機能するかはわかりませんが、簡単に思えます。
kukac67 14

数字のリストを作成するのはなぜ問題なのですか?それは非常に数学的です-それは多項式として数を表します。
2rs2ts 14

@ 2rs2ts数字のリストを数学的に作成できる場合、つまり、文字列を配列に解析せずに作成できる場合は、受け入れ可能です。
kukac67 14

回答:


2

dc、12バイト

?dZ?-Ar^/A%p

これは数学的な答えです。仕組みは次のとおりです。

  • ? 入力番号を読み取り、スタックにプッシュ
  • d スタックの先頭を複製
  • Z スタックから値をポップし、桁数を計算してプッシュします
  • ? 数字インデックスを読み取り、スタックにプッシュします
  • - 桁数から桁インデックスを引きます
  • A スタックに10を押します
  • r スタックの上位2つの値を交換します
  • ^ べき乗10 ^(桁数-桁インデックス)
  • / べき乗の結果で数値を除算します
  • A スタックに10を押します
  • % 10のmodを計算して最後の数字を取得し、スタックの一番上にプッシュします
  • p スタックの上部をポップして印刷します

動作中:

$ {echo 987654321; エコー1; } | dc ndigit.dc
9
$ {echo 987654321; エコー2; } | dc ndigit.dc
8
$ {echo 987654321; エコー8; } | dc ndigit.dc
2
$ {echo 987654321; エコー9; } | dc ndigit.dc
1
$ 

1
あなたが勝者だと思います。これは3番目に短いコードですが、最短の2が使用されbase conversion -> arraysます。
kukac67 14

5

GolfScript(10バイト)

~(\10base=

これは、入力が文字列(たとえば、stdin経由)であることを前提としています。スタック上の2つの整数の場合、イニシャル~は削除され、1文字節約されます。

基本変換が組み込み関数の規則に違反すると見なされる場合、16文字の代替があります。

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

ベース変換を行う最初のプログラムは、「0」を入力した場合にのみ最初の数字を出力し、「1」を入力した場合に2番目の数字を出力します。golfscript.apphb.com/?c=MjcwNiAxCgpcMTBiYXNlPQ%3D%3D
kukac67

@ kukac67、修正済み。
ピーターテイラー14

4

CJam-7

l~(\Ab=

CJamは、GolfScript- http: //sf.net/p/cjamに似た、私が開発している新しい言語です。説明は次のとおりです。

l入力から行を読み取り、
~文字列を評価し(2つの数値を取得します)
(、2番目の数値をデクリメントします。
\数値
Aは10に事前初期化された変数で
bあり、ベース変換を行い
=ます。配列の要素

このプログラムは、基本的にPeter Taylorのソリューションの翻訳です。


基数10桁を配列に入れることは、数学的な操作よりも文字列操作のほうが多いと思います。
デジタル外傷14

4

Haskell 60バイトおよび読み取り可能

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

関与する文字列はありません!

*Main> nth 1234567 4
4


すごいバイトごとに戦ったわ。1 <2" "真の代わりに" - 。かわいい
マーティンDrautzburg


3

J- 15 24文字

十分に「数学的な答え」。

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

以下と同じ結果になりますが、数学的であるという神秘的な性質を備えています。


ベース10拡張を使用したショートバージョン。

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

0を先頭に追加して、1ベースのインデックス作成を調整します。

使用法:

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

2
文字列は許可されていません。
0xcaff

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

if n>k: return -1ケースの健全性チェックを行う必要はありません。
SMCI

...そして、k(iの桁数)をカウントするためだけに最初のパスを作成する必要はありません。
SMCI

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 14

それが言うように、最初のものはそうです;)2番目のものは、ログを使用するよりも短いという理由だけで私が選んだstrlenを除いて、明らかにそうではありません。それが問題である場合、それは簡単な修正であり、家に帰ったときに追加できます。
SBI 14

純粋に数学的なバージョンを追加しました。
SBI

2
数学-1回でもない!
ポッツブリッツ14

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受け入れ票に感謝します!しかし、より多くの回答を促すために、コードゴルフの質問を2時間以上開いたままにするのが慣習だと思います。おそらく一週間かそこら。この回答を受け入れなくても気分を害することはありません:)
デジタルトラウマ14

1
OK。私はそれから受け入れません。あなたが勝てないことを願っています!:P
kukac67 14

1

Mathematica- 24 23

これは一種の明らかです:)

IntegerDigits[#][[#2]]&

例:

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

出力:

3

2つの整数をハードコーディングすることで短くすることができます。例えば

IntegerDigits[n][[m]]

しかし、あなたは最初に書かなければなりませんn = 726433; m = 5;。関数呼び出しはプログラムに似ているように感じました。


1
番号を削除できます1
DavidC 14

今、これは不正行為です..:D
kukac67 14

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

これは大幅にゴルフすることができます。 これらのヒントから開始
デジタル外傷14

開始のために、(int)キャストおよび関連する括弧は不要です
デジタル外傷14

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);}
デジタル外傷

1

Wolfram Alpha-40〜43

もちろん、私はそれを使用してそれを完全に防御することができます IntegerDigitsは、することがトリックに該当しない

「nthDigit(x、n)」などの組み込み関数

しかし、私の以前の答えはまだ少し浮気のように感じたので、ここに代替案があります。残念ながら、かなり長くなりますが、短縮する方法がわかりませんでした。

前と同様の方法でカウントする(アンパサンドを使用し、引数を渡さずに)

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

43文字です。指数を否定し、項をシャッフルすることにより、1つの算術演算子(10^(...)xれる可能性があります乗算として解釈されます)

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

テストするMathematicaが手元にないので、疑わしい(そしてkukac67によって親切に検証されたように))ので、これは受け入れられませんが、WolframAlpha実行されます

の使用には疑問がありますRealDigits。なぜなら、私IntegerDigitsはこの回答に使用することを制限しており、それらは非常によく似ているからです。しかし、私は自分自身がそれを含めるように(すべての後に、それがどれだけ、直接整数を返さない許可した場合に多く、私は別の2つの文字をオフにスラッシュすることができますがありますそれらの):

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

Mathematicaで試しましたが、値は出力されません。43文字1 ouputsこの:Mod[Trunc[57 2^(3 - Trunc[Log[456]/Log[10]])5^Trunc[Log[456]/Log[10]]], 10]
kukac67

ええ、私は同じくらい考えました。Wolfram Alphaは入力を解釈するのに少し寛容です。幸いなことに、私はそれに正しいヘッダーを与えました;)
CompuChip 14

しかし、それはWolframAlphaで動作するようです。
kukac67 14

{編集}リンクは壊れていますが、[文字がエンコードされていても文字が好きではないようです。URL短縮サービスを使用して取得します。{edit2}どうやらW.Alphaが持っているようです-リンクを変更しました。
CompuChip 14

1

Tcl(42バイト、ラムダ):

{{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バイト):

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

これはどのように作動しますか?
kukac67 14

説明を追加しました。それは数学的にそれを行う最も明白な方法です。紙の上でどうするか。
スリーブマン14

あなたは間違った終わりから数えていると思います。
ピーターテイラー14

うーん。そのように見える。左から数えるように修正します。
slebetman

31バイトを受け入れます。どうやってラムダを実行できますか?Tclにはそれを使用できるインタープリターがありますか?または、引数を定義するプログラムの一部としてのみ?
kukac67 14

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

ソリューションをテストしました:k(Array( "1234"、 "7"))これは9を返します。n> #digits(x)では機能しませんか?
lambruscoAcido

これは、この表記では10 ^ -1が正確ではないため、10%pow(10、-1)を取得するときに丸めエラーが発生するためです。この副作用に対応するために私の答えを修正しました。
ミカエルメイヤー14

1

ハスケル、142

私は質問を正しく理解したかどうかはわかりませんが、これはあなたが望むと思うものです:stdin(文字列)を読んで、2つの数値を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)

純粋に数学的で、文字列はなく、文字列はありません。最初のプロンプトで最初の番号を取り、2番目のプロンプトで2番目の番号を取ります。

テストケース

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

パール、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]スクリプトの2番目の引数に1を追加すると、文字列または最初の引数のその位置にある要素に対応します。次に、式を繰り返し処理()する1つの要素のリストとして内部に保持sayします。短い短いバージョンでshiftは、最初の引数だけを使用し、@ ARGVの残りの部分を使用してインデックスに使用します。いったんshiftedにすると、2番目の引数だけが残るためpop()、1を減算します。

これは数学の練習になるはずですか?入力から読み取った文字列にインデックスを付けていることに気付いたので、...失ったと思いますか?並列ゴルフコースで理にかなっている場合はマークアップして、別の答えで-より数学的に-再試行します。

乾杯、


Yup, sorry, Without using strings. Welcome to PPCG anyway!
Digital Trauma

OK sorry 'bout that ... so far my mathematical approaches are not very golf-worthy :-)
G. Cito

0

PHP, 58

Using math only

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


1
Doesn't this find from the right?
cjfaure

2
You can save 1 char by changing it to echo$n%10.
Amal Murali

@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).
dkasipovic

But it is true that if the second number is bigger than the number of digits, you output 9 and not zero
Mikaël Mayer

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.
dkasipovic

0

~-~! - 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?
VisioN

@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
cjfaure

1
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 :)
VisioN

@VisioN It gets easy to read after a while. :P
cjfaure

0

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.


0

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

Scheme (R6RS): 100 (without unnecessary whitespace)

(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. 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;
}

0

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 

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, 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. :)
kukac67

OK, I wasn't looking properly. I've added a solution avoiding arrays.
V-X

0

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

0

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

0

Perl6 - 85 chars

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

0

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]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.