Складні відсотки… з майстрами грошей


15

Ґрінґотс - це не просто скарбничка, але і авторитетна фінансова установа, і чарівники також потребують позик. Оскільки ви не хочете, щоб вас накрутили грінґотські гобліни, ви вирішили, що було б хорошою ідеєю написати програму для обчислення відсотків. Відсотки посилюються лише щорічно.

Ваше завдання - обчислити загальну суму заборгованості після відсотків з урахуванням основної суми, процентної ставки та часу (цілих років), що працює у цілих купюрах грошей майстра, округлюючи їх до найближчого цілого Кнута. Є 29 бронзових кнутів на срібному серпі та 17 серп у золотому галеоні.

Приклад

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

Total owed after interest:
 24 Knuts
  4 Sickles
128 Galleons

Примітки та правила

  • Введення та вихід можуть бути у будь-якому зручному форматі. Ви повинні брати в Кнутс, Серпи, Галеони, процентну ставку та час. Усі, крім процентної ставки, будуть цілими цифрами. Процентна ставка збільшується в 0,125%.
  • Гроші, що вводяться, не гарантуються як канонічні (тобто ви можете мати 29 і більше кнутів і 17 і більше серп.)
  • Результатом повинно бути канонічне зображення. (тобто менше 29 кнутів і менше 17 серпів)
  • Сума заборгованості, до 1000 галеонів, повинна бути точною до 1 Кнут на рік відсотків у порівнянні з довільними розрахунками точності.
    • Ви можете округляти їх після кожного року інтересу або лише наприкінці. Довідкові розрахунки можуть враховувати це для перевірки точності.

Щасливого гольфу!


4
Чи можемо ми взяти процентну ставку як десяткову замість відсотка? (наприклад, 0.0725замість 7.25)
Shaggy

@Shaggy Я також хотів би це знати
senox13

Якщо позика становить рівно 1 кнут, а відсоток становить 99% на рік, а термін - 1 рік, чи повинен результат бути "1 кнут" або "2 кнути"?
Час Браун

Іншими словами, уточніть, будь ласка, математичне значення фразиrounding down
senox13

1
@ChasBrown: 1 Кнут. Функція скорочення / підлоги до найближчого цілого Кнута.
Beefster

Відповіді:


6

R , 70 62 байт

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

Спробуйте в Інтернеті!

Вводиться як d: депозит у сучках, серпах, галеонах; i: процентна ставка у вигляді десяткової; y: років. Виводиться остаточний депозит у сучках, серпах, галеонах. Завдяки @Giuseppe за використання матричного множення для збереження деяких байтів (і вказує, як уникнути необхідності завершення на 1e99).


Я не знаю R; що їх перемогти?
dfeuer

@dfeuer вони взяли мод 1e99, тож якщо ваші галеони набудуть такої висоти, вони впадуть до нуля
Нік Кеннеді

Мені цікаво, що ви отримуєте, приймаючи їх мод 1e99.
dfeuer

