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.