Giúp tôi tôi bị lạc trong đại dương!


11

Giới thiệu

Hôm nay tôi đi câu cá một mình bằng xuồng, không may tôi ngủ thiếp đi và dòng suối đưa tôi đi, tôi bị mất mái chèo, bây giờ là đêm và tôi bị lạc trong đại dương! Tôi không thể nhìn thấy bờ biển nên tôi phải ở rất xa!

Tôi có điện thoại di động nhưng bị trục trặc vì bị ướt bởi nước mặn, tôi không thể nói hoặc nghe bất cứ điều gì vì mic và loa điện thoại bị hỏng, nhưng tôi có thể gửi SMS cho người bạn đang ở trên bờ biển!

Bạn tôi có một ngọn đuốc rất mạnh và anh ta giơ nó lên trên những tán tre để chỉ cho tôi hướng đi đúng, nhưng tôi không thể chèo thuyền vì tôi không có mái chèo, vì vậy tôi phải nói cho anh ta biết tôi có thể gửi ai đó đến đâu bắt tôi!

Bạn tôi nói với tôi rằng anh ta đang giữ ngọn đuốc ở độ cao 11,50 mét trên mực nước biển, và tôi có thể nhìn thấy ánh sáng ngay phía chân trời. Bây giờ tôi chỉ nhớ từ trường học rằng bán kính Trái đất phải là 6371 Km ở mực nước biển, và tôi đang ngồi trên xuồng để bạn có thể cho rằng mắt tôi cũng ở mực nước biển.

Bài tập

Vì dòng chảy đang di chuyển tôi từng khoảnh khắc, bạn tôi thỉnh thoảng giơ cao ngọn đuốc (bây giờ là 12,30 mét), xin vui lòng viết một chương trình hoặc chức năng đầy đủ sẽ giúp tôi tính khoảng cách từ vị trí của bạn tôi!

Đây là một sơ đồ (không chia tỷ lệ):

nhập mô tả hình ảnh ở đây

Điểm màu cam được dán nhãn Mlà tôi, điểm màu đỏ được dán nhãn Tlà ngọn đuốc. Đường màu xanh là khoảng cách tuyến tính giữa MT

Đầu vào

Lấy từ đầu vào tiêu chuẩn chiều cao ngọn đuốc tính hbằng mét ở mực nước biển, mà tôi nhìn thấy ngay trên đỉnh của đường chân trời, dưới dạng số dấu phẩy động với độ chính xác hai số thập phân (với độ chính xác là 1 cm hoặc 0,01 mét), trong phạm vi từ 0 đến 100 bao gồm.

Đầu ra

Bạn nên trả về chiều dài euclide của đường màu xanh lá cây với độ chính xác là 1 cm. Ví dụ: nếu bạn xuất ra theo mét, nên có hai số thập phân (ít nhất). Đầu ra có thể là mét hoặc km, nhưng tôn trọng độ chính xác.

Các trường hợp thử nghiệm:

Tất cả các giá trị tính bằng mét.

11.5 > 12105.08
13.8 > 13260.45

Quy tắc

Mã ngắn nhất sẽ thắng.


Kết quả có phải đúng về mặt toán học hay không, nếu 2 số thập phân đầu tiên ổn? Ý tôi là hxh nhỏ so với 2xRxh và có thể bị bỏ qua trong khoảng cách nhỏ. (R là bán kính Trái đất và h là chiều cao của ngọn đuốc).
Osable

@ 2 số thập phân đầu tiên có thể chấp nhận được nếu bạn xuất ra theo mét
Mario

Phạm vi của đầu vào là gì?
Osable

@Osable bạn có thể coi đầu vào là từ 0 đến 100 (thậm chí quá nhiều so với mức cần thiết / có thể trong trường hợp này).
Mario

1
Bạn nên thử trao đổi Coast Guard Stack Exchange - golferse mã không thể giúp bạn ra khỏi đại dương, anh bạn!
corsiKa

Câu trả lời:


4

05AB1E ,13 12 10 byte

Đã lưu 2 byte nhờ Emigna.

Vì không có hàm lượng giác nào được gọi bằng giả định của OP rằng trái đất là cục bộ của một mặt phẳng, nên có thể tạo ra một giải pháp 05AB1E.

•1#oC•+¹*t

           For understanding purposes input is referred to as 'h'
•1#oC•     Push 12742000 [ = 2*R, where R is the radius of earth]
      +    Compute 2*R+h
       ¹*  Multiply by h. Result is (2*R*+h)*h
         t Take the square root of it and implicitly display it

