코드 골프 : 우주선의 운명은 무엇입니까? [부동 소수점 버전]


12

이 질문은 ASCII 아트 버전보다 약간 어렵습니다. 예술은 없으며, 이제 부동 소수점 산술을 할 수 있습니다!

도전

USS StackExchange는 천문 폭발이 발생했을 때 cg-00DLEF 행성의 중력장을 통과하고있었습니다. 선박의 수석 프로그래밍 책임자로서 cg-00DELF의 태양계에서 땅을 추락시킬 것인지 예측하기 위해 선박의 궤도를 시뮬레이션하는 것이 귀하의 임무입니다. 폭발하는 동안 배가 심하게 손상되었습니다. 우주선의 제한된 무료 DEEEPRAROM *으로 인해 가능한 적은 문자로 프로그램을 작성해야합니다.

* 동적으로 실행 가능한 전자 소거 가능 프로그램 가능 임의 액세스 읽기 전용 메모리

시뮬레이션

ASCII 아트 버전과 마찬가지로 시간 단계에 대한 아이디어가 있습니다. 다른 버전에서, 시간 단계는 비교적 많은 시간이었다 : 배는 단일 시간 단계에서 행성의 중력을 넘어서 이동할 수 있었다. 여기서, 시간 간격은 관련된 더 큰 거리로 인해 훨씬 ​​작은 시간 단위입니다. 그러나 한 가지 주요 차이점은 셀이 존재하지 않는다는 것입니다. 우주선의 현재 위치와 속도는 관련된 중력과 함께 부동 소수점 수입니다. 또 다른 변화는 행성의 크기가 훨씬 크다는 사실입니다.

시뮬레이션에는 최대 3 개의 행성이 있습니다. 세 가지 모두 특정 위치, 반경 및 중력을 갖습니다. 각 행성의 중력은 행성 중심을 향해 직접 힘을 가하는 벡터입니다. 이 벡터의 강도를 구하는 공식은입니다 (Gravity)/(Distance**2). 여기서 거리는 우주선에서 지구 중심까지의 정확한 거리입니다. 이것은 중력에 도달 할 수있는 곳에 제한이 없음을 의미합니다.

특정 시점에서 우주선의 속도는 마지막 단계에서 현재까지 이동 한 거리와 각도입니다. 배도 추진력이 있습니다. 현재 시간 단계와 다음 단계 사이를 이동할 거리는 해당 위치의 모든 중력 벡터에 추가 된 현재 속도의 합입니다. 이것은 우주선의 새로운 속도가됩니다.

각 시뮬레이션의 시간 제한은 10000 개의 시간 단계입니다. 우주선이 행성 내부를 여행하면 (행성의 반경보다 행성의 중심에 더 가까움), 그 행성에 충돌합니다. 우주선이 시뮬레이션이 끝날 때까지 행성에 충돌하지 않으면 중력에서 탈출 한 것으로 추정됩니다. 배가 10001 시간 간격으로 추락하면서 10000 시간 간격으로 궤도에 머무를 수 있도록 완벽하게 정렬 될 수는 없습니다.

입력

STDIN에 4 줄이 입력됩니다. 각 줄은 쉼표로 구분 된 4 개의 숫자로 구성됩니다. 숫자 형식은 다음과 같습니다.

ShipLocX,ShipLocY,ShipVelX,ShipVelY
Planet1LocX,Planet1LocY,Planet1Gravity,Planet1Radius
Planet2LocX,Planet2LocY,Planet2Gravity,Planet2Radius
Planet3LocX,Planet3LocY,Planet3Gravity,Planet3Radius

3 개 미만의 행성이있는 경우 남은 선은 모든 값에 대해 0으로 채워집니다. 입력 예는 다음과 같습니다.

60,0,0,10
0,0,4000,50
100,100,4000,50
0,0,0,0

이것은 우주선이 (60,0)에 위치하고 10 단위 / 시간 간격의 속도로 "위 / 북쪽"으로 직진하고 있음을 의미합니다. 두 개의 행성이 있는데, 하나는 (0,0)에 있고 다른 하나는 (100,100)에 있습니다. 둘 다 중력은 4000이고 반지름은 50입니다. 이들 모두가 정수이지만 항상 정수는 아닙니다.

산출

우주선이 착륙했는지 여부를 알려주는 출력은 STDOUT에 한 단어가됩니다. 선박 충돌이 발생하면을 인쇄하십시오 crash. 그렇지 않으면을 인쇄하십시오 escape. 위 입력에 대한 예상 출력은 다음과 같습니다.

crash

무슨 일이 있었는지 궁금 할 것입니다. 다음 은 우주선에 대한 자세한 비행 기록이있는 Pastebin 게시물입니다. 숫자는 사람들이 사건을 시각화하는 데 도움이되지 않으므로 여기에 무슨 일이 있었습니까? 북쪽으로 이동 한 다음 두 번째 행성의 서쪽으로 약간 지나간 후 ​​간신히 빠져 나갑니다. 그런 다음 행성의 북쪽을 중심으로 구부러져 두 번째 행성의 동쪽으로 충돌합니다.

더 많은 검사 사례

60,0,10,-10
0,0,2000,50
100,100,1357.9,47.5
0,0,0,0

탈출 (역 제곱 법으로 인해 60 단위 떨어져 있다면 2000은 중력이 아닙니다)

0,0,0,0
100,100,20000,140
-50,-50,50,50
-100,-100,50,50

