ไม่มีสิ่งใดเป็นอาหารกลางวันฟรี


17

... หรือไม่

ความท้าทายของคุณคือการแยกการเรียกเก็บเงินอาหารกลางวันของฉันซึ่งมีฐานราคาและเคล็ดลับ, ส่วนลด, คูปองและความพิเศษและดูว่าอาหารกลางวันของฉันคือ $ 0 หรือน้อยกว่า หากนี่คืออินพุต:

12.34
15 tip
25 discount
1.5 extra
2 coupon

falseจากนั้นการส่งออกอาจจะมี นี่คือวิธีการทำงาน:

12.34 เป็นราคาฐาน

15 tipหมายถึงการเพิ่ม 15% ของผลรวม

25 discountหมายถึงการลบ 25% จากผลรวม

1.5 extraหมายถึงการเพิ่ม 1.5 ถึงผลรวม

2 couponหมายถึงการลบ 2 จากผลรวม

อาจมีจำนวนเคล็ดลับส่วนลดคูปองและสิ่งเพิ่มเติมใด ๆ แต่จะมีราคาพื้นฐานหนึ่งราคาเสมอ

จากนั้นเราทำ(12.34 * 1.15) * 0.75 + 1.5 - 2ผลลัพธ์ออกมาเป็น 10.14 10.14 มากกว่า 0 ดังนั้นเราจึงออกเท็จ อาหารกลางวันของฉันไม่ฟรี

กฎระเบียบ

number tipหมายถึงการเพิ่มเปอร์เซ็นต์จำนวนให้กับผลรวม

number discountหมายถึงการลบจำนวนเปอร์เซ็นต์จากผลรวม

number extraหมายถึงการเพิ่มหมายเลขให้กับผลรวม

number couponหมายถึงการลบจำนวนจากผลรวม

ตัวอย่างอื่น:

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

ราคาคือ-0.24((10 * 1.20 * 0.80 - 2 - 2 - 1) * 0.5 - 2.55) ดังนั้นผลลัพธ์จะเป็นจริง (อาหารกลางวันของฉันฟรี)

หมายเหตุ:

  • ความแม่นยำต้องมีทศนิยมอย่างน้อย 2 ตำแหน่ง
  • คุณสามารถรับอินพุตเป็นสตริงที่มีการขึ้นบรรทัดใหม่ (ต่อท้ายการขึ้นบรรทัดใหม่ทางเลือก) หรืออักขระการแยกอื่นหรืออาร์เรย์ / รายการของอินพุต

5
อินพุตต้องมีชื่อหรือไม่หรือเราสามารถสมมติคำสั่งนั้นได้ถ้าเราใส่อาร์เรย์ของตัวเลข [12.34,15,25,1.5,2]
Sinusoid

@StewieGriffin คุณไม่สามารถเลือกคำสั่งซื้อได้ อาจมีมากกว่า 5 แถวหรือน้อยกว่านั้น คุณสามารถใช้คูปอง 2 ใบเป็น 2.00 คูปองและ15 tipเป็น0.15 tip
programmer5000

อินพุตนี้คำนึงถึงขนาดตัวพิมพ์หรือไม่? นั่นคือคำทั้งหมดที่เราต้องการสนับสนุนหรือไม่?
Rɪᴋᴇʀ

@Riker นั่นคือคำทั้งหมดที่จำเป็นและอินพุตจะเป็นตัวพิมพ์เล็กเสมอ
programmer5000

5
ใบสั่งการประเมินทำงานอย่างไร ตัวอย่างเช่นหากเรามีส่วนลดเคล็ดลับจะนำไปใช้กับจำนวนเงินดั้งเดิมหรือจำนวนที่ได้รับส่วนลดหรือไม่

คำตอบ:


2

05AB1E , 37 33 34 ไบต์

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

ลองออนไลน์!

คำอธิบาย

ยืมmod 7เคล็ดลับจากคำตอบ Jelly ของ 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

ฉันได้รับ1เมื่อค่าคือ <1
12431234123412341234123

@ 12431234123412341234123: จับได้ดี เห็นได้ชัดว่าการเปรียบเทียบนำไปสู่จำนวนเต็ม: /
Emigna

9

JavaScript (ES6), 88 85 ไบต์

รับอินพุตเป็นอาร์เรย์ของสตริง ส่งคืนสินค้า0ไม่ฟรีหรือ1ฟรี

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

มันทำงานอย่างไร

