ネイスミスのルール


12

Naismithのルールは、距離と上昇を考慮して、ウォーキングまたはハイキングに必要な時間の長さを計算するのに役立ちます。

パスに沿って等間隔に配置されたポイントの高度の空でないリストと、そのパスの合計距離(メートル)が与えられている場合、Naismithのルールに従って必要な時間を計算する必要があります。

ネイスミスのルールでは、5キロメートルごとに1時間、さらに600メートルの上昇ごとに1時間を許可する必要があります。

入力は非負の整数で構成されることが保証されているメートル単位で入力する必要があり、出力は常に時間または分(両方ではなく)である必要があり、必要に応じて10進数を指定できる必要があります(浮動小数点の不正確さは問題ありません) 。

たとえば、次の場合:

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

最初の2つの要素[100, 200]には、100メートルの上昇があり、これは10分です。では[200, 400]、あなたが20分で上昇の200メートルを持って、[400, 200]もう時間がそのために追加されていないので、昇順されていません。[200, 700]500メートルの上昇は50分で、最終的に[700, 400]は上昇しません。5キロメートルの距離に1時間余分に追加されます。これは合計で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

テストケースの出力はすべて1分間の結果になりますが、それは意図的なものですか?入力のようなもの[10], 5125[10, 25, 55], 1000、有効と扱われるために必要な?
スンダ

@sundarはい、そうすべきです。
Okx

[10, 25, 55], 1000 -> 0.275 OR 16.5
クルドラエセスナバルヤ18

回答:


6

R 44  43 42バイト

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

オンラインでお試しください!

pmax他の複数の回答と同様に-1バイトを使用

入力を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

@ Shayne03は、この答えを技術的に「R + pryr」に変更します。これは、サイトのルールではベースRとは異なる言語としてカウントされるため、このままにします。しかし提案をありがとう!
ジュゼッペ

説明は丘のような形をしています
-user70585


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。
ケビンCruijssen


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

オンラインでお試しください!

最初の引数は標高付きのリスト、2番目の引数はトレッキングの長さです。

すべてがWhateverCodeです。式がそのように認識される場合、それぞれ*が1つの引数になります。

そのため、*.&{sum (.skip Z-$_)Xmax 0}/600では、最初の引数(の最初の出現*)を取得し、メソッドのような構造を持つブロックを使用します.&{}。ブロックは1つの引数(リスト)を取ります。これはになり$_.skip最初の要素のないリストも同様になります。を使用して、元の配列を要素ごとに減算しZ-ます。短いリストがなくなるとすぐに圧縮が停止します。これは問題ありません。

次に、外積演算子を使用しXます。list X(op) list最初の要素が左のリストにあり、2番目の要素が右のリストにあるすべての可能なペアを作成し(op)、それらに対して演算子を使用します。結果はSeq(ワンショットリスト)として返されます。ただし、右側のリストには1つの要素(0)しかありません* max 0。これにより、トレッキングの上昇部分のみがカウントされます。次に、合計して600で割ります。

次にを追加します*/5e3。ここで*が2回目に発生するため、2番目の引数になり、5000で除算されます。合計は時間単位の時間になります。(これは、乗算*する必要があり、WhateverStarからスペースで区切る必要があるため、分単位の時間よりも効率的です*。)



@JoKing、それは素晴らしい使い方ですX、ありがとう!
ラミリーズ

1
実際、X/合計を10で割るだけで最後を回避できます。39バイト
ジョーキング

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 ストリースターのおかげ。

k、23バイト

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

オンラインでお試しください!


{y+/0|1_-':x}..1.012*21バイト?でアキュムレータを開始しyます。
ストリートスター

確かに!私はkコードに同様の機能拡張を適用しますが、残念ながら、私が持っているkインタープリター(2016.08.09)は、そのような方法でアキュムレーターを起動することを嫌います。:/
zgrep



1

Pyth、15バイト

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

完全なプログラムでは、最初の引数として高さのセット、2番目の引数として距離が必要です。時間を分単位で返します。

ここでオンライン試すか、ここですべてのテストケースを一度に検証します

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 ⎕= Heights / Depths、2nd ⎕= Distance として(右から左へ)入力を受け取る従来の関数。

@ngnに1バイトのウィザードをしくれてありがとう。

使い方:

.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.サール

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

スタックス、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バイトの整数入力に対して機能します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.