Seberapa jauh Matahari?


20

pengantar

tl; dr

Terus menampilkan jarak saat ini dari Bumi ke Matahari.


Sederhana, orbit Bumi di sekitar Matahari adalah elips. Jadi jarak yang sebenarnya antara keduanya terus berubah. Jarak ini dapat dihitung untuk hari tertentu menggunakan rumus ini :

d / AU = 1-0.01672 cos (0,9856 (hari ke-4))

Persamaan dapat dibagi menjadi bagian-bagian 2 berikut :

  • 1mewakili 1 AU (unit astronomi), sama dengan149,597,870.691 km
  • 0.01672adalah eksentrisitas orbit antara Bumi dan Matahari
  • costentu saja fungsi cosinus, tetapi dengan argumen dalam derajat daripada radian
  • 0.9856adalah 360 ° / 365,256363 hari , rotasi penuh dalam satu tahun, di mana 365.256363panjang tahun sidereal, dalam rata-rata hari matahari
  • day adalah hari dalam setahun [1-365]
  • 4mewakili offset ke perihelion , yaitu antara 4 dan 6 Januari

Formula ini membutuhkan satu hari penuh tetapi untuk tujuan tantangan ini - hasil yang terus menerus - Anda harus lebih akurat; atau tidak banyak yang akan terjadi sampai hari berikutnya. Cukup tambahkan persentase dari waktu lampau ke hari saat ini, seperti 1 :

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

Beberapa Contoh:

  • 1 Januari, 23:59:59 1.99998842592593
  • 1 Januari, 18:00:00 1.75
  • 1 Januari, 12:00:00 1.50
  • 1 Januari, 06:00:00 1.25

Memasukkan

Tantangan ini tidak memiliki input.


Jika bahasa Anda tidak bisa mendapatkan waktu saat ini, Anda bisa mendapatkannya sebagai masukan untuk program Anda. Input yang valid adalah cap waktu atau string tanggal-waktu lengkap yang paling sesuai dengan bahasa. Melewati hari ini saja (seperti 5untuk 5 Januari atau 5.25untuk hari yang sama pukul 6) tidak diperbolehkan.

Keluaran

Keluarkan jarak saat ini dari Bumi ke Matahari:

  • Keluarkan nilai dalam km.
  • Perbarui nilainya setidaknya setiap detik .

Contoh output:

152098342

Jika tidak meningkatkan jumlah byte Anda, Anda juga dapat mencetak hasilnya:

152,098,342
152,098,342 km

Persyaratan

  • Anda dapat menulis suatu program atau fungsi. Jika ini adalah fungsi anonim, harap sertakan contoh cara memintanya.
  • Ini adalah sehingga jawaban terpendek dalam byte menang.
  • Celah standar tidak diijinkan.

Contoh implementasi

Saya sudah menyiapkan contoh implementasi dalam JavaScript. Ini tidak kompetitif atau golf.

// 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 Untuk tidak menambah kerumitan tanpa alasan, Anda tidak perlu mengubah waktu lokal Anda ke UTC. Jika Anda menggunakan UTC, harap tambahkan catatan untuk jawaban Anda.

2 Untuk lebih jelasnya lihat " Jarak Bumi-Matahari pada hari tertentu dalam setahun " di Fisika


Apa yang harus dilakukan oleh bahasa pemrograman yang tidak dapat mengakses waktu saat ini? Seperti BF dll?
flawr

3
Saya percaya contoh Anda salah, karena Math.cosmenggunakan radian. Dan karena rumus ini tampaknya sangat perkiraan, Anda harus jelas tentang bagaimana jawaban harus diverifikasi.
grc

@ grc Saya telah memperbaiki kesalahan dalam contoh saya - terima kasih telah menunjukkannya.
masukkan nama pengguna di sini

@ flawr Anda bisa mendapatkan waktu sebagai input ke program Anda. Pertanyaannya diperbarui sesuai.
masukkan nama pengguna di sini

1
Saya yakin Mathematica memiliki bawaan untuk itu!
sergiol

Jawaban:


5

TI-BASIC, 38 byte

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

Untuk kalkulator TI-84 + series. Beri nama ini prgmA. Perhatikan bahwa ini meluap tumpukan setelah beberapa ribu iterasi; gunakan While 1:...:Endsebaliknya jika ini merupakan masalah, untuk dua byte tambahan.

Ini menggunakan perihelion pada 1 Januari 1997, 23:16 UTC untuk referensi, dan akurat dalam beberapa lusin kilometer (sekitar 7 digit akurasi) untuk beberapa tahun ke depan.


Sekarang ini singkat. Pujian!
masukkan nama pengguna di sini

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)))));}}

Ini menggunakan fakta bahwa ada 86.400 detik dalam sehari dan menggunakan waktu setempat, bukan GMT. Output terjadi jauh lebih dari sekali per detik. Tidak yakin apakah pernyataan impor harus dimasukkan dalam jumlah byte.

Untuk memasukkan penundaan 1 detik, tambahkan sekitar 26 byte misalnya

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 jelas bukan bahasa yang paling golf. :)

Dihapus beberapa byte berkat @insertusernamehere


1
Bagus. Tidak bisa 1.0menjadi 1? Dan bisakah Anda menghapus yang memimpin 0dari 0.01672dan 0.9856?
masukkan nama pengguna di sini

Sangat benar, itulah yang saya dapatkan untuk copy-paste dari pertanyaan: p Saya bisa menjatuhkan beberapa byte lagi jika saya gunakan import statictetapi itu mungkin "curang" ... Saya masih agak baru di sini.
Robert Benson

