Không có gì gọi là bữa trưa miễn phí


17

... Hay là ở đó?

Thử thách của bạn là phân tích hóa đơn ăn trưa của tôi, trong đó có giá cơ bản, mẹo, giảm giá, phiếu giảm giá và các tính năng bổ sung và tìm hiểu xem bữa trưa của tôi có $ 0 trở xuống . Nếu đây là đầu vào:

12.34
15 tip
25 discount
1.5 extra
2 coupon

Sau đó, đầu ra có thể được false. Đây là cách nó hoạt động:

12.34 là giá cơ sở.

15 tipcó nghĩa là thêm 15% vào tổng số.

25 discountcó nghĩa là trừ 25% trên tổng số.

1.5 extracó nghĩa là thêm 1,5 vào tổng số.

2 couponcó nghĩa là trừ 2 từ tổng số.

Có thể có bất kỳ số tiền tip, giảm giá, phiếu giảm giá, và các tính năng bổ sung, nhưng sẽ luôn có một mức giá cơ bản.

Sau đó, chúng tôi làm (12.34 * 1.15) * 0.75 + 1.5 - 2cho đầu ra 10.14. 10,14 lớn hơn 0, vì vậy chúng tôi xuất sai. Bữa trưa của tôi không miễn phí.

Quy tắc

số tip có nghĩa là thêm phần trăm số vào tổng số.

số discount có nghĩa là trừ phần trăm số trong tổng số

số extra có nghĩa là thêm số vào tổng số

số coupon có nghĩa là trừ số từ tổng số

Một vi dụ khac:

10
20 tip
20 discount
2 coupon
2 coupon
1 coupon
50 discount
2.55 coupon

Giá là -0.24((10 * 1,20 * 0,80 - 2 - 2 - 1) * 0,5 - 2,55), vì vậy đầu ra là đúng (bữa trưa của tôi là miễn phí.)

Ghi chú:

  • Độ chính xác phải có ít nhất 2 chữ số thập phân.
  • Bạn có thể lấy đầu vào dưới dạng một chuỗi với các dòng mới (theo dõi dòng mới tùy chọn) hoặc một ký tự phân tách khác hoặc một mảng / danh sách các đầu vào.

5
Đầu vào có cần phải có tên không, hoặc chúng ta có thể giả sử thứ tự nếu chúng ta chỉ nhập một mảng các số [12,34,15,25,1.5,2]?
Sinusoid

@StewieGriffin Bạn không thể chọn đơn hàng. Có thể có nhiều hơn 5 hàng hoặc có thể ít hơn. Bạn có thể lấy 2 phiếu giảm giá là 2,00 phiếu giảm giá và 15 tip0.15 tip
lập trình

Đây có phải là trường hợp đầu vào nhạy cảm? Đó có phải là tất cả những từ chúng ta cần hỗ trợ?
Rɪᴋᴇʀ

@Riker đó là tất cả các từ cần thiết, và đầu vào sẽ luôn luôn là chữ thường.
lập trình

5
Làm thế nào để thứ tự đánh giá hoạt động? Ví dụ: nếu chúng tôi có giảm giá, thì một mẹo, tiền boa có áp dụng cho số tiền ban đầu hoặc số tiền chiết khấu không?

Câu trả lời:


2

05AB1E , 37 33 34 byte

I|vy#`0èÇ7%`">* - (>* +"#sè.V}î0›_

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

Giải trình

Mượn mod 7mánh khóe từ câu trả lời Jelly của Jonathan Allan

