La facture d'eau de Fred

9

Fred est un gars presque amical, mais en réalité, il est méchant.

Pour cette raison, Fred vit seul dans un petit appartement à Los Altos, en Californie. Fred est si méchant parce qu'il est très particulier avec l'eau. Il a donc besoin de votre aide pour déterminer quelle est sa facture d'eau.

Votre travail consiste à écrire une fonction ou un programme qui renvoie sa facture d'eau compte tenu de la quantité d'eau utilisée comme entrée (qui est toujours un entier).

La consommation d'eau est échelonnée. Cela signifie qu'il existe des gammes de prix en fonction de la quantité d'eau.

Ce sont les niveaux, leurs prix et les quantités d'eau auxquelles ils correspondent:

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

Pour n centaines de pieds cubes (Ccf), il y a également les frais supplémentaires suivants:

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

La somme des frais de niveau I, de niveau II, de niveau III, CPUC, LIRA et PBOP correspond à la facture totale d'eau. Cette somme doit être retournée ou imprimée sur la console arrondie à deux décimales.

Voici deux exemples:

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

C'est le code golf, donc le code le plus court en octets gagne!

Daniel
la source
Veuillez vérifier que ma modification correspond à votre intention.
msh210
Ouais merci @ msh210, c'est beaucoup plus clair que ce que j'avais
Daniel
Si vous êtes prêt à gaspiller votre réputation en votant, pourriez-vous au moins expliquer pourquoi?
Daniel
@Dopapp Certaines personnes pourraient ne pas aimer le défi. Vous ne pouvez rien y faire. Pour ce que ça vaut, les défis de downvoting ne soustraient pas la réputation de downvoter - seulement des réponses.
Mego
Faut-il gérer des non-entiers n?
PurkkaKoodari

Réponses:

1

Pyth, 55 41 octets

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

Le code contient des caractères non imprimables, voici donc un xxdvidage hexadécimal.

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

Explication

  1. ."…"est une chaîne compressée qui contient 3.8476,4.0932,4.9118.
  2. vévalue cela au tuple (3.8476, 4.0932, 4.9118). Ce sont les prix des niveaux multipliés par les CPUC ajoutés.
  3. UQgénère la gamme 0n-1.
  4. c,T27Divise cette plage aux indices 10 et 27, avec des listes vides supplémentaires à la fin si la plage est trop courte.
  5. lM trouve la longueur de chaque partie, donnant la quantité d'eau pour chaque niveau.
  6. *V multiplie cela par le tuple de l'étape 2 pour obtenir les prix des niveaux.
  7. s résume les résultats.
  8. +*Q.051Ajoute l'entrée multipliée par 0,051, c'est-à-dire LIRA + PBOP.
  9. .R2Arrondit le résultat à 2 décimales.

Essayez-le en ligne.

PurkkaKoodari
la source
2

Mathematica, 83 76 69 octets

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

Fonction anonyme qui construit un tableau des trois niveaux dans la première colonne plus le LIRA et le PBOP représentés comme un nombre à précision arbitraire dans la quatrième colonne. Le tout est multiplié par 1.015et tous les éléments du tableau sont additionnés et arrondis à .01. Étant donné que ce 51/1015*1.015sera le résultat souhaité, 0.051la sortie est exactement aussi précise que la spécification dans OP.

Une solution plus courte, en 76 octets , comme je l'ai suggéré dans mon commentaire sous la solution Perl

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

1.015est pris en compte dans les prix dès le départ, puis le CRI et le PBOP sont ajoutés au-dessus du premier niveau.

73 octets (mais je suis réticent à mettre à jour mon nombre d'octets car c'est assez proche de la solution Perl simple):

69 octets - ah quoi diable, le golf a pris un certain effort aussi.

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

EDIT concernant l'erreur en virgule flottante
Les trois premières itérations de ma réponse sont en effet exactes dans leur représentation décimale, car tous les coefficients impliqués ont des représentations décimales terminales. Cependant, comme les coefficients sont des flottants explicites, stockés en binaire et ayant des représentations binaires sans terminaison, des entrées suffisamment grandes commenceront à accumuler des erreurs dans les chiffres les moins significatifs de la représentation binaire. Je suppose que lorsque le flotteur est si grand qu'il ne tient que de 3 à 4 chiffres à droite de la virgule décimale, nous pouvons nous attendre à des erreurs d'environ 1 cent. Voir ci-dessous pour une réponse exacte .

