Construye una calculadora de impuestos marginales

8

Aquí ha habido algunos problemas de cálculo de tasas impositivas que dependen de tasas definidas (específicamente tasas federales de EE. UU.), Pero ninguna que lo haya hecho para listas arbitrarias.

Su tarea es crear un programa o función que tome una lista arbitraria de tramos impositivos marginales y calcule la cantidad efectiva de impuestos pagados sobre una cantidad dada de ingresos imponibles.

Su programa tomará como entrada:

  • Npares de números en el formulario (amt, rate), cada uno representando un tramo impositivo.

    • amtes la cantidad de renta imponible por encima de la cual comienza a aplicarse la tasa impositiva. Estas cantidades serán todas enteras y aparecerán en orden creciente.

    • rate es la tasa impositiva, expresada como un porcentaje decimal de 0 a 100 inclusive.

  • El importe de la renta imponible, como un entero no negativo.

Si no se especifica una tasa para $ 0, se supone que la tasa es 0%.

Alternativamente, su programa también puede tomar como entrada dos listas (amt1, amt2, ...)y (rate1, rate2, ...), que contienen las cantidades y tasas en el mismo orden.

Su programa entonces la salida del impuesto a pagar, ya sea con dos cifras decimales, redondeada o abajo a la unidad monetaria entera más cercana.


Un ejemplo de entrada (los tramos fiscales canadienses más recientes, de 2016, con el crédito fiscal personal básico aplicado y nada más):

11474 15
45282 20.5
90563 26
140388 29
200000 33

393216

Y su salida correspondiente:

108357.07  or  108357

El programa más corto en cualquier idioma para hacer esto gana.

Joe Z.
fuente
¿La entrada como [[amt, amt, amt], [rate, rate, rate]] está bien? ¿O tiene que ser pares de [amt, rate]?
Emigna
¿Podría la entrada ser 1 lista de montos, 1 lista de tasas y el valor de los ingresos fiscales (3 entradas en total)?
Emigna
Bueno, he especificado (amt, rate), pero no cambia el problema fundamentalmente para aceptar la otra lista, por lo que lo modificaré para que pueda.
Joe Z.

Respuestas:

2

05AB1E, 35 24 bytes

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

Explicación

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

Pruébalo en línea

Emigna
fuente
¿Los seres humanos realmente leen y entienden el código 05AB1E?
DavidC
@DavidC: He aprendido a entender la mayor parte. Sin embargo, escribiré una explicación. Ya lo habría hecho, pero no estaba seguro si ambos métodos de entrada estaban bien.
Emigna
3

Haskell, 67 66 bytes

Gracias Damien por -1 byte.

Esta solución tiene la forma de una función infija ?, de tipo (Integral b, RealFrac r) => [(r, r)] -> r -> b. La función auxiliar #, realiza los cálculos necesarios mientras ?sirve para manejar las especificaciones IO.

a?b=floor$reverse a#b
((m,p):r)#i|v<-min i m=p/100*(i-v)+r#v
_#_=0
ankh-morpork
fuente
((m,p):r)#i|v<-min i m=p/100*(i-v)+r#vahorra 1 byte
Damien
Gracias @Damien! No sabía que podía asignar valores dentro de un guardia como ese.
ankh-morpork
2

Mathematica 85 82 bytes

Derivado del código de Josh O'Brien en 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
fuente
Esto se ha preguntado antes, pero no en este sitio en particular. Tiene sentido.
Joe Z.
1

Matlab, 79 bytes

Asumiendo que podemos tomar amty ratecomo vectores de columna separados:

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

Si no podemos (entonces aes una matriz de dos columnas de amty rate) son 87 bytes.

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

Explicación:

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

aes una matriz de matrices de banda y velocidad, que sería [[11474, 15], [45282, 20.5], [90563, 26], [140388, 29], [200000, 33]]para el ejemplo dado, y nes el ingreso ( 393216).

Neil
fuente
¿Puede proporcionar más información sobre el formato de entrada?
Joe Z.
0

Swift, 61 bytes

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

Sin golf, con casos de prueba:

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 - Restablece a Monica
fuente