++ 만 사용하여 제곱근 계산


13

당신의 작업은 다음과 같이 수학 연산자를 사용하여 숫자를 변경하지 않고 양의 정수의 제곱근을 계산하는 것입니다.

  • 변수 설정 (예 : squareRoot = 5)
  • 추가 (A + B)
  • 빼기 (AB)
  • 곱셈 (A * B)
  • 구분 (A / B)
  • 정사각형, 큐브, 네 번째 등 뿌리
  • 지수

비교 연산자 (예 : <,>, == 등)는이 질문의 목적 상 "수학적 연산자"로 간주되지 않으며 변수 값을 변경하지 않는 한 허용됩니다.

사용할 수있는 유일한 연산자는 ++입니다. 다음과 같은 예외가 있습니다.

  • 원하는 경우 변수를 0으로 설정하여 변수를 초기화 할 수 있습니다.
  • 언어에 ++ 구문이 포함되어 있지 않으면 foo + = 1 또는 foo = foo + 1과 같은 구문을 사용할 수 있습니다.
  • 제곱근은 소수점 이하 자릿수 (1 만 자리)를 넘어 6 자리 이상으로 계산하고 소수점 이하의 정수로 출력해야합니다 (예 : 2를 입력하면 반올림에 따라 14142135624 또는 1414213으로 나올 수 있음) . 반올림 또는 내림은 중요하지 않습니다.

사용자 정의 함수는 허용되지 않습니다. 또한 goto로 기능을 시뮬레이션하는 것도 허용되지 않습니다.

모두가 제출 한 내용을보고 싶습니다. 행복한 코딩!

설명

숫자가 양의 정수임을 명확히하십시오. 숫자에 관계없이 코드를 만들 수는 있지만 꼭 필요한 것은 아닙니다.

설명 # 2

비교 연산자가 허용됨을 명확히하십시오.

설명 # 3

추가는, 뺄셈은 곱셈, 변경 번호로 구분하고, 기능은 허용되지 않습니다 전혀 관계없이 변수 여부에 저장되어 있는지 여부. 죄송합니다. 기존 답변이 무효화되어 죄송하지만 트롤 답변을 방지하기 위해이 연산자 그룹을 "숫자 변경"으로 정의했습니다 (예 : 방금 sqrt () 함수를 사용했습니다. 곱하기, 나누기 및 빼기). 혼란을 드려 죄송합니다.

설명 # 4

최소 5 자리 숫자가 필요하다는 것을 분명히하십시오. 10 자리 숫자로 인해 코드가 오랫동안 실행되었습니다.


1
아니,-허용되지 않습니다. 혼란을 드려 죄송합니다! 나는 원래 ++를 계획했지만 마지막 순간에 꺼내기로 결정했습니다.
iggyvolz

5
"수학적 연산자를 사용하여 숫자를 변경하지 않고" -설명이 필요할 수 있습니다. 당신은 이러한 연산자를 사용하지 않을 수 있음을 의미합니까 전혀 , 또는, 그들이 사용할 수 있다는 것을,하지만 경우에만 결과가 예를 들어, 변수에 저장되지 않습니다 while r*r<n*10e20:r+=1매우 사소한 -. 또한 필요한 출력을 10 ^ 8 정도로 줄이는 것을 고려할 수 있습니다. 첫째, 10 ^ 10은 2 ^ 31보다 크기 때문에 두 번째는 그 값을 높이는 데 시간이 걸리기 때문입니다.
primo

1
왜 것 이제까지 "변화"전혀 어떤 변수에 싶어? 당신은 명령적인 사람들이 이상한 생각을 가지고 있습니다 ...
시계 반대 방향으로 돌리는 것을 중단했습니다

4
이 질문을 닫으려고합니다. 질문에 대한 근본적인 변화. 실제로이 질문은 샌드 박스를 통해 확인해야합니다. 그렇지 않으면 답변을 위해 노력하는 사람들을 실망시킬 것입니다.
Abhijit

3
필요한 자릿수를 줄이는 것은 시간 / 메모리 제한이 없으면 의미가 없습니다. 내 코드는 5 자리를 처리 할 수 ​​있지만 컴퓨터에 충분한 RAM이 없습니다.
데니스

답변:


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

이 솔루션은 복잡한 평면에서 Theodorus Spiral을 사용 하여 결과를 얻습니다.


2
나는 그것을 감싸 야한다고 생각합니다 int(...*1e10). 그렇지 않으면 매우 좋습니다. abs복잡한 값을 취하는 것은 다소 sqrt변합니다.
primo

