Rachunek za wodę Freda

9

Fred jest quasi-przyjaznym facetem, ale w rzeczywistości jest podły.

Z tego powodu Fred mieszka sam w małym mieszkaniu w Los Altos w Kalifornii. Fred jest taki podły, ponieważ bardzo przywiązuje wagę do wody. Dlatego potrzebuje twojej pomocy w ustaleniu, jaki jest jego rachunek za wodę.

Twoim zadaniem jest napisanie funkcji lub programu, który zwraca rachunek za wodę, biorąc pod uwagę ilość wody użytej jako dane wejściowe (która zawsze jest liczbą całkowitą).

Zużycie wody jest podzielone na poziomy. Oznacza to, że istnieją przedziały cen w zależności od ilości wody.

Są to poziomy, ich ceny i odpowiadające im ilości wody:

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

Dla n setek stóp sześciennych (Ccf) obowiązują również następujące dodatkowe opłaty:

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

Suma opłat na poziomie I, poziomie II, poziomie III, CPUC, LIRA i PBOP to całkowity rachunek za wodę. Suma ta powinna zostać zwrócona lub wydrukowana na konsoli w zaokrągleniu do dwóch miejsc po przecinku.

Oto dwa przykłady:

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

To jest kod golfowy, więc wygrywa najkrótszy kod w bajtach!

Daniel
źródło
Sprawdź, czy moja edycja odpowiada twojemu zamiarowi.
msh210
Tak, dziękuję @ msh210, to jest o wiele jaśniejsze niż to, co miałem
Daniel
Jeśli chcesz zmarnować reputację podczas głosowania w dół, możesz przynajmniej wyjaśnić dlaczego?
Daniel
@Dopapp Niektórzy ludzie mogą nie lubić wyzwania. Nic tam nie możesz zrobić. Jeśli chodzi o to, co jest warte, wyzwania downvotera nie odejmują reputacji downvotera - tylko odpowiedzi.
Mego
Czy mamy do czynienia z liczbą całkowitą n?
PurkkaKoodari

Odpowiedzi:

1

Pyth, 55 41 bajtów

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

Kod zawiera znaki niedrukowalne, więc oto xxdzrzut heksowy.

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

Wyjaśnienie

  1. ."…"jest spakowanym ciągiem zawierającym 3.8476,4.0932,4.9118.
  2. vocenia to do krotki (3.8476, 4.0932, 4.9118). Są to ceny poziomów pomnożone przez dodanie CPUC.
  3. UQgeneruje szereg 0... n-1.
  4. c,T27Dzieli ten zakres według wskaźników 10 i 27, z dodatkowymi pustymi listami na końcu, jeśli zakres jest zbyt krótki.
  5. lM określa długość każdej części, podając ilość wody dla każdego poziomu.
  6. *V mnoży to przez krotkę z kroku 2, aby uzyskać ceny dla poziomów.
  7. s sumuje wyniki.
  8. +*Q.051Dodaje dane wejściowe pomnożone przez 0,051, tj. LIRA + PBOP.
  9. .R2Zaokrągla wynik do 2 miejsc po przecinku.

Wypróbuj online.

PurkkaKoodari
źródło
2

Matematyka, 83 76 69 bajtów

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

Anonimowa funkcja, która konstruuje tablicę trzech warstw w pierwszej kolumnie plus LIRA i PBOP reprezentowane jako liczba o dowolnej dokładności w czwartej kolumnie. Całość mnoży się, 1.015a wszystkie elementy tablicy są sumowane i zaokrąglane do .01. Ponieważ 51/1015*1.015będzie pożądany, 0.051wynik jest dokładnie tak dokładny, jak specyfikacja w OP.

Krótsze rozwiązanie, w 76 bajtach , jak zasugerowałem w moim komentarzu do rozwiązania Perl

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

gdzie 1.015od początku uwzględnia się ceny, a następnie dodaje się LIRA i PBOP na pierwszym poziomie.

73 bajty (ale niechętnie aktualizuję moją liczbę bajtów, ponieważ jest to dość zbliżone do prostego rozwiązania Perla):

69 bajtów - och, do cholery, gra w golfa również wymagała wysiłku.

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

EDYCJA dotycząca błędu zmiennoprzecinkowego
Pierwsze trzy iteracje mojej odpowiedzi są rzeczywiście dokładne w ich reprezentacji dziesiętnej, ponieważ wszystkie zaangażowane współczynniki mają końcowe reprezentacje dziesiętne. Ponieważ jednak współczynniki są jawnie zmiennoprzecinkowe, przechowywane w postaci binarnej i mają nie kończące się reprezentacje binarne, wystarczająco duże dane wejściowe zaczną gromadzić błędy w najmniej znaczących cyfrach reprezentacji binarnej. Sądzę, że gdy liczba zmiennoprzecinkowa jest tak duża, że ​​mieści się ona tylko 3-4 cyfry po prawej stronie przecinka dziesiętnego, możemy spodziewać się błędów około 1 centa. Dokładna odpowiedź poniżej .

