La bolletta dell'acqua di Fred


9

Fred è un ragazzo quasi amichevole, ma in realtà è cattivo.

Per questo motivo, Fred vive da solo in un piccolo appartamento a Los Altos, in California. Fred è così cattivo perché è molto attento all'acqua. Pertanto, ha bisogno del tuo aiuto per capire quale sia la sua bolletta dell'acqua.

Il tuo compito è scrivere una funzione o un programma che restituisca la sua bolletta dell'acqua data la quantità di acqua utilizzata come input (che è sempre un numero intero).

Il consumo di acqua è suddiviso in livelli. Ciò significa che ci sono intervalli di prezzi che dipendono dalla quantità di acqua.

Questi sono i livelli, i loro prezzi e le quantità di acqua a cui corrispondono:

Tier I
   First 10 Ccf: $3.8476/Ccf
Tier II
   Next 17 Ccf: $4.0932/Ccf
Tier III
   All subsequent water: $4.9118/Ccf

Per n centinaia di piedi cubi (Ccf), ci sono anche i seguenti costi aggiuntivi:

CPUC fee: 1.5% of above charges
LIRA quantity surcharge: $0.047*n
PBOP amoritization surcharge: $0.004*n

La somma delle tasse di Livello I, Livello II, Livello III, CPUC, LIRA e PBOP è la bolletta dell'acqua totale. Questa somma deve essere restituita o stampata sulla console arrotondata al secondo decimale.

Ecco due esempi:

Input: 15
... Calculations which you do not need to output but here to help explain:
Tier I: 10*3.8476 = 38.476
Tier II: (15-10)*4.0932 = 20.466
Tier III: 0*4.9118 = 0
Tiers sum: 58.942
CPUC: 1.5% of 58.942 = 0.88413
LIRA: 0.047*15 = 0.705
PBOP: 0.004*15 = 0.06
Total sum: 58.942 + 0.88413 + 0.705 + 0.06 = 60.59113
...
Output: 60.59

Input: 100
... Calculations which you do not need to output but here to help explain:
Tier I: 10*3.8476 = 38.476
Tier II: 17*4.0932 = 69.5844
Tier III: (100-10-17)*4.9118 = 358.5614
Tiers sum: 466.6218
CPUC: 1.5% of  = 6.999327
LIRA: 0.047*100 = 4.7
PBOP: 0.004*100 = 0.4
Total sum: 478.721127
...
Output: 478.72

Questo è il codice golf, quindi vince il codice più breve in byte!


Verifica che la mia modifica corrisponda alle tue intenzioni.
msh210,

Sì grazie @ msh210, è molto più chiaro di quello che avevo
Daniel,

Se sei disposto a perdere la reputazione con il voto negativo, potresti almeno spiegare perché?
Daniel,

@Dopapp Ad alcune persone potrebbe non piacere la sfida. Niente che tu possa fare lì. Per quello che vale, le sfide di downvoting non sottraggono alla reputazione del downvoter - solo risposte.
Mego,

Dobbiamo gestire un numero intero n?
PurkkaKoodari,

Risposte:


1

Pyth, 55 41 byte

.R+s*Vv.",9t¬®Ï0NwÝ"lMcUQ,T27*.051Q2

Il codice contiene caratteri non stampabili, quindi ecco un xxdhexdump.

00000000: 2e52 2b73 2a56 762e 222c 3904 1874 c2ac  .R+s*Vv.",9..t..
00000010: c2ae c280 c293 c38f 301c 4e77 c39d 226c  ........0.Nw.."l
00000020: 4d63 5551 2c54 3237 2a2e 3035 3151 32    McUQ,T27*.051Q2

Spiegazione

  1. ."…"è una stringa compressa che contiene 3.8476,4.0932,4.9118.
  2. vlo valuta alla tupla (3.8476, 4.0932, 4.9118). Questi sono i prezzi dei livelli moltiplicati con l'aggiunta di CPUC.
  3. UQgenera la gamma 0... n-1.
  4. c... ,T27divide tale intervallo agli indici 10 e 27, con elenchi vuoti extra alla fine se l'intervallo è troppo corto.
  5. lM trova la lunghezza di ogni parte, fornendo la quantità di acqua per ogni livello.
  6. *V moltiplica quello per la tupla dal passaggio 2 per ottenere i prezzi per i livelli.
  7. s somma i risultati.
  8. +... *Q.051aggiunge l'ingresso moltiplicato per 0,051, ovvero LIRA + PBOP.
  9. .R... 2arrotonda il risultato a 2 decimali.