Hãy thử trực tuyến!


1
12742000có thể được viết là•1#oC•
Emigna

Để tham khảo, nó sẽ có 9 byte: •1#oC•+*ttrong 2 giây
Emigna

Một chuỗi có nguồn gốc với mô tả một ... số cơ sở 214? Đôi khi 05AB1E bị thiếu tài liệu về các chức năng đặc biệt như vậy. Đẹp 2sable trả lời cũng được. Tôi đã phát hiện ra nó vài ngày trước nhưng tôi đã không nghĩ về việc sử dụng nó cho câu hỏi này.
Có thể truy cập

Chính xác. Đó là một số cơ sở 10 được mã hóa trong cơ sở 214.
Emigna

Kết quả có thể đạt được cũng bằng lượng giác nhưng có lẽ lâu hơn.
Mario

4

Python, 34 26 byte:

( -8 byte nhờ vào Osable! )

lambda i:(i*(i+12742))**.5

Một chức năng lambda ẩn danh. Mất đầu vào tính bằng km và đầu ra tính bằng km. Gọi như print(<Function Name>(<Input>)).


lambda i:(i*(i+12742))**.5thậm chí sẽ ngắn hơn
Osable

@Osable Đẹp! Tôi chỉ định làm điều đó. :)
R. Kap

Nếu có dung sai toán học, với sự khác biệt giữa ivà 12742, biểu thức có thể được rút ngắn để:(i*12742)**.5
Có thể điều chỉnh được vào

Kết quả sai. 11,5m -> ~ 380km thay vì ~ 12km
GB

@GB Chương trình đọc đầu vào của nó là km.
Osable

4

PHP, 34 byte

<?=sqrt((12742e3+$h=$argv[1])*$h);

phá vỡ

   r^2+x^2=(r+h)^2      # Pythagoras base
   r^2+x^2=r^2+2rh+h^2  # right term distributed
       x^2=    2rh+h^2  # -r^2
       x =sqrt(2rh+h^2) # sqrt

cho đến nay, điều này giống hệt với câu trả lời cũ của Mathicala

sqrt(2*6371e3*$h+$h*$h) # to PHP
sqrt(14742e3*$h+$h+$h)  # constants combined
sqrt((14742e3+$h)*$h)   # conjugation to save a byte
((14742e3+$h)*$h)**.5   # same size

bây giờ tất cả những gì còn lại để làm là thêm đầu vào =$argv[1]và đầu ra <?=- đã xong


4

dc, 16 11 byte:

?d12742+*vp

Nhắc nhở đầu vào thông qua dòng lệnh theo km và sau đó xuất khoảng cách theo km.

Giải trình

?           # Prompt for input
 d          # Duplicate the top-of-stack value
  12742     # Push 12,742 onto the stack
       +    # Pop the top 2 values of the stack and push their sum
        *   # Pop top 2 values of the stack and push their product
         v  # Pop the remaining value and push the square root
          p # Output the result to STDOUT

Điều này tận dụng những điều sau đây:

((6371+h)**2-6371**2)**.5 
=> ((6371**2+12742h+h**2)-6371**2)**0.5 
=> (h**2+12742h)**0.5 
=> (h*(h+12742))**0.5


4

Haskell, 22 byte

d h=sqrt$h*(h+12742e3)

Sử dụng:

Prelude> d 11.5
12105.087040166212

Pointfree: (23 byte)

sqrt.((*)=<<(+12742e3))

3

R, 29 byte

h=scan();sqrt(h^2+2*h*6371e3)

Lấy đầu vào từ stdin


Một vài byte ngắn hơn là (h=scan())*(1+12742e3/h)^.5.
Flounderer

2

Toán học, 16 byte

Một trong hai công việc này cho cả đầu vào và đầu ra tính bằng km:

