Mặt trời bao xa?


20

Giới thiệu

tl; dr

Liên tục xuất khoảng cách hiện tại từ Trái đất đến Mặt trời.


Đơn giản hóa, quỹ đạo của Trái đất quanh Mặt trời là một hình elip. Vì vậy, khoảng cách thực tế giữa cả hai liên tục thay đổi. Khoảng cách này có thể được tính cho bất kỳ ngày nào bằng cách sử dụng công thức này :

d / AU = 1-0,01672 cos (0,9856 (ngày 4))

Phương trình có thể được chia thành các phần sau 2 :

  • 1đại diện cho 1 AU (đơn vị thiên văn), bằng149,597,870.691 km
  • 0.01672độ lệch tâm quỹ đạo giữa Trái đất và Mặt trời
  • cosTất nhiên là hàm cosin, nhưng với đối số theo độ chứ không phải radian
  • 0.9856360 ° / 365.256363 ngày , một vòng quay đầy đủ trong một năm, trong đó 365.256363độ dài của một năm thiên văn, tính theo ngày mặt trời
  • day là ngày trong năm [1-365]
  • 4đại diện cho phần bù cho perihelion , nằm trong khoảng từ ngày 4 đến ngày 6 tháng 1

Công thức mất cả ngày nhưng với mục đích của thử thách này - đầu ra liên tục - bạn phải chính xác hơn; hoặc không có gì nhiều sẽ xảy ra cho đến ngày hôm sau. Chỉ cần thêm phần trăm thời gian trong quá khứ vào ngày hiện tại, như 1 :

day + (h * 3600 + m * 60 + s) / 864 / 100

Một vài ví dụ:

  • Ngày 1 tháng 1, 23:59:59 1.99998842592593
  • Ngày 1 tháng 1, 18:00:00 1.75
  • Ngày 1 tháng 1, 12:00:00 1.50
  • 1 tháng 1, 06:00:00 1.25

Đầu vào

Thách thức này không có đầu vào.


Nếu ngôn ngữ của bạn không thể có được thời gian hiện tại, bạn có thể lấy nó làm đầu vào cho chương trình của mình. Đầu vào hợp lệ là dấu thời gian hoặc chuỗi thời gian hoàn thành phù hợp nhất với ngôn ngữ. Không được phép vượt qua ngày hiện tại một mình (như 5ngày 5 tháng 1 hoặc 5.25cùng ngày lúc 6 giờ).

Đầu ra

Xuất khoảng cách hiện tại từ Trái đất đến Mặt trời:

  • Xuất giá trị trong km.
  • Cập nhật giá trị ít nhất mỗi giây .

Ví dụ đầu ra:

152098342

Nếu nó không tăng số byte của bạn, bạn cũng có thể in kết quả:

152,098,342
152,098,342 km

Yêu cầu

  • Bạn có thể viết một chương trình hoặc một chức năng. Nếu đó là một hàm ẩn danh, vui lòng bao gồm một ví dụ về cách gọi nó.
  • Đây là để câu trả lời ngắn nhất trong byte thắng.
  • Sơ hở tiêu chuẩn là không được phép.

Ví dụ thực hiện

Tôi đã chuẩn bị một triển khai ví dụ trong JavaScript. Nó không cạnh tranh cũng không phải chơi gôn.

// dayOfYear from http://stackoverflow.com/a/8620357/1456376
Date.prototype.dayOfYear = function() {
    var j1= new Date(this);
    j1.setMonth(0, 0);
    return Math.round((this-j1)/8.64e7);
}

// vars
var e = document.getElementById('view'),
    au = 149597870.691,
    deg2rad = Math.PI/180,
    date = now = value = null;

// actual logic
function calculate() {
    date = new Date();
    now = date.dayOfYear() + (date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds()) / 864 / 100;
    value = 1 - 0.01672 * Math.cos(deg2rad * 0.9856 * (now - 4));
    // supported in Firefox and Chrome, unfortunately not in Safari
    e.innerHTML = Math.round(value * au).toLocaleString('en-US') + ' km';

    setTimeout(calculate, 1000);
}

// let's do this
calculate();
<div id="view"></div>


