Tính tiền boa bằng số xu nhỏ nhất


23

Hầu hết các ứng dụng máy tính tiền tip chỉ đơn giản là chiếm một tỷ lệ cố định trong giá bữa ăn. Vì vậy, ví dụ, nếu bữa ăn của bạn là 23,45 đô la, bạn có thể để lại 15% tiền tip = 3,52 đô la, hoặc một khoản tiền 20% hào phóng hơn = 4,69 đô la.

Đủ tiện lợi cho người dùng thẻ tín dụng. Nhưng không phải như vậy nếu bạn muốn để lại lời khuyên về tiền mặt, trong trường hợp đó, số tiền lẻ này sẽ gây cản trở. Vì vậy, hãy sửa đổi ý tưởng để thuận tiện hơn cho người dùng tiền mặt.

Nhiệm vụ của bạn

Viết, càng ít byte càng tốt, một chương trình hoặc hàm lấy làm đầu vào:

  • Giá của bữa ăn
  • Tỷ lệ phần trăm tối thiểu
  • Tỷ lệ phần trăm tối đa

Và xuất bất kỳ số tiền tip nào trong phạm vi [price * min_percentage / 100, price * max_percentage / 100] để giảm thiểu số lượng hóa đơn / tiền giấy và tiền xu cần thiết.

Giả sử các mệnh giá tiền tệ của Mỹ là 1, 5 ¢, 10 ¢, 25, $ 1, $ 5, $ 10, $ 20, $ 50 và $ 100.

Thí dụ

Đây là một chương trình ví dụ không chơi gôn trong Python:

import math
import sys

# Do the math in cents so we can use integer arithmetic
DENOMINATIONS = [10000, 5000, 2000, 1000, 500, 100, 25, 10, 5, 1]

def count_bills_and_coins(amount_cents):
    # Use the Greedy method, which works on this set of denominations.
    result = 0
    for denomination in DENOMINATIONS:
        num_coins, amount_cents = divmod(amount_cents, denomination)
        result += num_coins
    return result

def optimize_tip(meal_price, min_tip_percent, max_tip_percent):
    min_tip_cents = int(math.ceil(meal_price * min_tip_percent))
    max_tip_cents = int(math.floor(meal_price * max_tip_percent))
    best_tip_cents = None
    best_coins = float('inf')
    for tip_cents in range(min_tip_cents, max_tip_cents + 1):
        num_coins = count_bills_and_coins(tip_cents)
        if num_coins < best_coins:
            best_tip_cents = tip_cents
            best_coins = num_coins
    return best_tip_cents / 100.0

# Get inputs from command-line
meal_price = float(sys.argv[1])
min_tip_percent = float(sys.argv[2])
max_tip_percent = float(sys.argv[3])
print('{:.2f}'.format(optimize_tip(meal_price, min_tip_percent, max_tip_percent)))

Một số mẫu đầu vào và đầu ra:

~$ python tipcalc.py 23.45 15 20
4.00
~$ python tipcalc.py 23.45 15 17
3.55
~$ python tipcalc.py 59.99 15 25
10.00
~$ python tipcalc.py 8.00 13 20
1.05

8
Nếu bạn không sử dụng thẻ tín dụng thì bạn đang trả bằng tiền mặt, phải không? Không phải tổng số tiền kiểm tra + tiền tip là số tiền có liên quan sau đó, không chỉ là tiền boa?
Sparr

4
a program that takes as input (stdin, command-line arguments, or GUI input box, whichever is most convenient in your language)Đây có phải là để ghi đè mặc định của chúng tôi cho đầu vào và đầu ra? Đó là, ví dụ, một hàm có ba số và trả về kết quả được phép?
Laikoni

3
Tôi có đúng khi nói điều đó 3.513.75cũng là đầu ra hợp lệ cho trường hợp thử nghiệm 23.45 15 17không? Họ sử dụng cùng một lượng tiền và cũng nằm trong phạm vi.
Kevin Cruijssen

3
@Sparr Ngay cả những người thanh toán hóa đơn bằng thẻ muốn để lại tiền boa; có nhiều lý do được đưa ra cho điều này vì vậy tôi sẽ không lặp lại chúng ở đây.
Neil

3
@Laikoni: Tôi đã chỉnh sửa các yêu cầu để sử dụng "chương trình hoặc chức năng" mặc định của trang web và do đó, chấp nhận hồi tố các câu trả lời chỉ có chức năng hiện có.
dan04

Câu trả lời:


3

Than , 60 byte

Nθ≔×θNη≔×θNζ≔⁰θFI⪪”;‴üφ↷Σ↗SEX&¿h'⊟”³«W‹θη≧⁺ιθ¿›θζ≧⁻ιθ»﹪%.2fθ

Hãy thử trực tuyến! Lấy đầu vào là số thập phân. Liên kết là phiên bản dài dòng của mã. Giải trình:

Nθ

Nhập hóa đơn.

≔×θNη≔×θNζ

Nhập phân số thập phân đầu tip và tính toán minium và đầu cực đại.

≔⁰θ

Bắt đầu với số không.

