奈史密斯法则


12

奈史密斯的规则有助于计算出步行或徒步旅行所需的时间长度(考虑到距离和上升情况)。

给定沿路径平均间隔的点处的高度的非空列表以及该路径的总距离(以米为单位),您应该根据奈史密斯规则计算所需的时间。

奈史密斯(Naismith)的规则是,每五公里应该允许一个小时,而每上升600米,则需要增加一个小时。

输入必须以米为单位,保证由非负整数组成,并且输出应始终为小时或分钟(但不能同时为两者),并且在适用的情况下必须能够提供十进制数字(浮点数可以确定) 。

例如,给定:

[100, 200, 400, 200, 700, 400], 5000

对于前两个元素,[100, 200]您有100米的上升路程,即10分钟。在[200, 400]您有200米的上升距离(即20分钟)的情况下,[400, 200]它不会上升,因此不会为此增加时间。[200, 700]是500米的上升,这是50分钟,最后[700, 400]没有上升。五公里的距离增加了一个小时。总计140分钟或2.333 ...小时。

测试用例

[0, 600] 2500 -> 1.5 OR 90
[100, 200, 300, 0, 100, 200, 300] 10000 -> 2.8333... OR 170
[40, 5, 35] 1000 -> 0.25 OR 15
[604] 5000 -> 1 OR 60
[10, 10, 10] 2000 -> 0.4 OR 24
[10, 25, 55] 1000 -> 0.275 OR 16.5

测试用例的输出全部都有完整的结果,这是故意的吗?输入是否类似[10], 5125[10, 25, 55], 1000有效且需要处理?
sundar-恢复莫妮卡

@sundar是的,他们应该。
Okx

[10, 25, 55], 1000 -> 0.275 OR 16.5
Khuldraeseth na'Barya

Answers:


6

R 44  43 42字节

function(A,D)sum(pmax(0,diff(A)),D*.12)/10

在线尝试!

-1字节pmax用作其他多个答案

将输入作为A气味和D等距,并以分钟为单位返回时间。

function(A,D)                                 # take Ascent and Distance
                        diff(A)               # take successive differences of ascents
                 pmax(0,       )              # get the positive elements of those
                                 D*.12        # multiply distance by 0.12
             sum(               ,     )       # take the sum of all elements
                                       /10    # and divide by 10, returning the result

您可以使用pryr :: f(sum(pmax(0,diff(A)),D * .12)/ 10)而不是使用函数来获得4个字节
Shayne03,18年

@ Shayne03会从技术上将此答案更改为“ R + pryr”,根据网站的规则,该答案将被视为与基本R不同的语言,因此我将保持原样。还是)感谢你的建议!
朱塞佩

说明的形状像小山
user70585 '18

3

JavaScript(ES6),50个字节

感谢Giuseppe的回答,节省了1个字节(在过程结束时除以10)

将输入作为([altitudes])(distance)。以分钟为单位返回时间。

a=>d=>a.map(p=n=>d-=(x=p-(p=n))<0&&x,d*=.12)&&d/10

在线尝试!


2

05AB1E,15个字节

¥ʒ0›}OT÷s₄;6//+

在线尝试!

以分钟为单位返回时间。

说明

              + # sum of ...
¥ʒ0›}OT÷        # the sum of positive deltas of the altitude divided by 10
        s₄;6//  # the distance divided by 83.33333333 (500/6, or the amount of meters per minute) 

几乎正是我的想法。唯一的区别我是₄12//不是₄;6//。我很明显+1。
凯文·克鲁伊森


2

Python 2,62 60字节

由于ovs,节省了2个字节。

lambda e,d:sum((a-b)*(a>b)for a,b in zip(e[1:],e))*.1+d*.012

在线尝试!

以分钟为单位返回时间。

# add all increasing slope differences together
sum(
    # multiply the difference by 0 if a<b, else by 1
    (a-b)*(a>b)
                # create a list of pairs by index, like [(1,0), (2,1) ...(n, n-1)]
                # then interate thru the pairs where a is the higher indexed item and b is the lower indexed item
                for a,b in zip(e[1:],e)
    )
    # * 60 minutes / 600 meters == .1 min/m
    *.1 
    # 60 minutes / 5000 meters = .012 min/m
    +d*.012


2

Perl 645 39 37字节

感谢Jo King,节省了6个字节。

感谢nwellnhof,节省了2个字节。

(感谢他们俩,这看起来不再像我最初提交的内容:-)。

*.&{sum (.skip Z-$_)Xmax 0}/600+*/5e3

在线尝试!

第一个参数是带有高程的列表,第二个参数是跋涉的长度。

整个过程是一个WhateverCode。如果这样识别一个表达式,则每个表达式*都是一个参数。

因此,在中*.&{sum (.skip Z-$_)Xmax 0}/600,我们采用第一个参数(的第一次出现*),并在其上使用类似方法的构造块.&{}。该块采用一个参数(列表),该参数进入$_,因此.skip没有第一个元素的列表也是如此。我们使用逐个元素地减去原始数组Z-。较短的列表耗尽后,压缩就会停止,这是可以的。

