Interés compuesto ... con dinero de mago


15

Gringotts no es solo una bóveda, sino que una institución financiera y magos acreditados también necesitan préstamos. Como no quieres que los duendes de Gringotts te fastidien, decidiste que sería una buena idea escribir un programa para calcular el interés. El interés se agrava solo anualmente.

Su tarea es calcular el monto total adeudado después del interés dado el principal, la tasa de interés y el tiempo (años completos), operando en denominaciones completas de dinero de magos, redondeando al Knut entero más cercano. Hay 29 Knuts de bronce en una hoz plateada y 17 hoces en un galeón de oro.

Ejemplo

Loan taken out:
 23 Knuts
 16 Sickles
103 Galleons
@ 7.250%
For 3 years

Total owed after interest:
 24 Knuts
  4 Sickles
128 Galleons

Notas y reglas

  • La entrada y salida pueden estar en cualquier formato conveniente. Debe tomar Knuts, Hoces, Galeones, tasa de interés y tiempo. Todos menos la tasa de interés serán números enteros. La tasa de interés es en incrementos de 0.125%.
  • No se garantiza que el dinero de entrada sea canónico (es decir, puede tener 29 o más Knuts y 17 o más Hoces).
  • La salida debe ser la representación canónica. (es decir, menos de 29 Knuts y menos de 17 Hoces)
  • Los totales adeudados, hasta 1,000 galeones, deben tener una precisión de 1 Knut por año de interés en comparación con los cálculos de precisión arbitrarios.
    • Puede redondear después de cada año de interés o solo al final. Los cálculos de referencia pueden tener esto en cuenta para las comprobaciones de precisión.

¡Feliz golf!


44
¿Podemos tomar la tasa de interés como un decimal en lugar de un porcentaje? (por ejemplo, en 0.0725lugar de 7.25)
Shaggy

@ Shaggy También me gustaría saber esto
senox13

Si el préstamo es exactamente 1 Knut, y el interés es del 99% anual, y el plazo es de 1 año, ¿el resultado debería ser "1 Knut" o "2 Knuts"?
Chas Brown

En otras palabras, aclare el significado matemático de la fraserounding down
senox13

1
@ChasBrown: 1 Knut. Función truncar / piso al Knut completo más cercano.
Beefster

Respuestas:


6

R , 70 62 bytes

function(d,i,y)(x=d%*%(a=c(1,29,493))*(1+i)^y)%/%a%%c(29,17,x)

Pruébalo en línea!

Toma entrada como d: depósito en knuts, hoces, galeones; i: tasa de interés como decimal; y: años. Salidas de depósito final en knuts, hoces, galeones. Gracias a @Giuseppe por usar la multiplicación de matrices para guardar algunos bytes (y señalar cómo evitar la necesidad de ajustar en 1e99).


No se R; ¿Qué te hace tenerlos envueltos?
dfeuer

@dfeuer se toman mod 1e99, así que si tus galeones alcanzan ese nivel, caerán a cero
Nick Kennedy

Lo que me pregunto es qué ganas al tomarlos mod 1e99.
dfeuer

