제곱근 실행 취소


16

당신의 작업은 소수점을 정수의 제곱근의 합으로 다시 변환하는 것입니다. 결과는 유효 소수점 6 자리 이상의 정확도를 가져야합니다.

입력 :

제곱근의 수를 나타내는 숫자와 근사 할 숫자를 나타내는 10 진수

입력 예 :

2 3.414213562373095

출력 : 제곱근을 더하고 추가 할 때 대략 6 자리 이상의 유효 소수점 자리수에 해당하는 정수로 공백으로 구분 된 정수입니다.

솔루션에는 0이 허용되지 않습니다.

여러 솔루션이있는 경우 한 가지만 인쇄하면됩니다.

예제 출력 (순서대로) :

4 2

이 때문에 작동합니다 Math.sqrt(4) + Math.sqrt(2) == 3.414213562373095.

이것은 코드 골프입니다. 최단 코드 (선택적인 보너스 포함)가 승리합니다!

정수가있는 솔루션이 없을 때 프로그램이 "아니오"를 출력하면 항상 -10이 될 것입니다. 또한 프로그램이 하나의 솔루션 대신 모든 솔루션 (줄 바꾸기 또는 세미콜론 등으로 구분)을 인쇄하는 경우 -10입니다.

테스트 사례 :

3 7.923668178593959 --> 6 7 8
2 2.8284271247461903 --> 2 2
5 5.0 --> 1 1 1 1 1
5 13.0 --> 4 4 9 9 9 --> 81 1 1 1 1 --> 36 9 4 1 1 etc. [print any, but print all for the "all solutions bonus"]

그리고 네, 당신의 프로그램은 적당한 기계에서 유한 한 메모리를 사용하여 유한 한 시간 안에 끝나야합니다. "이론적으로"작동 할 수는 없으며 실제로 테스트 할 수 있어야합니다.


여러 솔루션이있는 경우 어떤 솔루션을 인쇄해야합니까? 예를 들어, 마지막 테스트 사례 (5 13.0)의 경우에도 유효한 솔루션입니다. 81 1 1 1 1
Jakube November

그리고 솔루션에서 0이 허용됩니까?
Jakube

1
입력은 항상 공백으로 구분됩니까?
Sp3000

그리고 함수 호출을 통한 입력이 허용됩니까?
Jakube

또한 중복 솔루션은 어떻습니까? 첫 번째 예에서, 우리의 코드 6 7 8는 두 번째 보너스 에 대한 6 개의 순열을 모두 인쇄 할 수 있습니까?
Martin Ender

답변:


9

파이썬 3, 90-10 = 80

def S(N,x,n=[],i=1):
 if x*x<1e-12>N==0:print(*n)
 while.1+x*x>i:S(N-1,x-i**.5,n+[i]);i+=1

(팁에 대한 @xnor의 감사, 특히 for 루프를 잠시 동안 재구성)

간단한 재귀 시도. 대상 번호부터 시작하여 0 이하가 될 때까지 지속적으로 제곱근을 뺍니다. 함수 S는 다음과 같이 호출 될 수 있습니다 S(2,3.414213562373095)(두 번째 인수는 양의 것으로 가정).

이 프로그램은 모든 솔루션을 인쇄하는 것이 아니라 솔루션의 모든 순열 을 인쇄합니다 (약간의 외 견적입니다). 마지막 경우에 대한 출력은 다음과 같습니다. Pastebin .

약간의 조정은 98-10 = 88 솔루션을 제공하여 순열을 인쇄하지 않으므로 더 효율적입니다.

def S(N,x,n=[]):
 *_,i=[1]+n
 if x*x<1e-12>N==0:print(*n)
 while.1+x*x>i:S(N-1,x-i**.5,n+[i]);i+=1

