A que distância está o sol?


20

Introdução

tl; dr

Saída contínua da distância atual da Terra ao Sol.


Simplificado, a órbita da Terra ao redor do Sol é uma elipse. Portanto, a distância real entre ambos muda constantemente. Essa distância pode ser calculada para qualquer dia usando esta fórmula :

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

A equação pode ser dividida nas seguintes partes 2 :

  • 1representa 1 AU (unidade astronômica), é igual a149,597,870.691 km
  • 0.01672é a excentricidade orbital entre a Terra e o Sol
  • cosé obviamente a função cosseno, mas com argumentos em graus, em vez de radianos
  • 0.9856é 360 ° / 365.256363 dias , uma rotação completa em um ano, onde 365.256363é a duração de um ano sideral, em dias solares médios
  • day é o dia do ano [1-365]
  • 4representa o deslocamento para o periélio , que é entre 4 e 6 de janeiro

A fórmula leva um dia inteiro, mas para o objetivo desse desafio - uma saída contínua - você precisa ser mais preciso; ou nada vai acontecer até o dia seguinte. Basta adicionar a porcentagem do tempo passado ao dia atual, como 1 :

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

Alguns exemplos:

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

Entrada

Este desafio não tem entrada.


Se o seu idioma não conseguir obter a hora atual, você poderá obtê-la como uma entrada para o seu programa. Entradas válidas são carimbos de data / hora ou seqüências completas de data e hora que melhor se adaptam ao idioma. Passar o dia atual sozinho (como 5em 5 de janeiro ou 5.25no mesmo dia às 6 horas) não é permitido.

Saída

Emita a distância atual da Terra ao Sol:

  • Emita o valor em km.
  • Atualize o valor pelo menos a cada segundo .

Exemplo de saída:

152098342

Se não aumentar sua contagem de bytes, você também pode imprimir o resultado:

152,098,342
152,098,342 km

Exigências

  • Você pode escrever um programa ou uma função. Se for uma função anônima, inclua um exemplo de como invocá-la.
  • Este é o pelo que a resposta mais curta em bytes vence.
  • As brechas padrão não são permitidas.

Implementação de exemplo

Eu preparei um exemplo de implementação em JavaScript. Não é competitivo nem jogado de golfe.

// 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 não aumentar excessivamente a complexidade, você não precisa converter a hora local em UTC. Se você usa o UTC, adicione uma nota à sua resposta.

2 Para mais detalhes, consulte " Distância Terra-Sol em um determinado dia do ano ", em Física


O que as linguagens de programação devem fazer para não acessar o horário atual? Como BF etc?
flawr

3
Acredito que seu exemplo esteja incorreto, pois Math.cosusa radianos. E como essa fórmula parece muito aproximada, você terá que ser claro sobre como as respostas devem ser verificadas.
grc

@grc Corrigi o erro no meu exemplo - obrigado por me apontar para ele.
usar o seguinte comando

@flawr Você pode obter tempo como uma entrada para o seu programa. A pergunta é atualizada de acordo.
usar o seguinte comando

1
Aposto que o Mathematica tem um built-in para isso!
Sergiol # 11/18

Respostas:


5

TI-BASIC, 38 bytes

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

Para uma calculadora da série TI-84 +. Nomeie isso prgmA. Observe que isso excede a pilha após alguns milhares de iterações; use um, While 1:...:Endse isso for um problema, por dois bytes extras.

Ele usa o periélio em 1 de janeiro de 1997, às 23:16 UTC como referência, e tem uma precisão de algumas dezenas de quilômetros (cerca de 7 dígitos de precisão) nos próximos anos.


Agora isso é curto. Parabéns!
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)))));}}

Isso usa o fato de que existem 86.400 segundos em um dia e está usando a hora local, não o GMT. A saída acontece muito mais de uma vez por segundo. Não tenho certeza se as instruções de importação devem ser incluídas na contagem de bytes.

Para incluir um atraso de 1 segundo, adiciona cerca de 26 bytes, por exemplo

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 não é a linguagem mais golfável. :)

Removidos alguns bytes graças a @insertusernamehere


1
Agradável. Não poderia se 1.0tornar 1? E você pode remover a liderança 0de 0.01672e 0.9856?
usar o seguinte comando

É verdade que é o que recebo para copiar e colar da pergunta: p Eu poderia soltar mais alguns bytes se eu usasse, import staticmas isso pode ser "trapaça" ... Ainda sou novo por aqui.
Robert Benson

Por que System.err?
precisa saber é o seguinte

