無料のランチのようなものはありません


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引くことを意味します。

があるかもしれませヒント、割引、クーポン、およびエキストラが、常に1台の価格が存在します。

それから (12.34 * 1.15) * 0.75 + 1.5 - 2、10.14の出力を作成します。10.14は0より大きいため、falseを出力します。私の昼食は無料ではありませんでした。

ルール

数値 tipは、合計に数値パーセントを追加することを意味します。

number discountは、合計からnumberパーセントを引くことを意味します

数値 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枚のクーポンを2.00クーポンとして受け取り15 tip0.15 tip
programmer5000

この入力では大文字と小文字が区別されますか?サポートする必要があるすべての言葉ですか?
Rɪᴋᴇʀ

@Rikerは必要なすべての単語であり、入力は常に小文字になります。
Programmer5000

5
評価順序はどのように機能しますか?たとえば、割引がある場合、チップは元の金額に適用されますか、それとも割引金額に適用されますか?

回答:


2

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

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
}

:法案が1つの要素のみで構成されている場合、map()されている場合、|演算子を適用すると整数に強制される単一要素配列が返され、最終テストは失敗します。しかし、OPはこれが起こらないことを確認しました。(2つ以上の要素の配列は0に強制されます。)

デモ


3

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

10進形式の数値を持つ文字列のリストを取得します
(先行ゼロ機能しますが、最終結果の前に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

ああ、多分私はフォーマットが小数を使用していると言うべきですか?
ジョナサンアラン

ああ。はい、そうすべきです。
Programmer5000

私はmoで説明を書いています。ここに無料のランチの例を示します。
ジョナサンアラン

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 /

入力はすでに逆ポーランド記法に非常に近いので、変換extracoupon+およびに変換するのは簡単なこと-であり、パーセンテージを乗数に変更することはあまりありません。次にdc-見つかったかどうかに応じて読み取り可能な結果を呼び出して生成します(結果を否定する必要があるため、-「not free」を意味します。それ以外の場合、0は独自の処理が必要な特殊なケースです)

質問の2番目のケースは次のとおりです。

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上でテストするためにそれを使用
アルベルト・リベラ

私はそれを試すためのスタックスニペットを追加しました。気に入らなければ、気軽にロールバックしてください。
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

正規表現は、dおよびbの各行の数値部分とオプションのテキスト部分を分割します。
計算は多かれ少なかれ曖昧でなければなりません。ただ、いくつかの注意:
-使用して-=文字列で数を混合問題を避けるために
-最後のチェックをするためにあるので合計は、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#324219バイト

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

それはきれいではなく、おそらく最善の方法ではありませんが、ここにあります。入力は文字列配列として渡され、tips / discountsは(の0.15 tip代わりに15 tip)floatとして渡される必要があります。これは、仕様のコメントで受け入れられることが明確になったためです。

説明:

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
ワイハリー

@WaiHaLeeおっと、良い点、それを1に変更するのを忘れていた
-Skidsdev

ヒント:float.Parse(s.Split(' ')[0])重複を減らすために何かを入れます。約80文字節約できます。
ワイハリー

ああ、すごいゴルファーだから、不要な空白も削除しなかった。Visual Studioのせいにします。
Skidsdev

まったく悪い努力ではありません!
ワイハリー

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

オンラインでお試しください!

事前にパイプ変数を分割して保存バイトを編集

EDIT 2文字列の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の値には型変換が必要です。

説明:

最初の値を抽出して、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

Java 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


かなり良い... Javaに!
Programmer5000

1
@ programmer5000公正C#のようにして、わずかに少ない冗長Java以外のみである主な利点は、C#のようなもの「のsのサポートされてvarジェネリック型、およびラムダ(私はJavaがそれらを持って知っているが、C#」sがgolfierある)
Skidsdev

1

JQ 1.5129の 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.