++のみを使用して平方根を計算する


13

あなたの仕事は、次のような数学的な演算子を使用して数値を変更することなく、正の整数の平方根を計算することです。

  • 変数の設定(例:squareRoot = 5)
  • 加算(A + B)
  • 減算(AB)
  • 乗算(A * B)
  • 部門(A / B)
  • 正方形、立方体、4番目などの根
  • 指数

比較演算子(<、>、==など)は、この質問の目的では「数学演算子」とは見なされず、変数の値を変更しない限り許可されます。

使用できる唯一の演算子は++です。次の例外があります。

  • 必要に応じて、変数を0に設定して初期化できます。
  • 言語に++構文が含まれていない場合、foo + = 1やfoo = foo + 1などの同等の構文を使用できます。
  • 平方根は、小数を超える少なくとも6桁(1万桁)で計算し、小数の整数として出力する必要があります(例:2を入力すると、丸めに応じて14142135624または1414213として出力される可能性があります) 。切り上げまたは切り捨ては重要ではありません。

ユーザー定義関数は許可されていません。また、gotoを使用した関数のシミュレーションも許可されていません。

みんなが投稿したものを見てみたいです!ハッピーコーディング!

明確化

数値が正の整数であることを明確にします。任意の数のコードを作成できますが、必須ではありません。

明確化#2

比較演算子が許可されていることを明確にします。

明確化#3

加算、減算、乗算、除算、および数値を変更する関数は、変数に保存されているかどうかに関係なく、まったく許可されていません。申し訳ありませんが、これはいくつかの既存の回答を無効にしますが、トロールの回答を防止するために、この演算子グループを「番号の変更」と定義するつもりでした(例:sqrt()関数を使用しましたが、追加のみを禁止し、乗算、除算、減算)。混乱させて申し訳ありません。

明確化#4

少なくとも5桁が必要であることを明確にします。10桁により、コードが長時間実行されました。


1
いいえ、混同して申し訳ありません!私はもともと++を持っているつもりだった-と私は最後の最後に取り出すことにしました。
iggyvolz 14

5
「数学的演算子を使用して数値を変更することなく」 -これには明確化が必要かもしれません。あなたはこれらの演算子を使用しなくてもよいことを意味するかは全く例えば、あるいは、彼らは使用することができることが、結果を変数に保存されていない場合にのみ、while r*r<n*10e20:r+=1些細な- 。また、必要な出力を10 ^ 8程度に減らすことを検討することもできます。1つ目は10 ^ 10が2 ^ 31よりも大きいため、2つ目はその高さを増分するのに時間がかかるためです。
プリモ14

1
なぜだろう、これまで「変更」すべてで任意の変数にしたいですか?あなた不可欠たちは思考の奇妙な方法を持っている...
counterclockwis回すために中止した

4
この質問を終了するようフラグを立てています。質問に大幅な変更を加えました。実際には、Sandboxを介してこの質問を検証する必要があります。そうしないと、回答するための努力を投資する人々を苛立たせます。
アビジット2014

3
必要な桁数を減らすことは、時間/メモリの制限がなければ意味がありません。私のコードは5桁を処理できますが、マシンには十分なRAMがありません。
デニス14年

回答:


13

パイソン66

print'%.0f'%reduce(lambda a,b:abs(a)+1e10j,range(-2,input())).real

出力

>>> print'%.0f'%reduce(lambda a,b:abs(a)+1e10j,range(-2,input())).real
121
110000000000
>>> print'%.0f'%reduce(lambda a,b:abs(a)+1e10j,range(-2,input())).real
1000
316227766017

このソリューションでは、複雑な平面でテオドロスのらせんを使用して結果を達成します。


2
私はそれをラップする必要があると思うint(...*1e10)、そうでなければ非常にいい。ただし、abs複雑な値をとることは多かれ少なかれsqrt変装しています。
primo 14

1
@primo私はあなたが許可されているとは思わない*1e10...
たけた