(12742#+#*#)^.5&
((12742+#)#)^.5&

Đây là một ứng dụng đơn giản của Pythagoras cho vấn đề:

   x*x + R*R = (R+h)*(R+h)
=> x*x = (R+h)*(R+h) - R*R
       = R*R + 2*R*h + h*h - R*R
       = 2*R*h + h*h
=>   x = √(2*R*h + h*h)

2

Jelly, 9 byte trong trang mã của Jelly

Tôi quyết định bắt đầu viết chương trình bằng ngôn ngữ chơi gôn. Tôi thực sự đã tìm thấy một thuật toán hiệu quả hơn so với những người khác đang sử dụng (ít nhất là trong khoảng cách ngắn như câu hỏi trong câu hỏi), nhưng nó yêu cầu các số dấu phẩy động theo nghĩa đen mà Jelly dường như không thể nén được, vì vậy Pythagoras nó là.

+“Ȯịż’×µ½

Giải trình:

 “Ȯịż’     12742000, compressed base-250
+          add to argument
      ×    multiply with original argument
       µ   separator to avoid what would otherwise be a parsing ambiguity
        ½  square root everything seen so far
           implicit output at EOF

Sự cần thiết của µdải phân cách làm tôi khó chịu, nhưng tôi nghĩ đó là điều không thể tránh khỏi; Jelly đã lưu một byte trên 05AB1E thông qua việc có thể đoán được những đối số mà nhiều lệnh cần, nhưng trong trường hợp này, nó không thể đoán chính xác đến cuối, vì vậy tôi cần đưa ra gợi ý.

Jelly, 7 byte trong trang mã của Jelly

דȮịż’½

Như tôi đã giải thích trong câu trả lời khác của mình , chuỗi gần đúng với xấp xỉ Pythagoras thực sự tạo ra kết quả tốt hơn so với độ dài trong câu hỏi (ít nhất, chúng gần với kết quả đầu ra mẫu hơn) và cũng có công thức ngắn hơn. Trong khi tôi đang viết nó, tôi nhận ra rằng thay vì tính căn bậc hai của 12742000 trước, tôi có thể nhân số đó với 12742000 trước, và sau đó là căn bậc hai cùng một lúc. Điều này về cơ bản tương đương với công thức khác mà không cần bổ sung, và do đó, nó có thể được sản xuất từ ​​chương trình trước đó thông qua việc loại bỏ bổ sung khỏi nó. Điều này tiết kiệm hai byte, vì bây giờ nó phân tích rõ ràng và vì vậy chúng tôi không cần µthêm nữa.


Tôi quyết định không sử dụng tối ưu hóa này bởi vì nó không mang lại cùng các giá trị nếu bạn nhìn vào centimet (xem đầu ra được yêu cầu) với phạm vi h. Nó cũng sẽ lưu 2 byte trong 05AB1E.
Osable

Với việc tối ưu hóa, tôi nhận được kết quả đầu ra là 12105,081577585506 và 13260,452480967608; những cái này rất gần với đầu ra của trường hợp thử nghiệm và làm tròn chúng. Không có, tôi nhận được 12105,087040166212 và 13260.459661716106, ở xa hơn (và cái sau không chính xác trong centimet, làm tròn đến 13260,46). Như đã đề cập trong câu trả lời khác, việc tối ưu hóa xảy ra gần với giá trị chính xác hơn mã được tối ưu hóa vì nó chứa hai lỗi phần lớn triệt tiêu lẫn nhau, thay vì chỉ có một lỗi không có gì để hủy bỏ.

Vì bạn vừa bỏ phiếu để "Để ngỏ" trong hàng đánh giá, tôi cho rằng bạn tin rằng bạn biết câu trả lời cho các câu hỏi mà tôi đã yêu cầu làm rõ trong các nhận xét. Do đó, vui lòng chỉnh sửa câu hỏi để nó rõ ràng.
Peter Taylor

1
Câu hỏi không rõ ràng: tác giả cần biết khoảng cách với bạn mình để giúp điều hướng. Anh ta có thể xác định vị trí của ngọn đuốc với độ chính xác 0,1 mét (chúng ta có thể xác định điều này từ câu chuyện được kể). Điều này chắc chắn sẽ tạo ra khoảng 1 mét không chắc chắn từ đầu ra ở khoảng cách hiện tại (lưu ý: tác giả đang trôi dạt xung quanh, do đó không có khả năng di chuyển rất nhanh rất nhanh), và do đó, bất cứ điều gì gần như chính xác đều có khả năng xảy ra chấp nhận được Một phần của vấn đề là xác định mức độ chính xác mà bạn cần có trong tình huống này!

1
Sản lượng yêu cầu hiển thị 2 số thập phân tính bằng mét. Vì vậy, độ chính xác dự kiến ​​là 1 centimet. Trong các bình luận cho câu hỏi, OP nói rằng h có thể lên tới 100. Với h = 100, có sự khác biệt 14 cm so với thuật toán ban đầu.
Osable

2

Ruby, 23

23 byte, tính bằng km

->h{(h*h+h*12742)**0.5}

25 byte, tính bằng m

->h{(h*h+h*12742e3)**0.5}

1

Tcl, 49 byte:

set A [get stdin];puts [expr ($A*($A+12742))**.5]

Chà, tôi là người hoàn toàn mới với Tcl, vì vậy bất kỳ lời khuyên nào để chơi golf này đều được đánh giá cao. Giống như các câu trả lời khác của tôi, lời nhắc cho đầu vào dòng lệnh tính bằng km và đầu ra tính bằng km. Về cơ bản một sự thích nghi của Tcl hiện tại của tôi dcpythoncâu trả lời.


có một s mất tích trên get s
sergiol

1

x86_64 + mã máy SSE, 16 byte

Các byte của chương trình nằm ở bên trái (theo hệ thập lục phân), có một sự phân tách ở bên phải để làm cho nó dễ đọc hơn một chút. Đây là một hàm tuân theo quy ước x86_64 thông thường cho các hàm lấy và trả về một số dấu phẩy động có độ chính xác đơn (nó lấy tham số trong% xmm0 và trả về câu trả lời của nó trong cùng một thanh ghi, và sử dụng% xmm1 và% eax làm tạm thời; là các quy ước gọi giống nhau mà chương trình C sẽ sử dụng và do đó bạn có thể gọi hàm trực tiếp từ chương trình C, đó là cách tôi đã kiểm tra nó).

b8 80 19 5f 45          mov    $0x455f1980,%eax
66 0f 6e c8             movd   %eax,%xmm1
0f 51 c0                sqrtps %xmm0,%xmm0
0f 59 c1                mulps  %xmm1,%xmm0
c3                      retq

Ngay cả với một sự tháo gỡ, mặc dù, điều này vẫn cần một lời giải thích. Đầu tiên, nó đáng để thảo luận về công thức. Hầu hết mọi người đang bỏ qua độ cong của trái đất và sử dụng công thức của Pythagoras để đo khoảng cách. Tôi cũng đang làm điều đó, nhưng tôi đang sử dụng một xấp xỉ mở rộng chuỗi; Tôi chỉ sử dụng thuật ngữ liên quan đến sức mạnh đầu tiên của đầu vào và bỏ qua các quyền lực thứ ba, thứ năm, thứ bảy, v.v., tất cả chỉ có ảnh hưởng rất nhỏ ở khoảng cách ngắn này. (Bên cạnh đó, phép tính gần đúng Pythagoras cho giá trị thấp, trong khi các thuật ngữ sau trong mở rộng chuỗi phục vụ để giảm giá trị; do đó, bằng cách bỏ qua một yếu tố nhỏ sẽ phục vụ để đẩy xấp xỉ theo hướng sai, tôi thực sự xảy ra để có được một kết quả chính xác hơn bằng cách sử dụng một công thức kém chính xác hơn.) Công thức hóa ra là √12742000 × h;0x455f1980.

Điều tiếp theo có thể khiến mọi người nhầm lẫn là tại sao tôi sử dụng các hướng dẫn vectơ cho căn bậc hai và bội số; %xmm0%xmm1có thể giữ bốn số dấu phẩy động chính xác duy nhất cho mỗi số và tôi đang hoạt động trên cả bốn số. Lý do ở đây thực sự đơn giản: mã hóa của chúng ngắn hơn một byte so với hướng dẫn vô hướng tương ứng. Vì vậy, tôi có thể làm cho FPU thực hiện một loạt các công việc bổ sung vuông và nhân các số 0 để tiết kiệm cho mình hai byte, theo một phương pháp rất giống với thuật toán ngôn ngữ golf thông thường. (Tôi đã gọi trình biên dịch x86 là ngôn ngữ chơi gôn của các nhà lắp ráp trong trò chuyện một lúc trước và tôi vẫn không thay đổi suy nghĩ của mình về điều đó.)

Từ đó, thuật toán rất đơn giản: tải %xmm1với √12742000 qua %eax(ngắn hơn về số byte so với tải từ bộ nhớ), căn bậc hai đối số (và ba số 0), nhân các phần tử tương ứng của %xmm1%xmm0(chúng tôi chỉ quan tâm về phần tử đầu tiên), sau đó quay trở lại.


1

Chồnolang v0.15, 22 byte

ndd*$r'12742000'*+1MN.

Hãy thử trực tuyến!

n                               gets input in the form of a number
 dd                             duplicates it twice
   *                            multiplies 2 of the duplicates with each other
                                STACK: [h, h*h]
    $r                          swap top two stack values
                                STACK: [h*h, h]
      '12742000'*               push this number and multiply the original input by it
                                STACK: [h*h, h*12742000]
                 +1M            adds the two values and takes their square root
                                STACK: [sqrt(h*h+h*12742000)]
                    N.          output as a number and end program

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.