Juros compostos ... com dinheiro do mago


15

Gringotes não é apenas um cofre, mas uma instituição financeira respeitável e assistentes também precisam de empréstimos. Como você não quer ser ferrado pelos duendes de Gringotes, decidiu que seria uma boa ideia escrever um programa para calcular juros. Os juros são compostos apenas anualmente.

Sua tarefa é calcular o valor total devido após os juros, considerando o principal, a taxa de juros e o tempo (anos inteiros), operando em denominações inteiras de dinheiro dos feiticeiros, arredondando para o Knut inteiro mais próximo. Existem 29 Knuts de bronze em uma foice de prata e 17 foices em um galeão de ouro.

Exemplo

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 e Regras

  • A entrada e a saída podem estar em qualquer formato conveniente. Você deve conhecer Knuts, Foice, Galeão, taxa de juros e tempo. Todos, exceto a taxa de juros, serão números inteiros. A taxa de juros está em incrementos de 0,125%.
  • O dinheiro de entrada não é garantido como canônico (ou seja, você pode ter 29 ou mais Knuts e 17 ou mais foices.)
  • A saída deve ser a representação canônica. (ou seja, menos de 29 Knuts e menos de 17 Foices)
  • Os totais devidos, até 1.000 galeões, devem ser precisos dentro de 1 Knut por ano de interesse, quando comparados com cálculos de precisão arbitrários.
    • Você pode arredondar para baixo após cada ano de interesse ou apenas no final. Os cálculos de referência podem levar isso em consideração para verificações de precisão.

Feliz golfe!


4
Podemos tomar a taxa de juros como um decimal em vez de uma porcentagem? (por exemplo, em 0.0725vez de 7.25)
Shaggy

@Shaggy eu também gostaria de saber isso
senox13

Se o empréstimo for exatamente 1 Knut e os juros forem de 99% ao ano e o prazo for 1 ano, o resultado deve ser "1 Knut" ou "2 Knuts"?
Chas Brown

Em outras palavras, esclareça o significado matemático da fraserounding down
senox13

1
@ChasBrown: 1 Knut. Truncar / andar a função até o Knut inteiro mais próximo.
precisa saber é o seguinte

Respostas:


6

R , 70 62 bytes

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

Experimente online!

Toma entrada como d: depósito em knuts, foices, galeões; i: taxa de juros como decimal; y: anos. Produz depósito final em knuts, foices, galeões. Obrigado a @ Giuseppe por usar a multiplicação de matrizes para economizar alguns bytes (e apontar como evitar a necessidade de quebrar em 1e99).


Eu não sei R; o que tê-los ao redor ganha você?
dfeuer

@dfeuer ele é levado 1E99 modificação, por isso, se seus galeões obter essa alta que vai cair a zero
Nick Kennedy

O que eu estou querendo saber é o que você ganha tomando-os mod 1e99.
Dfeuer # 419

A maioria das funções R é vetorizada. Nesse caso, estou passando a saída pela %%função, que é mod. Idealmente, eu gostaria de deixar os galeões sozinhos, mas usar um número infinito de mod retorna NaN e, portanto, acabei de usar um número muito grande (mas que é pequeno em bytes). As alternativas que eu vim acima com são mais longos (por exemplo, [ tio.run/##JYrLCsIwEEV/... Experimente online!])
Nick Kennedy

@NickKennedy você poderia fazer 9e99bem ... Além disso, você pode golfe até 63 bytes
Giuseppe

4

Python 3.8 (pré-lançamento) , 75 74 71 bytes

-1 bytes graças a @EmbodimentofIgnorance
-3 bytes graças a @xnor

Isso leva Knuts, Sickles e Galeões como ints, juros como float (decimal, não porcentagem) e anos como int. Retorna uma tupla contendo o número após o interesse de Knuts, Foice e Galeão, 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)

Experimente online!


Boa pegada. Atualizando resposta
senox13

A pergunta diz operating in whole denominations of wizard money, rounding down. Tomei rounding downa significar chop off everything after the decimal point.Usando o cabeçalho definitivamente soa como uma maneira mais fácil de fazer as coisas. Eu vou fazer isso para posts futuros, graças
senox13

Isso parece muito mais com "truncamento" do que "arredondamento"; mas pedi esclarecimentos ao OP (porque nit-picking é o nome do jogo aqui no PPCG :)).
Chas Brown

