Jak daleko jest Słońce?

20

Wprowadzenie

tl; dr

Ciągle wysyłaj aktualną odległość od Ziemi do Słońca.


Uproszczona orbita Ziemi wokół Słońca jest elipsą. Rzeczywista odległość między nimi ciągle się zmienia. Odległość tę można obliczyć dla dowolnego dnia za pomocą tego wzoru :

d / AU = 1-0,01672 cos (0,9856 (dzień-4))

Równanie można podzielić na następujące części 2 :

  • 1reprezentuje 1 AU (jednostka astronomiczna), jest równy149,597,870.691 km
  • 0.01672to ekscentryczność orbity między Ziemią a Słońcem
  • cosjest oczywiście funkcją cosinus, ale z argumentami w stopniach, a nie w radianach
  • 0.9856wynosi 360 ° / 365.256363 dni , pełny obrót w ciągu jednego roku, gdzie 365.256363jest długość roku gwiazdowego, w średnich dniach słonecznych
  • day jest dniem roku [1-365]
  • 4reprezentuje przesunięcie w stosunku do peryhelium , które przypada między 4 a 6 stycznia

Formuła trwa cały dzień, ale w celu sprostania temu wyzwaniu - ciągłej wydajności - musisz być bardziej dokładny; albo nic więcej się nie wydarzy do następnego dnia. Po prostu dodaj procent czasu przeszłego do bieżącego dnia, na przykład 1 :

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

Kilka przykładów:

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

Wejście

To wyzwanie nie ma wkładu.


Jeśli twój język nie może uzyskać aktualnego czasu, możesz go uzyskać jako dane wejściowe do swojego programu. Poprawne dane wejściowe to znaczniki czasu lub pełne ciągi daty i godziny, które najlepiej pasują do języka. Minięcie bieżącego dnia samemu (jak 5na 5 stycznia lub 5.25tego samego dnia o godzinie 6) jest niedozwolone.

Wynik

Wyjście aktualnej odległości od Ziemi do Słońca:

  • Podaj wartość w km.
  • Aktualizuj wartość przynajmniej co sekundę .

Przykładowe dane wyjściowe:

152098342

Jeśli nie zwiększy to liczby bajtów, możesz również całkiem wydrukować wynik:

152,098,342
152,098,342 km

Wymagania

  • Możesz napisać program lub funkcję. Jeśli jest to funkcja anonimowa, podaj przykład jej wywołania.
  • To jest więc wygrywa najkrótsza odpowiedź w bajtach.
  • Standardowe luki są niedozwolone.

Przykładowa implementacja

Przygotowałem przykładową implementację w JavaScript. Nie jest konkurencyjny ani golfowy.

// 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 Aby nieracjonalnie zwiększyć złożoności, nie musisz przeliczać czasu lokalnego na UTC. Jeśli korzystasz z UTC, dodaj notatkę do swojej odpowiedzi.

2 Aby uzyskać więcej informacji, patrz „ Odległość Ziemia-Słońce w danym dniu roku ” w Physics

wstawić nazwę tutaj
źródło
Co powinny robić języki programowania, które nie mają dostępu do aktualnego czasu? Jak BF itp?
flawr
3
Uważam, że twój przykład jest niepoprawny, ponieważ Math.cosużywa radianów. A ponieważ ta formuła wydaje się bardzo przybliżona, musisz wyjaśnić, w jaki sposób należy weryfikować odpowiedzi.
grc
@grc Naprawiłem błąd w moim przykładzie - dziękuję za wskazanie mi go.
inserttusernamehere
@flawr Możesz uzyskać czas jako wkład do swojego programu. Pytanie jest odpowiednio aktualizowane.
inserttusernamehere 25.01.16
1
Założę się, że Mathematica ma wbudowaną funkcję!
sergiol

Odpowiedzi:

5

TI-BASIC, 38 bajtów

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

Do kalkulatora serii TI-84 +. Nazwij to prgmA. Zauważ, że to przepełnia stos po kilku tysiącach iteracji; użyj While 1:...:Endzamiast tego, jeśli jest to problem, dla dwóch dodatkowych bajtów.

Wykorzystuje peryhelium 1 stycznia 1997 r., 23:16 UTC w celach informacyjnych i jest dokładny z dokładnością do kilkudziesięciu kilometrów (około 7 cyfr dokładności) przez kilka następnych lat.

lirtosiast
źródło
To jest krótkie. Sława!
inserttusernamehere
5

Java - 185 180 bajtów

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

Wykorzystuje to fakt, że dziennie jest 86 400 sekund i używa czasu lokalnego, a nie GMT. Wyjście odbywa się znacznie częściej niż raz na sekundę. Nie jestem pewien, czy instrukcje importu powinny być uwzględnione w liczbie bajtów.

Uwzględnienie 1-sekundowego opóźnienia dodaje około 26 bajtów, np

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 zdecydowanie nie jest najbardziej golfowym językiem. :)

Usunięto kilka bajtów dzięki @insertusernameherehere

Robert Benson
źródło
1
Ładny. Nie mogłeś 1.0się stać 1? Czy możesz usunąć wiodące pozycje 0z 0.01672i 0.9856?
inserttusernamehere
Bardzo prawda, właśnie to otrzymuję z kopiuj-wklej z pytania: p Gdybym użył, mógłbym upuścić jeszcze więcej bajtów, import staticale to może być „oszukiwanie” ... Nadal jestem tu nowy.
Robert Benson
Dlaczego System.err?
SuperJedi224,
Użyłem, System.errwięc nie byłoby buforowania. Wiem, że i printlntak powinien drukować natychmiast, ale nie zawsze tak się dzieje. Oczywiście można go przekonwertować na System.out bez zmiany liczby bajtów :)
Robert Benson
2
Zauważyłem, że wiele osób zapomina o konwersji ze stopni na radiany. Skomentowałbym je, ale jestem nowicjuszem ze zbyt małym przedstawicielem: p
Robert Benson
4

