Ücretsiz öğle yemeği diye bir şey yoktur.


17

... yoksa var mı?

Zorluk, baz fiyat, ipuçları, indirimler, kuponlar ve ekstraları içeren öğle yemeği faturamı ayrıştırmak ve öğle yemeğimin 0 $ veya daha düşük olup olmadığını öğrenmek . Bu giriş ise:

12.34
15 tip
25 discount
1.5 extra
2 coupon

Sonra çıktı olabilir false. Şöyle çalışır:

12.34 taban fiyattır.

15 tiptoplama% 15 eklemek anlamına gelir .

25 discounttoplamdan% 25 çıkarmak anlamına gelir .

1.5 extratoplamda 1.5 eklemek anlamına gelir .

2 coupontoplamdan 2 çıkarmak anlamına gelir .

Olabilir herhangi bir miktar ipuçları, indirimler, kuponlar ve ekstralar, ama her zaman bir taban fiyat olacaktır.

Sonra (12.34 * 1.15) * 0.75 + 1.5 - 210.14 çıktı için yapıyoruz . 10.14 0'dan büyük olduğu için yanlış çıktı veriyoruz. Öğle yemeğim serbest değildi.

kurallar

sayı tip aracı ekleme sayısı toplam yüzde.

sayı discount , sayıları toplamdan çıkarmak anlamına gelir

sayı , toplama sayıextra eklemek anlamına gelir

sayı coupon , sayıyı çıkarmak anlamına gelir toplamdan

Başka bir örnek:

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

Fiyat -0.24((10 * 1.20 * 0.80 - 2 - 2 - 1) * 0.5 - 2.55), bu nedenle çıktı doğrudur (öğle yemeğim ücretsizdi.)

Notlar:

  • Hassasiyet en az 2 ondalık basamak olmalıdır.
  • Girişi satırsonu (isteğe bağlı satırsonu karakteri) veya başka bir ayırma karakteri ya da girdilerin bir dizisi / listesi olan bir dize olarak alabilirsiniz.

5
Girişin isme ihtiyacı var mı yoksa sadece bir sayı dizisi girersek siparişi alabilir miyiz? [12.34,15,25,1.5,2]?
Sinüsoid

@StewieGriffin Siparişi seçemezsiniz. 5'ten fazla satır veya daha az olabilir. 2 kuponu 2.00 kupon 15 tipolarak ve0.15 tip
programcı5000 olarak alabilirsiniz

Bu girdi büyük / küçük harfe duyarlı mı? Desteklememiz gereken tüm kelimeler bu mu?
Rɪᴋᴇʀ

@Riker gereken tüm kelimeler ve giriş her zaman küçük harf olacaktır.
programmer5000

5
Değerlendirme sırası nasıl çalışır? Örneğin, bir indirimimiz varsa, bir ipucu varsa, ipucu orijinal miktara veya indirimli miktara uygulanır mı?

Yanıtlar:


2

05AB1E , 37 33 34 bayt

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

Çevrimiçi deneyin!

açıklama

mod 7Hüner ödünç alırJonathan Allan'ın Jelly cevabından

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

1Değer <1 olduğunda elde ederim .
12431234123412341234123

@ 12431234123412341234123: İyi yakala. Karşılaştırma görünüşe göre tamsayıya atıldı: /
Emigna

9

JavaScript (ES6), 88 85 bayt

Girdiyi dizeler dizisi olarak alır. İade 0bedava değil ya1 .

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

Nasıl çalışır

Her satır boşlukta bölünerek a= miktar, b= işlem türü. Hiçbir işlem yoksa (ilk satırdaki durum budur),b varsayılan olarak "e""ekstra" olarak ayarlanır .

Toplama doğru miktarı eklemek için t, anahtarları işlemin ilk harfi olan bir nesne kullanırız:

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

