Quanto dista il sole?


20

introduzione

tl; dr

Emetti continuamente la distanza corrente dalla Terra al Sole.


Semplificata, l'orbita della Terra attorno al Sole è un'ellisse. Quindi la distanza effettiva tra i due cambia costantemente. Questa distanza può essere calcolata per un dato giorno usando questa formula :

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

L'equazione può essere suddivisa nelle seguenti parti 2 :

  • 1rappresenta 1 UA (unità astronomica), uguale a149,597,870.691 km
  • 0.01672è l' eccentricità orbitale tra la Terra e il Sole
  • cosè ovviamente la funzione del coseno, ma con argomento in gradi piuttosto che radianti
  • 0.9856è 360 ° / 365.256363 giorni , una rotazione completa in un anno, dove 365.256363è la lunghezza di un anno siderale, in giorni solari medi
  • day è il giorno dell'anno [1-365]
  • 4rappresenta la compensazione con il perielio , che è tra il 4 e il 6 gennaio

La formula richiede un'intera giornata ma ai fini di questa sfida - un risultato continuo - devi essere più preciso; o non succederà molto fino al giorno successivo. Aggiungi semplicemente la percentuale del tempo passato al giorno corrente, come 1 :

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

Alcuni esempi:

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

Ingresso

Questa sfida non ha input.


Se la tua lingua non è in grado di ottenere l'ora corrente, puoi ottenerla come input per il tuo programma. Gli input validi sono timestamp o stringhe di data e ora complete che si adattano meglio alla lingua. Passare il giorno corrente da solo (come 5per il 5 gennaio o 5.25per lo stesso giorno alle 6) non è permesso.

Produzione

Emetti la distanza corrente dalla Terra al Sole:

  • Emette il valore in km.
  • Aggiorna il valore almeno ogni secondo .

Esempio di output:

152098342

Se non aumenta il numero di byte, puoi anche stampare piuttosto il risultato:

152,098,342
152,098,342 km

Requisiti

  • È possibile scrivere un programma o una funzione. Se si tratta di una funzione anonima, si prega di includere un esempio di come invocarlo.
  • Questo è quindi la risposta più breve in byte vince.
  • Le scappatoie standard non sono ammesse.

Esempio di implementazione

Ho preparato un'implementazione di esempio in JavaScript. Non è né competitivo né 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 Per non aumentare irragionevolmente la complessità, non è necessario convertire l'ora locale in UTC. Se usi UTC, aggiungi una nota alla tua risposta.

2 Per maggiori dettagli, vedi " Distanza Terra-Sole in un determinato giorno dell'anno " in Fisica


Cosa dovrebbero fare i linguaggi di programmazione che non possono accedere all'ora corrente? Come BF ecc?
flawr

3
Credo che il tuo esempio sia errato, poiché Math.cosutilizza i radianti. E poiché questa formula sembra molto approssimativa, dovrai essere chiaro su come verificare le risposte.
GRC

@grc Ho corretto l'errore nel mio esempio, grazie per avermi indicato.
inserisci nomeutentequi

@flawr Puoi ottenere il tempo come input per il tuo programma. La domanda viene aggiornata di conseguenza.
inserire nomeutentequi

1
Scommetto che Mathematica ha un built-in per questo!
sergiol,

Risposte:


5

TI-BASIC, 38 byte

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

Per una calcolatrice serie TI-84 +. Nomina questo prgmA. Si noti che questo trabocca lo stack dopo alcune migliaia di iterazioni; utilizzare un While 1:...:Endinvece se questo è un problema, per due byte extra.

Questo utilizza il perielio il 1 ° gennaio 1997, alle 23:16 UTC come riferimento, ed è preciso entro poche decine di chilometri (circa 7 cifre di precisione) per i prossimi anni.


Ora questo è breve. Complimenti!
inserireusernamehere il

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

Questo utilizza il fatto che ci sono 86.400 secondi in un giorno e utilizza l'ora locale, non GMT. L'output avviene molto più di una volta al secondo. Non sono sicuro se le istruzioni di importazione debbano essere incluse nel conteggio dei byte.

Per includere un ritardo di 1 secondo si aggiungono circa 26 byte ad es

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 sicuramente non è il linguaggio più giocabile. :)

Rimossi pochi byte grazie a @insertusernamehere


1
Bello. Non potresti 1.0diventare 1? E puoi rimuovere il comando 0da 0.01672e 0.9856?
inserisci nomeutentequi

È vero, questo è quello che ottengo per copia-incolla dalla domanda: p Potrei lasciare qualche byte in più se lo usassi, import staticma potrebbe essere "imbroglione" ... Sono ancora piuttosto nuovo qui.
Robert Benson,

Perché System.err?
SuperJedi224,