1 Để không làm tăng sự phức tạp một cách vô lý, bạn không phải chuyển đổi giờ địa phương sang UTC. Nếu bạn sử dụng UTC, vui lòng thêm một ghi chú vào câu trả lời của bạn.

2 Để biết thêm chi tiết, hãy xem " Khoảng cách Trái đất-Mặt trời vào một ngày nhất định trong năm " tại Vật lý


Ngôn ngữ lập trình nên làm gì mà không thể truy cập vào thời điểm hiện tại? Giống như BF vv?
flawr

3
Tôi tin rằng ví dụ của bạn là không chính xác, vì Math.cossử dụng radian. Và vì công thức này có vẻ rất gần đúng, bạn sẽ phải rõ ràng về cách xác minh câu trả lời.
grc

@grc Tôi đã sửa lỗi trong ví dụ của mình - cảm ơn vì đã chỉ cho tôi.
insertusernamehere

@flawr Bạn có thể lấy thời gian làm đầu vào cho chương trình của mình. Câu hỏi được cập nhật tương ứng.
insertusernamehere

1
Tôi cá là Mathicala có tích hợp sẵn cho nó!
sergiol

Câu trả lời:


5

TI-BASIC, 38 byte

Disp 25018086(59.8086-cos(5022635.4⁻¹checkTmr(83761
prgmA

Đối với máy tính sê-ri TI-84 +. Đặt tên này prgmA. Lưu ý rằng điều này tràn qua ngăn xếp sau vài nghìn lần lặp; sử dụng While 1:...:Endthay thế nếu đây là một vấn đề, cho hai byte thêm.

Điều này sử dụng perihelion vào ngày 1 tháng 1 năm 1997, 23:16 UTC để tham khảo và chính xác trong phạm vi vài chục km (khoảng 7 chữ số chính xác) trong vài năm tới.


Bây giờ điều này là ngắn. Thanh danh!
insertusernamehere

5

Java - 185 180 byte

static void d(){while(true){System.err.println(149597870.691*(1-.01672*Math.cos(Math.toRadians(.9856*(Calendar.getInstance().get(6)+LocalTime.now().toSecondOfDay()/8.64e4-4)))));}}

Điều này sử dụng thực tế là có 86.400 giây trong một ngày và đang sử dụng giờ địa phương, không phải GMT. Đầu ra xảy ra nhiều hơn một lần mỗi giây. Không chắc chắn nếu các câu lệnh nhập nên được bao gồm trong số byte.

Để bao gồm độ trễ 1 giây, thêm khoảng 26 byte, vd

static void d(){try{while(true){System.err.println(149597870.691*((1-.01672*Math.cos(Math.toRadians(.9856*(Calendar.getInstance().get(6)+LocalTime.now().toSecondOfDay()/8.64e4-4)))));Thread.sleep(1000L);}}catch(Exception e){}}

Java chắc chắn không phải là ngôn ngữ dễ chơi nhất. :)

Đã xóa một vài byte nhờ @insertusernamehere


1
Tốt đẹp. Không thể 1.0trở thành 1? Và bạn có thể loại bỏ hàng đầu 0từ 0.016720.9856?
insertusernamehere

Rất đúng, đó là những gì tôi nhận được khi sao chép-dán từ câu hỏi: p Tôi có thể bỏ thêm một số byte nếu tôi sử dụng import staticnhưng đó có thể là "gian lận" ... Tôi vẫn còn khá mới ở đây.
Robert Benson

Tại sao System.err?
SuperJedi224

Tôi đã sử dụng System.errvì vậy sẽ không có bộ đệm. Tôi biết printlndù sao cũng phải in ngay lập tức, nhưng dường như không phải lúc nào cũng làm được điều đó. Tất nhiên nó có thể được chuyển đổi thành System.out mà không thay đổi số byte :)
Robert Benson

2
Tôi đã nhận thấy rằng nhiều người đang quên chuyển đổi từ độ sang radian. Tôi muốn nhận xét về họ, nhưng tôi là người mới với quá ít đại diện: p
Robert Benson

4

Python, 101 byte

import time,math
a=149597870.691
while 1:print(a-a*.01672*math.cos((time.time()-345600)/5022635.53))

345600 = 4 * 24 * 3600 (bốn ngày)

5022635,53 (365.256363 * 24 * 3600) / (2π) (giây tính theo năm / 2π)


Chào mừng bạn đến với Câu đố lập trình và Code Golf. Đây là một giải pháp tốt, +1. Tuy nhiên, nó có thể cải thiện câu trả lời nếu bạn đã thêm một phiên bản không được bình luận và nhận xét, giải thích những gì bạn đã làm hoặc thậm chí chỉ cần thêm một nhận xét đơn giản trước mã.
wizzwizz4

Tôi nhận được 107 cho số byte.
Morgan Thrapp

Phải, tôi đã bao gồm dòng mới nhất.
pacholik

Bạn có thể lưu 7 byte bằng cách kết hợp imports : import time,math. Ngoài ra, nếu bạn sử dụng Python 2, bạn có thể bỏ dấu ngoặc đơn từ đó print.
PurkkaKoodari

Cũng đúng, với tất cả PEP đó tôi đã quên điều đó là có thể :)
pacholik

3

Bash / coreutils / bc, 101 byte

#!/bin/bash
bc -l <<<"149597870.691*(1-.01672*c((`date +%s`-`date -d 4-Jan +%s`)/5022635.5296))"
sleep .5
exec $0

Điều này sẽ tính toán phần bù từ ngày 4 tháng 1 tính bằng giây, do đó sử dụng hằng số tương ứng để chuyển đổi thành radian. Nửa năm chuyển đổi thành khoảng pi:

$ bc -l <<<"(365.256363/2*86400)/5022635.5296"
3.14159265361957033371

Phần còn lại của tính toán là thẳng từ câu hỏi.


Công việc tốt. Tôi tự hỏi nếu bccó thể hữu ích cho việc này. Tôi nhận thấy rằng bạn có dctrong tiêu đề của bạn, nhưng sử dụng bctrong mã. Tôi thường nhầm lẫn hai mình.
Robert Benson

1
Cảm ơn, @Robert - Tôi đã sửa tiêu đề. Tôi bắt đầu nhìn vào dc, rồi nhận ra tôi cần mathlib của bc, vì vậy có cả hai máy tính trong tâm trí tôi không đúng lúc!
Toby Speight

Đúng, đã ở đó, làm điều đó. Tôi luôn quên cái nào là cái nào.
Robert Benson

2

F #, 178 byte

open System
Seq.initInfinite(fun _->
let n=DateTime.Now
(1.-0.01672*Math.Cos(0.0172*((n-DateTime.Today).TotalDays+float(n.DayOfYear-4))))*149597870.691)|>Seq.iter(printfn"%f")

Đây là tập lệnh F # chạy tốt trong F # Interactive. Để đơn giản, yêu cầu "đầu ra liên tục" được đưa đến mức theo nghĩa đen, mặc dù tôi đã mất một byte để tạo đầu ra in trên một dòng mới mỗi lần lặp để nó không quá tệ. = P

Ungolfed và giải thích:

Seq.initInfinite (fun _ ->            // Create an infinite sequence, with each element being defined by the following function
    let n = DateTime.Now
    let dayOffset = n.DayOfYear - 4   // Day of year returns the day as a number between 1 and 366
    let today = n - DateTime.Today    // Extract the current day, so the hours, minutes and all
    let partialDay = today.TotalDays  // Get the value of 'today' as a floating point number of days
                                      // so between 0 and 1 in this case - exactly what I needed
    // And now, the formula - note that 0.9856 has been combined with the conversion from degrees to radians, giving 0.0172
    (1. - 0.01672 * Math.Cos (0.0172 * (partialDay + float dayOffset))) * 149597870.691
)
|> Seq.iter (fun i -> printfn "%f" i) // For each of the (infinity of) numbers, print it

1

Toán học, 97 byte

Dynamic[1496*^5-2501*^3Cos[.9856#&@@Now~DateDifference~{DateValue@"Year",1,4}],UpdateInterval->1]

Giải trình

{DateValue@"Year",1,5}đại diện cho ngày 5 tháng 1 năm nay và ...~DateDifference~...đưa ra khoảng cách thời gian.

Dynamic[...,UpdateInterval->1] cập nhật biểu thức một lần mỗi giây.


Chỉ cần nhắc nhở bạn, bạn cần xuất câu trả lời theo km, không phải AU. Tôi cho rằng Mathicala có các bộ chuyển đổi tích hợp để bạn có thể lưu một số byte cho chuyển đổi đơn vị, đúng không?
busukxuan

@busukxuan Tôi đã nhân hệ số cho công thức.
njpipe tổ chức

Oh sry tôi đã bỏ lỡ nó. Không hy vọng nó sẽ có trong 4 con số quan trọng.
busukxuan

2
Ngoài ra,Dynamic[Round[PlanetData["Earth", "DistanceFromSun"]~QuantityMagnitude~"Kilometers"]]
2012rcampion

1

Bình thường, 51 byte

#*149597870.691-1*.01672.t*c-.dZ86400 31558149*2.nZ1

Công thức thay thế

d / AU = 1 - 0,01672 cos (2π [thời gian kể từ khi perihelion] / [chu kỳ quỹ đạo])
Công thức này về cơ bản giống như công thức của OP, ngoại trừ nó được khái quát hóa để có thể sử dụng bất kỳ sự tấn công nào làm ngày tham chiếu.

Công thức của OP có [thời gian kể từ khi perihelion] là (ngày - 4) và có (2π rad / [chu kỳ quỹ đạo]) được tính trước là 0,9856deg / ngày.

Trong giải pháp của tôi, tôi đang sử dụng các điểm cận nhật gần nhất với thời đại Unix, 2 nd tháng 1 năm 1970.

Mật mã

Biên dịch bằng tay cho mã giả pythonic:

#                        while 1:
  *149597870.691             print( 149597870.691 * (                 # implicit print
    -1                           1 - (
      *.01672                        0.1672 * (
        .t                               trigo(
          *                                  multiply(
            c                                    divide(
              -.dZ86400                              unixTime-86400,
              31558149                               31558149
                                                 ),
            *2.nZ                                2*pi
                                             ),
          1                                  1                        # 1 means cos
                             )))))

Điều này về cơ bản chỉ là biến công thức sau thành mã:
d = (1 - 0,01672 cos (2π (t - 86400) / 31558149)) * 149597870.691
trong đó t là thời gian Unix.


1

Python 2,4 - 158 byte

import time,math
while 1:t=time.localtime();print(int(149597870.691*(1-.01672*math.cos(math.radians(.9856*(t[7]+(t[3]*3600+t[4]*60+t[5])/864.0/100.0-4))))))

Mất thời gian địa phương và phun ra khoảng cách. time.localtime () trả về một tuple và có thể được tham chiếu ở đây .


Bạn có thể loại bỏ .0khỏi 864.0100.0để lưu một vài byte?
insertusernamehere

Điều duy nhất tôi lo lắng khi làm điều đó là nó sẽ không còn là một phân chia điểm nổi. Tôi giữ nguyên .0để chúng là dấu phẩy động và không phải là số nguyên.
linkian209

0

C, 338

#include <stdio.h>
#include <time.h>
#include <math.h>
int main ()
{
  time_t rt;
  struct tm * ti;
  while(1) {
  time(&rt);
  ti = localtime(&rt);
  double d = 1.0 - .01672*cos(0.0174533 * .9856*((ti->tm_yday + (ti->tm_hour * 3600.0 + ti->tm_mday * 60.0 + ti->tm_sec) / 86400.0) - 4));
  printf ("%f\n", d * 149598000.0);}
}

3
Chào mừng bạn đến với Câu đố lập trình và Code Golf! Mặc dù đây có vẻ là một câu trả lời đúng, nhưng nó dường như không được đánh gôn nhiều. Đối với các câu hỏi với thẻ [code-golf], câu trả lời cần phải nỗ lực giảm kích thước của chúng càng nhiều càng tốt để được xem xét theo chủ đề - xem trung tâm trợ giúp . Tôi sẽ mong được xem phiên bản chơi gôn! =)
Roujo
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.