FI⪪”;‴üφ↷Σ↗SEX&¿h'⊟”³«

Chuỗi SEXy mở rộng tới 10050.20.10.5.01.0.250.1.05.01đó được chia thành các nhóm gồm ba ký tự và được thả nổi.

W‹θη≧⁺ιθ

Thêm càng nhiều mệnh giá hiện tại càng cần thiết để đạt đến mức tối thiểu.

¿›θζ≧⁻ιθ»

Xóa một mệnh giá nếu vượt quá số tiền tối đa.

﹪%.2fθ

Định dạng các mẹo để hiển thị.


1
Tôi không nghĩ định dạng là một yêu cầu (chứ không phải là thứ mà ví dụ mã thực hiện).
Jonathan Allan

@Jonathan ALLan Trong trường hợp đó, bạn có thể tiết kiệm 4 byte bằng cách sử dụng thay vì ﹪%.2f.
Neil

6

JavaScript (ES6), 93 byte

(x,m,M)=>(g=(t,c=1e4)=>t>x*M?0:t<x*m?[...'1343397439'].some(d=>g(t+(c/=-~d/2)))*r:r=t)(0)/100

Hãy thử trực tuyến!

Làm sao?

Chúng tôi tính toán đệ quy một tổng giá trị hóa đơn / xu cho đến khi nó nằm trong phạm vi chấp nhận được, luôn thử giá trị cao nhất trước tiên.

{b0,,bn}

  • b0bn{b0,,bk1,x}xbk0k<n
  • 0k<nxbn{b0,,bk1,bkx,bk+1,,bn}{b0,,bn1}
  • 0<x<bn{b0,,bn1,x}

cn

{c0=10000cn+1=cn(dn+1)/2

(d0,,d9)=(1,3,4,3,3,9,7,4,3,9)

 n | c(n)  | d(n) | k = (d(n)+1)/2 | c(n+1) = c(n)/k
---+-------+------+----------------+-----------------
 0 | 10000 |   1  | (1+1)/2 = 1    |      10000
 1 | 10000 |   3  | (3+1)/2 = 2    |       5000
 2 |  5000 |   4  | (4+1)/2 = 2.5  |       2000
 3 |  2000 |   3  | (3+1)/2 = 2    |       1000
 4 |  1000 |   3  | (3+1)/2 = 2    |        500
 5 |   500 |   9  | (9+1)/2 = 5    |        100
 6 |   100 |   7  | (7+1)/2 = 4    |         25
 7 |    25 |   4  | (4+1)/2 = 2.5  |         10
 8 |    10 |   3  | (3+1)/2 = 2    |          5
 9 |     5 |   9  | (9+1)/2 = 5    |          1

4

Python 3.x: 266 185 byte

Một sửa đổi đơn giản cho chương trình ví dụ của tôi trong câu hỏi. Lưu ý rằng đầu ra không còn được định dạng để yêu cầu 2 chữ số thập phân.

Chỉnh sửa: Cảm ơn Jo King đã làm cho nó nhỏ hơn.

import sys
p,m,M,T=*map(float,sys.argv[1:]),0
C=p*M
for t in range(-int(-p*m),int(p*M)+1):
 n,a=0,t
 for d in 1e4,5e3,2e3,1e3,500,100,25,10,5,1:n+=a//d;a%=d
 if n<C:T,C=t,n
print(T/100)

1
Chơi gôn nhanh để đạt được 185 byte
Jo King

4

Java 10, 186 185 byte

(p,m,M)->{double r=0,t,Q=99,q;for(m*=p+.02;m<M*p;m+=.01){q=0;t=m;for(var c:new double[]{100,50,20,10,5,1,.25,.1,.05,.01})for(;t>=c;t-=c)q++;if(q<Q){Q=q;r=m;}}return"".format("%.2f",r);}

Lấy tỷ lệ phần trăm tối thiểu và tối đa là /100số thập phân (ví dụ 15%như 0.15).

-1 byte để khắc phục sự cố với 3.51đầu ra tiềm năng và đánh golf cách khắc phục lỗi làm tròn 1 byte cùng một lúc.

Hãy thử trực tuyến.

Giải trình:

(p,m,M)->{                // Method with three double parameters and String return-type
  double r=0,             //  Result-double, starting at 0
         t,               //  Temp-double
         Q=99,            //  Min amount of coins, starting at 99
         q;               //  Temp-double for the amount of coins
  for(m*=p-.02;m<M*p;     //  Loop in the range [`m*p-0.02`, `M*p`]
           m+=.01){       //  in steps of 0.01 (1 cent) per iteration
                          //  (the -0.02 (minus 2 cents) is to fix rounding errors)
    q=0;                  //   Reset `q` to 0
    t=m;                  //   Reset `t` to the current iteration `m`
    for(var c:new double[]{100,50,20,10,5,1,.25,.1,.05,.01})
                          //   Loop over the coins (largest to smallest)
      for(;t>=c;          //    As long as `t` is larger than or equal to the current coin
          t-=c)           //     Remove the coin from the value `t`
          q++;            //     And increase the quantity-counter by 1
      if(q<Q){            //   If the quantity-counter is smaller than the current smallest
        Q=q;              //    Replace the smallest with the current
        r=m;}}            //    And replace the result with the current `m`
  return"".format("%.2f",r)l;}
                          //  Return the result with 2 decimal places

Tôi không nghĩ rằng điều này có giá trị về mặt kỹ thuật tại thời điểm này vì câu hỏi chỉ định một chương trình, nhưng OP chưa làm rõ.
Οurous

1
OP đã làm rõ các chức năng hiện đã được cho phép, vì vậy bạn không cần phải lo lắng về việc tăng gấp đôi kích thước.
Οurous

3

Sạch sẽ , 207 156 byte

Trao đổi với một chức năng đã lưu 51 byte, không có gì đáng ngạc nhiên.

import StdEnv
d=[10000,2000,1000,500,100,25,10,5,1]
$n u l=snd(hd(sort[(sum[foldl(rem)m(d%(0,i))/k\\k<-d&i<-[-1..]],toReal m)\\m<-map toInt[n*u..n*l]]))/1E2

Hãy thử trực tuyến!


2
OP làm rõ rằng các chức năng hiện đã được cho phép.
Laikoni

@Laikoni Cảm ơn đã cho tôi biết :) Tiết kiệm rất nhiều byte - các chương trình đầy đủ rất tốn kém trong Clean!
Οurous

