Як далеко знаходиться Сонце?


20

Вступ

тл; д-р

Постійно виводить поточну відстань від Землі до Сонця.


Спрощено, орбіта Землі навколо Сонця - це еліпс. Тож фактична відстань між обома постійно змінюється. Ця відстань може бути розрахована за будь-який день за цією формулою :

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

Рівняння можна розділити на наступні частини 2 :

  • 1являє собою 1 АС (астрономічна одиниця), дорівнює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 тощо?
недолік

3
Я вважаю, що ваш приклад є невірним, оскільки Math.cosвикористовує радіани. А оскільки ця формула здається дуже приблизною, вам доведеться зрозуміти, як відповідати, щоб перевірити.
grc

@grc Я усунув помилку в своєму прикладі - дякую, що вказав на мене.
вставтекористування

@flawr Ви можете отримати час як вхід до вашої програми. Питання оновлено відповідно.
вставитикористувач туди

1
Б'юсь об заклад, що в Mathematica є вбудована версія для цього!
Серхіол

Відповіді:


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 цифр точності) протягом наступних кількох років.


Зараз це коротко. Кудо!
insertusernamehere

5

Java - 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 секунд і використовується місцевий час, а не GMT. Вихід відбувається набагато частіше, ніж раз на секунду. Не впевнені, чи слід включати заяви про імпорт у кількість байтів.

Для включення затримки на 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){}}

Java, безумовно, не найголовніша мова. :)

Видалено кілька байтів завдяки @insertusernameтут


1
Приємно. Не міг 1.0стати 1? А ви можете видалити провідні 0з 0.01672і 0.9856?
insertusernamehere

Дуже правда, ось що я отримую від copy-paste з питання: p Я міг би скинути ще декілька байтів, якби я використав, import staticале це може бути "обманом" ... Я все ще досить новий.
Роберт Бенсон

Чому System.err?
SuperJedi224

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

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

4

Пітон, 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π)


Ласкаво просимо до головоломки програмування та коду для гольфу. Це хороше рішення, +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, потім зрозумів, що мені потрібен mathlib bc, тому мав обидва калькулятори в моїй свідомості в неправильний момент!
Toby Speight

Так, робив це. Я завжди забуваю, що є.
Роберт Бенсон

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

Математика, 97 байт

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

Пояснення

{DateValue@"Year",1,5}представляє 5 січня цього року і ...~DateDifference~...дає часову відстань.

Dynamic[...,UpdateInterval->1] оновлюйте вираз один раз на секунду.


Нагадую, відповідь потрібно виводити в км, а не AU. Я припускаю, що в Mathematica є вбудовані перетворювачі, щоб ви могли зберегти кілька байт для перетворення одиниці, так?
busukxuan

@busukxuan Я помножив коефіцієнт на формулу.
njpipeorgan

О, се, я пропустив це. Не очікував, що це буде у 4 значущих цифрах.
busukxuan

2
Як варіант,Dynamic[Round[PlanetData["Earth", "DistanceFromSun"]~QuantityMagnitude~"Kilometers"]]
2012р. Кампіон,

1

Pyth, 51 байт

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

Чергова формула

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

Формула ОП [час з періоду] як (день - 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заощадити кілька байт?
вставитикористувач туди

Єдине, про що я хвилююся, - це більше не буде поділом з плаваючою комою. Я зберігав .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] відповіді потрібно докласти зусиль, щоб максимально зменшити їх розмір, щоб їх можна було розглядати на тему - див. Довідковий центр . Я буду з нетерпінням чекати побачити версію для гольфу! =)
Рухо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.