그리고 재미로,이 99-10 = 89 하나는 얻는 것만 큼 효율적입니다 (다른 것과 달리 스택을 날려 버리지 않습니다 S(1,1000):

def S(N,x,n=[]):
 *_,i=[1]+n
 if x*x<1e-12>N:print(*n)
 while(.1+x*x>i)*N:S(N-1,x-i**.5,n+[i]);i+=1

변경 가능한 기본 인수가 있지만 n+[i]새 목록을 작성하기 때문에 함수를 다시 실행해도 문제가 발생하지 않습니다 .


정확성 증명

무한 루프 상태가 되려면 x <00.1 + x 2 > 1 인 지점을 찾아야합니다 . 이것은 x <-0.948 ...에 의해 만족됩니다 .

그러나 우리는 양의 x 에서 시작 하고 x 는 항상 감소하므로 x <-0.948을 누르기 위해서는 x '-i 0.5 <-0.948 ... 가 있어야합니다. 일부 x'> -0.948 .. . 전에 X 및 양의 정수 I . while 루프를 실행하려면 0.1 + x ' 2 > i 가 있어야합니다 .

재정렬하면 x ' 2 + 1.897x'+ 0.948 <i <0.1 + x ' 2가 되며, 바깥 부분은 x'<-0.447을 나타냅니다 . 그러나 -0.948 <x '<-0.447 인 경우 양의 정수 i 는 위의 불평등의 격차에 맞지 않을 수 있습니다.

따라서 우리는 무한 루프로 끝나지 않을 것입니다.


당신은 피할 수 absx*x<1e-12 .
xnor

1
while루프 가 함수 매개 변수에서 초기화 된 for: 을 대체하는 것으로 생각합니다 . 아이디어는 s 로 변환 할 필요가 없도록하는 것입니다 . 플로트 부정확성을 처리 하는 것 입니다. 무한 루프에 대해 안전하다고 생각합니다. while.1+x*x>i:S(x-i**.5,n+[i]);i+=1i=1int.1
xnor

@ xnor 나는 지금 첫 번째 팁을 구현했습니다. 나는 여전히 두 번째 것의 정확성을 확인하고 있지만 그것이 좋다면 많은 바이트가 절약됩니다! (또한 실제로 솔루션을 게시 할 것으로 기대했습니다 : P)
Sp3000

1
그리고 N이제 함수 인수를 사용하면로 돌아가서 N-1확인 N==0하는 것이 더 짧 습니다 len(n)==N.
xnor

@ Sp3000 .1안전하다고 확신 합니다. 원한다면 논쟁을 할 수 있습니다.
xnor December

6

ECLiPSe 프롤로그-118 (138-20)

다음과 같은 Prolog 구현을 사용했습니다. http://eclipseclp.org/

:-lib(util).
t(0,S,[]):-!,S<0.00001,S> -0.00001.
t(N,S,[X|Y]):-A is integer(ceiling(S*S)),between(1,A,X),M is N-1,T is S-sqrt(X),t(M,T,Y).

이것은 매우 순진한 지수 접근 방식입니다. 가능한 모든 솔루션을 나열 하려면 모든 조합을 처리하는 데 시간이 걸립니다 ( 편집 : 방문한 정수의 범위가 각 단계에서 감소하여 많은 쓸모없는 조합이 제거됨).

다음은 시험 세션의 성적표입니다. 기본적으로 환경은 가능한 모든 솔루션을 찾으려고 시도하고 (-10) 실패하면 "아니오"로 인쇄합니다.

주석에서 Sp3000이 올바르게 언급했듯이 성공하면 "예"도 인쇄합니다. 그것은 확실히 10 점을 더 제거 할 수 있음을 의미합니다 ;-)

[eclipse 19]: t(1,0.5,R).

No (0.00s cpu)
[eclipse 20]: t(2,3.414213562373095,R).

R = [2, 4]
Yes (0.00s cpu, solution 1, maybe more) ? ;

R = [4, 2]
Yes (0.00s cpu, solution 2, maybe more) ? ;

No (0.01s cpu)
[eclipse 21]: t(3,7.923668178593959,R).

R = [6, 7, 8]
Yes (0.02s cpu, solution 1, maybe more) ? ;

R = [6, 8, 7]
Yes (0.02s cpu, solution 2, maybe more) ? ;

R = [7, 6, 8]
Yes (0.02s cpu, solution 3, maybe more) ? 
[eclipse 22]: t(5,5.0,R).

R = [1, 1, 1, 1, 1]
Yes (0.00s cpu, solution 1, maybe more) ? ;
^C