Provalo online.


2

Matematica, 83 76 69 byte

1.015{3.8476,.2456(b=Boole)[#>10],.8186b[#>27],51/1015}&~Array~#~Total~2~Round~.01&

Funzione anonima che costruisce un array di tre livelli nella prima colonna più LIRA e PBOP rappresentati come un numero di precisione arbitraria nella quarta colonna. Il tutto viene moltiplicato per 1.015e tutti gli elementi dell'array vengono sommati e arrotondati a .01. Poiché 51/1015*1.015sarà desiderato, 0.051l'uscita è esattamente precisa, come le specifiche in OP.

Una soluzione più breve, in 76 byte , come ho suggerito nel mio commento sotto la soluzione Perl

{3.956314,.249284(b=Boole)[#>10],.830879b[#>27]}&~Array~#~Total~2~Round~.01&

dove 1.015viene preso in considerazione i prezzi dall'inizio e quindi il LIRA e il PBOP vengono aggiunti in cima al primo livello.

73 byte (ma sono riluttante ad aggiornare il mio conteggio byte poiché questo è abbastanza vicino alla semplice soluzione Perl):

69 byte - ah che diamine, anche il golf ha richiesto qualche sforzo.

.01Round[395.6314#+{24.9284,83.0879}.(UnitStep[#-1]#&/@{#-10,#-27})]&

EDIT relativo all'errore in virgola mobile
Le prime tre iterazioni della mia risposta sono effettivamente esatte nella loro rappresentazione decimale, poiché tutti i coefficienti coinvolti hanno rappresentazioni decimali finali. Tuttavia, poiché i coefficienti sono esplicitamente float, memorizzati in binario e con rappresentazioni binarie non terminanti, input abbastanza grandi inizieranno ad accumulare errori nelle cifre meno significative della rappresentazione binaria. Immagino che, quando il float è così grande, che si adatta solo a 3-4 cifre alla destra del punto decimale, possiamo aspettarci errori di circa 1 centesimo. Vedi sotto per una risposta esatta .

72 byte, un po 'immune alle imprecisioni del galleggiante

.01Round[{3956314,249284,830879}.(UnitStep[#-1]#&)/@(#-{0,10,27})/10^4]&

La moltiplicazione per il leader .01viene effettuata all'ultimo passo. Fino a quel momento, tutti i calcoli vengono eseguiti con numeri interi. Ciò significa che se .01viene omesso, ci sarà un risultato esatto , ma espresso in centesimi, piuttosto che in dollari. Naturalmente, la moltiplicazione per un float converte l'intera cosa in float e, come detto, deve essere abbastanza piccola da contenere 64 bit e comunque precisa .01.


2

05AB1E, 64 58 51 byte

0T27¹)vy¹‚ï{0è})¥•_ÄÄ™wu24@•2'.:7ô)ø€PO¹"5.1"*+ïTn/

spiegato

0T27¹)                                               # list of price brackets
      vy¹‚ï{0è})                                     # min of each with input
                ¥                                    # calculate deltas to get amounts within each bracket
                 •_ÄÄ™wu24@•2'.:7ô                   # list of price rates with CPUC included
                                  )ø                 # zip with amounts for each rate
                                    €PO              # multiply amounts by their rates and sum
                                       ¹"5.1"*+      # add LIRA/PBOP
                                               ïTn/  # round to 2 decimals

Provalo online


1

Perl 5, 73 byte

La soluzione ovvia. 72 byte, più 1 per -neanziché -e.

printf'%.2f',$_*3.956314+($_-10)*($_>10)*.249284+($_-27)*($_>27)*.830879

5 byte salvati grazie a LLlAMnYP . Grazie!


Per quanto riguarda il mio commento precedente, questa modifica risulta effettivamente eliminare gli errori in virgola mobile che hai avuto nell'originale.
LLlAMnYP,

@LLlAMnYP, sicuramente ogni approssimazione deve avere un errore per un valore abbastanza alto dell'input. Spero che quel limite sia abbastanza alto da non interessare all'OP (perché è una quantità irragionevole di acqua per la residenza di una sola persona).
msh210,

@ msh210 Non conosci la storia di Fred !!
gatto,

No, perché si stanno moltiplicando e aggiungendo numeri con rappresentazione decimale finita. Naturalmente, quando li rappresentate come float, potrebbero avere una rappresentazione binaria non eccezionale. È quindi possibile prevedere errori quando la rappresentazione float consente solo 3-4 cifre a destra del decimale. La mia "risposta bonus" in fondo al mio post lo supera, usando numeri interi fino all'ultimo passo (che converte centesimi in dollari). Se dovessi omettere la moltiplicazione .01, rimarrebbe preciso fino a quando l'intero può essere memorizzato.
LLlAMnYP,

1

Oracle SQL 11.2, 151 byte

SELECT ((DECODE(SIGN(:1-10),1,10,:1)*3.8476)+(DECODE(SIGN(:1-27),1,17,:1-10)*4.0932)+(DECODE(SIGN(:1-27),-1,0,:1-27)*4.9118))*1.015+:1*0.051 FROM DUAL;

Un-golfed

SELECT ((DECODE(SIGN(:1-10),1,10,:1)*3.8476)+
       (DECODE(SIGN(:1-27),1,17,:1-10)*4.0932)+
       (DECODE(SIGN(:1-27),-1,0,:1-27)*4.9118))*1.015+
       :1*0.051
FROM DUAL

Sbarazzarsi dello spazio tra SELECTe ((DECODEper salvare un byte. Salva più 10 byte usando una tabella denominata! 7 rimuovendo i due punti e usando un nome di colonna di un carattere più tre usando un nome di tabella di un carattere.
Giacomo Garabello,

@Giacomo Garabello: la rimozione dello spazio restituisce sempre null con il rospo e restituisce un errore con SQLDeveloper. Lo script di creazione tabella aggiunge più di 10 byte.
Jeto,

non devi aggiungere lo script della creazione ... guarda qui
Giacomo Garabello,

1

JavaScript ES6, 77 byte

x=>(x>27?(x-27)*4.985477+109.681:(x>10?(x-10)*4.1546+39.053:x*3.9053))+.051*x

Un-golfed

f = x => {
  if (x > 27) {
    res = (x - 27) * 4.985477 + 109.681306
  } else if (x > 10) {
    res = (x - 10) * 4.154598 + 39.05314
  } else {
    res = x * 3.905314
  }
  return res + 0.051 * x
}

Ho preso in considerazione i coefficienti LIRA e PBOP. L'1,5% in più viene aggiunto alla fine.

Probabilmente non è la soluzione più efficiente in termini di golf ma in qualche modo diversa da quella del Perl.

L'errore in virgola mobile dovrebbe verificarsi con numeri più grandi e può essere corretto aggiungendo 1 o 2 byte extra a ciascun coefficiente.

f=x=>(x>27?(x-27)*4.985477+109.681:(x>10?(x-10)*4.1546+39.053:x*3.9053))+.051*x

console.log(f(15))
console.log(f(100))
console.log(f(200000))


Non hai bisogno delle ()s attorno a x>10?:, ?:soci da destra a sinistra. Penso che puoi anche salvare alcuni byte moltiplicando i parentesi, ad esempio (x-10)*4.154598+39.05314uguale a x*4.154598-41.54598+39.05314uguale x*4.154598-2.49284.
Neil,

1

R , 52 byte

approxfun(c(0,10,27,10^6),c(0,39.56,111.06,5036475))

Provalo online!

Genera una funzione di approssimazione lineare, basata sui valori della mia risposta precedente a 0,10,27 e 10 ^ 6. Il problema: il limite superiore sull'ingresso è 10 ^ 6.

approxfun(con ecdf, stepfun, splinefun, etc.) è una delle molte caratteristiche di R.


0

VBA, 88 byte

Function W(V):W=Round(.051*V+.203*(V*19.238-(V-10)*(V>10)*1.228-(V-27)*(V>27)*4.093),2)
 

Il tasso base e i tassi differenziali di utilizzo più elevati sono stati moltiplicati per 5 e il moltiplicatore della commissione CPUC diviso per 5 (0.203).

L'editor VB aggiungerà una End Functionriga, motivo per cui è incluso il feed della linea terminale.


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.