La regola di Naismith


12

La regola di Naismith aiuta a calcolare il tempo necessario per una passeggiata o un'escursione, data la distanza e l'ascesa.

Dato un elenco non vuoto dell'altitudine in punti distribuiti uniformemente lungo un percorso e la distanza totale di quel percorso in metri, è necessario calcolare il tempo necessario secondo la regola di Naismith.

La regola di Naismith è che dovresti concedere un'ora ogni cinque chilometri, più un'ora aggiuntiva ogni 600 metri di salita.

L'input deve essere preso in metri, che è garantito che sia costituito da numeri interi non negativi, e l'output dovrebbe essere costantemente in ore o minuti (ma non entrambi) e deve essere in grado di fornire numeri decimali ove applicabile (le imprecisioni in virgola mobile sono OK) .

Ad esempio, dato:

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

Per i primi due elementi [100, 200]hai 100 metri di salita che è di 10 minuti. Con [200, 400]te hai 200 metri di salita che è di 20 minuti, [400, 200]non è in salita, quindi non è stato aggiunto alcun tempo. [200, 700]sono 500 metri di salita che è di 50 minuti e infine [700, 400]non è in salita. Viene aggiunta un'ora in più per la distanza di cinque chilometri. Questo ammonta a 140 minuti o 2.333 ... ore.

Casi test

[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

Tutti gli output dei casi di test hanno risultati di un minuto intero, è intenzionale? Gli input sono simili [10], 5125o [10, 25, 55], 1000validi e devono essere gestiti?
Sundar - Ripristina Monica il

@sundar Sì, dovrebbero.
Okx,

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

Risposte:


6

R ,  44  43 42 byte

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

Provalo online!

-1 byte usando pmaxcome fanno più altre risposte

Accetta input come Aprofumo e Distanza e restituisce il tempo in minuti.

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

Puoi ottenere altri 4 byte usando pryr :: f (sum (pmax (0, diff (A)), D * .12) / 10) invece di usare la funzione
Shayne03

@ Shayne03 che cambierebbe tecnicamente questa risposta in "R + pryr" che sulle regole del sito conta come una lingua diversa dalla base R, quindi la terrò così com'è. Grazie per il suggerimento, però!
Giuseppe,

La spiegazione ha la forma di una collina
user70585

3

JavaScript (ES6), 50 byte

Salvato 1 byte grazie alla risposta di Giuseppe (dividendo per 10 alla fine del processo)

Accetta input come ([altitudes])(distance). Restituisce il tempo in minuti.

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

Provalo online!


2

05AB1E , 15 byte

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

Provalo online!

Restituisce il tempo in minuti.

Spiegazione

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

Quasi esattamente quello che avevo in mente. L'unica differenza che avevo era ₄12//invece di ₄;6//. Così evidente +1 da parte mia.
Kevin Cruijssen il


2

Python 2, 62 60 byte

Salvato 2 byte grazie a ovs.

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

Provalo online!

Restituisce il tempo in minuti.

# 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 byte

6 byte salvati grazie a Jo King.

2 byte salvati grazie a nwellnhof.

(Grazie a entrambi, questo non assomiglia più alla mia presentazione originale: -).

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

Provalo online!

Il primo argomento è l'elenco con elevazioni, il secondo argomento è la lunghezza del percorso.

Il tutto è un qualunque codice. Se un'espressione viene riconosciuta come tale, allora ciascuno *è un argomento.

Quindi, in *.&{sum (.skip Z-$_)Xmax 0}/600, prendiamo il primo argomento (la prima occorrenza di *) e usiamo un blocco su di esso con un costrutto simile a un metodo .&{}. Il blocco accetta un argomento (la lista), che entra $_, così .skipè quella lista senza il primo elemento. Sottraiamo l'array originale, elemento per elemento, da quello, usando Z-. Lo zipping si interrompe non appena si esaurisce l'elenco più breve, il che è OK.

Quindi utilizziamo l'operatore prodotto incrociato X. list X(op) listcrea tutte le possibili coppie in cui il primo elemento è dall'elenco di sinistra e il secondo da destra e utilizza l'operatore (op)su di essi. Il risultato viene restituito come Seq (un elenco one-shot). Tuttavia, l'elenco a destra ha solo un elemento, 0, quindi lo fa * max 0, elemento per elemento. Questo assicura che contiamo solo le parti ascendenti del trekking. Quindi lo sommiamo e lo dividiamo per 600.

Quindi aggiungiamo */5e3, dove si *verifica per la seconda volta, e quindi è il secondo argomento, e lo dividiamo per 5000. La somma è quindi il tempo in ore. (Questo è più efficiente del tempo in minuti dal momento in cui avremmo bisogno di moltiplicarci, e *dovrebbe essere separato da uno spazio da WhatStar *.)



@JoKing, è un buon uso X, grazie!
Ramillies,

1
In realtà, possiamo evitare l'ultimo X/dividendo semplicemente la somma per 10. 39 byte
Jo King

37 byte utilizzando qualunque codice e .&{}(restituisce ore).
nwellnhof,

2

ok , 21 byte

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

Provalo online! Abusare di un bug di analisi dove .1.012è uguale a .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 grazie a streester .

k , 23 byte

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

Provalo online!


{y+/0|1_-':x}..1.012*per 21 byte? avviare l'accumulatore con y.
streetster

Infatti! Applicerei un miglioramento simile al codice k, ma sfortunatamente l'interprete k che ho (09.08.2016) non mi piace che avvii l'accumulatore con qualcosa del genere. :/
zgrep,



1

Pyth , 15 byte

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

Programma completo, prevede l'insieme di altezze come primo argomento, distanza come secondo. Restituisce il tempo in minuti.

Provalo online qui o verifica tutti i casi di test contemporaneamente qui .

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 byte

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

Provalo online!

Funzione tradizionale che accetta input (da destra a sinistra) come 1st ⎕= Altezze / Profondità, 2nd ⎕= Distanza.

Grazie a @ngn per essere un wizard uno tre byte.

Come funziona:

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

grazie per "procedura guidata" :) non è necessario copiare più volte l'espressione per testarla, inserendola invece in una tradfn ; ,0non è necessario, il test per il problema dovrebbe essere ,604, non604
ngn

Vedi, ecco perché sei un mago. Copiare l'espressione più volte è totalmente colpa mia, ho appena sostituito il e nel vecchio codice con ed ero troppo pigro per mettere l'intestazione / piè di pagina tradfn. Il ,0piccolo però? Oro.
J. Sallé,

0

Java 8, 89 byte

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

Provalo online.

Spiegazione:

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 byte

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

Eseguilo e esegui il debug su staxlang.xyz!

Prende tutti gli input come float, sebbene ciò salvi un byte solo nella versione decompressa. Probabilmente migliorabile; proprio ora tornando al codice golf, sono un po 'arrugginito.

Spacchettato (20 byte) e spiegazione:

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|++ funziona con input integrali per 21 byte decompressi e ancora 17 compressi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.