帮助诺文模拟重力!


9

诺特温想研究在均匀重力场中从高处抛出的物体的运动学,但是不幸的是,他没有技术上的可能性去足够高的地方并在跌落时观察物体。但是谁不想看到科学的进步,那么……让我们来帮助Notwen建立一个重力模拟器吧!

物理背景

物体从高处掉落 h没有初始速度)在均匀的引力场中,而忽略了诸如风阻或风等大气影响,会获得速度并随着时间的推移而加速向地面移动。单位时间内速度的这种“变化率”称为重力加速度。在地球表面附近,它大约等于g9.8ms2,但出于此挑战的目的,我们将使用该值 10ms2,意味着一秒钟内一个物体的速度增加了大约 10ms。考虑身高h,是的倍数 100m 并想象将那个高度分成相等的间隔,每个间隔 100米长。Notwen想要测量物体落入每个间隔所需的时间,因此这也是我们要计算的目标。现代运动学 -跳过技术知识-告诉我们:

Δhk=vktk+12gtk2
哪里 ΔhkΔh=100m 对于的所有值 k 就我们而言 vk 是我们开始时的初始速度 kth 间隔和 tk 是持续时间 kth 时间间隔(仅供参考,索引从 0v0=0)。我们也知道vk 具有以下表达式:
vk=2g(Δh0+Δh1++Δhk1)=2gkΔh
在数值上,我们得到 vk=2000kms 并插入第一个方程并求解 tk
(*)tk=25(k+1k)s
因此,物体经过第一个间隔(k=0)在 4.4721s,第二个间隔(k=1)在 1.8524s等等(具有更多值的pastebin)。

挑战

输入:高度h 从哪个对象抛出该对象:的正整数倍 100h 间隔数N=h100 (所以 700 要么 7 意味着 h=700m)–哪个取决于您。

输出:坠落物体的ASCII艺术动画,从高处掉落h (详细信息如下)。

输出帧的结构必须如下:

  • N在“地面”之前的换行符,由至少一个非空白字符(例如@)表示。地面上的至少一个字符必须位于物体落在的垂直线上。
  • 另一个非空白字符代表对象(例如X),而不是您为地面选择的字符。
  • 可选地,每行开头的字符代表垂直轴或在其上制成的墙N线。只要在框架之间保持一致,并且在墙壁和物体之间有任何间距,任何大小的前后间距都可以。有效帧的示例包括1(用于h=700m 要么 N=7):
    | X                                       >
    |                             @           >   A
    |                                         >
    |        or            or           or    > 
    |               O                         >
    |                                         >
    |                                         >
    @@@             ^           -----            &&&
    

对象必须从第一帧的第一行开始,然后在 t04.47s输出应该被刷新,并且您的程序应该在相同的垂直方向上但在第二帧的下一行上显示对象;然后t11.85s输出应再次刷新,并且程序应在相同的垂直方向上显示该对象,但在第三帧的下一行上以此类推,以此类推,直到该对象到达地面上方的那一行为止。例:

动画范例

规则

  • 输出应该是一些写入交互式(可冲洗)控制台的文本,一个GIF,每帧的单独文件或某种其他合理的输出技术。
  • 每个帧应完全覆盖最后一个帧,并且应位于同一位置。
  • 您可以假设编译器/解释器输出文本所需的时间可以忽略不计,并且计算平方根所允许的最小精度为2个小数位。
  • 您可以通过任何标准方法进行输入并提供输出,同时请注意,默认情况下,这些漏洞是禁止的。这是,因此请尝试以您可以选择的语言管理的最少字节来完成任务。

1:我对有效框架的构成很宽容,因为我想允许任何最适合您解决方案的东西,而我并不想在挑战中添加多余的内容。如果不清楚,请在评论中提出。

Answers:


3

JavaScript(ES7)+ CSS + HTML,340字节

f=n=>{o.style.height=n+'em';x.style.animationDuration=(n*20)**.5+'s';o.appendChild(x,x.remove())}
pre{position:relative;border:1px solid;height:5em;overflow:hidden}span{position:absolute;top:0;animation:x 10s cubic-bezier(0.33,0,0.67,0.33)both}@keyframes x{to{top:100%}}
<input type=number value=5 oninput=f(this.value)><pre id=o><span id=x>X

如果我计算正确,则动画持续时间为 20N 然后由CSS三次贝塞尔曲线完成其余的工作。


2

木炭,28字节

Nθ↓θ⁴Fθ«J²ιPXR⌊×φ×₂²⁰⁻₂⊕ι₂ι 