interruption: type a, b, c, e, or h for help : ? abort
Aborting execution ...
Abort
[eclipse 23]: t(5,13.0,R).

R = [1, 1, 1, 1, 81]
Yes (0.00s cpu, solution 1, maybe more) ? ;

R = [1, 1, 1, 4, 64]
Yes (0.00s cpu, solution 2, maybe more) ? ;

R = [1, 1, 1, 9, 49]
Yes (0.00s cpu, solution 3, maybe more) ?
[eclipse 24]:

(편집) 성능과 관련하여 적어도 다른 것과 비교하면 상당히 좋습니다 (예 : FryAmTheEggman의 주석 ). 먼저 모든 결과를 인쇄하려면 다음 술어를 추가하십시오.

    p(N,S):-t(N,S,L),write(L),fail.
    p(_,_).

0.24 초 안에 완료되고 495 솔루션을 찾는 (5,13.0) 사례는 http://pastebin.com/ugjfEHpw 를 참조 하십시오 (그러나 어쩌면 일부 솔루션이 누락되었을 수도 있습니다).


3
또한 성공하면 "예"를 인쇄합니다! 오 프롤로그
Sp3000

3

얼랭, 305-10 302-10

f(M,D)->E=round(D*D),t(p(E,M,1),{M,E,D}).
p(_,0,A)->A;p(E,N,A)->p(E,N-1,A*E).
t(-1,_)->"No";t(I,{N,E,D}=T)->L=q(I,N,E,[]),V=lists:sum([math:sqrt(M)||M<-L])-D,if V*V<0.1e-9->lists:flatten([integer_to_list(J)++" "||J<-L]);true->t(I-1,T)end.
q(I,1,_,A)->[I+1|A];q(I,N,E,A)->q(I div E,N-1,E,[I rem E+1|A]).

이 함수는 문자열 "No"또는 공백으로 구분 된 값을 가진 문자열을 반환합니다. 그것은 가능한 모든 값을 큰 정수로 인코딩하고 더 높은 값으로 시작하여 비효율적으로 처리합니다. 솔루션에서 0은 허용되지 않으며 인코딩 된 0은 모든 것을 나타냅니다. 오류는 제곱입니다.

예:

f(1,0.5).               % returns "No"
f(2,3.414213562373095). % returns "4 2 "
f(3,7.923668178593959). % returns "8 7 6 "
f(5,5.0).               % returns "1 1 1 1 1 "
f(5,13.0).              % returns "81 1 1 1 1 "

f(5,13.0)기능 검색 공간은 13 ^ 10이므로 인내하십시오 . 추가 바이트 2 개로 더 빠르게 만들 수 있습니다.


3

파이썬 3 2 : 177359-10 = 149

설명 : 각 솔루션은 x_1 x_2 ... x_n 형식으로 1 <= x_1 <= x ^ 2이며 여기서 x는 대상 합계입니다. 따라서 우리는 각 솔루션을 x x2의 정수로 인코딩 할 수 있습니다. while 루프는 모든 (x ^ 2) ^ n 가능성을 반복합니다. 그런 다음 정수를 다시 변환하고 합계를 테스트하십시오. 꽤 직설적 인.

i=input;n=int(i());x=float(i());m=int(x*x);a=m**n
while a:
 s=[a/m**b%m+1for b in range(n)];a-=1
 if abs(x-sum(b**.5for b in s))<1e-5:print' '.join(map(str,s))

모든 솔루션을 찾았지만 마지막 테스트 사례가 너무 오래 걸립니다.


3

자바 스크립트 (ES6) 162 (172-10) 173

약간 짧게, 느리게 편집하십시오 .

2 개의 매개 변수가있는 함수로서 javascript 콘솔에 출력됩니다. 반복없이 모든 솔루션을 인쇄합니다 (솔루션 튜플은 이미 정렬되어 생성됨).
나는 문자 수보다 타이밍에 관심이있어 표준 자바 스크립트 시간 제한 내에서 브라우저 콘솔에서 쉽게 테스트 할 수 있습니다.

(2016 년 2 월 업데이트) 마지막 테스트 케이스의 현재 시간 : 약 1150 초 . 메모리 요구 사항 : 무시할 만하다.