2

Python ( 264 222 byte)

Hơi nhiều golf hơn.

m=[.01,.05,.1,.25,.5,1,5,10,20,50,100]
def f(a,i,j):
 t,u=9**9,a*j
 def g(s,d,c):
  nonlocal t
  if(a*i<s<u)+(c>t):t=min(c,t);return c,s
  return(t+1,s)if(s>u)+(d>9)else min(g(s+m[d],d,c+1),g(s,d+1,c))
 return g(0,0,0)[1]

Hãy thử trực tuyến!


2

Perl 6 , 93 92 89 byte

{.01*($^a*$^b+|0...$a*$^c).min:{$!=$_;sum '✐ᎈߐϨǴd
'.ords>>.&{($!%=$_)xx$!/$_}}}

Hãy thử trực tuyến!

Khối mã ẩn danh nhận ba đối số (giá, tỷ lệ phần trăm tối thiểu và tỷ lệ phần trăm tối đa) và trả về tiền boa.



0

Kotlin , 215 byte

{p:Double,l:Int,h:Int->val d=listOf(10000,5000,2000,1000,500,100,25,10,5,1)
var m=Int.MAX_VALUE
var r=0.0
(Math.ceil(p*l).toInt()..(p*h).toInt()).map{var a=it
var c=0
d.map{c+=a/it
a%=it}
if(c<m){m=c
r=it/100.0}}
r}

Hãy thử trực tuyến!


0

Thạch ,  33  32 byte

“ñṇzi;’b⁴×H¥\ɓ_>Ƈ-Ṫ
PĊ1¦r/ÇƬL$ÞḢ

Một liên kết đơn âm chấp nhận một danh sách [cost in cents, [minimum ratio, maximum ratio]]mang lại số tiền tip bằng xu.

Hãy thử trực tuyến!

Làm sao?

Dòng đầu tiên là Liên kết người trợ giúp mang lại số tiền được đưa ra ít hơn so với tiền mệnh giá / đồng xu lớn nhất:

“ñṇzi;’b⁴×H¥\ɓ_>Ƈ-Ṫ - Link 1, get next lower amount: integer, V
“ñṇzi;’             - base 250 number = 112835839060
       b⁴           - to base 16 = [1,10,4,5,8,10,4,4,5,4]
            \       - cumulative reduce with:       e.g.: 1,10   5,4   10,5   25,8
           ¥        -   last two links as a dyad:
         ×          -     multiply                        10     20    50     200
          H         -     halve                            5     10    25     100
                    - ...yielding: [1,5,10,25,100,500,1000,2000,5000,10000]
             ɓ      - start a new dyadic link with swapped arguments
              _     - subtract (vectorises) ...i.e. [V-1,V-5,V-10,...]
                Ƈ   - filter keep those which satisfy:
                 -  -   literal -1
               >    -   greater than? (i.e. if V-X > -1)
                  Ṫ - tail (tailing an empty list yields 0)

Số lượng cuộc gọi được yêu cầu để đạt đến số 0 được sử dụng để sắp xếp phạm vi số tiền tip và sau đó kết quả ngoài cùng bên trái:

PĊ1¦r/ÇƬL$ÞḢ - Main Link: [cost, [min, max]]
P            - product = [cost*min, cost*max]
   ¦         - sparse application...
  1          - ...to indices: 1
 Ċ           - ...what: ceiling   -> [ceil(cost*min), cost*max]
     /       - reduce by:
    r        -   inclusive range (implicit floor of arguments)
          Þ  - sort by:
         $   -   last two links as a monad:
       Ƭ     -     repeat collecting results until a fixed point is reached:
      Ç      -       last link (1) as a monad  (e.g. 32 -> [32,7,2,1,0])
        L    -     length (i.e. coins/notes required + 1)
           Ḣ - head
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.