추락 (첫 번째 행성은 매우 방대하고 매우 가깝습니다)

0,0,0,0
0,0,0,0
0,0,0,0
0,0,0,0

탈출 (이것은 중요한 경우입니다. 행성이 없으며 우주선이 행성의 바로 위에 있음을 간단하게 해석 할 수 있습니다)

규칙, 제한 및 참고

이것은 코드 골프입니다. 표준 코드 골프 규칙이 적용됩니다. 프로그램은 인쇄 가능한 ASCII 문자로만 작성해야합니다. 어떤 종류의 외부 데이터베이스에도 액세스 할 수 없습니다. 이 문제를 해결하기 위해 전문화 된 언어 이외의 다른 언어로 항목을 작성할 수 있습니다.

전송 종료


rofl DEEEPRAROM! — 행성의 중력 상호 작용은 시뮬레이션되지 않아야합니까? 그래도 여전히 수치 적으로 비싸지는 않지만 충분합니다. — 참조 시뮬레이션이 표준 Runge-Kutta 4 차 통합을 사용한다고 가정하고, 프로그램이 동등한 결과를 생성해야합니까?
반 시계 회전을 중지

여러 행성이 상호 작용하는 방법을 알지 못했습니다. 문제는 그들이 즉시 서로 충돌하는 경향이 있다는 것입니다. 이 문제를 해결하려면 시뮬레이션의 규모를 엄청나게 부풀려 야합니다.
PhiNotPi

Runge-Kutta 방법에 관해서는, 나는 정직하게 수학에서 아직 진보하지 않았습니다. :( 내가 한 것은 선박의 현재 위치에서 중력을 계산하고 이것을 선박의 속도에 추가하여 선박의 새로운 속도를 생성하는 것입니다. 나는 매 단계마다 이것을했습니다. 이것이 완전히 정확하지는 않다는 것을 알았습니다. 우주선의 시작 속도와 행성의 중력을 10으로
나누면

아, 그것이 오일러의 방법 일 것입니다. 충분히 작은 시간 단계를 위해서도 하나는 정확합니다. 그러나 Runge-Kutta 또는 더 정교한 것은 IMO를 구현하는 데 더 흥미로울 것입니다. 어쩌면 내가 내 자신의 도전을 고안해야한다, 내가 쉽게 만족할 수없는 것 ...
차례에 중단는 counterclockwis

@leftaroundabout 계속 진행하십시오. "미분 방정식을 사용하여 전체 태양계를 시뮬레이션"또는 이와 같은 멋진 것을 만들거나 3 차원을 추가 할 수 있습니다.
PhiNotPi

답변:


6

파이썬, 178170

p=input
a,b,c,d=p()
x=a+b*1j
v=c+d*1j
P=(p(),p(),p())
R='escape'
for i in' '*10000:
 for a,b,g,r in P:
  d=a+b*1j-x;v+=g*d/abs(d)**3
  if abs(d)<r:R='crash'
 x+=v
print R

2
당신은 오늘 복잡한 분위기에 있지 않습니까?
counterclockwis 설정을 중단

8
네, i오전 ....
Keith Randall

그걸 어떻게 경쟁 할 수 있습니까?
Neil

@ 닐 : 코드, 재치있는 농담?
Keith Randall

글쎄요 내가 참을 수있는 재치있는 농담.
Neil

2

Golfrun / GolfScript ?, 243 232 자

10000:M;n%(','%2/{{~}%}/{{M*}%}:_~:v;_:x;'escape':R;{[','%2/{{~M*}%}/]}%:P;
M,{;P{~\x{0\-}%{+~@+@@+[\]}:|~:d.[~0\-]{[+.2%~*\.-2%~*@\-\.3%~*\(;);~*+]}:&~);~sqrt:z
..**\~d@[`~0]\&@M.*/\{1$/}%v|:v;;z\<{'crash':R;}{}if}/x v|:x;}/R puts

Golfrun은 내가 작업하고있는 언어이며 GolfScript C 인터프리터로 태어 났지만 곧 어딘가에 표류했습니다. 의도적으로 특정 Golfrun 기능을 사용하지 않고이 코드를 작성했지만 (을 제외하고 sqrt) 원래 GolfScript 테스트는 실패했습니다 (원래 코드에 sqrt 기능을 추가해야했지만 Ruby 전문가는 아니지만 문제는 있다고 생각합니다 내 조정이 아님).

이 솔루션의 첫 번째 문제는 GolfScript와 같은 Golfrun에 부동 소수점 연산이 없다는 것입니다. 올바른 방법으로 숫자를 확대하여 "시뮬레이션"합니다 (그러나 100 % 확실하게 일관성있게 수행 한 것은 아닙니다). 그럼에도 불구하고 솔루션은 부동 소수점 숫자를 입력으로 처리하지 않으므로 정수만 갖도록 수동으로 확대해야했습니다.

파이썬 코드에서 알고리즘을 구현하려고 시도하면서, 나는 다소 "일반적인"방식으로 복잡한 수학 비트를 구현했습니다. 이를 피하기 위해 알고리즘을 조작하거나 가능할 때마다 인라인하여 정의를 지연 시키면 다른 문자를 저장할 수 있습니다

이 코드가 작동하는지 어떻게 알 수 있습니까? 실제로, 나는 확실하지 않다! 그러나 예제를 입력으로 표시하면 ( "제거 된"지점이 나타난 후) "corner case"(Python에서도 예외를 발생)를 제외하고 예상 된 결과를 작성했습니다.

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