@primo:1e10を掛ける代わりに、少し違うルートを取りました。そして、私は腹筋が変装でsqrtかもしれないことに同意しますが、問題で現在述べられているように、私はそれが完全に合法であると感じます。
アビジット2014

私は下票を見て、それは非常に憂鬱です。私はこの答えに大きな期待を持っていたので、投票した人はコメントを残してください。
アビジット2014

9
@iggyvolz:質問を増やし続け、さらに制限を追加していくことに本当に驚いています。人々は答えを書くために時間と労力を費やしますが、あなたは彼らが精神異常であることを期待することはできません。
Abhijit

6

Python、184文字

次のPythonソリューションでは、インクリメント演算子のみを使用し、他の算術演算子は一切使用しません。ただし、必要な精度(10桁)では、実行に非常に長い時間がかかります。あなたは減らすことによって、低精度(3桁)でそれをテストすることができます1e201e6

import sys;t=0
for _ in range(int(sys.argv[1])):
 for _ in range(int(1e20)):t+=1
q=0
while 1:
 z=0
 for _ in range(q):
  for _ in range(q):z+=1
 if z>=t:break
 q+=1
print(q)

ゴルフをしていない:

import sys

# t = N * 100000000000000000000 (magnitude of twice the precision)
t = 0
for _ in range(int(sys.argv[1])):
    for _ in range(int(1e20)):
        t += 1
q = 0
while True:
    # z = q * q
    z = 0
    for _ in range(q):
        for _ in range(q):
            z += 1
    if z >= t:
        break
    q += 1
print(q)

私は質問を明確にした。あなたはそれをあなたが望むだけの数(少なくとも5)まで行うことができる。私はPythonに精通していませんが、int()は単なるタイプキャスターであると仮定していますか?もしそうなら、それは数の値を変更しないので問題ありません。
iggyvolz

@iggyvolz:そうです、文字列の引数値(コマンドラインで指定)を整数に変換する必要があります。単純な関数はそれを必要としません。
グレッグヒューギル14年

2

Fortran 73

read*,t;s=0;do while(abs(s*s/1e10-t)>1e-10);s=s+1;enddo;print*,s/1e5;end

特定の値の答えを実際に決定するのに苦労するかもしれませんが、それは確実に機能します。私が使用していますが*-これらは任意の値を変更していない、だけでs=s+1実際には何も変更されます。


うわー、静的な値を変更するために演算子を使用することを考えていなかったと思います。それは完全に罰金と+1(私はupvoteする15の評判を持っていた場合)だ
iggyvolz

これは*演算子を使用しますが、これは明らかに許可されていません。それとも、与えられた制限を何らかの形で誤解していますか?
グレッグヒューギル14

@GregHewgill:数を変更するために数学演算子を使用せずに、OP状態。これらの演算子は値を変更していません。
カイルカノス14

7
ただし、*演算子を使用して数値を変更しているため、結果をどこにも保存していません。OPが(以外の)割り当てを単に禁止したい場合、s=s+1なぜ許可されていない算術演算子をすべて挙げるのですか?
グレッグヒューギル14

1
@iggyvolz:20時間後にルールを変更するのは悪い形です。そうしないで、代わりにサンドボックスを使用して、問題のねじれを解決してください。
カイルカノス14

2

CJam、26バイト

q~,1e20,m*,:N!{)_,_m*,N<}g

オンラインでお試しください。コードを貼り付け、入力に目的の整数を入力し、[ 実行 ]をクリックします。あなたがする前1e101e4、しかしに変更することをお勧めします。

Javaインタプリタのハンドル1e6を約15秒で入力「2」と。1e20必要となる膨大な RAMの量を。

