Naismith'in kuralı


12

Naismith'in kuralı , mesafe ve tırmanış göz önüne alındığında, bir yürüyüş veya yürüyüş için gereken sürenin hesaplanmasına yardımcı olur.

Bir yol boyunca eşit aralıklarla yerleştirilmiş noktalardaki boşluğun boş olmayan bir listesi ve bu yolun metre cinsinden toplam mesafesi göz önüne alındığında, Naismith'in kuralına göre gereken zamanı hesaplamalısınız.

Naismith'in kuralı, her beş kilometrede bir saatin yanı sıra her 600 metrelik yükseliş için bir saat daha izin vermenizdir.

Giriş, negatif olmayan tamsayılardan oluşması garanti edilen metre cinsinden alınmalı ve çıktı sürekli olarak saat veya dakika olmalıdır (ancak her ikisi birden değil) ve uygulanabilir olduğunda ondalık sayılar verebilmelidir (kayan nokta yanlışlıkları TAMAM) .

Örneğin, verilenler:

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

İlk iki unsur [100, 200]için 100 metre yükselişiniz var, bu da 10 dakika. İle [200, 400]20 dakika olan yükselişin 200 metre var, [400, 200]hiçbir zaman bunun için ilave edilir, böylece yükselen değildir. [200, 700]50 metre olan ve nihayetinde yükselmeyen 500 metre yükseliş [700, 400]. Beş kilometre uzaklık için bir saat daha eklenir. Bu toplam 140 dakika veya 2.333 ... saattir.

Test Durumları

[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

Test senaryo çıktılarının hepsinin tam dakika sonuçları var, bu kasıtlı mı? Gibi girişler Are [10], 5125veya [10, 25, 55], 1000geçerli ve gerekli işlenecek?
sundar - Monica'yı geri

@ sundar Evet, yapmalılar.
Okx

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

Yanıtlar:


6

R ,  44  43 42 bayt

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

Çevrimiçi deneyin!

-1 bayt pmaxbirden fazla cevap olarak kullanarak

Girdileri Akoku ve Distans olarak alır ve zamanı dakika cinsinden döndürür.

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

Fonksiyonu kullanmak yerine pryr :: f (toplam (pmax (0, fark (A)), D * .12) / 10) kullanarak 4 bayt daha alabilirsiniz)
Shayne03

@ Shayne03 teknik olarak bu cevabı sitenin kuralları R tabanından farklı bir dil olarak sayılan "R + pryr" olarak değiştirir, bu yüzden bunu olduğu gibi tutacağım. Yine de öneri için teşekkürler!
Giuseppe

Açıklama bir tepe şeklindedir
user70585

3

JavaScript (ES6), 50 bayt

Giuseppe'nın cevabı sayesinde 1 bayt kaydedildi (işlem sonunda 10'a bölünerek)

Girişi alır ([altitudes])(distance). Süreyi dakika cinsinden döndürür.

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

Çevrimiçi deneyin!


2

05AB1E , 15 bayt

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

Çevrimiçi deneyin!

Süreyi dakika olarak döndürür.

açıklama

              + # 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) 

Neredeyse tam olarak aklımdakilerdi. Ben tek fark oldu ₄12//yerine ₄;6//. Benden çok açık +1.
Kevin Cruijssen


2

Python 2, 62 60 bayt

Ovs sayesinde 2 bayt tasarruf etti.

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

Çevrimiçi deneyin!

Süreyi dakika olarak döndürür.

# 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 6 ,45 39 37 bayt

Jo King sayesinde 6 bayt tasarruf etti.

Nwellnhof sayesinde 2 bayt kurtardı.

(Her ikisi de sayesinde, bu benim orijinal sunumum gibi görünmüyor :—).)

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

Çevrimiçi deneyin!

İlk argüman yükselti içeren listedir, ikinci argüman trek uzunluğudur.

Her şey bir WhateverCode. Bir ifade bu şekilde tanınırsa, her *biri bir bağımsız değişkendir.

