A conta da água de Fred

9

Fred é um cara quase amigável, mas na realidade ele é mau.

Por isso, Fred mora sozinho em um pequeno apartamento em Los Altos, CA. Fred é tão cruel, porque ele é muito especial sobre a água. Ele, portanto, precisa de sua ajuda para descobrir qual é a conta de água.

Seu trabalho é escrever uma função ou programa que retorne sua conta de água, dada a quantidade de água usada como entrada (que é sempre um número inteiro).

O consumo de água é dividido em camadas. Isso significa que existem faixas de preços, dependendo da quantidade de água.

Estes são os níveis, seus preços e as quantidades de água a que correspondem:

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

Para n centenas de pés cúbicos (Ccf), também existem as seguintes taxas adicionais:

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

A soma das taxas de Nível I, Nível II, Nível III, CPUC, LIRA e PBOP é a conta total da água. Nesta soma, você deve retornar ou imprimir no console arredondado para duas casas decimais.

Aqui estão dois exemplos:

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

Este é o código de golfe, então o código mais curto em bytes ganha!

Daniel
fonte
Verifique se minha edição corresponde à sua intenção.
Msh210
Sim, obrigado @ msh210, que é muito mais clara do que o que eu tinha
Daniel
Se você está disposto a desperdiçar reputação com uma votação negativa, pelo menos, poderia explicar por quê?
Daniel
@Dopapp Algumas pessoas podem não gostar do desafio. Nada que você possa fazer lá. Pelo que vale, os desafios de redução de votos não subtraem a reputação do votante - apenas respostas.
Mego 28/06
Temos que lidar com não inteiro n?
PurkkaKoodari

Respostas:

1

Pitão, 55 41 bytes

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

O código contém caracteres não imprimíveis, então aqui está um 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

Explicação

  1. ."…"é uma sequência compactada que contém 3.8476,4.0932,4.9118.
  2. vavalia isso para a tupla (3.8476, 4.0932, 4.9118). Estes são os preços dos níveis multiplicados pelo CPUC adicionado.
  3. UQgera a gama 0... n-1.
  4. c,T27Divide esse intervalo nos índices 10 e 27, com listas vazias extras no final, se o intervalo for muito curto.
  5. lM encontra o comprimento de cada parte, fornecendo a quantidade de água para cada camada.
  6. *V multiplica isso pela tupla da etapa 2 para obter os preços das camadas.
  7. s soma os resultados.
  8. +*Q.051Adiciona a entrada multiplicada por 0,051, ou seja, LIRA + PBOP.
  9. .R2Arredonda o resultado para 2 casas decimais.

Experimente online.

PurkkaKoodari
fonte
2

Mathematica, 83 76 69 bytes

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

Função anônima que constrói uma matriz das três camadas na primeira coluna mais o LIRA e o PBOP representados como um número de precisão arbitrária na quarta coluna. A coisa toda é multiplicada 1.015e todos os elementos da matriz são somados e arredondados para .01. Como 51/1015*1.015será o desejado, 0.051a saída é exatamente tão precisa quanto a especificação em OP.

Uma solução mais curta, em 76 bytes , como sugeri no meu comentário na solução Perl

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

onde 1.015é levado em consideração os preços desde o início e, em seguida, o LIRA e o PBOP são adicionados no topo da primeira camada.

73 bytes (mas estou relutante em atualizar minha contagem de bytes, pois isso é bastante próximo da solução Perl direta):

69 bytes - ah, que diabos, o golfe também levou algum esforço.

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

EDIT referente ao erro de ponto flutuante
As três primeiras iterações da minha resposta são de fato exatas em sua representação decimal, uma vez que todos os coeficientes envolvidos têm representações decimais finais. No entanto, como os coeficientes são explicitamente flutuantes, armazenados em binários e com representações binárias sem terminação, entradas grandes o suficiente começarão a acumular erros nos dígitos menos significativos da representação binária. Eu acho que, quando o flutuador é tão grande, que cabe apenas 3-4 dígitos à direita do ponto decimal, podemos esperar erros de cerca de 1 centavo. Veja abaixo uma resposta exata .