F=(k,t,z=t- --k,r=[])=>{
  for(r[k]=z=z*z|0;r[k];)
  { 
    for(;k;)r[--k]=z;
    for(w=t,j=0;r[j];)w-=Math.sqrt(r[j++]);
    w*w<1e-12&&console.log(r.join(' '));
    for(--r[k];r[k]<1;)z=--r[++k];
  }
}

ES 5 버전 모든 브라우저

function F(k,t)
{
  var z=t- --k,r=[];  
  for(r[k]=z=z*z|0;r[k];)
  {
    for(;k;)r[--k]=z;
    for(w=t,j=0;r[j];)w-=Math.sqrt(r[j++]);
    w*w<1e-12&&console.log(r.join(' '));
    for(--r[k];r[k]<1;)z=--r[++k];
  }
}

최신 브라우저 에서 실행되는 테스트 스 니펫

F=(k,t)=>
{
   z=t- --k,r=[];
   for(r[k]=z=z*z|0;r[k];)
   { 
      for(;k;)r[--k]=z;
      for(w=t,j=0;r[j];)w-=Math.sqrt(r[j++]);
      w*w<1e-12&&console.log(r.join(' '));
      for(--r[k];r[k]<1;)z=--r[++k];
   }
}

console.log=x=>O.textContent+=x+'\n'

t=~new Date
console.log('\n2, 3.414213562373095')
F(2, 3.414213562373095)
console.log('\n5, 5')
F(5, 5)
console.log('\n3, 7.923668178593959')
F(3, 7.923668178593959)
console.log('\n5, 13')
F(5, 13)

t-=~new Date
O.textContent = 'Total time (ms) '+t+ '\n'+O.textContent
<pre id=O></pre>

( 편집 ) 아래는 15 개월 전에이 답변을 게시했을 때의 PC 결과입니다. 오늘 시도했지만 64 비트 알파 버전의 Firefox와 동일한 PC에서 100 배 빠릅니다 (Chrome이 뒤쳐집니다)! -Firefox 40 Alpha 64 비트의 현재 시간 : ~ 2 초, Chrome 48 : ~ 29 초

출력 (내 PC-마지막 숫자는 밀리 초 단위입니다)

2 4
1 1 1 1 1
6 7 8
1 1 1 1 81
1 1 1 4 64
1 1 1 9 49
1 1 4 4 49
1 1 1 16 36
1 1 4 9 36
1 4 4 4 36
1 1 1 25 25
1 1 4 16 25
1 1 9 9 25
1 4 4 9 25
4 4 4 4 25
1 1 9 16 16
1 4 4 16 16
1 4 9 9 16
4 4 4 9 16
1 9 9 9 9
4 4 9 9 9
281889

2

수학-76-20 = 56