72 octets, peu à l'abri des inexactitudes de flottement

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

La multiplication par l'interligne .01se fait à la toute dernière étape. Jusqu'à ce point, tous les calculs sont effectués avec des entiers. Cela signifie que si le .01est omis, il y aura un résultat exact , mais exprimé en cents plutôt qu'en dollars. Bien sûr, la multiplication par un flotteur convertit le tout en un flottant, et, comme mentionné, il doit être suffisamment petit pour tenir sur 64 bits et toujours précis .01.

LLlAMnYP
la source
2

05AB1E, 64 58 51 octets

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

Expliqué

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

Essayez-le en ligne

Emigna
la source
1

Perl 5, 73 octets

La solution évidente. 72 octets, plus 1 pour -neau lieu de -e.

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

5 octets enregistrés grâce à LLlAMnYP . Merci!

msh210
la source
Concernant mon commentaire précédent, cette modification s'avère effectivement éliminer les erreurs en virgule flottante que vous aviez dans l'original.
LLlAMnYP
@LLlAMnYP, toute approximation doit sûrement avoir une erreur pour une valeur suffisamment élevée de l'entrée. Espérons que cette limite soit suffisamment élevée pour que le PO ne s'en soucie pas (car il s'agit d'une quantité déraisonnable d'eau pour la résidence d'une seule personne).
msh210
@ msh210 Vous ne connaissez pas l'histoire de Fred !!
cat
Non, car vous multipliez et ajoutez des nombres avec une représentation décimale finie. Bien sûr, lorsque vous les représentez comme des flottants, ils peuvent avoir une représentation binaire pas si grande. Vous pouvez alors vous attendre à des erreurs lorsque la représentation flottante ne permet que 3-4 chiffres à droite de la décimale. Ma "réponse bonus" au bas de mon message surmonte cela, en utilisant des entiers jusqu'à la toute dernière étape (qui convertit les cents en dollars). Si je devais omettre la multiplication par .01, elle resterait précise tant que l'entier peut être stocké.
LLlAMnYP
1

Oracle SQL 11.2, 151 octets

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;

Non golfé

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
Jeto
la source
Débarrassez-vous de l'espace entre SELECTet ((DECODEpour enregistrer un octet. Économisez plus de 10 octets en utilisant une table nommée! 7 en supprimant les deux-points et en utilisant un nom de colonne d'un caractère plus trois en utilisant un nom de table d'un caractère.
Giacomo Garabello
@Giacomo Garabello: la suppression de l'espace renvoie toujours null avec crapaud et renvoie une erreur avec SQLDeveloper. Le script de création de table ajoute plus de 10 octets.
Jeto
vous n'avez pas besoin d'ajouter le script de création ... regardez ici
Giacomo Garabello
1

JavaScript ES6, 77 octets

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

Non golfé

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
}

J'ai pris en compte les coefficients LIRA et PBOP. Le 1,5% supplémentaire est ajouté à la fin.

Probablement pas la solution la plus efficace en termes de golf mais quelque peu différente de celle de Perl.

Une erreur en virgule flottante doit se produire avec des nombres plus importants et peut être corrigée en ajoutant 1 ou 2 octets supplémentaires à chaque coefficient.

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

Hugo
la source
Vous n'avez pas besoin des ()s autour du x>10?:, ?:associe de droite à gauche. Je pense que vous pouvez également économiser quelques octets en multipliant les parenthèses, par exemple (x-10)*4.154598+39.05314égal à x*4.154598-41.54598+39.05314égal x*4.154598-2.49284.
Neil
1

R , 52 octets

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

Essayez-le en ligne!

Génère une fonction d'approximation linéaire, basée sur les valeurs de ma réponse précédente à 0,10,27 et 10 ^ 6. Le hic: la limite supérieure de l'entrée est 10 ^ 6.

approxfun(avec ecdf, stepfun, splinefun, etc.) est l' une des nombreuses caractéristiques de belles de R.

JayCe
la source
0

VBA, 88 octets

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

Le taux de base et les taux différentiels d'utilisation plus élevés ont été multipliés par 5, et le multiplicateur des frais CPUC divisé par 5 (0,203).

L'éditeur VB ajoutera une End Functionligne, c'est pourquoi le fil de ligne du terminal est inclus.

Joffan
la source