Більшість функцій R векторизовані. У цьому випадку я передаю вихід через %%функцію, яка є модом. В ідеалі я хотів би залишити галеони в спокої, але беручи нескінченність числа мод повертає NaN, і тому я просто використав дійсно велике число (але таке, яке мало в байтах). Альтернативи, які я придумав, довші (наприклад, [ tio.run/##JYrLCsIwEEV/… Спробуйте в Інтернеті!])
Нік Кеннеді

@NickKennedy ви могли б зробити 9e99так само ... Крім того, ви можете
Джузеппе

4

Python 3.8 (передвипуск) , 75 74 71 байт

-1 байт завдяки @EmbodimentofIgnorance
-3 байти завдяки @xnor

Це сприймає Кнутс, Серпи та Галеони як інти, інтерес як поплавок (десятковий, а не відсотковий), а роки як цілий. Він повертає кортеж, що містить число після зацікавлення Knuts, Sickles і Galleons відповідно.

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

Використання:

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

Спробуйте в Інтернеті!


Хороший улов. Оновлення відповіді
senox13

Питання говорить operating in whole denominations of wizard money, rounding down. Я мав rounding downна увазі chop off everything after the decimal point.Використання заголовка, безумовно, звучить як простіший спосіб робити речі. Я буду робити це для майбутніх публікацій, дякую
senox13

Це звучить набагато більше, як "обрізання", ніж "округлення"; але я попросив ОП роз'яснити (адже збирання ніт - це назва гри тут, на PPCG :)).
Час Браун

Я не погоджуюся з вами, це якраз той сенс, який я завжди бачив, використовуючи для округлення вниз, тому що ви завжди круглі до цілого числа нижче вашого результату. Інакше це просто нормальне округлення. Дозволити ОП вирішити - це гарна ідея
senox13,

FYI, корисний трюк , щоб зробити анонімні функції перевіряється на TIO повинен помістити I\=в заголовок , як це . Також, схоже, це k//29//17може бути k//493.
xnor

3

APL + WIN, 37 28 26 байт

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

2 байти збережено завдяки lirtosiast

Спробуйте в Інтернеті! Надано Dyalog Classic

Пояснення:

(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+⎕за 24?
lirtosiast

@lirtosiast Дякую, але я боюся, що мій стародавній перекладач APL + WIN не має функції ⍨. У будь-якому разі подайте це як власне рішення APL.
Грем

@lirtosiast Ще раз дякую, я взяв 2 байти, отримані в результаті присвоєння а.
Грем

3

Perl 6 , 47 байт

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

Спробуйте в Інтернеті!

Я здивований, що мені вдалося перетворити це на анонімне Яке б лямбда! Особливо та частина, де це більше *, ніж усе інше. Вводиться як interest rate (e.g. 0.0725), years, [Knuts, Sickles, Galleons]і повертає список валют у тому ж порядку.

Пояснення:

 (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

Я здивований, що ви не придумали способу отримати також кількість кнутів / серпів / галеонів, щоб вони також вміщувались у whatevers. Тоді це було б просто так, як ************************* ;-)
user0721090601

@guifa Whatevers - це вхідні дані, тому їх може бути дійсно лише 3 (хоча я можу розділити вклад валюти на ще кілька *s, але більше байтів). Решта *s - від множення ( *) та експонентів ( **)
Jo King

Я мав на увазі, якщо ви також отримали в них коефіцієнти конверсії (номер 29/17). Але, звичайно, це був жарт, адже ці цифри потрібно використовувати не один раз. Вибачте, якщо мій гумор не пройшов
користувач0721090601

2

Желе , 29 байт

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

Повна програма, що приймає аргументи rate:; [Galleons, Sickles, Knuts]; years.
Друкує [Galleons, Sickles, Knuts].

Спробуйте в Інтернеті!

Підлоги в кінці всього терміну.
÷ȷ2може бути видалено, якщо ми можемо прийняти ставку як відношення, а не як відсоток.

Як?

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

Збірка FPU Intel 8087, 86 байт

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

Нерозібрані та задокументовані:

; 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

Реалізований як MACRO (в основному це функція), це не специфічний для ОС машинний код, використовуючи для обчислення лише процесор Intel 80x87 FPU / math.

Приклад тестової програми з виходом:

    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

Вихідні дані

enter image description here



1

Haskell , 73 байти

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

Спробуйте в Інтернеті!

Дякуємо @Laikoni за два байти.

Брудні хитрощі: кількість монет на вході є плаваючою точкою ( Double), тоді як кількість монет на виході є інтегральним ( Integer). В результаті виходить вкладена пара, ((Galleons, Sickles), Knotts)щоб уникнути необхідності сплющуватися до трійки.

Пояснення

-- 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
Збережіть два байти за допомогою (truncate$ ... )-> truncate( ... )і (g#s)k r nзамість c g s k r n.
Лайконі

@Laikoni, велике спасибі!
dfeuer

@Laikoni, я дуже вдячний, якщо ви зможете знайти мені пару байтів у codegolf.stackexchange.com/questions/55960/… , якщо у вас є час.
dfeuer

1
Я загляну в це, коли знайду час. Тим часом я можу вказати вам на нашу чатку Haskell Monads and Men, а також на це питання, яке вам може сподобатися, враховуючи свої поліглоти Hugs / GHC.
Лайконі


1

TI-BASIC (TI-84), 96 90 байт

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

Вхідний Ansсписок - це список із 5 предметів: гачки, серпи, галеони, відсотки (десятковий) та час (роки).
Вихід є Ansі автоматично роздруковується після завершення програми.

Без гольфу:

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

Приклад:

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

Пояснення:

:SetUpEditor C
:Ans→∟C

Новий список, ∟C, створюється і Ansзберігається в ній.

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

Кнути, серпи та галеони перетворюються на кнути та зберігаються в них T.

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

Забирає суму Кнутів і застосовує до неї складні відсотки.
Тут нараховуються відсотки.

:remainder(iPart(T),493→R

Зберігає частину I nteger з модуля 493 . Використовується для скорочення кількості байтів.TR

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

Оцінює список із 3-х предметів (гачки, серпи та галеони). Список автоматично зберігається в Ans.


Примітка: кількість байтів оцінюється, приймаючи кількість байтів, наведену в [MEM][2][7] (список програм в оперативній пам'яті) і віднімаючи кількість символів у назві програми та додаткових 8 байт, використовуваних для програми:

103 - 5 - 8 = 90 байт


0

К, 46 байт

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

c зберігати список для базової конверсії

t це функція, яка обчислює загальну суму

Приклад використання:

t[103 16 23;7.25;3]

пише (128;4;24.29209)

Пояснення:

  • c/:x перетворити список (галеон; серп; кнути) в кути

  • 1+y%100 розрахунок процентної ставки (приклад 1,0725 для 7,25% ставки)

  • lambda {z(y*)\x}виконує роботу: повторює 3 рази, застосовуючи interes * main і повертає остаточне головне.

  • c\: генерує галлеон, серпи, кнури з кнутів

ПРИМІТКА. - якщо вам не потрібна функція імен, ми можемо використовувати лямбда, економлячи 2 байти {c\:{z(y*)/x}[c/:x;1+y%100;z]}inputArgs


0

C # (Visual C # Interactive Compiler) , 86 байт

(a,b,c)=>((k=(int)((a.a*493+a.b*29+a.c)*Math.Pow(1+b,c)))/493,(k%=493)/29,k%29);int k;

Приймається як іменований кортеж з 3 значеннями, що представляють кнути, серпи та галеони, а відсоткова ставка як подвійна (не відсоток). Я б дуже хотів, щоб у C # був оператор експоненції. Math.Pow занадто довгий :(

Спробуйте в Інтернеті!


0

Пакетна, 171 байт

@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%

Приймає дані як аргументи командного рядка у порядку Galleons, Sickles, Knuts, відсотки, роки. Процентні відсотки, але виражені без знаку%. Тринькає після кожного року. Вихід є в порядку Галеони, Серпи, Кнуц. Підтримує щонайменше 5000 галеонів. Пояснення:

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

Пакет має лише цілу арифметику. На щастя, процентна ставка завжди кратна 0.125. Почнемо з розбиття на десяткову точку, так що це iстає цілою частиною відсоткової ставки та fдесятковою часткою. Потім їх множать на 8. Перша цифра f- це число восьмих відсотків відсоткової ставки.

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

Потім це витягується за допомогою нарізки струн і додається для отримання процентної ставки в 1/800. Кількість кнутів також розраховується.

@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%

Перетворити назад до галеонів та серпів.


0

05AB1E (спадщина) , 24 байти

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

Відповідь Perl 6 на порту @JoKing , тому обов'язково підтримайте його, якщо вам подобається ця відповідь!

Я використовую застарілу версію через помилку в новій версії, де £не працює над цілими числами, тому необхідний явний переклад на рядок §(між другою та 3) (поки помилка не буде виправлена).

Зацікавлення сприймається як десятковий з наступним роком, а за списком [Кнут, Серп, галеон].

Спробуйте в Інтернеті.

Пояснення:

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

Дивіться цей мінний наконечник 05AB1E (розділ Як стискати великі цілі числа? ), Щоб зрозуміти, чому •1ýÑ•це так 119493.


0

APL (NARS), 37 знаків, 74 байти

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

переклад дуже хорошого і дуже мало байтного рішення APL користувачем Graham на рішення, яке використовує одну функцію замість стандартного введення ... тест і як ним користуватися:

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

(я не кажу, що я зрозумів алгоритм)


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.