Não discordo de você, esse é apenas o significado que sempre vi usado para arredondar para baixo, porque você sempre arredonda para o número inteiro abaixo do resultado. Caso contrário, é apenas o arredondamento normal. Deixando OP decidir é uma boa idéia
senox13

Para sua informação, um truque útil para tornar testáveis ​​as funções anônimas no TIO é colocar I\=o cabeçalho dessa maneira . Além disso, parece que k//29//17pode ser k//493.
Xnor

3

APL + WIN, 37 28 26 bytes

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

2 bytes economizados graças ao lirtosiast

Experimente online! Cortesia de Dyalog Classic

Explicação:

(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?
precisa saber é o seguinte

@lirtosiast Obrigado, mas receio que meu antigo intérprete APL + WIN não tenha a função ⍨. Por todos os meios, envie-o como sua própria solução de APL.
Graham

@lirtosiast Obrigado novamente, eu peguei os 2 bytes resultantes da atribuição a a.
Graham

3

Perl 6 , 47 bytes

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

Experimente online!

Estou surpreso por ter conseguido colocar isso em um anonimamente, lambda! Especialmente a parte em que é mais* do que qualquer outra coisa. Toma entrada como interest rate (e.g. 0.0725), years, [Knuts, Sickles, Galleons]e retorna uma lista de moedas na mesma ordem.

Explicação:

 (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

Estou surpreso que você não tenha encontrado uma maneira de fazer com que o número de Knuts / Sickles / Galleons também se encaixe no que for. Em seguida, ele tinha acabado de ser eh, como ************************* ;-)
user0721090601

@guifa Os Whatevers são as entradas, então só pode haver realmente 3 delas (embora eu possa dividir a entrada de moeda por mais alguns *segundos, mas mais bytes). O resto dos *s são de multiplicação ( *) e exponenciais ( **)
Jo Rei

Eu quis dizer se você conseguiu as taxas de conversão (o número 29/17) nelas também. Mas é claro que foi uma piada, porque você precisa usar esses números mais de uma vez. Desculpe se o meu humor não passar
user0721090601

2

Gelatina , 29 bytes

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

Um programa completo aceitar argumentos: rate; [Galleons, Sickles, Knuts]; years.
Impressões[Galleons, Sickles, Knuts] .

Experimente online!

Pisos no final de todo o período.
÷ȷ2pode ser removido se aceitarmos a taxa como uma proporção e não como uma porcentagem.

Quão?

“¢×ø‘©×\ - 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

Conjunto de FPU Intel 8087, 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 e 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 um MACRO (basicamente uma função), este é um código de máquina não específico do SO, usando apenas o co-processador Intel 80x87 FPU / matemática para o cálculo.

Exemplo de programa de teste com saída:

    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

Resultado

insira a descrição da imagem aqui


1

Japonês, 48 ​​bytes

XÄ pY *(U*493+V*29+W)f
Uu493
[Uz493 ,Vz29 ,Vu29]

Minha primeira tentativa no Japt, indo para a recompensa de @ Shaggy! Escusado será dizer que isso não é muito golfe :(

Experimente Online!


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

Experimente online!

Obrigado a @Laikoni por dois bytes.

Os truques sujos: o número de moedas na entrada é ponto flutuante ( Double), enquanto o número de moedas na saída é integral ( Integer). O resultado é um par aninhado((Galleons, Sickles), Knotts) para evitar ter que achatar para um triplo.

Explicação

-- 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
Salve dois bytes com (truncate$ ... )-> truncate( ... )e em (g#s)k r nvez de c g s k r n.
Laikoni 4/03/19

@Laikoni, muito obrigado!
dfeuer

@Laikoni, eu realmente aprecio se você puder me encontrar alguns bytes em codegolf.stackexchange.com/questions/55960/… , se você tiver tempo.
Dfeuer # 6/19

1
Vou investigar quando encontrar tempo. Enquanto isso, posso apontar para a nossa sala de bate-papo Haskell, Monads and Men, e também para esta pergunta que você pode gostar, considerando seus poliglotas Hugs / GHC.
Laikoni 6/03/19

1

Stax , 24 bytes

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

Execute e depure

Entrada é valores separados por espaço. interest years knuts sickles galleons

A saída é separada por nova linha.

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)}

A entrada é Ansuma lista com 5 itens: Knuts, Foice, Galeões, Juros (decimal) e Tempo (anos).
A saída é Ansimpressa e automaticamente impressa quando o programa é concluído.

Sem golfe:

: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)}

