정사 면적


16

도전

이 도전은 매우 간단합니다. 4 개의 3 차원 점이 주어지면 4 면체의 표면적을 계산합니다. 이것은 이므로 가장 짧은 코드가 승리합니다. 표준 허점은 적용되며, 4 점으로이 작업을 수행하는 내장 기능이 금지된다는 규정이 추가되었습니다.

4 개의 점이 모두 구별되고 STDIN을 통해 줄당 1 점씩 제공된다고 가정 할 수 있습니다. 각 포인트는 3 개의 16 비트 부호없는 정수로 구성됩니다. 세 개의 공백으로 구분 된 정수와 같이 일을 더 쉽게 만들면 각 점의 정확한 형식을 수정할 수 있습니다. 그러나 각 지점을 별도의 선에 두어야합니다. 출력은 STDOUT을 통해 소수점 2 자리 이상이어야합니다.

모르는 사람들을 위해 사면체 는 3 차원의 입체로 4 개의 삼각형면으로 형성됩니다.

# input (format is up to you, see clarification above)
[23822, 47484, 57901]
[3305, 23847, 42159]
[19804, 11366, 14013]
[52278, 28626, 52757]

# output
2932496435.95

내 수학이 틀렸다는 것을 기록해 두십시오.


@BetaDecay 아니요, 아이디어는 STDIN을 통해 4 개의 개별 라인에 입력 될 것입니다. 이를 명확하게하기 위해 질문을 편집하겠습니다.
stokastic

입력이 [[list],[of],[lists]]? 일 수 있습니까 ?
phosgene

@phosgene 나는 입력을 읽는 것이 도전의 일부라고 생각하고 싶습니다. 그래서 나는 아니오라고 말할 것입니다. 향후 과제에서 입력 사양에 대해보다 관대하게 노력할 것입니다.
stokastic

이것은 규칙적이거나 불규칙적 인 4 면체입니까?
James Williams

@JamesWilliams 게시 된 예제는 불규칙합니다. 프로그램은 일반 사면체를 포함하여 모든 입력을 처리해야합니다.
stokastic

답변:


5

Python, 198178161

V=eval('input(),'*4)
A=0
for i in range(4):F=V[:i]+V[i+1:];a,b,c=map(lambda e:sum((a-b)**2for a,b in zip(*e)),zip(F,F[1:]+F));A+=(4*a*b-(a+b-c)**2)**.5
print A/4

입력 형식은 질문에 나와 있습니다.

각면에 인접한 모서리의 길이를 계산 한 다음 헤론의 공식 을 사용합니다 .


4

MATLAB / 옥타브 103

변수에 값을 저장한다고 가정합니다 c. 이것은 삼각형의 면적이 두 개의 측면 벡터의 교차 곱의 절반 길이라는 사실을 사용합니다.

%input
[23822, 47484, 57901;
3305, 23847, 42159;
19804, 11366, 14013;
52278, 28626, 52757]



%actual code
c=input('');
a=0;
for i=1:4;
    d=c;d(i,:)=[];
    d=d(1:2,:)-[1 1]'*d(3,:);
    a=a+norm(cross(d(1,:),d(2,:)))/2;
end
a

각 점은 표준 입력으로 별도의 줄에 입력해야합니다.
DavidC

처음에는 Matlab에 표준 입력과 같은 것이 없다고 생각했지만 명령 창을 통해 이것을 시뮬레이션하는 데 사용할 수있는 기능을 발견 했으므로 이제 다른 언어로 입력을 전달할 수 있습니다.
flawr

흥미 롭군 그것은 Mathematica가 사용하는 것과 같은 명령입니다.Input[]
DavidC

왜 이것이 재미 있다고 생각합니까? '입력'은 이것을 수행하는 함수의 일반적인 이름처럼 보입니다.
flawr

어제까지, 정말 "표준 입력이"무슨 뜻인지 몰랐다, 나는 티카는 내가 정기적으로 사용했다하더라도, "표준"입력을하지 않았다 생각 Input[], InputString[], Import[],와 ImportString[].
DavidC

4

APL, 59

