Как далеко Солнце?


20

Вступление

ТЛ; др

Постоянно выводить текущее расстояние от Земли до Солнца.


Упрощенно, орбита Земли вокруг Солнца является эллипсом. Таким образом, фактическое расстояние между ними постоянно меняется. Это расстояние можно рассчитать для любого данного дня, используя эту формулу :

д / д = 1-0,01672 cos (0,9856 (день 4))

Уравнение можно разбить на следующие части 2 :

  • 1представляет 1 AU (астрономическая единица), равно149,597,870.691 km
  • 0.01672это орбитальный эксцентриситет между Землей и Солнцем
  • cosконечно функция косинуса, но с аргументом в градусах, а не в радианах
  • 0.9856составляет 360 ° / 365,256363 дней , полный оборот за один год, где 365.256363длина сидерического года, в средних солнечные дни
  • day это день года [1-365]
  • 4представляет смещение перигелия , которое находится между 4 и 6 января

Формула занимает целый день, но для решения этой задачи - непрерывного вывода - вам нужно быть более точным; или ничего особенного не произойдет до следующего дня. Просто добавьте процент прошедшего времени к текущему дню, например 1 :

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

Несколько примеров:

  • 1 января 23:59:59 1.99998842592593
  • 1 января, 18:00:00 1.75
  • 1 января, 12:00:00 1.50
  • 1 января, 06:00:00 1.25

вход

Этот вызов не имеет вклада.


Если ваш язык не может получить текущее время, вы можете получить его в качестве входных данных для вашей программы. Допустимые входные данные - это метки времени или полные строки даты и времени, которые лучше всего подходят для языка. Прохождение текущего дня в одиночку (например, 55 января или 5.25в тот же день в 6 часов) не допускается.

Выход

Выведите текущее расстояние от Земли до Солнца:

  • Выведите значение в km.
  • Обновите значение по крайней мере каждую секунду .

Пример вывода:

152098342

Если это не увеличивает количество байт, вы также можете распечатать результат:

152,098,342
152,098,342 km

Требования

  • Вы можете написать программу или функцию. Если это анонимная функция, пожалуйста, включите пример того, как ее вызвать.
  • Это поэтому выигрывает самый короткий ответ в байтах.
  • Стандартные лазейки запрещены.

Пример реализации

Я подготовил пример реализации в JavaScript. Это ни соревнование, ни игра в гольф.

// 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 Чтобы не чрезмерно увеличивать сложность, вам не нужно переводить местное время в UTC. Если вы используете UTC, пожалуйста, добавьте примечание к вашему ответу.

2 Более подробную информацию см. В разделе « Расстояние Земля-Солнце в определенный день года» в разделе « Физика».


Что должны делать языки программирования, которые не могут получить доступ к текущему времени? Как BF и т. Д.?
flawr

3
Я считаю, что ваш пример неверен, так как Math.cosиспользует радианы. И поскольку эта формула кажется очень приблизительной, вам нужно будет четко определить, как нужно проверять ответы.
GRC

@grc Я исправил ошибку в своем примере - спасибо, что указал мне на это.
insertusername здесь

@flawr Вы можете получить время в качестве входных данных для вашей программы. Вопрос обновляется соответственно.
insertusername здесь

1
Бьюсь об заклад, Mathematica имеет встроенный для этого!
sergiol

Ответы:


5

TI-BASIC, 38 байт

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

Для калькулятора серии TI-84 +. Назовите это prgmA. Обратите внимание, что это переполняет стек после нескольких тысяч итераций; используйте While 1:...:Endвместо этого, если это проблема, для двух дополнительных байтов.

При этом для справки используется перигелий 1 января 1997 года, 23:16 UTC, и с точностью до нескольких десятков километров (около 7 цифр точности) в течение следующих нескольких лет.


Теперь это коротко. Престижность!
insertusername здесь

5

Ява - 185 180 байт

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

При этом используется тот факт, что в дне 86 400 секунд, и используется местное время, а не время по Гринвичу. Вывод происходит гораздо чаще, чем раз в секунду. Не уверен, что операторы импорта должны быть включены в число байтов.

Для включения задержки в 1 секунду добавляется около 26 байтов, например

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

Ява определенно не самый подходящий для игры язык. :)

Удалено несколько байтов благодаря @insertusernameherehere


1
Ницца. Не мог 1.0стать 1? И можете ли вы удалить ведущие 0из 0.01672и 0.9856?
insertusername здесь

Совершенно верно, это то, что я получаю для копирования-вставки из вопроса: p Я мог бы отбросить еще несколько байтов, если бы использовал, import staticно это могло бы быть "обманом" ... Я все еще довольно новичок здесь.
Роберт Бенсон

Почему System.err?
SuperJedi224

