Chỉ tính căn bậc hai bằng ++


13

Nhiệm vụ của bạn là tính căn bậc hai của một số nguyên dương mà không sử dụng bất kỳ toán tử toán học nào để thay đổi số, chẳng hạn như:

  • Đặt một biến (ví dụ: SquareRoot = 5)
  • Ngoài ra (A + B)
  • Phép trừ (AB)
  • Phép nhân (A * B)
  • Bộ phận (A / B)
  • Rễ vuông, khối lập phương, thứ tư, vv
  • Số mũ

Các toán tử so sánh (chẳng hạn như <,>, ==, v.v.) không được coi là "toán tử toán học" cho mục đích của câu hỏi này và được cho phép miễn là chúng không thay đổi giá trị của biến.

Toán tử duy nhất mà bạn có thể sử dụng là ++. Các ngoại lệ sau đây được đặt ra:

  • Nếu bạn muốn, bạn có thể khởi tạo một biến bằng cách đặt nó thành 0.
  • Nếu ngôn ngữ của bạn không bao gồm cú pháp ++, bạn có thể sử dụng cú pháp tương đương, chẳng hạn như foo + = 1 hoặc foo = foo + 1
  • Căn bậc hai phải được tính ít nhất là 6 chữ số ngoài số thập phân (vị trí hàng trăm nghìn) và xuất ra dưới dạng toàn bộ số thập phân (ví dụ: nếu tôi nhập 2, nó có thể xuất hiện là 14142135624 hoặc 1414213 tùy thuộc vào làm tròn) . Làm tròn lên hoặc xuống không quan trọng.

Chức năng do người dùng xác định không được phép. Ngoài ra, chức năng mô phỏng với goto cũng không được phép.

Tôi quan tâm để xem những gì mọi người gửi! Chúc mừng mã hóa!

LÀM RÕ

Làm rõ số đó là một số nguyên dương. Bạn có thể tạo mã có thể làm bất kỳ số nào nhưng không cần thiết.

YÊU CẦU # 2

Làm rõ rằng các toán tử so sánh được cho phép.

LỚP # 3

Cộng, trừ, nhân, chia, và chức năng để thay đổi số không được phép ở tất cả , bất kể họ được lưu vào một biến hay không. Tôi xin lỗi vì điều này làm mất hiệu lực một vài câu trả lời hiện có, nhưng tôi muốn định nghĩa nhóm toán tử này bằng "thay đổi số" để ngăn câu trả lời troll (ví dụ: tôi chỉ sử dụng hàm sqrt (), bạn chỉ cấm bổ sung, nhân, chia và trừ). Xin lỗi vì sự nhầm lẫn.

LỚP # 4

Làm rõ rằng chúng ta cần ít nhất 5 chữ số. 10 chữ số gây ra mã để chạy trong một thời gian dài.


1
Không, - không được phép, xin lỗi vì sự nhầm lẫn! Ban đầu tôi dự định có ++ và - nhưng tôi quyết định lấy ra vào phút cuối.
iggyvolz

5
"Không sử dụng bất kỳ toán tử toán học nào để thay đổi số" - Tôi nghĩ rằng điều này có thể cần làm rõ. Bạn có nghĩa là các nhà khai thác có thể không được sử dụng ở tất cả , hoặc, rằng họ có thể được sử dụng, nhưng chỉ khi kết quả không được lưu vào một biến, ví dụ while r*r<n*10e20:r+=1- khá tầm thường. Ngoài ra, bạn có thể xem xét giảm sản lượng yêu cầu xuống còn 10 ^ 8 hoặc hơn. Thứ nhất, vì 10 ^ 10 lớn hơn 2 ^ 31 và thứ hai, vì sẽ mất một thời gian để tăng mức cao đó.
Primo

1
Tại sao bạn sẽ không bao giờ muốn "thay đổi" bất kỳ biến ở tất cả? Những người cấp bách của bạn có những cách suy nghĩ kỳ lạ ...
đã ngừng quay ngược lại vào