I                                  # initialize stack with first input
 |v                                # loop over all other inputs
   y#`                             # split input on space as separate to stack
      0èÇ                          # get the character code of the first letter of the type
         7%`                       # mod by 7
            ">* - (>* +"#          # push the list ['>*','-','(>*','+'] where
                                   # '>*' =  increment and multiply
                                   # '-' =   subtract
                                   # '(>*' = negate, increment, multiply
                                   # '+' =   add
                         s         # swap the top 2 items on the stack
                          è        # use the mod result to index into the list
                           .V      # run as 05AB1E code
                             }     # end loop
                              î0›_ # check if the result rounded up to nearest integer 
                                   # is less than or equal to 0

Tôi nhận được 1khi giá trị <1.
12431234123412341234123

@ 12431234123412341234123: Bắt tốt. Sự so sánh rõ ràng được chuyển thành số nguyên: /
Emigna

9

JavaScript (ES6), 88 85 byte

Đưa đầu vào như một mảng của chuỗi. Trả lại 0không miễn phí hoặc 1miễn phí.

a=>a.map(s=>([a,b]=s.split` `,t+={e:+a,c:-a,t:x=t*a/100,d:-x}[(b||'e')[0]]),t=0)|t<=0

Làm thế nào nó hoạt động

Mỗi dòng được phân chia trên không gian để get a= lượng, b= loại hoạt động. Nếu hoàn toàn không có thao tác nào (đó là trường hợp trên dòng đầu tiên), bđược đặt mặc định thành "e""phụ".

Để thêm số tiền chính xác vào tổng số t, chúng tôi sử dụng một đối tượng có các khóa là chữ cái đầu tiên của hoạt động:

{
  e: +a,           // extra
  c: -a,           // coupon
  t: t * a / 100,  // tip
  d: -t * a / 100  // discount
}

Lưu ý : Nếu hóa đơn chỉ bao gồm một phần tử, map()sẽ trả về một mảng phần tử đơn sẽ bị ép buộc thành một số nguyên khi áp dụng |toán tử, làm cho thử nghiệm cuối cùng thất bại. Nhưng OP đã xác nhận rằng điều này không thể xảy ra. (Mảng gồm 2 hoặc nhiều phần tử được ép thành 0.)

Bản giới thiệu


3

CJam , 45 42 byte

q~Sf/(sd\{L(d\~ci6%"1\-* + )* -"S/=~}fL0>!

Lấy đầu vào dưới dạng một chuỗi các chuỗi, và lấy tiền boa và chiết khấu dưới dạng số thập phân.

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

Giải trình

q~                e# Read and eval the input.
Sf/               e# Split each string by spaces.
(sd               e# Pull out the first element (base price) and cast it to a double.
\                 e# Bring the array back to the top.
{                 e# For each element L in the array:
 L                e#  Push L.
 (d               e#  Pop out the first element and cast it to a double.
 \~               e#  Bring the second element to the top of the stack.
 ci6%             e#  Mod its first character's ASCII value by 6. (c,d,e,t) -> (3,4,5,2)
 "1\-* + )* -"S/  e#  Push this string and split it on spaces.
 =                e#  Get the element given by number from the mod. CJam uses modular arrays,
                  e#    so 4 and 5 get elements 0 and 1 respectively.
 ~                e#  Eval whichever string was retrieved.
}fL               e# (end of loop)
0>!               e# Check if it's not greater than 0.

Mã được đánh giá tùy thuộc vào các chữ cái đầu tiên:

t -> ")*"    Adds 1 to the tip amount and multiplies it by the current price.

d -> "1\-*"  Subtracts the discount amount from 1 and multiplies it by the current price.

e -> "+"     Adds the extra amount to the current price.

c -> "-"     Subtracts the coupon amount from the current price.

3

Thạch ,  42 39 byte

⁾_@
⁾C×
”+
⁾‘×
ḲµṪḢO%7µĿṭ
ḢW;Ç€j”µFV>0¬

Đưa ra một danh sách các chuỗi có số được định dạng thập phân
(Các số 0 đứng đầu sẽ hoạt động, nhưng có tác dụng phụ là in các số 0 thành STDOUT trước kết quả cuối cùng).

Hãy thử trực tuyến! - không miễn phí; hoặc miễn phí .

Làm sao?

⁾_@ - Link 1: a coupon
⁾_@ - literal "_@" - the Jelly code for subtraction with reversed arguments

⁾C× - Link 2: a discount
⁾C× - literal "C×" - the Jelly code for complement (1-input) then multiply

”+ - Link 3: extra cost
”+ - literal '+' - the Jelly code for add

⁾‘× - Link 4: a tip
⁾‘× - literal "‘×" - the Jelly code for increment (input+1) then multiply

ḲµṪḢO%7µĿṭ - Link 5, switch: char list
Ḳ          - split on spaces (gives [amount, type] as char lists)
 µ     µ   - monadic chain separation to get a value, say v
  Ṫ        - tail (get the type: "coupon", "discount", "extra", or "tip")
   Ḣ       - head (get the first character: 'c', 'd', 'e' or 't') 
    O      - cast to ordinal (99, 100, 101, or 116)
     %7    - mod 7 (1, 2, 3, or 4)
        Ŀ  - call link v as a monad
         ṭ - tack to the amount char list

ḢW;Ç€j”µFV>0¬ - Main link: list of strings (char lists)
Ḣ             - head - the base price char list
 W            - wrap in a list
   Ç€         - call the last link (5) as a monad for €ach of the rest
  ;           - concatenate
      ”µ      - literal 'µ' - Jelly's monadic chain separator
     j        - join all the parts with 'µ's             "10",".2 tip",".2 discount", "2 coupon","2 coupon","1 coupon",".5 discount","2.55 coupon":
        F     - flatten (makes a char list, for example: "10µ.20‘×µ.20C×µ2_@µ2_@µ1_@µ.50C×µ2.55_@")
         V    - evaluate as Jelly code (the above evaluates to -0.2499999999999991)
          >0  - greater than 0?
            ¬ - not

Liên tục xuất 0 cho tôi ...
lập trình

Ah, có lẽ tôi nên nói định dạng sử dụng thập phân?
Jonathan Allan

Oh. Vâng, bạn nên.
lập trình

Tôi đang viết lên lời giải thích tại mo, đây là một ví dụ về bữa trưa miễn phí.
Jonathan Allan

3

GNU sed + dc, 117 111 107 byte

Sử dụng -zcờ thông dịch (bao gồm số điểm là 1 byte):

s/discount/_tip/g
s/tip/.01*1+*/g
s/extra/+/g
s/coupon/-/g
s/.*/dc -e '& 0r-p'/e
s/[^-]*$/free/
s/-/not /

Giải trình

#!/bin/sed -fz

# Convert to dc expression (discount is just a negative tip)
s/discount/_tip/g
s/tip/.01*1+*/g
s/extra/+/g
s/coupon/-/g

# Run dc
s/.*/dc -e '& 0r-p'/e

# Convert to pretty output
s/[^-]*$/free/
s/-/not /

Vì đầu vào đã rất gần với ký hiệu đảo ngược của Ba Lan, nên việc chuyển đổi extravà chuyển couponsang +-, và không nhiều hơn nữa để thay đổi tỷ lệ phần trăm thành bội số. Sau đó gọi dcvà tạo ra một kết quả có thể đọc được tùy thuộc vào việc có -được tìm thấy hay không (chúng ta phải phủ nhận kết quả, do đó, -hàm ý "không miễn phí", nếu không, 0 sẽ là trường hợp đặc biệt cần xử lý riêng).

Thí dụ

Trường hợp thứ hai từ câu hỏi là:

10
20 tip
20 discount
2 coupon
2 coupon
1 coupon
50 discount
2.55 coupon

Điều đó trở thành dcchương trình này :

10
20 .01*1+*
20 _.01*1+*
2 -
2 -
1 -
50 _.01*1+*
2.55 -
 0r-p

Kết quả là:

free

2

JavaScript, 173 169 145 byte

i=>{w=i.split`\n`.map($=>$.split` `);t=+w.shift()[0];p=$=>t*$/100;w.map(x=>{k=+x[0];f=x[1][0];l={e:k,c:-k,t:p(k),d:-p(k)},t+=l[f]});return t<=0;}

Vẫn còn nhiều việc phải chơi golf

Hãy thử trực tuyến! (145 byte hiện tại)

Dùng thử:

<script>var _=i=>{w=i.split('\n').map($=>$.split(' '));t=+w.shift()[0];p=$=>t*$/100;w.map(x=>{k=+x[0];f=x[1][0];t+=f=='e'&&k||f=='c'&&(-k)||f=='t'&&p(k)||f=='d'&&(-p(k))});return t<=0;}</script>
<textarea oninput="document.querySelector('pre').innerText=_(this.value)"></textarea>
<pre></pre>

Cảm ơn lập trình viên 5000 vì tất cả lời khuyên chơi golf của anh ấy


Tại sao nút được yêu cầu?
lập trình

1
Ngoài ra, bạn có thể làm {w=i.split`<nl>`trong đó <nl> là một dòng mới theo nghĩa đen
lập trình

Nút không bắt buộc. Tôi vừa mới sử dụng nó để thử nghiệm trên TIO
Alberto Rivera

Tôi đã thêm một đoạn trích để thử nó. Hãy thoải mái quay lại nếu bạn không thích nó.
lập trình

1
Bạn có thể loại bỏ f=một phần, nó được cho phép bởi các quy tắc và bạn có thể thay thế $.split(' ')bằng $.split` `.
lập trình

2

JavaScript (ES6), 97 107

Nhập dưới dạng một chuỗi nhiều dòng với một dòng mới.

t=>t.replace(/(\S+) ?(.*)?\n/g,(x,d,b)=>t-=b>'t'?-t*d/100:b>'e'?d:b>'d'?t*d/100:b?-d:d,t=0)&&t>=0

Regrec chia phần văn bản số và tùy chọn cho mỗi dòng trong db .
Các tính toán nên ít nhiều obviuos. Chỉ cần một số lưu ý:
- sử dụng -=để tránh các vấn đề trộn số với chuỗi
- tổng bị phủ định để lưu 1 byte, vì vậy kiểm tra cuối cùng là >= 0thay vì<= 0

PS vẫn còn dài hơn @ Arnauld. Chuột

Kiểm tra

var f=
t=>t.replace(/(\S+) ?(.*)?\n/g,(x,d,b)=>t-=b>'t'?-t*d/100:b>'e'?d:b>'d'?t*d/100:b?-d:d,t=0)&&t>=0

a=`12.34
15 tip
25 discount
1.5 extra
2 coupon
`
b=`10
20 tip
20 discount
2 coupon
2 coupon
1 coupon
50 discount
2.55 coupon
`

console.log('Not free: '+a,f(a))
console.log('Free: '+b,f(b))


1

C # 324 219 byte

bool a(string[] l){var x=0f;foreach(var s in l){var b=float.Parse(s.Split(' ')[0]);if(s.EndsWith("p"))x*=b;else if(s.EndsWith("t"))x*=1-b;else if(s.EndsWith("n"))x-=b;else if(s.EndsWith("a"))x+=b;else x=b;}return x<=0;}

Nó không đẹp, và có lẽ không phải là cách tốt nhất, nhưng đây là. Yêu cầu đầu vào được chuyển qua dưới dạng một chuỗi chuỗi và mẹo / giảm giá được chuyển dưới dạng float (0.15 tip thay vì 15 tip) vì điều này đã được làm rõ là có thể chấp nhận được trong các nhận xét của thông số kỹ thuật.

Giải thích:

bool a(string[] l){                         //Define method with input string array l and bool output
    var x=0f;                               //Initialize float x
    foreach(var s in l){                    //Iterate through lines
        var b=float.Parse(s.Split(' ')[0]); //Parse the number from the line and store it in float b
        if(s.EndsWith("p"))                 //If line ends with "p" then line is "tip"
            x*=b;                           //Parse number from line to float add 1 and multiply by x
        else if(s.EndsWith("t"))            //If line ends with "t" then line is "discount"
            x*=1-b;                         //Parse number from line to float, subtract from 1 and multiply by x
        else if(s.EndsWith("n"))            //If line ends with "n" then line is "coupon"
            x-=b;                           //Parse number from line to float and subtract from x
        else if(s.EndsWith("a"))            //If line ends with "a" then line is "extra"
            x+=b;                           //Parse number from line to float and add to x
        else x=b;                           //Line is base price
    }                                       //End foreach
    return x<=0;                            //Return x less than or equal to 0
}                                           //End method

Có một cách tốt hơn để làm điều này, nhưng điều này ít nhất hoạt động


Nếu bạn đã được đưa ra lời khuyên / giảm giá dưới dạng nổi thì bạn không muốn điều đó 100trong tchi nhánh.
Wai Ha Lee

@WaiHaLee oops, điểm tốt, quên thay đổi thành 1
Skidsdev

Mẹo: đưa float.Parse(s.Split(' ')[0])vào một cái gì đó để giảm trùng lặp. Điều đó sẽ lưu khoảng 80 ký tự.
Wai Ha Lee

oh wow tôi là một tay golf khủng khiếp tôi thậm chí không xóa những khoảng trắng không cần thiết. Tôi đổ lỗi cho Visual Studio.
Skidsdev

Một nỗ lực không tồi chút nào!
Wai Ha Lee

1

PowerShell , 218 156 143 byte

($n=$args)|%{[float]$v,$w=$_-split' ';switch -w($w){"t*"{$t+=$v}"d*"{$d+=$v}"e*"{$e+=$v}"c*"{$c+=$v}}};($n[0]*(1+$t/100)*(1-$d/100)+$e-$c)-lt 0

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

EDIT Lưu byte bằng cách tách biến đường ống trước

EDIT 2 Được lưu trữ phần thứ hai của chuỗi để tôi có thể thực hiện các cuộc gọi ký tự đại diện tốt hơn


Có vẻ để làm việc, và định dạng đầu vào của bạn là tốt.
lập trình

1

Python 133 byte

def f(b):
 t=float(b.pop(0))
 for l in b:
  v,a=l.split(' ');v=float(v);t+={'t':t*v/100,'d':-t*v/100,'c':-v,'e':v}[a[0]]
 return t<=0

Tương tự như phiên bản JavaScript ES6. Nhưng chuyển đổi loại là cần thiết cho floatcác giá trị trong Python.

Giải trình:

Trích xuất giá trị đầu tiên và chuyển đổi nó để nổi.

Đối với mỗi dòng khác trong hóa đơn:

  1. tách và chuyển đổi giá trị thành float
  2. Sử dụng một dict để chọn đúng thao tác theo chữ cái đầu tiên
  3. Tích lũy giá trị

Sử dụng:

print(f([
'12.34',
'15 tip',
'25 discount',
'1.5 extra',
'2 coupon'
]))

print(f([
'10',
'20 tip',
'20 discount',
'2 coupon',
'2 coupon',
'1 coupon',
'50 discount',
'2.55 coupon'
]))

Chào mừng đến với trang web!
DJMcMayhem

1

Java 227 byte

Đã một thời gian và vẫn không có câu trả lời Java nào tôi có thể thấy, vì vậy đây là câu trả lời C # của tôi được chuyển sang Java, với chi phí 8 byte

boolean a(String[] l){Float x=0f;for(String s:l){Float b=Float.parseFloat(s.split(" ")[0]);if(s.endsWith("p"))x*=b;else if(s.endsWith("t"))x*=1-b;else if(s.endsWith("n"))x-=b;else if(s.endsWith("a"))x+=b;else x=b;}return x<=0;}

Để được giải thích và như vậy, hãy xem câu trả lời C # của tôi

Giống như câu trả lời đó, câu trả lời này hy vọng rằng tiền boa và chiết khấu được thông qua dưới dạng nổi ( 0.15không 15)


Khá tốt ... cho Java!
lập trình

1
@ lập trình viên5000 để công bằng C # chỉ hơi dài dòng hơn Java một chút, ưu điểm chính là những thứ như hỗ trợ của varloại C chung và lambdas (Tôi biết Java có chúng, nhưng C # là người chơi gôn)
Skidsdev

1

Jq 1.5 , 129 119 114 112 byte

reduce (.[]/" "|.[0]|=tonumber|.[1]|=length)as[$n,$c](0;[$n,0,0,.+.*($n/100),0,.+$n,.-$n,0,.-.*($n/100)][$c])<=0

Mở rộng

  reduce (
      .[]/" "             # split each element into [value,command] 
    | .[0]|=tonumber      # convert value to number    
    | .[1]|=length        # convert command to length
  ) as [$n,$c]
  (  0
   ; [ $n                 # "" -> set base
     , 0
     , 0
     , .+.*($n/100)       # "tip"
     , 0
     , .+$n               # "extra"
     , .-$n               # "coupon"
     , 0                  
     , .-.*($n/100)       # "discount"
     ][$c]                # ... depending on command length
  ) <=0                   # true if lunch was free

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

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.