然后,我们使用叉积运算符Xlist X(op) list创建所有可能的对,其中第一个元素来自左侧列表,第二个元素来自右侧,并(op)在其上使用运算符。结果作为Seq(单发列表)返回。但是,右边的列表只有一个元素0,因此它只是一个元素一个* max 0元素。这样可以确保我们仅计算跋涉的升序部分。然后我们将其相加并除以600。

然后我们加上*/5e3*第二次出现的位置是第二个参数,然后将其除以5000。总和就是以小时为单位的时间。(这比以分钟为单位的时间效率更高,因为我们需要相乘,并且*需要与WhateverStar之间用空格隔开*。)



@JoKing,很好用X,谢谢!
拉米利斯

1
实际上,我们可以X/通过将总和除以10 来避免最后一个。39个字节
Jo King

使用WhateverCode和的37个字节.&{}(返回小时)。
nwellnhof

2

OK,21字节

{y+/0|1_-':x}..1.012*

在线尝试!滥用解析错误,.1.012该错误与相同.1 .012

              .1.012* /a = [0.1 * input[0], 0.012 * input[1]]
{           }.        /function(x=a[0], y=a[1])
      1_-':x          /  a = subtract pairs of elements from x
    0|                /  a = max(a, 0) w/ implicit map
 y+/                  /  y + sum(a)

-1感谢streester

k,23个字节

{.1*(.12*y)++/0|1_-':x}

在线尝试!


{y+/0|1_-':x}..1.012*21个字节?从开始累加y
streetster '18

确实!我会对k代码应用类似的增强功能,但不幸的是,我拥有的k解释器(2016.08.09)不喜欢我以任何方式启动累加器。:/
zgrep



1

Pyth,15个字节

c+*E.12s>#0.+QT

完整程序,期望将高度作为第一个参数,将距离作为第二个参数。以分钟为单位返回时间。

在此处在线尝试,或在此处一次验证所有测试用例。

c+*E.12s>#0.+QT   Implicit: Q=input 1, E=input 2
           .+Q    Take the differences between each height point
        >#0       Filter to remove negative values
       s          Take the sum
  *E.12           Multiply the distance by 0.12
 +                Add the two previous results
c             T   Divide the above by 10, implicit print

1

APL(Dyalog Unicode)21 20 18字节

.1×.12⊥⎕,-+/0⌊2-/

在线尝试!

传统功能将输入(从右到左)作为1st ⎕=高度/深度,2nd ⎕=距离。

由于@ngn的是一个精灵一个三个字节。

怎么运行的:

.1×.12⊥⎕,-+/0⌊2-/  Function;
                   Append 0 to the heights vector;
              2-/  ⍝ Pairwise (2) differences (-/);
            0      Minimum between 0 and the vector's elements;
          +/       ⍝ Sum (yields the negated total height);
         -         ⍝ Subtract from;
   .12⊥⎕,          ⍝ Distance × 0.12;
.1×                ⍝ And divide by 10;

感谢“向导” :)您不必多次复制表达式即可对其进行测试,而只需将其放入tradfn中即可,0是不必要的,对于有问题的测试应该是,604,而不是604
ngn

瞧,这就是为什么你是一个向导。多次复制表达式部分完全是我的错,我只是用旧代码替换了and 并且懒得放置tradfn标头/页脚。虽然,0有点?金。
J.Sallé18年

0

Java 8,89字节

a->n->{int s=0,p=0,i=a.length;for(;i-->0;p=a[i])s+=(p=p-a[i])>0?p:0;return s/10+n/500*6;}

在线尝试。

说明:

a->n->{                   // Method with integer-array and integer parameter and integer return-type
  int s=0,                //  Sum-integers, starting at 0
      p=0,                //  Previous integer, starting at 0
  i=a.length;for(;i-->0;  //  Loop `i` backwards over the array
                 ;        //    After every iteration:
                  p=a[i]) //     Set `p` to the current value for the next iteration
    s+=(p=p-a[i])>0?      //   If the previous minus current item is larger than 0:
         p                //    Add that difference to the sum `s`
        :                 //   Else:
         0;               //    Leave the sum the same
   return s/10            //  Return the sum integer-divided by 10
          +n/500*6;}      //  Plus the second input divided by 500 and then multiplied by 6


0

Stax,17个字节

ü;█y☼òΓ▀ßîP<<╪⌠öß

在staxlang.xyz上运行并调试它!

将所有输入都视为浮点数,尽管这仅在解压缩版本中节省了一个字节。可能是可改进的;刚才回到编码高尔夫,我有些生锈。

解压缩(20字节)和说明:

0!012*s:-{0>f{A/m|++
0!012*                  Float literal and multiplication for distance
      s                 Swap top two stack values (altitudes to the top)
       :-               List of deltas
         {0>f           Filter: keep only positive changes
             {A_m       Map: divide all ascents by 10
                 |++    Add these times to that for horizontal travel
                        Implicit print

0!012*s:-{0>f{A_:m|++ 适用于21字节未压缩但仍为17压缩的整数输入。

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.