f[n_,x_]:=Select[Union[Sort/@Range[x^2]~Tuples~{n}],Abs[Plus@@√#-x]<10^-12&]

f[2, 3.414213562373095]
> {{2, 4}}
f[3, 7.923668178593959]
> {{6, 7, 8}}
f[3, 12]
> {{1, 1, 100}, {1, 4, 81}, {1, 9, 64}, {1, 16, 49}, {1, 25, 36}, {4, 4, 64}, {4, 9, 49}, {4, 16, 36}, {4, 25, 25}, {9, 9, 36}, {9, 16, 25}, {16, 16, 16}}

어떻게 인쇄 No합니까? 또한 출력은 공백으로 구분되지 않습니다. 또한 Tr@대신 사용할 수 없습니다Plus@@ 없습니까? 그리고 당신은 변경하여 일부 문자를 저장할 수 있습니다 SelectCases패턴의 끝에서 기능 및 제작 f익명의 순수 기능을.
Martin Ender

2

하스켈, 87 80-10 = 70

이것은 @ Sp3000의 Python 3 프로그램과 유사한 재귀 알고리즘입니다. #모든 솔루션의 모든 순열 목록을 반환 하는 infix 함수로 구성됩니다 .

0#n=[[]|n^2<0.1^12]
m#n=[k:v|k<-[1..round$n^2],v<-(m-1)#(n-fromInteger k**0.5)]

102 99 92-10 = 82 의 점수로 각 솔루션을 한 번만 정렬하여 인쇄 할 수 있습니다.

0#n=[[]|n^2<0.1^12]
m#n=[k:v|k<-[1..round$n^2],v<-(m-1)#(n-fromInteger k**0.5),m<2||[k]<=v]

2

피스 55 54 47-20 = 27

DgGHKf<^-Hsm^d.5T2^10_12^r1hh*HHGR?jbmjdkKK"No

온라인으로 사용해보십시오.

뻔뻔하게 차용 에서 XNOR의 코멘트 )

이 값은 제정신의 컴퓨터에서 메모리가 부족합니다 5,5.0. g처럼 호출 될 수 있는 함수를 정의합니다 g 3 7.923668178593959.

이 파이썬 3 프로그램은 본질적으로 동일한 알고리즘을 사용합니다 (모든 결과에 변수를 할당 한 다음을 작성하여 수행 할 수있는 마지막에 "아니오"인쇄를 수행 print(K if K else "No")하지는 않지만 생성기를 사용함). t 메모리 오류가 발생합니다 (여전히 시간이 오래 걸리지 만 값을 찾을 때 인쇄했습니다).

이는 @ Sp3000과 동일한 결과를 제공합니다. 또한, 완료하는 데 며칠이 걸렸습니다 (시간이 걸리지 않았지만 약 72 시간).

from itertools import*
def g(G,H):
    for x in product(range(1,int(H*H+2)),repeat=G):
        if (H-sum(map(lambda n:n**.5,x)))**2<1e-12:print(*x)

1

파이썬 3 - 157 (174) 169-10 = 159

Edit1 : 출력 형식을 쉼표로 구분하지 않고 공백으로 구분 된 정수로 변경했습니다. (n, x) 주변의 괄호를 제거해 주셔서 감사합니다.

Edit2 : 골프 팁 감사합니다! 1e-6 이내의 대략적인 동등성을 테스트하는 대신 == 테스트를 사용하면 다른 9 문자를 제거 할 수 있지만 그러한 경우 존재하는 대략적인 솔루션은 무효화됩니다.

itertools를 사용하여 가능한 모든 정수 조합을 효율적으로 생성하십시오 :)

"No"인쇄를 효율적으로 추가하는 방법을 찾지 못했습니다. 항상 10 자 이상이 필요합니다.

from itertools import*
n,x=eval(input())
for c in combinations_with_replacement(range(1,int(x*x)),n):
 if abs(sum(z**.5for z in c)-x)<1e-6:print(' '.join(map(str,c)))

프로그램의 출력 형식이 잘못되었습니다 (공백 대신 쉼표). 또한 괄호를 제거하여 2 바이트를 줄일 수 있습니다 n,x.
Zgarb

내가 라인을 SyntaxError시도 할 때 s를 얻는 것 같습니다 eval...
Sp3000

@ Sp3000 : 3,7.923668178593959를 입력하십시오. 당신은 ','가 필요합니다
Jakube

4 작은 개선 : from itertools import*1을 절약하고, 공간을 z**.5for절약하고 1을 절약하고, []in을 sum(z**.5for z in c)절약하고 2 ()if(...)절약 하고 in을 절약합니다.
Jakube

Python 2로 변경하고 사용하는 n,x=input()것이 더 간결합니까?
Octavia Togami

0

스칼라 (397 바이트-10)

import java.util.Scanner
object Z extends App{type S=Map[Int,Int]
def a(m:S,i:Int)=m updated(i,1+m.getOrElse(i,0))
def f(n:Int,x:Double):Set[S]={if(n==0){if(x.abs<1e-6)Set(Map())else Set()}
else((1 to(x*x+1).toInt)flatMap{(i:Int)=>f(n-1,x-Math.sqrt(i))map{(m:S)=>a(m,i)}}).toSet}
val s=new Scanner(System.in)
f(s.nextInt,s.nextDouble)foreach{(m:S)=>m foreach{case(k,v)=>print(s"$k "*v)};println}}

순열이 없으면이 프로그램은 아무것도 인쇄하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.