4
Tôi đang gắn cờ để đóng câu hỏi này. Để thay đổi nhiều triệt để cho câu hỏi. Bạn thực sự nên xác nhận câu hỏi này thông qua Sandbox nếu không bạn sẽ làm mọi người thất vọng khi đầu tư nỗ lực trả lời.
Abhijit

3
Giảm số chữ số cần thiết là vô nghĩa nếu không có giới hạn thời gian / bộ nhớ. Mã của tôi có thể xử lý 5 chữ số, nhưng máy của tôi không có đủ RAM.
Dennis

Câu trả lời:


13

Con trăn 66

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

Đầu ra

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

Giải pháp này sử dụng Xoắn ốc Theodorus trên một mặt phẳng phức tạp để đạt được kết quả.


2
Tôi nghĩ rằng sẽ cần phải được bọc trong int(...*1e10), nếu không rất tốt đẹp. Mặc dù, lấy absmột giá trị phức tạp ít nhiều được sqrtngụy trang.
primo

1
@primo Tôi không nghĩ bạn cho phép *1e10...
Cruncher

@primo: Thay vì nhân với 1e10, tôi đã chọn một tuyến đường khác một chút. Và mặc dù tôi đồng ý rằng abs có thể là sqrt ngụy trang, nhưng tôi cảm thấy nó hoàn toàn hợp pháp như được nêu trong vấn đề.
Abhijit

Tôi thấy một downvote, và nó khá buồn. Tôi đã hy vọng rất cao cho câu trả lời này, vì vậy bất kỳ ai đã đánh giá thấp, xin vui lòng để lại nhận xét.
Abhijit

9
@iggyvolz: Tôi thực sự ngạc nhiên khi bạn tiếp tục mở rộng câu hỏi của mình và thêm nhiều hạn chế. Mọi người đầu tư thời gian và công sức để viết một câu trả lời và bạn không thể mong đợi chúng sẽ là psycic.
Abhijit

6

Con trăn, 184 ký tự

Giải pháp Python sau chỉ sử dụng toán tử gia tăng và không có toán tử số học nào khác. Tuy nhiên, với độ chính xác cần thiết (10 chữ số), phải mất một thời gian dài không thể chạy được. Bạn có thể kiểm tra nó với độ chính xác thấp hơn (3 chữ số) bằng cách giảm 1e20xuống 1e6.

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)

Ung dung:

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)

Tôi đã làm rõ câu hỏi, bạn có thể làm nó với nhiều chữ số như bạn muốn (ít nhất là 5). Tôi không quen thuộc với python, nhưng tôi cho rằng int () chỉ là một caster loại? Nếu vậy, điều đó là tốt bởi vì nó không thay đổi giá trị của số.
iggyvolz

@iggyvolz: Đúng vậy, bạn cần điều đó để chuyển đổi giá trị đối số chuỗi (được chỉ định trên dòng lệnh) thành một số nguyên. Một hàm đơn giản sẽ không cần điều đó.
Greg Hewgill

2

Pháo đài 73

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

Có thể mất một loooong để thực sự xác định câu trả lời cho các giá trị nhất định, nhưng nó sẽ hoạt động chắc chắn. Trong khi tôi sử dụng *-, những thứ này không thay đổi bất kỳ giá trị nào , chỉ s=s+1thực sự thay đổi bất cứ thứ gì.


Ồ, đoán tôi đã không nghĩ về việc sử dụng các toán tử để thay đổi giá trị tĩnh. Điều đó hoàn toàn tốt và +1 (nếu tôi có 15 danh tiếng để nâng cấp)
iggyvolz

Điều này sử dụng *toán tử, khá rõ ràng là không được phép. Hay tôi bằng cách nào đó hiểu lầm những hạn chế nhất định?
Greg Hewgill

@GregHewgill: OP tuyên bố, không sử dụng bất kỳ toán tử toán học nào để thay đổi số ; các toán tử này không thay đổi bất kỳ giá trị nào.
Kyle Kanos

