太阳有多远?


20

介绍

tl; dr

连续输出当前从地球到太阳的距离。


简化地说,地球绕太阳的轨道是椭圆形的。因此两者之间的实际距离在不断变化。可以使用以下公式针对任何给定日期计算此距离:

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

该方程可被分成以下几部分2

  • 1代表1 AU(天文单位),等于149,597,870.691 km
  • 0.01672是地球和太阳之间的 轨道偏心率
  • cos当然是余弦函数,但是参数是度数而不是弧度
  • 0.9856360°/ 365.256363天,一年中的完整旋转,这365.256363是恒星年的长度,以平均太阳日为准
  • day 是一年中的一天 [1-365]
  • 4代表距近日点的偏移量,它在1月4日至6日之间

公式需要一整天,但要解决这一挑战(持续输出),您必须更加准确;否则直到第二天什么事情都不会发生。只需将过去时间的百分比添加到当天,例如1

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

几个例子:

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

输入值

这个挑战没有投入。


如果您的语言无法获取当前时间,则可以将其作为程序的输入。有效输入是最适合该语言的时间戳或完整的日期时间字符串。仅通过当天(例如51月5日或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我已修复示例中的错误-感谢您指出该错误。
此处插入用户名,2016年

@flawr您可以将时间用作程序的输入。该问题将相应更新。
此处插入用户名,2016年

1
我敢打赌Mathematica内置了它!
sergiol

Answers:


5

TI-BASIC,38个字节

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

对于TI-84 +系列计算器。为此命名prgmA。请注意,经过数千次迭代后,这会使堆栈溢出。用一个While 1:...:End如果有问题,请代替两个额外的字节。

它以1997年1月1日世界标准时间(UTC)的近日点为参考,并且在接下来的几年内精确到几十公里以内(大约7位数)。


现在这很短。荣誉!
insertusername此处,2016年

5

Java- 185180字节

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绝对不是最适用的语言。:)

感谢@insertusernamehere,删除了几个字节


1
真好 无法1.0成为1?并且您可以00.01672和中删除领导0.9856吗?
insertusername此处,2016年

的确如此,这就是我从问题中获取粘贴的原因:p如果使用的话我可以再丢弃一些字节, import static但这可能是“作弊”……我在这里还是很新的。
罗伯特·本森

为什么选择System.err?
SuperJedi224 '16

我用过,System.err所以不会有缓冲。我知道println无论如何应该立即打印出,但似乎并非总是如此。当然,可以在不更改字节数的情况下将其转换为System.out :)
Robert Benson

2
我注意到许多人都忘记了将度数转换为弧度。我会对它们发表评论,但我是代表很少的新手:p
Robert Benson

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 2016年

我得到107的字节数。
Morgan Thrapp '16

是的,我已经包含了最后一个换行符。
pacholik '16

您可以通过组合imports:保存7个字节import time,math。另外,如果您使用Python 2,则可以从中删除括号print
PurkkaKoodari

同样正确的是,我已经忘记了所有的PEP,这是可能的:)
pacholik 2016年

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

它以秒为单位计算从1月4日开始的偏移量,因此使用相应的常数转换为弧度。半年约等于pi:

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

其余的计算直接来自问题。


不错的工作。我想知道这是否bc有用。我注意到您dc在标头中,但是bc在代码中使用了。我经常把自己混为一谈。
罗伯特·本森

1
谢谢@Robert-我已经确定了标题。我开始研究直流电,然后意识到我需要不列颠哥伦比亚省的mathlib,所以在错误的时刻我都想到了这两个计算器!
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#Interactive中运行良好的F#脚本。为简单起见,尽管我确实丢失了一个字节以使输出在每次迭代时都在新行上打印,但“连续输出”的要求被带到了文字水平,因此并不太可能不错。= P

脱节并解释:

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} 表示今年1月5日,并且 ...~DateDifference~...给出了时间距离。

Dynamic[...,UpdateInterval->1] 每秒更新一次表达式。


提醒您,您需要以公里(而非AU)为单位输出答案。我想Mathematica具有内置转换器,因此您可以为单位转换节省一些字节,是吗?
busukxuan

@busukxuan我已将系数乘以公式。
njpipeorgan

哦,对不起,我错过了。没想到它会以4个重要数字出现。
busukxuan '16

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的公式具有[自近日起的时间]为(day-4),并且具有(2πrad / [轨道周期])的预先计算为0.9856deg / day。

在我的解决方案,我用最接近Unix纪元,2近日点 1970年1月。

代码

手工编译为pythonic伪代码:

#                        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.0100.0保存一些字节吗?
insertusername此处

我唯一担心的是它将不再是浮点除法。我保留了.0它们,所以它们将是浮点数而不是整数。
linkian209 '16

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
欢迎来到编程难题和Code Golf!虽然这看起来像是正确的答案,但似乎并不太适合打高尔夫球。对于带有[code-golf]标签的问题,需要尽最大努力减小答案的大小,以使它们成为主题-请参阅帮助中心。我期待看到高尔夫版本!=)
Roujo
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.