72 bajty, nieco odporne na niedokładności

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

Mnożenie przez wiodące .01odbywa się na ostatnim etapie. Do tego momentu wszystkie obliczenia są wykonywane za pomocą liczb całkowitych. Oznacza to, że jeśli .01zostanie pominięty, pojawi się dokładny wynik, ale wyrażony w centach, a nie w dolarach. Oczywiście, pomnożenie przez liczbę zmiennoprzecinkową przekształca całą rzecz w liczbę zmiennoprzecinkową i, jak wspomniano, musi być wystarczająco mała, aby zmieściła się w 64 bitach i nadal była dokładna .01.

LLAMAMYP
źródło
2

05AB1E, 64 58 51 bajtów

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

Wyjaśnione

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

Wypróbuj online

Emigna
źródło
1

Perl 5, 73 bajtów

Oczywiste rozwiązanie. 72 bajty plus 1 za -nezamiast -e.

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

Zaoszczędzono 5 bajtów dzięki LLlAMnYP . Dzięki!

msh210
źródło
Jeśli chodzi o mój poprzedni komentarz, ta edycja okazuje się faktycznie eliminować błędy zmiennoprzecinkowe, które wystąpiły w oryginale.
LLlAMnYP
@LLlAMnYP, z pewnością każde przybliżenie musi zawierać błąd dla wystarczająco wysokiej wartości wejściowej. Mam nadzieję, że ta granica jest na tyle wysoka, że ​​OP nie dba o to (ponieważ jest to nieuzasadniona ilość wody do zamieszkania dla jednej osoby).
msh210
@ msh210 Nie znasz historii Freda !!
kot
Nie, ponieważ mnożysz i dodajesz liczby ze skończoną reprezentacją dziesiętną. Oczywiście, gdy reprezentujesz je jako zmiennoprzecinkowe, mogą mieć niezbyt dobrą reprezentację binarną. Następnie można spodziewać się błędów, gdy reprezentacja zmiennoprzecinkowa dopuszcza tylko 3-4 cyfry po prawej stronie dziesiętnej. Moja „premia-odpowiedź” na dole mojego postu przezwycięża to, używając liczb całkowitych aż do ostatniego kroku (który przelicza centy na dolary). Gdybym pominął mnożenie .01, pozostałoby ono dokładne tak długo, jak długo można zapisać liczbę całkowitą.
LLlAMnYP
1

Oracle SQL 11.2, 151 bajtów

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;

Nie grał w golfa

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
źródło
Pozbądź się miejsca pomiędzy SELECTi, ((DECODEaby zaoszczędzić jeden bajt. Zaoszczędź więcej 10 bajtów, używając nazwanej tabeli! 7, usuwając dwukropki i używając nazwy kolumny o jednym znaku plus trzy, używając nazwy tabeli o jednym znaku.
Giacomo Garabello
@Giacomo Garabello: usunięcie spacji zawsze zwraca null z ropuchą i zwraca błąd z SQLDeveloper. Skrypt tworzenia tabeli dodaje więcej niż 10 bajtów.
Jeto
nie musisz dodawać skryptu tworzenia ... spójrz tutaj
Giacomo Garabello
1

JavaScript ES6, 77 bajtów

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

Nie grał w golfa

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
}

Wziąłem pod uwagę współczynniki LIRA i PBOP. Dodatkowe 1,5% zostaje dodane na końcu.

Prawdopodobnie nie jest to najbardziej wydajne rozwiązanie pod względem golfa, ale nieco różni się od Perla.

Błąd zmiennoprzecinkowy powinien wystąpić przy większych liczbach i można go naprawić, dodając 1 lub 2 dodatkowe bajty do każdego współczynnika.

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
źródło
Nie potrzebujesz ()s wokół x>10?:, ?:kojarzy od prawej do lewej. Myślę, że możesz także zaoszczędzić niektóre bajty, mnożąc nawiasy, np. (x-10)*4.154598+39.05314Równa się x*4.154598-41.54598+39.05314równa się x*4.154598-2.49284.
Neil
1

R , 52 bajty

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

Wypróbuj online!

Generuje liniową funkcję aproksymacyjną na podstawie wartości mojej poprzedniej odpowiedzi na 0,10,27 i 10 ^ 6. Haczyk: górna granica na wejściu wynosi 10 ^ 6.

approxfun(z ecdf, stepfun, splinefun, itd.) jest jedną z wielu cech miłe z R.

JayCe
źródło
0

VBA, 88 bajtów

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

Stawka podstawowa i wyższe stawki różnicowe za użytkowanie zostały pomnożone przez 5, a mnożnik opłaty CPUC podzielony przez 5 (0,203).

Edytor VB doda End Functionlinię, dlatego dołączone jest zasilanie linii terminala.

Joffan
źródło