À quelle distance est le soleil?

20

introduction

tl; dr

Émet en continu la distance actuelle de la Terre au Soleil.


Simplifiée, l'orbite de la Terre autour du Soleil est une ellipse. La distance réelle entre les deux est donc en constante évolution. Cette distance peut être calculée pour un jour donné en utilisant cette formule :

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

L'équation peut être divisée en les parties suivantes 2 :

  • 1représente 1 UA (unité astronomique), est égal à149,597,870.691 km
  • 0.01672est l' excentricité orbitale entre la Terre et le Soleil
  • cosest bien sûr la fonction cosinus, mais avec un argument en degrés plutôt qu'en radians
  • 0.9856est de 360 ° / 365.256363 jours , une rotation complète en un an, où 365.256363est la longueur d'une année sidérale, en jours solaires moyens
  • day est le jour de l'année [1-365]
  • 4représente le décalage par rapport au périhélie , qui se situe entre le 4 et le 6 janvier

La formule prend une journée entière, mais pour ce défi - une sortie continue - vous devez être plus précis; ou il ne se passera pas grand-chose jusqu'au lendemain. Ajoutez simplement le pourcentage du temps passé au jour actuel, comme 1 :

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

Quelques exemples:

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

Contribution

Ce défi n'a aucune entrée.


Si votre langue ne peut pas obtenir l'heure actuelle, vous pouvez l'obtenir comme entrée dans votre programme. Les entrées valides sont des horodatages ou des chaînes de date-heure complètes qui conviennent le mieux à la langue. Passer seul le jour en cours (comme 5pour le 5 janvier ou 5.25pour le même jour à 6 heures) n'est pas autorisé.

Production

Sortie de la distance actuelle de la Terre au Soleil:

  • Sortez la valeur en km.
  • Mettez à jour la valeur au moins toutes les secondes .

Exemple de sortie:

152098342

Si cela n'augmente pas votre nombre d'octets, vous pouvez également imprimer le résultat:

152,098,342
152,098,342 km

Exigences

  • Vous pouvez écrire un programme ou une fonction. S'il s'agit d'une fonction anonyme, veuillez inclure un exemple de la façon de l'invoquer.
  • C'est le donc la réponse la plus courte en octets gagne.
  • Les failles standard ne sont pas autorisées.

Exemple d'implémentation

J'ai préparé un exemple d'implémentation en JavaScript. Ce n'est ni compétitif ni 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 Pour ne pas augmenter déraisonnablement la complexité, vous n'avez pas besoin de convertir votre heure locale en UTC. Si vous utilisez UTC, veuillez ajouter une note à votre réponse.

2 Pour plus de détails, voir " Distance Terre-Soleil un jour donné de l'année " sur Physics

insertusernamehere
la source
Que doivent faire les langages de programmation qui ne peuvent pas accéder à l'heure actuelle? Comme BF, etc.?
flawr
3
Je crois que votre exemple est incorrect, car Math.cosutilise des radians. Et puisque cette formule semble très approximative, vous devrez être clair sur la façon dont les réponses doivent être vérifiées.
grc
@grc J'ai corrigé l'erreur dans mon exemple - merci de me l'avoir signalé.
insertusernamehere
@flawr Vous pouvez obtenir l'heure en entrée de votre programme. La question est mise à jour en conséquence.
insertusernamehere
1
Je parie que Mathematica en a un intégré!
sergiol

Réponses:

5

TI-BASIC, 38 octets

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

Pour une calculatrice de la série TI-84 +. Nommez ceci prgmA. Notez que cela déborde de la pile après quelques milliers d'itérations; utilisez un à la While 1:...:Endplace si c'est un problème, pour deux octets supplémentaires.

Celui-ci utilise le périhélie le 1er janvier 1997, 23:16 UTC pour référence, et est précis à quelques dizaines de kilomètres (environ 7 chiffres de précision) pour les prochaines années.

lirtosiast
la source
Maintenant, c'est court. Gloire!
insertusernamehere
5

Java - 185180 octets

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

Cela utilise le fait qu'il y a 86 400 secondes dans une journée et utilise l'heure locale, pas GMT. La sortie se produit beaucoup plus d'une fois par seconde. Je ne sais pas si les instructions d'importation doivent être incluses dans le nombre d'octets.

Pour inclure un délai de 1 seconde ajoute environ 26 octets, par exemple

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 n'est certainement pas le langage le plus jouable au golf. :)

Suppression de quelques octets grâce à @insertusernamehere

Robert Benson
la source
1
Agréable. Ne pouvait pas 1.0devenir 1? Et pouvez-vous supprimer le début 0de 0.01672et 0.9856?
insertusernamehere
C'est très vrai, c'est ce que j'obtiens pour le copier-coller de la question: p Je pourrais laisser tomber quelques octets de plus si j'utilisais import staticmais cela pourrait "tricher" ... Je suis encore assez nouveau ici.
Robert Benson
Pourquoi System.err?
SuperJedi224
J'ai utilisé System.errdonc il n'y aurait pas de mise en mémoire tampon. Je sais que le printlnest censé imprimer immédiatement de toute façon, mais cela ne semble pas toujours le faire. Bien sûr, il pourrait être converti en System.out sans changer le nombre d'octets :)
Robert Benson
2
J'ai remarqué que beaucoup de gens oublient de convertir des degrés en radians. Je les commenterais, mais je suis un débutant avec trop peu de représentants: p
Robert Benson
4

