¿A qué distancia está el sol?

20

Introducción

tl; dr

Salida continua de la distancia actual de la Tierra al Sol.


Simplificado, la órbita de la Tierra alrededor del Sol es una elipse. Entonces, la distancia real entre ambos está cambiando constantemente. Esta distancia se puede calcular para cualquier día usando esta fórmula :

d / AU = 1-0.01672 cos (0.9856 (día-4))

La ecuación se puede dividir en las siguientes partes 2 :

  • 1representa 1 UA (unidad astronómica), igual149,597,870.691 km
  • 0.01672es la excentricidad orbital entre la Tierra y el Sol
  • coses, por supuesto, la función coseno, pero con argumentos en grados en lugar de radianes
  • 0.9856es 360 ° / 365.256363 días , una rotación completa en un año, donde 365.256363es la duración de un año sideral, en días solares medios
  • day es el dia del año [1-365]
  • 4representa el desplazamiento del perihelio , que es entre el 4 y el 6 de enero

La fórmula lleva todo un día, pero para este desafío, una salida continua, debe ser más preciso; o no pasará mucho hasta el día siguiente. Simplemente agregue el porcentaje del tiempo pasado al día actual, como 1 :

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

Algunos ejemplos:

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

Entrada

Este desafío no tiene aportes.


Si su idioma no puede obtener la hora actual, puede obtenerla como entrada para su programa. Las entradas válidas son marcas de tiempo o cadenas completas de fecha y hora que se adaptan mejor al idioma. No está permitido pasar el día actual solo (como el 55 de enero o 5.25el mismo día a las 6 en punto).

Salida

Salida de la distancia actual de la Tierra al Sol:

  • Salida del valor en km.
  • Actualice el valor al menos cada segundo .

Salida de ejemplo:

152098342

Si no aumenta su número de bytes, también puede imprimir bastante el resultado:

152,098,342
152,098,342 km

Requisitos

  • Puedes escribir un programa o una función. Si es una función anónima, incluya un ejemplo de cómo invocarla.
  • Este es el por lo que la respuesta más corta en bytes gana.
  • Las lagunas estándar no están permitidas.

Implementación de ejemplo

He preparado un ejemplo de implementación en JavaScript. No es competitivo ni golfista.

// 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 Para no aumentar injustificadamente la complejidad, no tiene que convertir su hora local a UTC. Si usa UTC, agregue una nota a su respuesta.

2 Para más detalles, consulte " Distancia entre la Tierra y el Sol en un día determinado del año " en Física

insertusernamehere
fuente
¿Qué deben hacer los lenguajes de programación que no puedan acceder a la hora actual? ¿Como BF, etc.?
flawr
3
Creo que su ejemplo es incorrecto, ya que Math.cosusa radianes. Y dado que esta fórmula parece muy aproximada, tendrá que tener claro cómo deben verificarse las respuestas.
grc
@grc He arreglado el error en mi ejemplo, gracias por señalarme.
insertusernamehere
@flawr Puede obtener el tiempo como entrada para su programa. La pregunta se actualiza en consecuencia.
insertusernamehere
1
¡Apuesto a que Mathematica tiene una función incorporada!
sergiol

Respuestas:

5

TI-BASIC, 38 bytes

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

Para una calculadora de la serie TI-84 +. Nombra esto prgmA. Tenga en cuenta que esto desborda la pila después de unos pocos miles de iteraciones; use un While 1:...:Enden su lugar si esto es un problema, para dos bytes adicionales.

Utiliza el perihelio el 1 de enero de 1997 a las 23:16 UTC como referencia, y tiene una precisión de unas pocas docenas de kilómetros (aproximadamente 7 dígitos de precisión) para los próximos años.

lirtosiast
fuente
Ahora esto es corto. ¡Prestigio!
insertusernamehere
5

Java - 185 180 bytes

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

Esto utiliza el hecho de que hay 86,400 segundos en un día y está usando la hora local, no GMT. La salida ocurre mucho más de una vez por segundo. No estoy seguro si las declaraciones de importación deben incluirse en el recuento de bytes.

Para incluir un retraso de 1 segundo se agregan unos 26 bytes, por ejemplo

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 definitivamente no es el lenguaje más golfable. :)

Se eliminaron algunos bytes gracias a @insertusernamehere

Robert Benson
fuente
1
Agradable. No pudo 1.0ser 1? ¿Y puedes eliminar el líder 0de 0.01672y 0.9856?
insertusernamehere
Muy cierto, eso es lo que obtengo por copiar y pegar de la pregunta: p Podría eliminar algunos bytes más si lo usara, import staticpero eso podría ser "trampa" ... Todavía soy bastante nuevo aquí.
Robert Benson el
¿Por qué System.err?
SuperJedi224
Lo usé System.errpara que no hubiera buffering. Sé que printlnse supone que se imprime inmediatamente de todos modos, pero no siempre parece hacerlo. Por supuesto, podría convertirse a System.out sin cambiar el recuento de bytes :)
Robert Benson el
2
He notado que muchas personas se están olvidando de convertir de grados a radianes. Yo comentaría sobre ellos, pero soy un novato con muy poca reputación: p
Robert Benson el
4