7
Nhưng đó vẫn là sử dụng *toán tử để thay đổi số, bạn chỉ không lưu kết quả ở bất cứ đâu. Nếu OP chỉ muốn không cho phép các bài tập (trừ s=s+1), thì tại sao lại đề cập đến tất cả các toán tử số học không được phép?
Greg Hewgill

1
@iggyvolz: Thay đổi quy tắc ~ 20 giờ sau là hình thức xấu. Xin vui lòng không làm điều đó và sử dụng hộp cát để giải quyết các nút thắt trong vấn đề của bạn.
Kyle Kanos

2

CJam, 26 byte

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

Hãy thử trực tuyến. Dán , nhập số nguyên mong muốn vào Đầu vào và bấm Chạy . Trước khi bạn làm thế, tôi khuyên bạn nên thay đổi 1e10để 1e4mặc dù.

Các thông dịch Java xử lý 1e6với đầu vào 2 2 trong khoảng 15 giây. 1e20sẽ cần một lượng RAM rất lớn .

Ví dụ

$ 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

Lý lịch

Vì chúng tôi không cho phép các toán tử thay đổi số, chúng tôi sẽ sử dụng các toán tử setwise để thay đổi các mảng.

Mã bắt đầu bằng cách "nhân" đầu vào (định nghĩa i) với 1e20, nhưng không có bất kỳ phép nhân thực tế nào. Thay vào đó, chúng tôi đẩy một mảng chứa các số nguyên của i i, một mảng chứa các số nguyên 1e20, lấy sản phẩm cartesian của chúng và tính toán độ dài của nó.

Sau đó, chúng tôi đẩy số 0 và tăng dần cho đến khi chính tích của số nguyên (được tính như trên) không nhỏ hơn i * 1e20 . Điều này làm cho căn bậc hai được làm tròn lên.

Làm thế nào nó hoạt động

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

Rắn hổ mang - 62

Đăng trước lần chỉnh sửa thứ ba, không còn hiệu lực.

Nó không chỉ ngắn mà còn không bị tràn nếu n < Decimal.maxValue

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

Nhưng bạn đã sử dụng r/e*r/e, đó rõ ràng là một ++toán tử phi toán học ...
nneonneo

@nneonneo cái này đã được đăng trước lần chỉnh sửa thứ ba và tôi vẫn chưa thay đổi nó
urous

0

Scala, 117

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

Không hoàn thành trong một khoảng thời gian hợp lý, ngay cả đối với 2 là đầu vào, nhưng nó vẫn hoạt động. Bạn có thể nhận thấy rằng tôi đang làm _+_, nhưng điều đó chỉ bao giờ thêm 1 và Scala dù sao cũng không có ++nhà điều hành. Tôi có thể lưu hai ký tự bằng cách thay thế Luồng bên trong bằng Danh sách, nhưng sau đó nó sẽ hết bộ nhớ. Như đã viết, tôi nghĩ rằng nó chỉ có quy mô trong thời gian xử lý, không sử dụng bộ nhớ.


0

Haskell, 70 byte

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

fđưa ra căn bậc hai số nguyên bằng cách tìm số lớn nhất có bình phương nhỏ hơn hoặc bằng đầu vào. Hàm bình phương s ităng thêm một cho mỗi phần tử của (i,i)ma trận. (Gõ trên điện thoại nên có thể có lỗi chính tả).


0

PHP, 124 byte

Đó là một thuật toán toàn diện. Nó chỉ thử các số cho đến khi bình phương của số đó lớn hơn số "mục tiêu" (là số lần nhập number of decimalsbình phương 1E (10.000 cho kết quả 2 thập phân). Sau đó, nó in số cuối cùng đó.

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;

Chạy như thế này (chỉ -dthêm vào lý do thẩm mỹ):

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

Đừng khuyên bạn nên thử điều này với bất kỳ thứ gì nhiều hơn 3 số thập phân hoặc một số trên 10.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.