Ho usato System.errquindi non ci sarebbe stato buffering. So che printlndovrebbe stampare immediatamente comunque, ma non sempre sembra farlo. Naturalmente potrebbe essere convertito in System.out senza modificare il conteggio dei byte :)
Robert Benson,

2
Ho notato che molte persone dimenticano di convertirsi da gradi a radianti. Vorrei commentarli, ma sono un principiante con un rappresentante troppo piccolo: 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 (quattro giorni)

5022635,53 ≌ (365.256363 * 24 * 3600) / (2π) (secondi nell'anno / 2π)


Benvenuti in Programming Puzzle and Code Golf. Questa è una buona soluzione, +1. Tuttavia, potrebbe migliorare la risposta se hai aggiunto una versione non modificata e commentata, spiegando cosa hai fatto, o hai anche aggiunto un semplice commento prima del codice.
wizzwizz4,

Ottengo 107 per il conteggio dei byte.
Morgan Thrapp,

Bene, ho incluso l'ultima riga.
Pacholik,

È possibile salvare 7 byte combinando le imports: import time,math. Inoltre, se si utilizza Python 2 è possibile eliminare la parentesi print.
PurkkaKoodari,

Anche vero, con tutto quel PEP che ho dimenticato è possibile :)
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

Questo calcola l'offset dal 4 gennaio in secondi, quindi utilizza una costante corrispondente per convertire in radianti. Un anno e mezzo si converte in circa pi:

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

Il resto del calcolo è direttamente dalla domanda.


Bel lavoro. Mi chiedevo se bcpotesse essere utile per questo. Ho notato che hai dcnell'intestazione, ma usa bcnel codice. Confondo spesso i due da solo.
Robert Benson,

1
Grazie, @Robert - Ho risolto il titolo. Ho iniziato a guardare DC, poi ho capito che avevo bisogno di Math Math, quindi avevo entrambi i calcolatori in mente nel momento sbagliato!
Toby Speight,

Sì, ci sono stato, l'ho fatto. Dimentico sempre quale è quale.
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")

Questo è uno script F # che funziona bene in F # Interactive. Per semplicità, il requisito "output continuo" è portato a livelli letterali, anche se ho perso un byte per far stampare l'output su una nuova riga ogni iterazione in modo che non fosse troppo male. = P

Ungolfed e spiegato:

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]

Spiegazione

{DateValue@"Year",1,5}rappresenta il 5 gennaio di quest'anno e ...~DateDifference~...indica la distanza temporale.

Dynamic[...,UpdateInterval->1] aggiorna l'espressione una volta al secondo.


Solo per ricordarti, devi fornire la risposta in km, non in UA. Suppongo che Mathematica abbia convertitori integrati in modo da poter salvare alcuni byte per la conversione dell'unità, sì?
Busukxuan,

@busukxuan Ho moltiplicato il coefficiente per la formula.
njpipeorgan,

Oddio, l'ho perso. Non mi aspettavo che fosse in 4 cifre significative.
Busukxuan,

2
In alternativa,Dynamic[Round[PlanetData["Earth", "DistanceFromSun"]~QuantityMagnitude~"Kilometers"]]
Campion 2012

1

Pyth, 51 byte

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

Formula alternativa

d / AU = 1 - 0,01672 cos (2π [tempo dal perielio] / [periodo orbitale])
Questa formula è essenzialmente la stessa della formula del PO, tranne che è generalizzata per poter usare qualsiasi perielio come data di riferimento.

La formula del PO ha [tempo dal perielio] come (giorno - 4) e ha (2π rad / [periodo orbitale]) pre-calcolato come 0,9856 gradi / giorno.

Nella mia soluzione Sto usando il perielio più vicino all'epoca Unix, 2 ° gennaio 1970.

Il codice

Compilato a mano in pseudocodice pitonico:

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

Questo essenzialmente sta trasformando la seguente formula in codice:
d = (1 - 0,01672 cos (2π (t - 86400) / 31558149)) * 149597870,691
dove t è il tempo 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))))))

Prende l'ora locale e sputa la distanza. time.localtime () restituisce una tupla e può essere referenziato qui .


È possibile rimuovere .0da 864.0e 100.0per salvare qualche byte?
inserireusernamehere il

L'unica cosa di cui sono preoccupato nel farlo è che non sarà più una divisione in virgola mobile. Ho mantenuto il .0modo che fossero in virgola mobile e non interi.
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
Benvenuti in Puzzle di programmazione e Code Golf! Mentre questa sembra una risposta corretta, non sembra essere molto giocata a golf. Per domande con il tag [code-golf], le risposte devono fare uno sforzo per ridurne il più possibile le dimensioni per essere considerate sull'argomento - consultare il centro assistenza . Non vedo l'ora di vedere la versione da golf! =)
Roujo,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.