Я использовал, System.errчтобы не было никакой буферизации. Я знаю, что printlnв любом случае предполагается, что печать должна выполняться немедленно, но, похоже, это не всегда происходит. Конечно, его можно преобразовать в System.out без изменения количества байтов :)
Роберт Бенсон

2
Я заметил, что многие люди забывают перевести градусы в радианы. Я бы прокомментировал их, но я новичок со слишком маленьким представителем: p
Роберт Бенсон

4

Python, 101 байт

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

345600 = 4 * 24 * 3600 (четыре дня)

5022635,53 ≌ (365,256363 * 24 * 3600) / (2π) (секунды в году / 2π)


Добро пожаловать в Программирование головоломок и Code Golf. Это хорошее решение, +1. Однако, это может улучшить ответ, если вы добавили версию без комментариев и комментариев, объяснили, что вы сделали, или даже просто добавили простой комментарий перед кодом.
wizzwizz4

Я получаю 107 за счет байтов.
Морган Трепп

Хорошо, я включил последний перевод строки.
pacholik

Вы можете сэкономить 7 байт, комбинируя importS: import time,math. Кроме того, если вы используете Python 2, вы можете удалить скобки из print.
PurkkaKoodari

Также верно, со всем этим PEP я забыл, что это возможно :)
pacholik

3

Bash / coreutils / bc, 101 байт

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

Это вычисляет смещение от 4 января в секундах, поэтому использует соответствующую константу для преобразования в радианы. Пол года превращается примерно в пи:

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

Остальная часть расчета прямо из вопроса.


Хорошая работа. Я задавался вопросом, bcможет ли это быть полезным для этого. Я заметил, что у вас есть dcв вашем заголовке, но использовать bcв коде. Я часто путаю их обоих.
Роберт Бенсон

1
Спасибо, @Robert - я исправил название. Я начал смотреть на dc, потом понял, что мне нужна математика bc, поэтому оба калькулятора были у меня в голове в неподходящий момент!
Тоби Спейт

Да, был там, сделал это. Я всегда забываю, что есть что.
Роберт Бенсон

2

F #, 178 байт

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

Это скрипт F #, который хорошо работает в F # Interactive. Для простоты требование «непрерывного вывода» перенесено на буквальный уровень, хотя я потерял байт, чтобы выводить вывод на новую строку каждую итерацию, чтобы он не был слишком плохим. = Р

Разгромил и объяснил:

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 байт

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

объяснение

{DateValue@"Year",1,5}представляет 5 января этого года, и ...~DateDifference~...дает временную дистанцию.

Dynamic[...,UpdateInterval->1] обновлять выражение один раз в секунду.


Просто чтобы напомнить вам, вам нужно вывести ответ в км, а не в АС. Я предполагаю, что Mathematica имеет встроенные конвертеры, чтобы вы могли сэкономить несколько байтов для преобразования единиц, да?
busukxuan

@busukxuan Я умножил коэффициент на формулу.
njpipeorgan

Ох, простите, я пропустил это. Не ожидал, что это будет в 4 значимых цифрах.
busukxuan

2
В качестве альтернативыDynamic[Round[PlanetData["Earth", "DistanceFromSun"]~QuantityMagnitude~"Kilometers"]]
2012rcampion

1

Pyth, 51 байт

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

Альтернативная формула

d / AU = 1 - 0,01672 cos (2π [время с перигелия] / [орбитальный период])
Эта формула, по сути, такая же, как формула OP, за исключением того, что она обобщена, чтобы иметь возможность использовать любой перигелий в качестве контрольной даты.

Формула OP имеет [время с перигелия] как (день - 4) и имеет (2π рад / [орбитальный период]), предварительно рассчитанный как 0,9856 градусов в день.

В моем решении я использую перигелий ближе всего к эпохе Unix, 2 - го января 1970 года.

Код

Собранный вручную в питонический псевдокод:

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

По сути, это просто превращение следующей формулы в код:
d = (1 - 0,01672 cos (2π (t - 86400) / 31558149)) * 149597870.691,
где t - время Unix.


1

Python 2,4 - 158 байт

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

Занимает местное время и выплевывает расстояние. time.localtime () возвращает кортеж и на него можно ссылаться здесь .


Вы можете удалить .0из 864.0и 100.0сэкономить несколько байт?
insertusername здесь

Единственное, что меня беспокоит, так это то, что это больше не будет делением с плавающей запятой. Я сохранил, .0чтобы они были с плавающей точкой, а не целое число.
linkian209

0

С, 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
Добро пожаловать в Программирование Пазлов и Code Golf! Хотя это выглядит как правильный ответ, похоже, что это не слишком удачно. Для вопросов с тегом [code-golf] необходимо приложить усилия, чтобы максимально уменьшить их размер, чтобы их можно было рассматривать по теме - см. Справочный центр . Я с нетерпением жду возможности увидеть версию для гольфа! =)
Ружо
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.