1
@primo 나는 당신이 허용되는 것 같아요 *1e10...
Cruncher

@ primo : 1e10을 곱하는 대신 약간 다른 경로를 사용했습니다. 그리고 나는 복근이 변장에 sqrt 일 수 있음에 동의하지만, 현재 문제에서 언급 된 것처럼 완전히 합법적이라고 생각합니다.
Abhijit

나는 downvote와 그것의 상당히 우울한 것을 본다. 나는이 답변에 대한 높은 희망을 가지고 있었으므로 다운 투표 한 사람은 의견을 남겨주세요.
Abhijit

9
@ piggyvolz : 질문을 계속 확장하고 더 많은 제한을 추가하는 것이 정말 놀랍습니다. 사람들은 답을 작성하기 위해 시간과 노력을 투자하고 당신은 그들이 정신 나간 것으로 기대할 수 없습니다.
Abhijit

6

파이썬, 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 자릿수) 할 수 있습니다. 나는 파이썬에 익숙하지 않지만 int ()는 유형 캐스터라고 가정합니다. 그렇다면 숫자 값을 변경하지 않기 때문에 괜찮습니다.
iggyvolz 2016

@iggyvolz : 그렇습니다. 명령 행에 지정된 문자열 인수 값을 정수로 변환해야합니다. 평범한 기능에는 필요하지 않습니다.
Greg Hewgill

2

포트란 73

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

실제로 특정 값에 대한 답을 결정하기 위해 loooong을 취할 수는 있지만 확실하게 작동합니다. 내가 사용하는 동안 *-, 이 어떤 값을 변경하지 않습니다s=s+1실제로는 아무것도 변경됩니다.


와우, 정적 값을 변경하기 위해 연산자를 사용하는 것에 대해 생각하지 않았다고 생각합니다. 그것은 완벽하게 정상적으로 +1 (내가 upvote에 15 명성을 가지고있는 경우)입니다
iggyvolz

이것은 *명백히 허용되지 않는 연산자를 사용합니다 . 아니면 주어진 제한을 어떻게 든 오해하고 있습니까?
Greg Hewgill

@GregHewgill : 숫자를 변경하기 위해 수학 연산자를 사용하지 않고 OP 상태 ; 이 연산자는 값을 변경하지 않습니다.
Kyle Kanos

7
그러나 여전히 *연산자를 사용하여 숫자를 변경하고 있으므로 결과를 어디에도 저장하지 않습니다. OP가 단순히 (이외의 ) 할당을 허용하지 않으려면 s=s+1왜 허용되지 않는 모든 산술 연산자를 언급해야합니까?
Greg Hewgill

1
@iggyvolz : ~ 20 시간 후에 규칙을 변경하는 것은 잘못된 형식입니다. 그렇게하지 말고 샌드 박스 를 사용 하여 문제의 꼬임을 해결하십시오.
Kyle Kanos

2

CJam, 26 바이트

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

온라인으로 사용해보십시오. 코드를 붙여 넣고 입력에 원하는 정수를 입력 하고 실행을 클릭 하십시오 . 당신이하기 전에, 나는 비록 변경 1e10하는 것이 좋습니다 1e4.

자바 인터프리터 핸들 1e6약 15 초에서 입력 "2"와. 엄청난 양의 RAM 1e20이 필요합니다 .

$ 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 정수를 포함하는 배열을 푸시하고 직교 곱을 취하고 길이를 계산합니다.

그런 다음 0을 누르고 정수의 곱 자체 (위와 같이 계산 됨)가 더 이상 더 작을 때까지 증가합니다 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

세 번째 수정 전에 게시되어 더 이상 유효하지 않습니다.

짧을뿐만 아니라 다음과 같은 경우 오버플로가 없어야합니다. 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 이것은 세 번째 수정 전에 게시되었으며 아직 변경하지 않았습니다
Οurous

0

스칼라, 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에는 ++연산자 가 없습니다 . 내부 스트림을 List로 바꾸면 두 문자를 저장할 수 있지만 메모리가 부족합니다. 서면으로, 메모리 사용이 아닌 처리 시간에만 확장 할 수 있다고 생각합니다.


0

하스켈, 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)행렬의 모든 요소마다 하나씩 증가합니다 . 전화에 입력하여 오타가있을 수 있습니다.


0

PHP, 124 바이트

철저한 알고리즘입니다. 해당 숫자의 제곱이 "목표"숫자 (입력 시간 1E number of decimals제곱 (소수점 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.