Python, 101 octets

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

345600 = 4 * 24 * 3600 (quatre jours)

5022635.53 ≌ (365.256363 * 24 * 3600) / (2π) (secondes dans l'année / 2π)

pacholik
la source
Bienvenue dans Programming Puzzles et Code Golf. Ceci est une bonne solution, +1. Cependant, cela peut améliorer la réponse si vous avez ajouté une version non golfée et commentée, expliquant ce que vous avez fait, ou même simplement ajouté un simple commentaire avant le code.
wizzwizz4
J'obtiens 107 pour le nombre d'octets.
Morgan Thrapp du
Bon, j'ai inclus la dernière nouvelle ligne.
pacholik
Vous pouvez enregistrer 7 octets en combinant les imports: import time,math. De plus, si vous utilisez Python 2, vous pouvez supprimer la parenthèse de print.
PurkkaKoodari du
C'est aussi vrai, avec tout ce PEP, j'ai oublié que c'est possible :)
pacholik
3

Bash / coreutils / bc, 101 octets

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

Ceci calcule le décalage par rapport au 4 janvier en secondes, utilise donc une constante correspondante pour convertir en radians. Une demi-année se transforme en environ pi:

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

Le reste du calcul découle directement de la question.

Toby Speight
la source
Bon travail. Je me demandais si cela bcpouvait être utile. J'ai remarqué que vous en avez dcdans votre en-tête, mais utilisez-le bcdans le code. Je confond souvent les deux moi-même.
Robert Benson
1
Merci, @Robert - J'ai corrigé le titre. J'ai commencé par regarder dc, puis j'ai réalisé que j'avais besoin du mathlib de bc, alors j'avais les deux calculatrices en tête au mauvais moment!
Toby Speight
Oui, j'ai été là, j'ai fait ça. J'oublie toujours lequel est lequel.
Robert Benson
2

F #, 178 octets

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

Il s'agit d'un script F # qui fonctionne bien dans F # Interactive. Par souci de simplicité, l'exigence de "sortie continue" est portée à des niveaux littéraux, bien que j'ai perdu un octet pour faire imprimer la sortie sur une nouvelle ligne à chaque itération afin que ce ne soit pas trop mal. = P

Non golfé et expliqué:

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
la source
1

Mathematica, 97 octets

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

Explication

{DateValue@"Year",1,5}représente le 5 janvier de cette année et ...~DateDifference~...donne la distance temporelle.

Dynamic[...,UpdateInterval->1] mettre à jour l'expression une fois par seconde.

njpipeorgan
la source
Juste pour vous rappeler, vous devez sortir la réponse en km, pas en AU. Je suppose que Mathematica a des convertisseurs intégrés pour que vous puissiez économiser quelques octets pour la conversion d'unité, oui?
busukxuan
@busukxuan J'ai multiplié le coefficient par la formule.
njpipeorgan
Oh, je l'ai raté. Je ne m'attendais pas à ce qu'il soit en 4 chiffres significatifs.
busukxuan
2
Alternativement,Dynamic[Round[PlanetData["Earth", "DistanceFromSun"]~QuantityMagnitude~"Kilometers"]]
2012rcampion
1

Pyth, 51 octets

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

Formule alternative

d / AU = 1 - 0,01672 cos (2π [temps depuis le périhélie] / [période orbitale])
Cette formule est essentiellement la même que la formule du PO, sauf qu'elle est généralisée pour pouvoir utiliser n'importe quel périhélie comme date de référence.

La formule de l'OP a [temps depuis le périhélie] comme (jour - 4) et a (2π rad / [période orbitale]) pré-calculée à 0,9856deg / jour.

Dans ma solution , je suis en utilisant le périhélie le plus proche de l'époque Unix, 2 e Janvier 1970.

Le code

Compilé à la main en pseudocode pythonique:

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

Il s'agit essentiellement de transformer la formule suivante en code:
d = (1 - 0,01672 cos (2π (t - 86400) / 31558149)) * 149597870.691
où t est le temps Unix.

busukxuan
la source
1

Python 2.4 - 158 octets

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

Prend l'heure locale et crache la distance. time.localtime () renvoie un tuple et peut être référencé ici .

linkian209
la source
Pouvez - vous retirer .0de 864.0et 100.0pour sauver quelques octets?
insertusernamehere
La seule chose qui m'inquiète, c'est que ce ne sera plus une division en virgule flottante. J'ai gardé le .0afin qu'ils soient en virgule flottante et non en entier.
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
la source
3
Bienvenue dans Programmation d'énigmes et Code Golf! Bien que cela ressemble à une bonne réponse, cela ne semble pas beaucoup être joué au golf. Pour les questions avec la balise [code-golf], les réponses doivent faire un effort pour réduire leur taille autant que possible pour être considérées sur le sujet - voir le centre d'aide . J'attends avec impatience de voir la version golfée! =)
Roujo