แต่ละบรรทัดถูกแบ่งบนพื้นที่เพื่อรับa= จำนวน, b= ประเภทของการดำเนินการ หากไม่มีการดำเนินการเลย (ซึ่งเป็นกรณีในบรรทัดแรก) bตั้งค่าเริ่มต้นเป็น"e""พิเศษ"

ในการเพิ่มจำนวนที่ถูกต้องให้กับผลรวมtเราใช้วัตถุที่มีกุญแจเป็นตัวอักษรตัวแรกของการดำเนินการ:

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

หมายเหตุ : หากการเรียกเก็บเงินมีเพียงองค์ประกอบเดียวmap()ก็จะส่งกลับอาร์เรย์องค์ประกอบเดียวซึ่งจะถูกบังคับให้เป็นจำนวนเต็มเมื่อใช้|ผู้ประกอบการทำให้การทดสอบขั้นสุดท้ายล้มเหลว แต่ OP ยืนยันว่าสิ่งนี้จะไม่เกิดขึ้น (อาร์เรย์ขององค์ประกอบ 2 อย่างหรือมากกว่านั้นถูกบังคับเป็น 0)

การสาธิต


3

CJam , 45 42 ไบต์

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

รับอินพุตเป็นอาร์เรย์ของสตริงและนำส่วนปลายและส่วนลดเป็นทศนิยม

ลองออนไลน์!

คำอธิบาย

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.

รหัสที่ได้รับการประเมินขึ้นอยู่กับตัวอักษรตัวแรก:

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

เจลลี่ ,  42 39 ไบต์

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

รับรายการสตริงที่มีตัวเลขที่จัดรูปแบบทศนิยม
(เลขศูนย์นำหน้าจะใช้ได้ แต่มีผลข้างเคียงของการพิมพ์เลขศูนย์ไปที่ STDOUT ก่อนผลลัพธ์สุดท้าย)

ลองออนไลน์! - ไม่ฟรี; หรือฟรี

อย่างไร?

⁾_@ - 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

เอาท์พุทอย่างต่อเนื่อง 0 สำหรับฉัน ...
programmer5000

อาฉันอาจจะบอกว่ารูปแบบใช้ทศนิยม?
Jonathan Allan

โอ้ ใช่คุณควรจะ.
programmer5000

ฉันกำลังเขียนคำอธิบายที่ mo นี่เป็นตัวอย่างของอาหารกลางวันฟรี
Jonathan Allan

3

GNU sed + dc, 117 111 107 ไบต์

ใช้-zล่ามธง (รวมอยู่ในคะแนนเป็น 1 ไบต์):

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 /

คำอธิบาย

#!/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 /

เนื่องจากอินพุตอยู่ใกล้กับสัญกรณ์ Reverse โปแลนด์มากจึงเป็นเรื่องง่ายที่จะแปลง extraและcouponไป+และ-ไม่มากที่จะเปลี่ยนเข้าสู่เปอร์เซ็นต์คูณ จากนั้นเรียกใช้dcและสร้างผลลัพธ์ที่อ่านได้ขึ้นอยู่กับว่า-พบ (เราต้องลบล้างผลลัพธ์ดังนั้น-นัยก็คือ "ไม่ฟรี" มิฉะนั้น 0 จะเป็นกรณีพิเศษที่จะต้องมีการจัดการของตัวเอง)

ตัวอย่าง

กรณีที่สองจากคำถามคือ:

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

ที่กลายเป็นdcโปรแกรมนี้:

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

ที่เกิดขึ้นใน:

free

2

JavaScript, 173 169 145 ไบต์

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

ยังคงมีสนามกอล์ฟให้ทำมากมาย

ลองออนไลน์!(145 ไบต์ปัจจุบัน)

ลองดูสิ:

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

ขอบคุณ programmer5000 สำหรับคำแนะนำการเล่นกอล์ฟทั้งหมดของเขา


เหตุใดจึงต้องมีโหนด
programmer5000