$ cjam <(echo 'q~,1e2,m*,:N!{)_,_m*,N<}g') <<< 4; echo
20
$ cjam <(echo 'q~,1e2,m*,:N!{)_,_m*,N<}g') <<< 2; echo
15
$ cjam <(echo 'q~,1e4,m*,:N!{)_,_m*,N<}g') <<< 4; echo
200
$ cjam <(echo 'q~,1e4,m*,:N!{)_,_m*,N<}g') <<< 2; echo
142
$ cjam <(echo 'q~,1e6,m*,:N!{)_,_m*,N<}g') <<< 4; echo
2000
$ cjam <(echo 'q~,1e6,m*,:N!{)_,_m*,N<}g') <<< 2; echo
1415

バックグラウンド

数学的演算子で数値を変更することは許可されていないため、配列を変更するにはsetwise演算子を使用します。

コードは、入力(「i」)に1e20を「乗算」することから始まりますが、実際の乗算はありません。代わりに、「i」整数を含む配列、1e20整数を含む配列をプッシュし、デカルト積を取得してその長さを計算します。

次に、整数の積(上記のように計算された)が未満になるまで、ゼロを押して増分しますi * 1e20。これにより、平方根が切り上げられます。

使い方

q~     " Read for STDIN and interpret. ";
,      " Push an array containing that many integers. ";
1e20,  " Push the array [ 0   …   1e20 - 1]. ";
m*,:N  " Get the length of the cartesian product and save it in “N”. ";
!      " Logical NOT. Since the input is a positive integer, this pushes 0. " ;
{      " ";
  )    " Increment the integer on the stack.";
  _,   " Push an array containing that many integers. ";
  _m*, " Get the length of the cartesian product of the array by itself. ";
  N<   " If the product is smaller than the target value, push 1; otherwise push 0. ";
}g     " Repeat the loop if the result was 1. ";

1

コブラ-62

3回目の編集の前に投稿され、無効になりました。

短いだけでなく、次の場合はオーバーフローが発生しないはずです。 n < Decimal.maxValue

def f(n)
    r,e=0d,10000000000
    while r/e*r/e<n,r+=1
    print r

しかし、あなたが使用r/e*r/e明確に非とする、++数学演算子...
nneonneo

@nneonneoこれは3回目の編集の前に投稿されましたが、まだ変更していません。
urous 14年

0

Scala、117

val z=BigInt(readLine+"0000000000")
print(Stream.from(1)find(x=>(BigInt(0)/:Stream.fill(x,x)(1).flatten){_+_}>=z)get)

入力として2であっても、妥当な時間内に終了しませんが、機能します。あなたは私がやっていることに気付くかもしれ_+_ませんが、それは1を追加するだけで、Scalaには++演算子がありません。内側のStreamをListに置き換えることで2つの文字を保存できましたが、メモリが不足していました。書かれているように、メモリ使用量ではなく、処理時間のみでスケーリングすると思います。


0

Haskell、70バイト

s i|r<-[1..i]=foldl1(.)[(+1)|j<-r,k<-r]
f i=[j-1|j<-[0..],s j 0>=i]!!1

f入力以下の平方を持つ最大数を見つけることにより、整数平方根を与えます。二乗関数s iは、(i,i)行列のすべての要素に対して1ずつ増加します。(電話で入力したので、タイプミスがあるかもしれません)。


0

PHP、124バイト

これは徹底的なアルゴリズムです。その数値の2乗が「目標」数(入力の1Eのnumber of decimals2乗(10進数の2の結果に対して10.000))より大きくなるまで、数値を試行します。その後、最後の数値を出力します。

for(;$a++<$z=$argv[1];)for(;$$a++<1e6;)$g++;for(;$b++<$g;$i=$x=0)for(;$i++<$b;)for($j=0;$j++<$b;)if(++$x>=$g)break 3;echo$b;

次のように実行します(-d審美的な理由でのみ追加):

php -d error_reporting=32757 -r 'for(;$a++<$z=$argv[1];)for(;$$a++<1e6;)$g++;for(;$b++<$g;$i=$x=0)for(;$i++<$b;)for($j=0;$j++<$b;)if(++$x>=$g)break 3;echo"$b\n";' 2

3桁以上または10を超える数値でこれを試すことはお勧めしません。

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