Mengapa System.err?
SuperJedi224

Saya menggunakan System.errsehingga tidak akan ada buffering. Saya tahu printlnseharusnya mencetak segera, tapi sepertinya tidak selalu begitu. Tentu saja itu dapat dikonversi ke System.out tanpa mengubah jumlah byte :)
Robert Benson

2
Saya perhatikan bahwa banyak orang lupa untuk beralih dari derajat ke radian. Saya akan mengomentari mereka, tapi saya seorang pemula dengan terlalu sedikit perwakilan: 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 (empat hari)

5022635.53 ≌ (365.256363 * 24 * 3600) / (2π) (detik dalam tahun / 2π)


Selamat datang di Programming Puzzles and Code Golf. Ini adalah solusi yang bagus, +1. Namun, ini dapat meningkatkan jawaban jika Anda menambahkan versi yang tidak diklik dan dikomentari, menjelaskan apa yang telah Anda lakukan, atau bahkan hanya menambahkan komentar sederhana sebelum kode.
wizzwizz4

Saya mendapatkan 107 untuk jumlah byte.
Morgan Thrapp

Benar, saya sudah memasukkan baris baru terakhir.
pacholik

Anda dapat menyimpan 7 byte dengan menggabungkan imports: import time,math. Juga, jika Anda menggunakan Python 2, Anda dapat menghapus kurung dari print.
PurkkaKoodari

Juga benar, dengan semua PEP yang saya lupa itu mungkin :)
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

Ini menghitung offset dari 4 Januari dalam hitungan detik, jadi gunakan konstanta yang sesuai untuk mengkonversi ke radian. Setengah tahun dikonversi menjadi kira-kira pi:

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

Sisa perhitungannya langsung dari pertanyaan.


Pekerjaan yang baik. Saya bertanya-tanya apakah bcmungkin bermanfaat untuk ini. Saya perhatikan bahwa Anda ada dcdi header Anda, tetapi gunakan bcdalam kode. Saya sering membingungkan keduanya sendiri.
Robert Benson

1
Terima kasih, @Robert - Saya telah memperbaiki judulnya. Saya mulai melihat dc, kemudian menyadari bahwa saya memerlukan bc's mathlib, begitu juga kedua kalkulator di pikiran saya pada saat yang salah!
Toby Speight

Yap, pernah ke sana, melakukan itu. Saya selalu lupa yang mana.
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")

Ini adalah skrip F # yang berjalan dengan baik di F # Interactive. Demi kesederhanaan, persyaratan "output terus menerus" dibawa ke tingkat literal, meskipun saya kehilangan satu byte untuk membuat output cetak pada baris baru setiap iterasi sehingga tidak terlalu buruk. = P

Tidak digabungkan dan dijelaskan:

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

Mathematica, 97 byte

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

Penjelasan

{DateValue@"Year",1,5}mewakili 5 Januari tahun ini, dan ...~DateDifference~...memberikan jarak temporal.

Dynamic[...,UpdateInterval->1] perbarui ekspresi satu kali per detik.


Hanya untuk mengingatkan Anda, Anda perlu menampilkan jawabannya dalam km, bukan AU. Saya kira Mathematica memiliki konverter bawaan sehingga Anda dapat menyimpan beberapa byte untuk konversi unit, ya?
busukxuan

@busukxuan Saya telah mengalikan koefisien dengan rumus.
njpipeorgan

Oh, ayolah aku melewatkannya. Tidak mengharapkan itu dalam 4 angka signifikan.
busukxuan

2
Atau,Dynamic[Round[PlanetData["Earth", "DistanceFromSun"]~QuantityMagnitude~"Kilometers"]]
Arcampion

1

Pyth, 51 byte

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

Formula alternatif

d / AU = 1 - 0,01672 cos (2π [waktu sejak perihelion] / [periode orbital])
Rumus ini pada dasarnya sama dengan rumus OP, kecuali itu digeneralisasikan untuk dapat menggunakan perihelion sebagai tanggal referensi.

Formula OP memiliki [waktu sejak perihelion] sebagai (hari - 4) dan memiliki (2π rad / [periode orbital]) yang telah dihitung sebelumnya sebagai 0,9856deg / hari.

Dalam solusi saya Saya menggunakan perihelion paling dekat dengan zaman Unix, 2 nd Januari 1970.

Kode

Dikompilasi dengan tangan ke pseudocode 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
                             )))))

Ini pada dasarnya hanya mengubah rumus berikut menjadi kode:
d = (1 - 0,01672 cos (2π (t - 86400) / 31558149)) * 149597870.691 di
mana t adalah waktu 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))))))

Mengambil waktu setempat dan meludahkan jarak. time.localtime () mengembalikan tuple dan dapat dirujuk di sini .


Bisakah Anda menghapus .0dari 864.0dan 100.0untuk menyimpan beberapa byte?
masukkan nama pengguna di sini

Satu-satunya hal yang saya khawatirkan dengan melakukan itu adalah bahwa itu tidak akan lagi menjadi divisi floating point. Saya menjaga .0agar mereka menjadi floating point dan bukan integer.
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
Selamat Datang di Programming Puzzles dan Code Golf! Walaupun ini sepertinya jawaban yang benar, sepertinya tidak banyak bermain golf. Untuk pertanyaan dengan tag [golf-kode], jawaban perlu berupaya mengurangi ukurannya sebanyak mungkin untuk dipertimbangkan sesuai topik - lihat pusat bantuan . Saya akan menantikan untuk melihat versi golf! =)
Roujo
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.