在线尝试!链接是详细版本的代码。注意:尾随空格。您可以观察到TIO上的延迟,但是您无法观看动画,因此必须从输出中想象一下。注意到N作为输入。说明:

Nθ

输入N

↓θ⁴

打印墙壁和地面,以使输出的形状一致。

Fθ«

循环遍历每个间隔。

J²ιPX

将放置X在适当的高度。

R⌊×φ×₂²⁰⁻₂⊕ι₂ι

输出当前的画布内容,并等待适当的时间(截断为最接近的毫秒)。

 

X用空格覆盖。


2

Perl 6,81个字节

{say "\e[s{"\n"x$_}-";map {say "\e[u{" \n"x 4.9e-6*$_²}o";sleep .01},^452*.sqrt}

“在线尝试!”,但TIO无法处理动画。

说明

我选择了一些不同的方法(尽管不确定,我认为这样做会更好)。我没有在OP中公式给定的时间里睡觉,而是绘制了“每10毫秒”(由引起的±误差sleep)的适当情况。

这意味着每秒有100帧,所以如果我们用 k, 一定是 t=k/100。由于我们将垂直距离分为100米块,因此我们可以将高度写为h=100n,在哪里 n是块的数量(作为输入)。高度随时间推移t 是(谁)给的 h=gt2/2,因此经过的块数为

n=110012gt2=12g×106k24.905×106k2.
我们可以将其求反以获取需要渲染的帧总数:
k=n4.905×106452×n.

这足以编写函数。它需要一个参数,即要渲染的块数,即n。首先,我们做say "\e[s{"\n"x$_}-"。打印出一个名为Save Cursor的ANSI转义序列,然后打印n换行符,然后,它打印一个破折号(地面)和换行符。(这使用了Perl 6中双引号的酷功能:您可以将任何代码的结果直接内联到字符串中,方法是将这些代码写在花括号内。)

之后,我们从0到 452n(自动截断为整数)^452*.sqrt,然后我们对其进行映射。在每次迭代中,我们打印一个Unsave Cursor ANSI序列(将光标置于上次保存的位置),然后编写4.9×106k2字符串“ space + newline”(再次自动被截断),最后o是表示对象的。然后我们睡10毫秒,冲洗并重复。

由于具有自动截断功能,因此它仅执行正确的操作™,并且仅在每跌落100 m后才移动“ o”。

产生的动画


1

Haskell,145个字节

import Control.Concurrent
a!b=[a..b]>>"\n"
f h=mapM(\k->putStr("\27[2J"++1!k++'O':k!h++"-")>>threadDelay(round$4472135*(sqrt(k+1)-sqrt k)))[1..h]

需要在ANSI终端中运行。输入的是间隔数。

threadDelay的参数以纳秒为单位,因此文字4472135比短2*sqrt 5*10^6。不幸的46**4 = 4477456是不在要求的精度范围内。


1

Python 2中,117个120 123字节

-3个字节感谢“不要成为X三重点”和“乔纳森·弗雷奇”

import time
h=input()
for k in range(h):print'\33[2J'+'\n'*k+'O'+'\n'*(h-k)+'^';time.sleep(2*5**.5*((k+1)**.5-k**.5))

在线尝试!

在此处输入图片说明


1
向我+1,很好的解决方案!使用实际的不可打印字符会节省几个字节而不是chr(27)吗?
Xcoder先生19年

@ Don'tbeax-tripledot如果一个人不了解角色本身,则'\33'应该更短一些。
乔纳森·弗雷希

另外,2*5**.520**.5
乔纳森·弗雷奇

@JonathanFrech 20的平方根替换为4.47
mdahmoune

@mdahmoune好吧……如果该精度足够好,那就可以了。
乔纳森·弗雷希

1

C#(.NET Core)201,180 + 13 = 193字节

需要使用系统;13个额外的字节。

奇怪的是,Console.Clear()在TIO上似乎对我不起作用。但是,这可以在VS2017下的控制台应用程序中完美运行。

编辑:由于无知的体现缩短了循环,指出了我不必要的变量分配和不必要的使用System.Threading; 声明(VS复制的剩余部分),并指出需要地面!到目前为止,总共增加了8个字节的高尔夫球空间。泰!

x=>{for(var j=x;j>0;System.Threading.Thread.Sleep((int)(4470*(Math.Sqrt(x-j+1)-Math.Sqrt(x-j--))))){Console.Clear();Console.Write("X".PadLeft(x-j+1,'\n').PadRight(x+1,'\n')+"-");}}

在线尝试!

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.