Exemplo:

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

Explicação:

:SetUpEditor C
:Ans→∟C

Uma nova lista ∟C,, é criada e Ansarmazenada nela.

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

Os Knuts, Foices e Galeões são convertidos em Knuts e armazenados em T.

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

Toma a quantidade de Knuts e aplica juros compostos a ela.
Os juros são calculados aqui.

:remainder(iPart(T),493→R

Armazena o I nteger Parte do Tmodulo 493 em R. Usado para reduzir a contagem de bytes.

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

Avalia uma lista com 3 itens (Knuts, Foice e Galeão). A lista é automaticamente armazenada Ans.


Nota: A contagem de bytes é avaliada considerando a contagem de bytes fornecida em [MEM][2][7] (lista de programas na RAM) e subtraindo a quantidade de caracteres no nome do programa e mais 8 bytes usados ​​para o programa:

103-5-5 = 90 bytes


0

K, 46 bytes

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

c armazene a lista para conversão base

t é a função que calcula a quantidade total

Use exemplo:

t[103 16 23;7.25;3]

escreve (128;4;24.29209)

Explicação:

  • c/:x transformar a lista (galeão; foice; knuts) em kuts

  • 1+y%100 calcular taxa de juros (exemplo 1.0725 para taxa de 7,25%)

  • O lambda {z(y*)\x}faz o trabalho: itere 3 vezes, aplicando interes * main e retorna final main.

  • c\: gera galeão, foices, knuts a partir de knuts

NOTA.- se você não precisar de uma função de nomes, podemos usar um lambda, economizando 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%

Recebe entrada como argumentos de linha de comando na ordem Galleons, Sickles, Knuts, interesse, anos. O interesse é uma porcentagem, mas expresso sem o sinal de%. Trunca após todos os anos. A saída está na ordem Galeões, foices e Knuts. Suporta pelo menos 5000 galeões. Explicação:

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

O lote possui apenas aritmética inteira. Felizmente, a taxa de juros é sempre um múltiplo de 0.125. Começamos dividindo na vírgula decimal, para que ela ise torne a parte inteira da taxa de juros e fda fração decimal. Estes são multiplicados por 8. O primeiro dígito de fagora é o número de oitavos na taxa de juros percentual.

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

Isso é então extraído usando o fatiamento de cordas e adicionado para fornecer uma taxa de juros em 1/800ths. O número de Knuts também é calculado.

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

Calcule e adicione os juros de cada ano.

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

Converta de volta para Galeões e Foices.


0

05AB1E (herdado) , 24 bytes

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

Porto da resposta do Perl 6 do @JoKing , por isso não deixe de vota-lo também se você gosta desta resposta!

Estou usando a versão legada devido a um bug na nova versão em que £ que não funciona com números inteiros, portanto, uma conversão explícita para string §(entre o segundo e o3 ) (até que o bug seja corrigido).

Toma o interesse como decimal, seguido pelo ano, seguido pela lista de [Knuts, Foice, Galeões].

Experimente online.

Explicação:

>                      # 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)

Veja este 05AB1E ponta do meu (seção Como comprimir grandes inteiros? ) Para entender por que •1ýÑ•é 119493.


0

APL (NARS), 37 caracteres, 74 bytes

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

tradução da solução APL muito boa e com poucos bytes pelo usuário Graham para uma solução que usa uma função em vez da entrada padrão ... test e como usá-la:

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

(não digo que entendi algoritmo)


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.