f←{+.×⍨⊃1 2-.⌽(⊂⍵)×1 2⌽¨⊂⍺}
.5×.5+.*⍨(f/2-/x),2f/4⍴x←⎕⎕⎕-⊂⎕

교차 제품 계산으로 작동

설명
첫 번째 줄은 두 개의 인수 (이름 implicity받는 함수 정의 등을 암시 적 차원 벡터로 처리, 길이 3의 숫자 배열로 그것들을 기대하는,), 그리고 계산 제곱 자신의 외적의 크기를.

                        ⊂⍺   # Wrap the argument in a scalar
                   1 2⌽¨     # Create an array of 2 arrays, by rotating `⊂⍺` by 1 and 2 places
             (⊂⍵)×           # Coordinate-wise multiply each of them with the other argument
        1 2-.⌽               # This is a shorthand for:
        1 2  ⌽               #   Rotate the first array item by 1 and the second by 2
           -.                #   Then subtract the second from the first, coordinate-wise
       ⊃                     # Unwrap the resulting scalar to get the (sorta) cross product
   +.×                       # Calculate the dot product of that...
      ⍨                      # ...with itself
f←{+.×⍨⊃1 2-.⌽(⊂⍵)×1 2⌽¨⊂⍺} # Assign function to `f`

두 번째 줄은 나머지를 수행합니다.

                         ⎕⎕⎕-⊂⎕ # Take 4 array inputs, create an array of arrays by subtracting one of them from the other 3
                       x←        # Assign that to x
                     4⍴          # Duplicate the first item and append to the end
                  2f/            # Apply f to each consecutive pair
            2-/x                 # Apply subtraction to consecutive pairs in x
          f/                     # Apply f to the 2 resulting arrays
         (f/2-/x),2f/4⍴x←⎕⎕⎕-⊂⎕ # Concatenate to an array of 4 squared cross products
   .5+.*⍨                        # Again a shorthand for:
   .5  *⍨                        #   Take square root of each element (by raising to 0.5)
     +.                          #   And sum the results
.5×                              # Finally, divide by 2 to get the answer

상형 문자인지 손상된 dll 파일인지 확실하지 않은 경우 아마도 APL 일 것입니다. 이 심볼들 중 어떤 것이 무엇인지 좀 더 설명해 주시겠습니까? 배우고 싶지는 않지만 겉보기에는 애매 모호한 기호로 프로그래밍하는 방법에 여전히 흥미를 느낍니다. = P
flawr

@flawr 나는 보통 APL에서 골프를 치기 때문에 알고리즘 디자인을 주로 사용하기 때문에 문제에 대한 드문 접근 방식을 초래할 것입니다. 그러나 나는 "교차 계산 곱"이 알고리즘에 대해 충분히 전달하는 것처럼 느껴졌습니다. 자세한 설명을 원하면 오늘 나중에 설명하겠습니다.
TwiNight

교차 곱을 계산한다는 아이디어는 분명했지만 코드 자체는 실마리를 남기지 않으므로 코드의 어떤 부분이 큰 일을하는지에 대한 몇 마디 만 생각했지만 물론 나는 당신에게 자세한 설명을 작성하십시오!
flawr

3

파이썬 3, 308 298 292 279 258 254

from itertools import*
def a(t,u,v):w=(t+u+v)/2;return(w*(w-t)*(w-u)*(w-v))**.5
z,x,c,v,b,n=((lambda i,j:(sum((i[x]-j[x])**2for x in[0,1,2]))**.5)(x[0],x[1])for*x,in combinations([eval(input())for i in">"*4],2))
print(a(z,x,v)+a(z,c,b)+a(b,v,n)+a(x,c,n))

이것은 다음을 사용합니다.

  • 각 선의 길이를 계산하는 피타고라스 정리 (3D)
  • 각 삼각형의 면적을 계산하는 헤론의 공식

1
솔루션 테스트에 동일한 방법을 사용했습니다. 골프를해서 나중에 게시해야합니다.
stokastic

1
당신 for i in">"*4은 영리하다
stokastic

range 함수에서 len (i)을 사용하는 대신 길이 3을 하드 코딩 할 수 있습니다.
stokastic