1
นอกจากนี้คุณสามารถทำได้{w=i.split`<nl>`โดยที่ <nl> เป็นตัวอักษรขึ้นบรรทัดใหม่
programmer5000

ไม่จำเป็นต้องใช้โหนด ฉันเพิ่งใช้มันเพื่อทดสอบใน TIO
Alberto Rivera

ฉันเพิ่มตัวอย่างสแต็กเพื่อลองใช้ คุณสามารถย้อนกลับได้ถ้าคุณไม่ชอบ
programmer5000

1
คุณสามารถลบf=บางส่วนจะได้รับอนุญาตตามกฎและคุณสามารถแทนที่ด้วย$.split(' ') $.split` `
programmer5000

2

JavaScript (ES6), 97 107

อินพุตเป็นสตริงหลายบรรทัดพร้อมกับขึ้นบรรทัดใหม่

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

regexp แยกส่วนข้อความตัวเลขและตัวเลือกสำหรับแต่ละบรรทัดในdและข
การคำนวณควรเป็น obviuos มากกว่าหรือน้อยกว่า ทราบเพียงเล็กน้อย:
- ใช้-=เพื่อหลีกเลี่ยงปัญหาการผสมตัวเลขกับสตริง
- ผลรวมถูกทำให้ประหยัด 1 ไบต์ดังนั้นการตรวจสอบครั้งสุดท้ายจึงใช้>= 0แทน<= 0

PS ยังคงยาวนานกว่า @ Arnauld's หนู

ทดสอบ

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 ไบต์

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

มันไม่สวยและอาจไม่ใช่วิธีที่ดีที่สุด แต่นี่คือ ต้องป้อนข้อมูลให้ถูกส่งเป็นอาร์เรย์สตริงและเคล็ดลับ / ส่วนลดผ่านเป็นแบบลอยตัว (0.15 tipแทน15 tip) เนื่องจากมีการชี้แจงว่ายอมรับได้ในความคิดเห็นของข้อมูลจำเพาะ

ชี้แจง:

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

มีวิธีที่ดีกว่าในการทำเช่นนี้ แต่วิธีนี้ใช้งานได้อย่างน้อย


หากคุณได้รับเคล็ดลับ / ส่วนลดเป็นแบบลอยตัวคุณไม่ต้องการสิ่งนั้น100ในtสาขา
Wai Ha Lee

@WaiHaLee โอ๊ะดีจุดลืมเปลี่ยนเป็น 1
Skidsdev

เคล็ดลับ: ใส่float.Parse(s.Split(' ')[0])บางสิ่งเพื่อลดความซ้ำซ้อน ที่จะบันทึกประมาณ 80 ตัวอักษร
Wai Ha Lee

โอ้ว้าวฉันเป็นนักกอล์ฟที่น่ากลัวฉันไม่ได้ลบช่องว่างที่ไม่จำเป็นออก ฉันตำหนิ Visual Studio
Skidsdev

ไม่ใช่ความพยายามที่เลวร้ายเลย!
Wai Ha Lee

1

PowerShell , 218 156 143 ไบต์

($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

ลองออนไลน์!

แก้ไขไบต์ที่บันทึกไว้โดยแยกตัวแปร piped ไว้ล่วงหน้า

แก้ไข 2เก็บส่วนที่สองของสตริงดังนั้นฉันสามารถโทรหาตัวแทนที่ดีกว่าได้


ดูเหมือนว่าจะทำงานและรูปแบบอินพุตของคุณก็ใช้ได้
programmer5000

1

Python 133 ไบต์

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

คล้ายกับเวอร์ชัน JavaScript ES6 แต่จำเป็นต้องมีการแปลงประเภทสำหรับfloatค่าใน Python

คำอธิบาย:

แยกค่าแรกและแปลงเป็นทศนิยม

สำหรับแต่ละบรรทัดในบิล:

  1. แยกและแปลงค่าเป็น float
  2. ใช้ a dictเพื่อเลือกการทำงานที่ถูกต้องตามตัวอักษรตัวแรก
  3. สะสมค่า

การใช้งาน:

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'
]))

ยินดีต้อนรับสู่เว็บไซต์!
DJMcMayhem

1

Java 227 ไบต์

เคยผ่านไปแล้วและยังไม่มีคำตอบของ Java ที่ฉันเห็นดังนั้นนี่คือคำตอบ C #ของฉันที่ส่งไปยัง Java ที่ราคา 8 ไบต์

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 #ของฉัน

เช่นเดียวกับคำตอบนั้นคำตอบนี้คาดว่าเคล็ดลับและส่วนลดจะถูกส่งเป็นแบบลอยตัว ( 0.15ไม่15)


ค่อนข้างดี ... สำหรับ Java!
programmer5000

1
@ programmer5000 เป็นธรรม C # เป็นเพียงเล็กน้อย verbose น้อยกว่า Java, ข้อได้เปรียบหลักเป็นสิ่งเช่น C # 's การสนับสนุนของvarประเภททั่วไปและ lambdas (ฉันรู้ว่า Java มีพวกเขา แต่ C #' s มี golfier)
Skidsdev

1

Jq 1.5 , 129 119 114 112 ไบต์

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

ขยาย

  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

ลองออนไลน์!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.