Eu usei System.errpara que não houvesse buffer. Eu sei que printlné suposto imprimir imediatamente de qualquer maneira, mas nem sempre parece fazer isso. Claro que poderia ser convertido para System.out sem alterar a contagem de bytes :)
Robert Benson

2
Percebi que muitas pessoas estão esquecendo de converter de graus em radianos. Eu comentar sobre eles, mas eu sou um novato com muito pouco rep: p
Robert Benson

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 (quatro dias)

5022635,53 ≌ (365,256363 * 24 * 3600) / (2π) (segundos no ano / 2π)


Bem-vindo à programação de quebra-cabeças e código de golfe. Esta é uma boa solução, +1. No entanto, pode melhorar a resposta se você tiver adicionado uma versão não-comentada e comentada, explicando o que você fez ou apenas um comentário simples antes do código.
precisa saber é o seguinte

Recebo 107 pela contagem de bytes.
Morgan Thrapp

Certo, incluí a última nova linha.
Pacholik

Você pode economizar 7 bytes, combinando os imports: import time,math. Além disso, se você usa o Python 2, pode soltar os parênteses print.
PurkkaKoodari

Também é verdade, com tudo isso PEP esqueci é possível :)
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

Isso calcula o deslocamento a partir de 4 de janeiro em segundos, e usa uma constante correspondente para converter em radianos. Meio ano se converte em aproximadamente pi:

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

O restante do cálculo é direto da questão.


Bom trabalho. Gostaria de saber se bcpode ser útil para isso. Percebi que você tem dcno seu cabeçalho, mas use bcno código. Eu muitas vezes confundo os dois.
Robert Benson

1
Obrigado, @Robert - eu consertei o título. Comecei a olhar para dc, depois percebi que precisava do mathlib de bc, então as duas calculadoras estavam em minha mente no momento errado!
Toby Speight

Sim, esteve lá, fez isso. Eu sempre esqueço qual é qual.
Robert Benson

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 é um script F # que roda bem no F # Interactive. Por uma questão de simplicidade, o requisito de "saída contínua" é levado a níveis literais, embora eu tenha perdido um byte para imprimir a saída em uma nova linha a cada iteração, para que não seja muito ruim. = P

Ungolfed e explicou:

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 bytes

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

Explicação

{DateValue@"Year",1,5}representa 5 de janeiro deste ano e ...~DateDifference~...fornece a distância temporal.

Dynamic[...,UpdateInterval->1] atualize a expressão uma vez por segundo.


Só para lembrá-lo, você precisa fornecer a resposta em km, não em AU. Suponho que o Mathematica tenha conversores internos, para que você possa salvar alguns bytes para a conversão da unidade, sim?
busukxuan

@busukxuan Multipliquei o coeficiente para a fórmula.
Njpipeorgan 26/01

Oh sry, eu senti falta disso. Não esperava que fosse em quatro números significativos.
precisa saber é

2
Como alternativa,Dynamic[Round[PlanetData["Earth", "DistanceFromSun"]~QuantityMagnitude~"Kilometers"]]
2012rcampion

1

Pitão, 51 bytes

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

Fórmula alternativa

d / AU = 1 - 0,01672 cos (2π [tempo desde o periélio] / [período orbital])
Esta fórmula é essencialmente a mesma que a fórmula do OP, exceto que é generalizada para poder usar qualquer periélio como data de referência.

A fórmula do OP tem [tempo desde o periélio] como (dia - 4) e tem (2π rad / [período orbital]) pré-calculado como 0,9856deg / dia.

Na minha solução, estou usando o periélio mais próximo da época do Unix, 2 Janeiro de 1970.

O código

Compilado manualmente para pseudocódigo python:

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

Isso é basicamente transformar a seguinte fórmula no código:
d = (1 - 0,01672 cos (2π (t - 86400) / 31558149)) * 149597870.691
onde t é o tempo do Unix.


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

Leva a hora local e cospe a distância. time.localtime () retorna uma tupla e pode ser referenciada aqui .


Você pode remover .0a partir de 864.0e 100.0para economizar alguns bytes?
precisa saber é o seguinte

A única coisa que me preocupa é que não será mais uma divisão de ponto flutuante. Eu mantive o .0para que eles fossem ponto flutuante e não inteiro.
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
Bem-vindo à Programação de Puzzles e Code Golf! Embora isso pareça uma resposta correta, não parece ser muito praticado. Para perguntas com a tag [code-golf], as respostas precisam fazer um esforço para reduzir o tamanho o máximo possível para serem consideradas no tópico - consulte a Central de Ajuda . Estou ansioso para ver a versão do golfe! =)
Roujo 27/01
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.