Python, 101 bajtów

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

345600 = 4 * 24 * 3600 (cztery dni)

5022635,53 ≌ (365.256363 * 24 * 3600) / (2π) (sekundy w roku / 2π)

pacholik
źródło
Witamy w Programowaniu zagadek i Code Golf. To dobre rozwiązanie, +1. Może to jednak poprawić odpowiedź, jeśli dodałeś wersję bez komentarza i komentowania, wyjaśniając, co zrobiłeś, lub po prostu dodałeś prosty komentarz przed kodem.
wizzwizz4,
Dostaję 107 za liczbę bajtów.
Morgan Thrapp,
Tak, załączyłem ostatnią nową linię.
pacholik
Można zaoszczędzić 7 bajtów łącząc imports: import time,math. Ponadto, jeśli używasz języka Python 2, możesz usunąć nawias print.
PurkkaKoodari
Również prawda, z całym tym PEP zapomniałem, że to możliwe :)
pacholik
3

Bash / coreutils / bc, 101 bajtów

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

To oblicza przesunięcie od 4 stycznia w sekundach, więc używa odpowiedniej stałej do konwersji na radiany. Pół roku zmienia się w mniej więcej pi:

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

Reszta obliczeń pochodzi wprost z pytania.

Toby Speight
źródło
Dobra robota. Zastanawiałem się, czy bcmoże to być przydatne. Zauważyłem, że masz dcw nagłówku, ale użyj bcw kodzie. Często sam siebie mylę.
Robert Benson
1
Dzięki, @Robert - Naprawiłem tytuł. Zacząłem patrzeć na dc, a potem zdałem sobie sprawę, że potrzebuję mathlib bc, więc miałem oba kalkulatory w głowie w niewłaściwym momencie!
Toby Speight
Tak, byłem tam, zrobiłem to. Zawsze zapominam, która jest która.
Robert Benson
2

F #, 178 bajtów

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")

To jest skrypt F #, który działa dobrze w F # Interactive. Dla uproszczenia wymóg „ciągłego drukowania” jest przenoszony na poziomy dosłowne, chociaż straciłem bajt, aby wydruk był wyświetlany w nowej linii przy każdej iteracji, aby nie było tak źle. = P

Nie golfił i wyjaśnił:

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
Roujo
źródło
1

Mathematica, 97 bajtów

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

Wyjaśnienie

{DateValue@"Year",1,5}reprezentuje 5 stycznia tego roku i ...~DateDifference~...podaje dystans czasowy.

Dynamic[...,UpdateInterval->1] aktualizuj wyrażenie raz na sekundę.

njpipeorgan
źródło
Aby przypomnieć, musisz podać odpowiedź w kilometrach, a nie w AU. Podejrzewam, że Mathematica ma wbudowane konwertery, więc możesz zaoszczędzić trochę bajtów na konwersji jednostek, tak?
busukxuan
@busukxuan Mnożyłem współczynnik do wzoru.
njpipeorgan
Och, przepraszam, przegapiłem to. Nie spodziewałem się, że będzie to 4 znaczące liczby.
busukxuan
2
Alternatywnie,Dynamic[Round[PlanetData["Earth", "DistanceFromSun"]~QuantityMagnitude~"Kilometers"]]
2012rcampion
1

Pyth, 51 bajtów

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

Alternatywna formuła

d / AU = 1 - 0,01672 cos (2π [czas od peryhelium] / [okres obiegu orbitalnego])
Ta formuła jest zasadniczo taka sama jak formuła PO, z tym że uogólnia się, aby móc użyć dowolnego peryhelium jako daty odniesienia.

Formuła OP ma [czas od peryhelium] jako (dzień - 4) i ma (2π rad / [okres obiegu orbitalnego]) wstępnie obliczone jako 0,9856 stopni / dzień.

W moim rozwiązanie używam peryhelium najbliższą epoki Uniksa, 2 -go stycznia 1970 r.

Kod

Ręcznie skompilowany do pseudokodu pythonowego:

#                        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
                             )))))

Zasadniczo jest to po prostu przekształcenie następującej formuły w kod:
d = (1 - 0,01672 cos (2π (t - 86400) / 31558149)) * 149597870.691
gdzie t jest czasem uniksowym.

busukxuan
źródło
1

Python 2.4 - 158 bajtów

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

Zajmuje czas lokalny i wypluwa dystans. time.localtime () zwraca krotkę i można się do niej odwoływać tutaj .

linkian209
źródło
Można usunąć .0z 864.0i 100.0zaoszczędzić kilka bajtów?
inserttusernamehere
Martwię się tylko tym, że nie będzie to już podział zmiennoprzecinkowy. Trzymałem .0tak, żeby były zmiennoprzecinkowe, a nie całkowite.
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);}
}
samt1903
źródło
3
Witamy w Programowaniu zagadek i Code Golf! Chociaż wydaje się to prawidłową odpowiedzią, wydaje się, że nie jest zbyt mocno golfa. W przypadku pytań z tagiem [code-golf] odpowiedzi muszą starać się zmniejszyć ich rozmiar tak bardzo, jak to możliwe, aby były rozważane na temat - patrz centrum pomocy . Nie mogę się doczekać, aby zobaczyć wersję w golfa! =)
Roujo