Construa uma calculadora de imposto marginal

8

Houve alguns problemas na calculadora de taxas de impostos aqui que dependem de taxas definidas (especificamente as taxas federais dos EUA), mas nenhum que tenha feito isso para listas arbitrárias.

Sua tarefa é criar um programa ou função que faça uma lista arbitrária de faixas de impostos marginais e calcule o valor efetivo do imposto pago em um determinado valor da renda tributável.

Seu programa terá como entrada:

  • Npares de números no formulário (amt, rate), cada um representando um suporte de imposto.

    • amté o valor do lucro tributável acima do qual a taxa de imposto começa a ser aplicada. Esses valores serão todos números inteiros e aparecerão em ordem crescente.

    • rate é a taxa de imposto, expressa como uma porcentagem decimal de 0 a 100, inclusive.

  • O valor do lucro tributável, como um número inteiro não negativo.

Se nenhuma taxa for especificada para $ 0, presume-se que a taxa seja 0%.

Como alternativa, seu programa também pode levar como entrada duas listas (amt1, amt2, ...)e (rate1, rate2, ...), contendo os valores e taxas na mesma ordem.

Seu programa irá então a saída do imposto a pagar, quer para duas casas decimais, ou arredondado para baixo para a unidade de moeda inteiro mais próximo.


Um exemplo de entrada (os escalões de impostos canadenses mais recentes, de 2016, com o crédito tributário pessoal básico aplicado e nada mais):

11474 15
45282 20.5
90563 26
140388 29
200000 33

393216

E sua saída correspondente:

108357.07  or  108357

O programa mais curto em qualquer idioma para fazer isso vence.

Joe Z.
fonte
A entrada como [[amt, amt, amt], [taxa, taxa, taxa]] está OK? Ou tem que ser pares de [amt, rate]?
Emigna
A entrada poderia ser 1 lista de valores, 1 lista de taxas e o valor da receita tributária (3 entradas no total)?
Emigna
Bem, eu especifiquei (amt, rate), mas não altera fundamentalmente o problema para aceitar a outra lista, então eu o modificarei para que você possa.
Joe Z.

Respostas:

2

05AB1E, 35 24 bytes

vy³ï‚{0è)˜}³ï‚˜¥²ø€PTn/O

Explicação

vy                         # for each amount
  ³ï‚                      # pair with taxable income
     {0è                   # get min
        )˜}                # add to list
           ³ï‚˜            # add income to the end of the list
               ¥           # get deltas
                ²ø         # zip with tax rates
                  €P       # map product on each pair of [amount in tax bracket,rate]
                    Tn/    # divide by 100
                       O   # sum
                           # implicitly display result

Experimente online

Emigna
fonte
Os seres humanos realmente leem e entendem o código 05AB1E?
DavidC
@ DavidC: eu aprendi a entender a maior parte. Vou escrever uma explicação embora. Já o teria feito, mas não tinha certeza se os dois métodos de entrada estavam corretos.
Emigna
3

Haskell, 67 66 bytes

Obrigado Damien por -1 byte.

Esta solução está na forma de uma função infix,, ?do tipo (Integral b, RealFrac r) => [(r, r)] -> r -> b. A função auxiliar,, #faz os cálculos necessários enquanto ?serve para lidar com as especificações de E / S.

a?b=floor$reverse a#b
((m,p):r)#i|v<-min i m=p/100*(i-v)+r#v
_#_=0
ankh-morpork
fonte
((m,p):r)#i|v<-min i m=p/100*(i-v)+r#vsalva 1 byte
Damien
Obrigado @Damien! Eu não sabia que você poderia atribuir valores dentro de um guarda assim.
Ankh-morpork
2

Mathematica 85 82 bytes

Derivado do código de Josh O'Brien em R.

d_~f~i_:=Tr@Thread[Differences@((i~Min~#&/@d[[All,1]]~Append~∞))d[[All,2]]/100.]

Uso

f[{{11474, 15}, {45282, 20.5}, {90563, 26}, {140388, 29}, {200000, 33}}, 393216]

108357.

DavidC
fonte
Portanto, isso foi solicitado antes, mas não neste site em particular. Faz sentido.
Joe Z.
1

Matlab, 79 bytes

Supondo que podemos pegar amte ratecomo vetores de coluna separados:

function[]=f(a,b,c)
t=sort([0;a;c]);fix(sum(diff(t).*[0;b/100].*(t(2:end)<=c)))

Se não podemos (então aé uma matriz de duas colunas de amte rate) são 87 bytes.

function[]=f(a,c)
t=sort([0;a(:,1);c]);fix(sum(diff(t).*[0;a(:,2)/100].*(t(2:end)<=c)))

Explicação:

f(a,b,c)           -- takes amt, rate and income
[0;a;c]            -- gives a vector of amounts with 0 and the income amount
t=sort(...)        -- sort this vector
diff(t)            -- gives us amounts to be taxed in every bracket
diff(t).*[0;b/100] -- tax in every bracket
.*(t(2:end)<=c)    -- take only entries lower than the income
sum(...)           -- sum everything
fix(...)           -- round towards 0
pajonk
fonte
1

JavaScript (ES6), 60 bytes

(a,n)=>a.map(([b,r])=>{t+=n>b&&(n-b)*(r-p);p=r},p=t=0)|t/100

aé uma matriz de matrizes de banda e taxa, que seria [[11474, 15], [45282, 20.5], [90563, 26], [140388, 29], [200000, 33]]o exemplo dado e né a renda ( 393216).

Neil
fonte
Você pode fornecer mais informações sobre o formato de entrada?
Joe Z.
0

Rápido, 61 bytes

zip(zip(m+[i],[0]+m).map{$0-$1},[0]+r).map{$0*$1}.reduce(0,+)

Sem Golfe, com casos de teste:

struct TaxContext {
    let marginLowerBound: [Double]
    let rates: [Double]
}

// ungolfed
extension TaxContext {
    func calcAfterTaxIncome(_ income: Double) -> Double {
        //drop first element (0), append income
        let upper = marginLowerBound + [income]
        let lower = [0] + marginLowerBound

        let incomeInEachMargin = zip(upper, lower)
            .map{ upperBound, lowerBound in upperBound - lowerBound }

        let taxInEachMargin = zip(incomeInEachMargin, [0]+rates)
            .map{ incomeInMargin, rate in incomeInMargin * rate }

        let totalTax = taxInEachMargin.reduce(0, +)

        print(upper)
        print(lower)
        print(incomeInEachMargin)
        print(rates)
        print(taxInEachMargin)

        return totalTax    
    }
}

// golfed
extension TaxContext {
    // computed properties to serve as aliases for the golfed version
    var m: [Double] { return self.marginLowerBound }
    var r: [Double] { return self.rates }

    func f(_ i: Double) -> Double {
        return zip(zip(m+[i],[0]+m).map{$0-$1},[0]+r).map{$0*$1}.reduce(0,+)
    }
}

let testCase1 = TaxContext(
    marginLowerBound: [10_000, 20_000, 30_000],
    rates: [0.1, 0.2, 0.3, 0.4]
)
let result1 = testCase1.calcAfterTaxIncome(70_000)
print(result1)


let testCase2 = TaxContext(
    marginLowerBound: [11474 , 45282, 90563, 140388, 200000],
    rates: [0.15, 0.205, 0.26, 0.29, 0.33]
)
let result2 = testCase2.calcAfterTaxIncome(393216)
print(result2)
Alexander - Restabelecer Monica
fonte