72 bytes, um pouco imune a imprecisões de flutuação

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

A multiplicação pelo líder .01é feita no último passo. Até esse ponto, todo o cálculo é feito com números inteiros. Isso significa que, se o .01omitido, haverá um resultado exato , mas expresso em centavos, em vez de dólares. Obviamente, a multiplicação por um float converte tudo em um float e, como mencionado, ele precisa ser pequeno o suficiente para caber em 64 bits e ainda ser preciso .01.

LLlAMnYP
fonte
2

05AB1E, 64 58 51 bytes

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

Explicado

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

Experimente online

Emigna
fonte
1

Perl 5, 73 bytes

A solução óbvia. 72 bytes, mais 1 para em -nevez de -e.

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

Economizou 5 bytes graças ao LLlAMnYP . Obrigado!

msh210
fonte
No meu comentário anterior, essa edição acaba eliminando os erros de ponto flutuante que você tinha no original.
LLlAMnYP
@LLlAMnYP, certamente qualquer aproximação deve ter um erro para um valor suficientemente alto da entrada. Espero que esse limite seja alto o suficiente para que o OP não se importe (porque é uma quantidade razoável de água para a residência de uma única pessoa).
msh210
@ msh210 Você não conhece a história de Fred !!
gato
Não, porque você está multiplicando e adicionando números com representação decimal finita. Obviamente, quando você os representa como flutuadores, eles podem ter uma representação binária não tão boa. Você pode esperar erros quando a representação flutuante permitir apenas de 3 a 4 dígitos à direita do decimal. Minha "resposta de bônus" na parte inferior da minha postagem supera isso, usando números inteiros até a última etapa (que converte centavos em dólares). Se eu omitisse a multiplicação .01, ela permaneceria precisa enquanto o número inteiro pudesse ser armazenado.
28416 LLlAMnYP
1

Oracle SQL 11.2, 151 bytes

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;

Sem golfe

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
fonte
Livre-se do espaço entre SELECTe ((DECODEsalve um byte. Economize mais 10 bytes usando uma tabela nomeada! 7 removendo os dois pontos e usando um nome de coluna de um caractere mais três usando o nome de uma tabela de um caractere.
Giacomo Garabello
@ Giacomo Garabello: remover o espaço sempre retorna nulo com o sapo e retorna um erro com o SQLDeveloper. O script de criação de tabela adiciona mais de 10 bytes.
Jeto
você não tem que adicionar a criação script ... olhada aqui
Giacomo Garabello
1

JavaScript ES6, 77 bytes

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

Sem golfe

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
}

Eu considerei os coeficientes LIRA e PBOP. Os 1,5% extras são adicionados no final.

Provavelmente não é a solução mais eficiente em termos de golfe, mas um pouco diferente da solução Perl.

O erro de ponto flutuante deve ocorrer com números maiores e pode ser corrigido adicionando 1 ou 2 bytes extras a cada coeficiente.

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
fonte
Você não precisa as ()s em todo o x>10?:, ?:associados para a esquerda para a direita. Eu acho que você também pode salvar alguns bytes multiplicando os parênteses, por exemplo, (x-10)*4.154598+39.05314igual a x*4.154598-41.54598+39.05314igual x*4.154598-2.49284.
Neil
1

R , 52 bytes

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

Experimente online!

Gera uma função de aproximação linear, com base nos valores da minha resposta anterior em 0,10,27 e 10 ^ 6. O problema: o limite superior da entrada é 10 ^ 6.

approxfun(com ecdf, stepfun, splinefun, etc.) é uma das muitas características agradáveis de R.

JayCe
fonte
0

VBA, 88 bytes

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

A taxa básica e as taxas diferenciais de uso mais altas foram multiplicadas por 5 e o multiplicador de taxas da CPUC dividido por 5 (0,203).

O editor VB adicionará uma End Functionlinha, e é por isso que o feed da linha do terminal está incluído.

Joffan
fonte
0

Pitão - 58 51 bytes

.Rs+*Bs*V++m3.8476Tm4.0932 17m4.9118Qm1Q.015*.051Q2

Conjunto de Teste .

Maltysen
fonte