Not : Fatura yalnızca bir unsurdan oluşuyorsa,map() , |operatör uygulandığında tamsayıya zorlanacak tek bir eleman dizisi döndürür ve son test başarısız olur. Ancak OP bunun gerçekleşemeyeceğini doğruladı. (2 veya daha fazla elemandan oluşan diziler 0'a zorlanır.)

gösteri


3

CJam , 45 42 bayt

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

Girdiyi dizeler dizisi olarak alır ve ipucunu alır ve ondalık sayı olarak indirir.

Çevrimiçi deneyin!

açıklama

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.

İlk harflere bağlı olarak değerlendirilen kod:

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

Jöle ,  42 39 bayt

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

Ondalık biçimlendirilmiş sayılarla dizeleri listesini Alır
(baştaki sıfırlar olacak çalışır, ancak öncesinde nihai sonuca STDOUT sıfırları baskı yan etkisi var).

Çevrimiçi deneyin! - özgür değil; veya ücretsiz .

Nasıl?

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

Sürekli olarak benim için 0 çıktı ...
programmer5000

Ah, belki de biçim ondalık kullanır demeliyim?
Jonathan Allan

Ah. Evet yapmalısın.
programmer5000

Mo'daki açıklamayı yazıyorum, işte ücretsiz bir öğle yemeği örneği.
Jonathan Allan

3

GNU + dc, sed 117 111 107 bayt

-zTercüman bayrağını kullanma (1 bayt olarak skora dahil edilmiştir):

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 /

açıklama

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

Giriş zaten çok yakın Ters Polonya notasyonu olduğundan, basit bir mesele dönüştürmeye var extrave couponhiç +ve- , yüzdeyi çarpanlara daha fazlasını yapmak . Daha sonra dcbulunup -bulunmadığına bağlı olarak okunabilir bir sonuç üretin ve üretin (sonucu reddetmeliyiz, bu nedenle -"özgür değil" anlamına gelir, aksi takdirde 0, kendi işlenmesi gereken özel bir durum olacaktır).

Misal

Sorudan ikinci dava:

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

Bu olur dc program :

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

Sonuçlanan:

free

2

JavaScript, 173 169145 bayt

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

Hala yapacak çok golf olmalı

Çevrimiçi deneyin!(Şu anda 145 bayt)

Denemek:

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

Tüm golf tavsiyeleri için programcı5000'e teşekkürler


Düğüm neden gereklidir?
programmer5000

1
Ayrıca, {w=i.split`<nl>`<nl> gerçek bir satırsonu olduğunda yapabilirsiniz
programmer5000

Düğüm gerekli değildir. Ben sadece TIO üzerinde test için kullandım
Alberto Rivera

Denemek için bir yığın snippet'i ekledim. Beğenmediyseniz geri dönmekten çekinmeyin.
programmer5000

1
Sen kaldırabilirsiniz f=kurallara göre izin verilir, bölümünü ve yerini alabilir $.split(' ')ile $.split` `.
programmer5000

2

JavaScript (ES6), 97 107

Sondaki satırsonu olan çok satırlı bir dize olarak girin.

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

Normal ifade d ve b'deki her satır için sayısal ve isteğe bağlı metin bölümünü ayırır .
Hesaplamalar az çok obviuos olmalıdır. Sadece bir not:
- -=sayıları dizelerle karıştırmaktan kaçınmak için kullanma
- toplam 1 bayt tasarruf etmek için reddedilir, bu nedenle son kontrol>= 0 yerine<= 0

PS @ Arnauld'unkinden hala çok daha uzun. Sıçanlar.

Ölçek

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 bayt

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

Güzel değil ve muhtemelen en iyi yol değil, ama işte burada. Girdinin bir dize dizisi olarak geçirilmesini ve ipuçlarının / indirimlerin kayan nokta olarak iletilmesini gerektirir 0.15 tip(15 tip ) çünkü bu özellik yorumlarında kabul edilebilir olarak açıklanmıştır.

Açıklama:

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

Bunu yapmanın daha iyi bir yolu olmalı, ama en azından işe yarıyor


Size şamandıra olarak ipucu / indirim verildiyse 100, tşubede bunu istemezsiniz .
Wai Ha Lee

@WaiHaLee ayy, iyi bir nokta, bunu 1 olarak değiştirmeyi unuttum
Skidsdev

İpucu: float.Parse(s.Split(' ')[0])çoğaltmayı azaltmak için bir şey koyun . Bu yaklaşık 80 karakter kazandırır.
Wai Ha Lee

oh vay canım korkunç bir golfçüyüm gereksiz boşlukları bile kaldırmadım. Visual Studio'yu suçluyorum.
Skidsdev

Hiç de kötü bir çaba değil!
Wai Ha Lee

1

PowerShell , 218 156 143 bayt

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

Çevrimiçi deneyin!

DÜZENLE Borulu değişkeni önceden bölerek kaydedilmiş bayt

EDIT 2 Daha iyi joker aramalar yapabilmek için dizenin ikinci bölümünü sakladı


Çalışıyor gibi görünüyor ve giriş biçiminiz iyi.
programmer5000

1

Python 133 bayt

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 sürümüne benzer. Ancak floatPython'daki değerler için tür dönüşümü gerekir .

Açıklama:

İlk değeri çıkarın ve kayan noktaya dönüştürün.

Faturadaki diğer satırlar için:

  1. değeri böl ve dönüştür float
  2. dictİlk harfe göre doğru işlemi seçmek için a düğmesini kullanın.
  3. Değeri biriktirin

Kullanımı:

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

Siteye Hoşgeldiniz!
DJMcMayhem

1

Java 227 bayt

Bir süredir ve hala görebildiğim bir Java cevabı yok, bu yüzden 8 baytlık maliyetle Java'ya taşınan C # cevabım

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

Bir açıklama ve benzeri için C # cevabımı görün

Bu cevap gibi, bu cevap bahşiş ve indirimin şamandıra olarak geçmesini bekler ( 0.15değil 15)



1
@ programmer5000 adil olmak C # Java'dan sadece biraz daha az ayrıntılı, ana avantajları C # 'in varjenerik tip desteği ve lambdas gibi (Java'nın bunlara sahip olduğunu biliyorum, ancak C #' ın daha golfçü)
Skidsdev

1

JQ 1.5 , 129 119 114 112 bayt

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

Expanded

  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

Çevrimiçi deneyin!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.