Böylece, *.&{sum (.skip Z-$_)Xmax 0}/600ilk argümanı (ilk oluşumu *) alırız ve üzerinde yöntem benzeri bir yapı ile bir blok kullanırız .&{}. Blok gider bir argüman (liste), alır $_, bu nedenle .skipilk öğe olmadan listesidir. Orijinal diziyi, öğeden öğeye çıkarırız.Z- . Sıkıştırma işlemi kısa liste biter bitmez durur, bu da sorun değildir.

Daha sonra çapraz ürün operatörünü kullanıyoruz X. list X(op) listbirinci öğenin sol listeden, ikincisinin sağdan olduğu tüm olası çiftleri oluşturur ve (op)üzerinde işleci kullanır . Sonuç Seq (tek seferlik bir liste) olarak döndürülür. Ancak, sağ listede yalnızca bir öğe (0) vardır, bu nedenle * max 0ögeye göre öğe ögelerdir. Bu, sadece yürüyüşün artan bölümlerini saymamızı sağlar. Sonra toplayıp 600'e bölüyoruz.

Sonra , ikinci kez gerçekleştiği */5e3yeri ekliyoruz *ve böylece ikinci argüman ve 5000'e bölüyoruz. Toplam, o zaman saat cinsinden zamandır. (Bu, çarpmamız gerektiğinden *ve WhateverStar'dan bir boşlukla ayrılması gerektiğinden , dakika olarak geçen süreden daha etkilidir *.)



@JoKing, bu güzel bir kullanım X, teşekkürler!
Ramillies

1
Aslında, X/toplamı sadece 10'a bölerek sonuncuyu önleyebiliriz . 39 bayt
Jo King

WhateverCode kullanarak 37 bayt ve .&{}(saat döndürür).
nwellnhof

2

Tamam , 21 bayt

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

Çevrimiçi deneyin! Ayrıştırma hatasını kötüye kullanmakla .1.012aynıdır .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 sayesinde streester .

k , 23 bayt

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

Çevrimiçi deneyin!


{y+/0|1_-':x}..1.012*21 bayt için? akümülatörü ile başla y.
streetster

Aslında! K koduna benzer bir geliştirme uygulardım, ancak maalesef sahip olduğum k yorumlayıcısı (2016.08.09), akümülatöre bu tarzda herhangi bir şeyle başlamamı sevmiyor. :/
zgrep



1

Pyth , 15 bayt

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

Tam program, yükseklik kümesini ilk argüman olarak, mesafeyi ikincisi olarak bekler. Süreyi dakika cinsinden döndürür.

Buradan çevrimiçi olarak deneyin veya tüm test senaryolarını burada bir kerede doğrulayın .

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 bayt

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

Çevrimiçi deneyin!

1st ⎕= Yükseklik / Derinlik, 2nd ⎕= Mesafe gibi girdi (sağdan sola) alan geleneksel işlev .

Teşekkür için @ngn için bir sihirbaz olmak bir üç bayt.

Nasıl çalışır:

.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;

"sihirbaz" için teşekkürler :) ifadeyi test etmek için birden çok kez kopyalamak zorunda değilsiniz, bunun yerine bir tradfn koymak ; ,0gereksiz, sorunlu test için ,604değil, olmalıdır604
ngn

Bak, bu yüzden sen bir büyücüsün. İfade birden çok kez kopyalanması tamamen benim hatam, sadece yerine ve eski kod ile ve tradfn üstbilgi / altbilgi koymak için çok tembel oldu. ,0Gerçi biraz? Altın.
J. Sallé

0

Java 8, 89 bayt

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;}

Çevrimiçi deneyin.

Açıklama:

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 bayt

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

Çalıştırın ve hata ayıklayın staxlang.xyz!

Tüm girdileri yüzer olarak alır, ancak bu yalnızca paketlenmemiş versiyonda bir bayt tasarrufu sağlar. Muhtemelen geliştirilebilir; Sadece şimdi golf koduna dönüyor, biraz paslıyım.

Ambalajsız (20 bayt) ve açıklama:

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 bayt paketsiz ve hala 17 paket için entegre girişler için çalışır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.