La mayoría de las funciones R están vectorizadas. En este caso, estoy pasando la salida a través de la %%función, que es mod. Idealmente, me gustaría dejar los galeones solos, pero tomar un número infinito de mod devuelve NaN, por lo que acabo de usar un número realmente grande (pero uno que es pequeño en bytes). Las alternativas que se me ocurren son más largas (p. Ej., [ Tio.run/##JYrLCsIwEEV/… ¡ Pruébelo en línea!])
Nick Kennedy

@NickKennedy también podrías hacerlo 9e99... Además, puedes jugar golf hasta 63 bytes
Giuseppe

4

Python 3.8 (prelanzamiento) , 75 74 71 bytes

-1 bytes gracias a @EmbodimentofIgnorance
-3 bytes gracias a @xnor

Esto toma Knuts, Sickles y Galleons como ints, el interés como flotante (decimal, no porcentaje) y los años como int. Devuelve una tupla que contiene el número después del interés de Knuts, Sickles y Galleons, respectivamente.

lambda K,S,G,R,Y:((k:=int((K+G*493+S*29)*(1+R)**Y))%29,k//29%17,k//493)

Uso:

>>> print(I(23,16,103,0.0725,3))
(24, 4, 128)

Pruébalo en línea!


Buena atrapada. Actualizando respuesta
senox13

La pregunta dice operating in whole denominations of wizard money, rounding down. Supuse rounding downque chop off everything after the decimal point.usar el encabezado definitivamente parece una forma más fácil de hacer las cosas. Lo haré para futuras publicaciones, gracias
senox13

Eso suena mucho más a "truncar" que a "redondear"; pero le he pedido al OP que me aclare (porque el nombre del juego aquí es PPCG :)).
Chas Brown

No estoy en desacuerdo con usted, ese es el significado que siempre he usado para redondear, porque siempre redondea al número entero debajo de su resultado. De lo contrario, es solo redondeo normal. Dejar que OP decida es una buena idea
senox13

Para su información, un truco útil para hacer que las funciones anónimas sean comprobables en TIO es poner I\=el encabezado de esta manera . Además, parece que k//29//17puede ser k//493.
xnor

3

APL + WIN, 37 28 26 bytes

⌊a⊤((a←0 17 29)⊥⎕)×(1+⎕)*⎕

2 bytes guardados gracias a lirtosiast

Pruébalo en línea! Cortesía de Dyalog Classic.

Explicación:

(1+⎕)*⎕ prompts for years followed by decimal interest rate and calculates
         compounding multiplier

((a←0 17 29)⊥⎕) prompts for Galleons, Sickles and Knuts and converts to Knuts

⌊a⊤ converts back to Galleons, Sickles and Knuts and floor 
    after applying compound interest. 

⌊a⊤(⎕⊥⍨a←0 17 29)×⎕*⍨1+⎕por 24?
lirtosiast el

@lirtosiast Gracias, pero me temo que mi antiguo intérprete APL + WIN no tiene la función ⍨. Por supuesto, presente esto como su propia solución APL.
Graham

@lirtosiast Gracias de nuevo, he tomado los 2 bytes resultantes de la asignación a a.
Graham

3

Perl 6 , 47 bytes

((1+*)*** *(*Z*1,29,493).sum+|0).polymod(29,17)

Pruébalo en línea!

Me sorprende que logré poner esto en un anonimato ¡Lo que sea lambda! Especialmente la parte donde es más *s que otra cosa. Toma datos como interest rate (e.g. 0.0725), years, [Knuts, Sickles, Galleons]y devuelve una lista de monedas en el mismo orden.

Explicación:

 (1+*)           # Add one to the interest rate
      ***        # Raise to the power of the year
          *      # And multiply by
           (*Z*1,29,493).sum      # The number of Knuts in the input
                            +|0   # And floor it
(                              ).polymod(29,17)   # Get the modulos after divmoding by 29 and 17

Me sorprende que no hayas encontrado una manera de obtener también el número de Knuts / Sickles / Galleons para que encajen en lo que sea. Entonces sería eh, como ************************* ;-)
user0721090601

@guifa Los Whatevers son las entradas, por lo que solo puede haber 3 de ellas (aunque puedo dividir la entrada de la moneda para obtener más *s pero más bytes). El resto de los *s son de multiplicación ( *) y exponenciales ( **)
Jo King

Me refiero a si también obtuviste las tasas de conversión (el número 29/17). Pero, por supuesto, fue una broma porque necesitas usar esos números más de una vez. Lo siento si mi humor no pasó
user0721090601

2

Jalea , 29 bytes

“¢×ø‘©×\
÷ȷ2‘*⁵×÷¢S×¢d®U1¦Ṫ€Ḟ

Un programa completo de aceptar argumentos: rate; [Galleons, Sickles, Knuts]; years.
Impresiones [Galleons, Sickles, Knuts].

Pruébalo en línea!

Pisos al final de todo el plazo.
÷ȷ2puede eliminarse si aceptamos la tasa como una razón en lugar de un porcentaje.

¿Cómo?

“¢×ø‘©×\ - Link 1 multipliers: no arguments
“¢×ø‘    - list of code-age indices = [1,17,29]
     ©   - (copy this to the register for later use)
       \ - reduce by:
      ×  -   multiplication  = [1,17,493]

÷ȷ2‘*⁵×÷¢S×¢d®U1¦Ṫ€Ḟ - Main Link
 ȷ2                  - 10^2 = 100
÷                    - divide = rate/100
   ‘                 - increment = 1+rate/100
     ⁵               - 5th command line argument (3rd input) = years
    *                - exponentiate = (1+rate/100)^years --i.e. multiplicand
      ×              - multiply (by the borrowed amounts)
        ¢            - call last Link as a nilad
       ÷             - divide (all amounts in Galleons)
         S           - sum (total Galleons owed)
           ¢         - call last Link as a nilad
          ×          - multiply (total owed in each of Galleons, Sickles, Knuts)
             ®       - recall from register = [1,17,29]
            d        - divmod (vectorises) = [[G/1, G%1], [S/17, S^17], [K/17, K%17]]
              U1¦    - reverse first one = [[G%1, G/1], [S/17, S%17], [K/17, K%17]]
                 Ṫ€  - tail €ach = [G/1, S%17, K%17]
                   Ḟ - floor (vectorises)

2

Ensamblaje Intel 8087 FPU, 86 bytes

d9e8 d906 7f01 dec1 8b0e 8301 d9e8 d8c9 e2fc df06 7901 df06 8701 df06
7b01 df06 8501 df06 7d01 dec9 dec1 dec9 dec1 dec9 9bd9 2e89 01df 0687
01df 0685 01d9 c1de c9d9 c2d9 f8d8 f2df 1e7b 01d8 fadf 1e7d 01d9 c9d9
f8df 1e79 01

Desmontado y documentado:

; calculate P+I of loan from wizard
; input:
;   G: number of Galleons (mem16)
;   S: number of Sickles (mem16)
;   K: number of Knuts (mem16)
;   R: interest rate (float)
;   T: time in years (mem16)
;   GS: Galleons to Sickles exchange rate (mem16)
;   SK: Sickles to Knuts exchange rate (mem16)
; output:
;   G: number of Galleons (mem16)
;   S: number of Sickles (mem16)
;   K: number of Knuts (mem16)
WIZ_INT_CALC    MACRO   G, S, K, R, T, GS, SK
                LOCAL   LOOP_EXP
                    ; - calculate interet rate factor
    FLD1            ; load 1
    FLD   R         ; load interest rate
    FADD            ; ST = rate + 1
    MOV   CX, T     ; Exponent is count for loop
    FLD1            ; load 1 into ST as initial exponent value
LOOP_EXP:           ; loop calculate exponent
    FMUL  ST,ST(1)  ; multiply ST = ST * ST(1)
    LOOP  LOOP_EXP
                    ; - convert demonimations to Knuts
    FILD  K         ; load existing Knuts
    FILD  SK        ; load Sickles to Knuts rate 
    FILD  S         ; load existing Sickles
    FILD  GS        ; load Galleons-to-Sickles exchange rate
    FILD  G         ; load existing Galleons
    FMUL            ; multiply galleons to get sickles
    FADD            ; add existing sickles
    FMUL            ; multiply sickles to get knuts
    FADD            ; add existing knuts
    FMUL            ; calculate P+I (P in Knuts * Interest factor)
                    ; - redistribute demonimations to canonical form
    FLDCW  FRD      ; put FPU in round-down mode
    FILD   SK       ; load Sickles to Knuts rate
    FILD   GS       ; load Galleons-to-Sickles exchange rate
    FLD    ST(1)    ; copy Galleons-to-Sickles exchange rate to stack for later
    FMUL            ; multiply to get Galleons-to-Knuts rate
    FLD    ST(2)    ; push original total Knuts from ST(2) into ST (lost by FPREM)
    FPREM           ; get remainder
    FDIV   ST,ST(2) ; divide remainder to get number of Sickles
    FISTP  S        ; store Sickles to S
    FDIVR  ST,ST(2) ; divide to get number of Galleons
    FISTP  G        ; store Galleons to G
    FXCH            ; swap ST, ST(1) for FPREM
    FPREM           ; get remainder to get number of Knuts
    FISTP  K        ; store Knuts to K
        ENDM

Implementado como un MACRO (básicamente una función), este es un código de máquina no específico del sistema operativo que usa solo el coprocesador Intel 80x87 FPU / matemático para el cálculo.

Ejemplo de programa de prueba con salida:

    FINIT           ; reset FPU

    WIZ_INT_CALC    G,S,K,R,T,GS,SK     ; do the "Wizardy"

    MOV  AX, K      ; display Knuts
    CALL OUTDEC     ; generic decimal output routine
    CALL NL         ; CRLF

    MOV  AX, S      ; display Sickles
    CALL OUTDEC     ; generic decimal output routine
    CALL NL         ; CRLF

    MOV  AX, G      ; display Galleons
    CALL OUTDEC     ; generic decimal output routine
    CALL NL         ; CRLF

    RET             ; return to DOS

K   DW  23          ; initial Kunts
S   DW  16          ; initial Sickles
G   DW  103         ; initial Galleons
R   DD  0.0725      ; interest rate
T   DW  3           ; time (years)
GS  DW  17          ; Galleons to Sickles exchange rate
SK  DW  29          ; Sickles to Knuts exchange rate
FRD DW  177FH       ; 8087 control word to round down

Salida

ingrese la descripción de la imagen aquí



1

Haskell , 73 bytes

(g#s)k r n|(x,y)<-truncate((493*g+29*s+k)*(1+r)^n)%29=(x%17,y)
(%)=divMod

Pruébalo en línea!

Gracias a @Laikoni por dos bytes.

Los trucos sucios: el número de monedas en la entrada es de coma flotante ( Double), mientras que el número de monedas en la salida es integral ( Integer). El resultado es un par anidado ((Galleons, Sickles), Knotts)para evitar tener que aplanar a un triple.

Explicación

-- Define a binary operator # that
-- takes the number of Galleons
-- and Slivers and produces a
-- function taking the number of
-- Knots, the rate, and the
-- number of years and producing
-- the result.
(g#s) k r n
   -- Calculate the initial value
   -- in Knotts, calculate the
   -- final value in Knotts,
   -- and divide to get the number
   -- of Galleons and the
   -- remainder.
  |(x,y)<-truncate((493*g+29*s+k)*(1+r)^n)%29
  -- Calculate the number of Slivers
  -- and remaining Knotts.
  =(x%17,y)
(%)=divMod

1
Guarde dos bytes con (truncate$ ... )-> truncate( ... )y en (g#s)k r nlugar de c g s k r n.
Laikoni

@Laikoni, muchas gracias!
dfeuer

@Laikoni, realmente agradecería que me pudieras encontrar un par de bytes en codegolf.stackexchange.com/questions/55960/… , si tienes tiempo.
dfeuer

1
Lo investigaré cuando encuentre el tiempo. Mientras tanto, puedo señalarle nuestra sala de chat de Haskell Of Monads and Men y también a esta pregunta que podría disfrutar con sus políglotas Hugs / GHC.
Laikoni

1

Stax , 24 bytes

»♀(╪M╢ú!!«ε◘÷╛SI►U/)-f!ö

Ejecutar y depurarlo

La entrada es valores separados por espacios. interest years knuts sickles galleons

La salida está separada por una nueva línea.

knuts
sickles
galleons

1

TI-BASIC (TI-84), 96 90 bytes

:SetUpEditor C:Ans→∟C:∟C(1)+29∟C(2)+493∟C(3)→T:T(1+∟C(4))^∟C(5)→T:remainder(iPart(T),493→R:{remainder(R,29),iPart(R/29),iPart(T/493)}

La entrada es Ansuna lista con 5 elementos: Knuts, Hoces, Galeones, Interés (decimal) y Tiempo (años).
La salida está entrante Ansy se imprime automáticamente cuando se completa el programa.

Sin golf:

:SetUpEditor C 
:Ans→∟C
:∟C(1)+29∟C(2)+493∟C(3)→T
:T(1+∟C(4))^∟C(5)→T
:remainder(iPart(T),493→R
:{remainder(R,29),iPart(R/29),iPart(T/493)}

Ejemplo:

{32,2,5,0.05,5}
       {32 2 5 .05 5}
prgmCDGF1
            {12 10 6}

Explicación:

:SetUpEditor C
:Ans→∟C

Se ∟Ccrea una nueva lista, y Ansse almacena en ella.

:∟C(1)+29∟C(2)+493∟C(3)→T

Los Knuts, Hoces y Galeones se convierten en Knuts y se almacenan en T.

:T(1+∟C(4))^∟C(5)→T

Toma la cantidad de Knuts y le aplica un interés compuesto.
El interés se calcula aquí.

:remainder(iPart(T),493→R

Almacena el que nteger parte deT módulo 493 en R. Se usa para acortar el recuento de bytes.

:{remainder(R,29),iPart(R/29),iPart(T/493)}

Evalúa una lista con 3 elementos (Knuts, Sickles y Galleons). La lista se almacena automáticamente enAns .


Nota: El recuento de bytes se evalúa tomando el recuento de bytes dado en [MEM] [2][7] (lista de programas en RAM) y restando la cantidad de caracteres en el nombre del programa y 8 bytes adicionales utilizados para el programa:

103-5-8 = 90 bytes


0

K, 46 bytes

c:1000 17 29
t:{c\:{z(y*)/x}[c/:x;1+y%100;z]}

c almacenar la lista para conversión de base

t es la función que calcula la cantidad total

Use ejemplo:

t[103 16 23;7.25;3]

escribe (128;4;24.29209)

Explicación:

  • c/:x transforma la lista (galeón; hoz; knuts) en kuts

  • 1+y%100 calcular la tasa de interés (ejemplo 1.0725 para tasa de 7.25%)

  • lambda {z(y*)\x}hace el trabajo: itera 3 veces, aplica interes * main y devuelve main principal.

  • c\: genera galeón, hoces, knuts de knuts

NOTA.- si no necesita una función de nombres, podemos usar una lambda, ahorrando 2 bytes {c\:{z(y*)/x}[c/:x;1+y%100;z]}inputArgs



0

Lote, 171 bytes

@set i=%4
@set/af=0,i=8*%i:.=,f=%,f*=8
@set/ai+=%f:~,1%,k=%1*493+%2*29+%3
@for /l %%y in (1,1,%5)do @set/ak+=k*i/800
@set/ag=k/493,s=k/29%%17,k%%=29
@echo %g% %s% %k%

Toma datos como argumentos de la línea de comandos en el orden Galleones, Hoces, Knuts, interés, años. El interés es un porcentaje pero se expresa sin el signo%. Trunca después de cada año. La salida está en el orden de Galeones, Hoces, Knuts. Admite al menos 5000 galeones. Explicación:

@set i=%4
@set/af=0,i=8*%i:.=,f=%,f*=8

El lote solo tiene aritmética de enteros. Afortunadamente, la tasa de interés es siempre un múltiplo de 0.125. Comenzamos dividiendo en el punto decimal, de modo que se iconvierte en la parte entera de la tasa de interés y fla fracción decimal. Estos se multiplican por 8. El primer dígito de fahora es el número de octavos en la tasa de interés porcentual.

@set/ai+=%f:~,1%,k=%1*493+%2*29+%3

Esto luego se extrae mediante el corte de cadenas y se agrega para dar una tasa de interés en 1/800. El número de Knuts también se calcula.

@for /l %%y in (1,1,%5)do @set/ak+=k*i/800

Calcule y agregue el interés de cada año.

@set/ag=k/493,s=k/29%%17,k%%=29
@echo %g% %s% %k%

Convertir de nuevo a galeones y hoces.


0

05AB1E (heredado) , 24 bytes

>Im•1ýÑ•3L£I*O*ï29‰ć17‰ì

Puerto de la respuesta de Perl 6 de @JoKing , así que asegúrate de votarlo también si te gusta esta respuesta.

Estoy usando la versión heredada debido a un error en la nueva versión donde £no funciona en enteros, por lo que un reparto explícito en cadena §(entre el segundo y3 se requiere ) (hasta que se solucione el error).

Toma el interés como decimal, seguido del año, seguido de la lista de [Knuts, Sickles, Galleons].

Pruébalo en línea.

Explicación:

>                      # Increase the (implicit) interest decimal by 1
                       #  i.e. 0.0725 → 1.0725
 Im                    # Take this to the power of the year input
                       #  i.e. 1.0725 and 3 → 1.233...
1ýÑ•                  # Push compressed integer 119493
     3L                # Push list [1,2,3]
       £               # Split the integer into parts of that size: [1,19,493]
        I*             # Multiply it with the input-list
                       #  i.e. [1,19,493] * [23,16,103] → [23,464,50779]
          O            # Take the sum of this list
                       #  i.e. [23,464,50779] → 51266
           *           # Multiply it by the earlier calculated number
                       #  i.e. 51266 * 1.233... → 63244.292...
            ï          # Cast to integer, truncating the decimal values
                       #  i.e. 63244.292... → 63244
             29       # Take the divmod 29
                       #  i.e. 63244 → [2180,24]
                ć      # Extract the head; pushing the remainder-list and head separately
                       #  i.e. [2180,24] → [24] and 2180
                 17   # Take the divmod 17 on this head
                       #  i.e. 2180 → [128,4]
                    ì  # And prepend this list in front of the remainder-list
                       #  i.e. [24] and [128,4] → [128,4,24]
                       # (which is output implicitly as result)

Ver este consejo 05AB1E mío (sección Cómo comprimir grandes números enteros? ) Para entender por qué •1ýÑ•es 119493.


0

APL (NARS), 37 caracteres, 74 bytes

{(x y z)←⍵⋄⌊¨a⊤(z⊥⍨a←0 17 29)×x*⍨1+y}

traducción de la muy buena y muy pequeña solución APL de bytes por parte del usuario de Graham a una solución que usa una función en lugar de una entrada estándar ... prueba y cómo usarla:

  f←{(x y z)←⍵⋄⌊¨a⊤(z⊥⍨a←0 17 29)×x*⍨1+y}
  f 3 0.0725 (103 16 23)
128 4 24

(No digo que haya entendido el algoritmo)


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.