Правління Наїсміта


12

Правило Нейсміта допомагає визначити тривалість часу, необхідного для прогулянки або походу, враховуючи відстань і сходження.

Враховуючи не порожній список висоти в точках, рівномірно розташованих вздовж шляху і загальну відстань цього шляху в метрах, слід обчислити час, необхідний згідно з правилом Найсміта.

Правило Найсміта полягає в тому, що ви повинні дозволяти одну годину на кожні п’ять кілометрів плюс додаткову годину на кожні 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

Відповіді:


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

Ви можете отримати ще 4 байти за допомогою pryr :: f (sum (pmax (0, diff (A)), D * .12) / 10) замість функції
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 від мене.
Кевін Кройсейсен


2

Python 2, 62 60 байт

Збережено 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 6 ,45 39 37 байт

6 байт збережено завдяки Джо Кінгу.

2 байти збережено завдяки nwellnhof.

(Завдяки обом, це вже не схоже на моє оригінальне подання :—).)

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

Спробуйте в Інтернеті!

Перший аргумент - це список з висотами, другий аргумент - довжина походу.

Вся справа в коді WickerCode. Якщо вираз визнано таким, то кожен *є одним аргументом.

Отже, *.&{sum (.skip Z-$_)Xmax 0}/600ми беремо перший аргумент (перша поява *) і використовуємо на ньому блок з методом, як конструкція .&{}. Блок приймає один аргумент (список), який входить $_, так .skipце і список без першого елемента. Віднімаємо з цього вихідний масив, елемент за елементом, використовуючи Z-. Зіпсування припиняється, як тільки коротший список вичерпується, що добре.

Потім ми використовуємо оператор крос-продукту X. list X(op) listстворює всі можливі пари, де перший елемент знаходиться з лівого списку, а другий праворуч, і використовує оператор (op)на них. Результат повертається у вигляді послідовності (список з одним ударом). Однак у правильному списку є лише один елемент, 0, так що це просто * max 0, елемент за елементом. Це гарантує, що ми рахуємо лише висхідні частини походу. Потім додаємо його і ділимо на 600.

Потім додаємо */5e3, де це *відбувається вдруге, і так це другий аргумент, і ділимо його на 5000. Сума - це час у годинах. (Це більш ефективно, ніж час у хвилинах, оскільки нам потрібно було б помножити, і *потрібно було б відокремити пробіл від WeverStar *.)



@JoKing, це приємне використання X, дякую!
Раміллі

1
Власне, ми можемо уникнути останнього X/, поділивши суму на 10. 39 байт
Джо Кінг

37 байт за допомогою WickerCode і .&{}(повертає години).
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

Піт , 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
188

Дивіться, саме тому ви чарівник. Копіюючи вираз кілька разів частиною, я цілком винна, я просто замінив і в старому коді на, і було занадто ледачим, щоб покласти заголовок / нижній колонтитул tradfn. ,0Біт , хоча? Золото.
Дж. Салле

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 упакованих.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.