무료 점심과 같은 것은 없습니다


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 - 210.14의 출력을 수행 합니다. 10.14가 0보다 크므로 false를 출력합니다. 점심은 공짜가 아니었다.

규칙

숫자 는 전체에 숫자 백분율 tip을 추가하는 것을 의미합니다 .

숫자 는 총계에서 숫자 퍼센트 discount를 빼는 것을 의미합니다.

숫자 는 총계 extra숫자 를 추가하는 것을 의미합니다.

숫자 는 총계에서 숫자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)이므로 출력은 true입니다 (제 점심은 무료였습니다.)

노트:

  • 정밀도는 소수점 이하 2 자리 이상이어야합니다.
  • 줄 바꿈 (선택적 후행 줄 바꿈) 또는 다른 분리 문자 또는 입력 / 배열 목록이있는 문자열로 입력을 취할 수 있습니다.

5
입력에 이름이 필요합니까 아니면 숫자 배열 [12.34,15,25,1.5,2] 만 입력하면 순서를 가정 할 수 있습니까?
사인파

@StewieGriffin 주문을 선택할 수 없습니다. 행이 5 개보다 많거나 적을 수 있습니다. 당신은 2.00 쿠폰으로이 쿠폰을 가지고, 수 15 tip0.15 tip
programmer5000

이 입력은 대소 문자를 구분합니까? 그것이 우리가 지원해야 할 모든 단어입니까?
Rɪᴋᴇʀ

@Riker는 필요한 모든 단어이며 입력은 항상 소문자입니다.
programmer5000

5
평가 순서는 어떻게 작동합니까? 예를 들어 할인이있는 경우 팁은 팁이 원래 금액 또는 할인 된 금액에 적용됩니까?

답변:


2

05AB1E , 37 33 34 바이트

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

온라인으로 사용해보십시오!

설명

조나단 앨런의 젤리 답변mod 7 에서 얻은 트릭을 빌려줍니다

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

자바 스크립트 (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""추가" 로 설정됩니다 .

total에 올바른 금액을 추가하기 위해 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>!

입력을 문자열 배열로 사용하고 팁과 할인을 10 진수로 사용합니다.

온라인으로 사용해보십시오!

설명

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¬

10 진수 형식의 숫자가 포함 된 문자열 목록을 가져 옵니다
(제로 리드 작동하지만 최종 결과 전에 STDOUT에 0을 인쇄하는 부작용이 있습니다).

온라인으로 사용해보십시오! -무료가 아닙니다. 또는 무료 .

어떻게?

⁾_@ - 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는 + 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 Polish 표기법에 매우 가깝기 때문에 변환 extracoupon로 변환하는 간단한 문제 +이며 -, 백분율을 승수로 변경하는 것 이상은 아닙니다. 그런 다음 발견 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

자바 스크립트, 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에서 테스트를 위해 그것을 사용
알베르토 리베라에게

그것을 시도하기 위해 스택 스 니펫을 추가했습니다. 마음에 들지 않으면 롤백하십시오.
programmer5000

1
당신은 제거 할 수 있습니다 f=이 규칙에 의해 허용되고, 부분, 당신은 대체 할 수 있습니다 $.split(' ')$.split` `.
programmer5000

2

자바 스크립트 (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

정규 표현식은 db의 각 행에 대해 숫자 및 선택적 텍스트 부분을 분할합니다 .
계산은 다소 간결해야합니다. 몇 가지 참고 사항 :
- -=문자열과 숫자를 혼합 하는 데 문제가 발생하지 않도록 사용
-합계는 1 바이트를 절약하기 위해 무효화되므로 마지막 검사는 >= 0대신<= 0

PS는 여전히 @Arnauld보다 길다. 쥐.

테스트

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

이 작업을 수행하는 더 좋은 방법이 있지만 적어도 작동합니다.


수레로 팁 / 할인을 받았다 100t지점 에서 원하지 않습니다 .
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

온라인으로 사용해보십시오!

파이프 변수를 미리 분할하여 저장된 바이트를 편집

편집 2 더 나은 와일드 카드 호출을 할 수 있도록 문자열의 두 번째 부분을 저장했습니다.


작동하는 것 같고 입력 형식이 좋습니다.
programmer5000

1

파이썬 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파이썬의 값에는 유형 변환이 필요합니다 .

설명:

첫 번째 값을 추출하여 부동 소수점으로 변환하십시오.

청구서의 서로 다른 줄에 대해 :

  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

자바 227 바이트

잠시 동안 여전히 볼 수있는 Java 답변이 없으므로 8 바이트의 비용으로 Java로 포팅 된 C # 답변이 있습니다.

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)



1
공정한 C # 인 @ programmer5000은 Java보다 약간 덜 장황하며, C #의 var일반 유형 지원 및 람다 (Java가 있지만 C #은 골퍼임을 알 수 있습니다) 와 같은 주요 이점 이 있습니다.
Skidsdev

1

1 , 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.