Python, 101 bytes

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

345600 = 4 * 24 * 3600 (cuatro días)

5022635.53 ≌ (365.256363 * 24 * 3600) / (2π) (segundos en año / 2π)

pacholik
fuente
Bienvenido a Programming Puzzles y Code Golf. Esta es una buena solución, +1. Sin embargo, puede mejorar la respuesta si agregaste una versión no comentada y comentada, explicando lo que has hecho, o incluso si solo agregaste un comentario simple antes del código.
wizzwizz4
Tengo 107 para el recuento de bytes.
Morgan Thrapp
Bien, he incluido la última línea nueva.
pacholik
Puede guardar 7 bytes mediante la combinación de las imports: import time,math. Además, si usa Python 2, puede quitar el paréntesis print.
PurkkaKoodari
También es cierto, con todo ese PEP que he olvidado es posible :)
pacholik
3

Bash / coreutils / bc, 101 bytes

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

Esto calcula el desplazamiento desde el 4 de enero en segundos, por lo que utiliza una constante correspondiente para convertir a radianes. Medio año se convierte en aproximadamente pi:

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

El resto del cálculo es directamente de la pregunta.

Toby Speight
fuente
Buen trabajo. Me preguntaba si bcpodría ser útil para esto. Me di cuenta de que tiene dcen su encabezado, pero lo usa bcen el código. A menudo los confundo a los dos.
Robert Benson el
1
Gracias, @Robert. He arreglado el título. Comencé a mirar DC, luego me di cuenta de que necesitaba el mathlib de BC, ¡así que tenía las dos calculadoras en mi mente en el momento equivocado!
Toby Speight
Sí, he estado allí, hecho eso. Siempre olvido cuál es cuál.
Robert Benson el
2

F #, 178 bytes

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

Este es un script de F # que funciona bien en F # Interactive. En aras de la simplicidad, el requisito de "salida continua" se lleva a niveles literales, aunque perdí un byte para hacer que la salida se imprima en una nueva línea cada iteración para que no sea tan malo. = P

Ungolfed y explicó:

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
fuente
1

Mathematica, 97 bytes

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

Explicación

{DateValue@"Year",1,5}representa el 5 de enero de este año, y ...~DateDifference~...da la distancia temporal.

Dynamic[...,UpdateInterval->1] Actualice la expresión una vez por segundo.

njpipeorgan
fuente
Solo para recordarle, debe enviar la respuesta en km, no en AU. Supongo que Mathematica tiene convertidores incorporados para que pueda guardar algunos bytes para la conversión de la unidad, ¿sí?
busukxuan
@busukxuan He multiplicado el coeficiente por la fórmula.
njpipeorgan
Oh sry, me lo perdí. No esperaba que fuera en 4 cifras significativas.
busukxuan
2
Alternativamente,Dynamic[Round[PlanetData["Earth", "DistanceFromSun"]~QuantityMagnitude~"Kilometers"]]
2012rcampion
1

Pyth, 51 bytes

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

Fórmula alternativa

d / AU = 1 - 0.01672 cos (2π [tiempo desde el perihelio] / [período orbital])
Esta fórmula es esencialmente la misma que la fórmula del OP, excepto que está generalizada para poder usar cualquier perihelio como fecha de referencia.

La fórmula del OP tiene [tiempo desde el perihelio] como (día - 4) y tiene (2π rad / [período orbital]) precalculado como 0.9856deg / día.

En mi solución Estoy utilizando el perihelio más cercano a la época Unix, 2 nd de enero de 1970.

El código

Compilado a mano a pseudocódigo pitónico:

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

Esto es esencialmente convertir la siguiente fórmula en código:
d = (1 - 0.01672 cos (2π (t - 86400) / 31558149)) * 149597870.691
donde t es el tiempo Unix.

busukxuan
fuente
1

Python 2.4 - 158 bytes

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

Toma la hora local y escupe la distancia. time.localtime () devuelve una tupla y se puede hacer referencia aquí .

linkian209
fuente
Se puede eliminar .0desde 864.0y 100.0para ahorrar unos pocos bytes?
insertusernamehere
Lo único que me preocupa al hacerlo es que ya no será una división de coma flotante. Mantuve el .0para que fueran punto flotante y no entero.
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
fuente
3
¡Bienvenido a Programming Puzzles y Code Golf! Si bien esto parece una respuesta correcta, no parece que se juegue demasiado. Para preguntas con la etiqueta [code-golf], las respuestas deben hacer un esfuerzo para reducir su tamaño tanto como sea posible para ser consideradas en el tema; consulte el centro de ayuda . ¡Espero ver la versión de golf! =)
Roujo