1
x**0.5대신에 제곱근을 사용하여 몇 개의 문자를 더 저장할 수 math.sqrt(x)있습니다.
Snorfalorpagus

1
다음 def a(t,u,v)과 같이 한 줄로 두 바이트를 절약 할 수 있습니다 def a(t,u,v):w=(t+u+v)/2;return(w*(w-t)*(w-u)*(w-v))**0.5.
Beta Decay

2

매쓰 168 154

이것은 사면체의 가장자리 길이를 찾고 헤론의 공식 을 사용하여면의 면적을 결정합니다.

t = Subsets; p = Table[Input[], {4}];
f@{a_, b_, c_} := Module[{s = (a + b + c)/2}, N[Sqrt[s (s - #) (s - #2) (s -#3)] &[a, b, c], 25]]
  Tr[f /@ (EuclideanDistance @@@ t[#, {2}] & /@ t[p, {3}])]

60 개의 문자 만 필요한 더 직접적인 경로가 있지만 내장 함수를 사용하여 각 얼굴의 영역을 계산하는 한 규칙을 위반합니다 Area.

p = Table[Input[], {4}];
N[Tr[Area /@ Polygon /@ Subsets[p, {3}]], 25]

1

세이지 – 103

print sum((x*x*y*y-x*y*x*y)^.5for x,y in map(differences,Combinations(eval('vector(input()),'*4),3)))/2

입력 판독 부분은 Keith Randall의 답변 에서 수정되었습니다 .


0

파이썬-260

귀하의 질문에 대한 답변을 게시 할 때의 에티켓이 무엇인지 잘 모르겠지만, 그녀는 내 솔루션이며, 내 예를 검증하는 데 사용되었습니다.

import copy,math
P=[input()for i in"1234"]
def e(a, b):return math.sqrt(sum([(b[i]-a[i])**2 for i in range(3)]))
o=0
for j in range(4):p=copy.copy(P);p.pop(j);a,b,c=[e(p[i],p[(i+1)%3])for i in range(3)];s=(a+b+c)/2;A=math.sqrt(s*(s-a)*(s-b)*(s-c));o+=A
print o

laurencevs와 동일한 절차를 사용합니다.


4
경험상, 특히 시청자의 동기를 식 히지 않기 위해 자신의 질문에 대답하기 전에 며칠을 기다리는 것이 가장 좋습니다.
Blackhole

몇 가지 팁 :으로 일부 문자를 저장할 수 있습니다 r=range. lambda보다 짧습니다 def. math.sqrt로 대체 할 수 있습니다 (…)**.5. p=copy.copy(P);p.pop(j);로 단축 할 수 있습니다 p=P[:j-1]+P[j:]. A한 번만 사용됩니다.
Wrzlprmft 2016 년

0

C, 303

불필요한 공백 제외. 그러나 여기에 수행 할 골프의 많은 여전히 거기에 (내가 다시 와서 나중에 수행하려고 할 것입니다.) 내가 선언 한 처음 forA의 루프를#define . 나는 항상 루프 수를 최소화하는 방법을 찾았습니다.

나는에서 변경했습니다 floatdouble테스트 케이스의 영업 이익과 같은 답변을 얻을 수 있습니다. 그 전에는 300 라운드였습니다.

scanf 공백이나 줄 바꿈으로 입력을 구분하든 상관없이 동일하게 작동하므로 원하는만큼 줄을 지정할 수 있습니다.

#define F ;for(i=0;i<12;i++)
#define D(k) (q[i]-q[(i+k)%12])
double q[12],r[12],s[4],p,n;

main(i){
  F scanf("%lf",&q[i])
  F r[i/3*3]+=D(3)*D(3),r[i/3*3+1]+=D(6)*D(6)
  F r[i]=sqrt(r[i])
  F i%3||(s[i/3]=r[(i+3)%12]/2),s[i/3]+=r[i]/2
  F i%3||(p=s[i/3]-r[(i+3)%12]),p*=s[i/3]-r[i],n+=(i%3>1)*sqrt(p)   
  ;printf("%lf",n);       
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.