Bir pasta dükkanını yönet!


12

özet

Kod golf iyidir. Pie iyidir . İkisini bir araya getirdiğinizde, sadece iyi şeyler olabilir.

Özellikler

Bu meydan okumada bir pasta dükkanı yöneteceksiniz. Kullanıcı beş farklı giriş komutları mümkün olacak: list, count, buy, sell, ve exit. Her birinin özellikleri şunlardır:

  • list

    • Sahip olunan tüm turtaların bir listesini ve kaç tane yazdırın. |Her iki tarafında bir boşluk bırakarak ve ped ile ayırın . |s hizalanmalıdır. Pasta miktarı negatif olabilir (bu, birine pasta borcunuz olduğu anlamına gelir :(). Örneğin:

      | apple     | 500 |
      | blueberry | 2   |
      | cherry    | -30 |
      
  • count [type]

    • Kaç {{type}}turta olduğunu yazdırın . Yazdır " {{type}}Pasta yok !" eğer yoksa. {{type}}her zaman normal \w+ifadeyle eşleşecektir (yani, her zaman tek bir kelime olacaktır). Örneğin, yukarıdaki örnek listesinde gösterilen turta miktarım varsa,

      > count apple
      500
      > count peach
      There is no peach pie!
      
  • buy [n] [type]

    • Pasta {{n}}sayısına ekleyin {{type}}ve yazdırın. {{type}}Eğer yoksa pasta yaratın . {{n}}her zaman normal [0-9]+ifadeyle eşleşir (yani, her zaman bir sayı olur). İşte başka bir örnek (önceki örneklerle aynı pasta envanterine sahip):

      > count blueberry
      2
      > buy 8 blueberry
      10
      
  • sell [n] [type]

    • Çıkar {{n}}sayısından {{type}}pasta ve yazdırabilirsiniz. {{type}}Eğer yoksa pasta yaratın . Pasta negatif olabilir (oh hayır, bu birine pasta borcunuz olduğu anlamına gelir!).

      > sell 15 blueberry
      -5
      > buy 5 blueberry
      0
      
  • exit

    • Yazdır "Pasta dükkanı kapandı!" ve programdan çıkın.

      > exit
      The pie store has closed!
      

Diğer açıklamalar

  • Var olmayan bir işlev çağrılırsa (ilk sözcük), "Bu geçerli bir komut değil" yazdırın.
  • Mevcut bir işlev geçersiz argümanlarla çağrılırsa (ilk kelimeden sonraki kelimeler), programınızın nasıl davrandığı önemli değildir. "Geçersiz bağımsız değişkenler" çok fazla sayıda bağımsız değişken, çok az sayıda bağımsız değişken, {{n}}sayı olmamak vb. İçeriyor.
  • Pie iyidir.
  • Girişiniz çıkışınızdan ayırt edilmelidir. Programı komut satırında / terminal / kabuk / diğer metin tabanlı bir şey üzerinde çalıştırıyorsanız, girdiye " > ​"(" işaretinden "işareti ve boşluktan büyük) veya başka bir kabuk girdi önekiyle önek eklemelisiniz.
  • Pie iyidir.
  • Tüm bu açıklamalar yeterince iyi değilse, bazı örnek çıktılar:

    > list
    > buy 10 apple
    10
    > sell 10 blueberry
    -10
    > list
    | apple     | 10  |
    | blueberry | -10 |
    > count apple
    10
    > count peach
    There is no peach pie!
    > exit
    The pie store has closed!
    
  • Pasta alırsanız / satarsanız ve net sayı 0olursa, ya da içinde tutabilir ya da tutamazsınız listve ya geri döndüğünüzde 0ya da There is no {{type}} pie!ne zaman döndüğünüzde count.

  • Bu ; en kısa kod kazanır.
  • Turtanın iyi olduğunu söylemiş miydim?

3
Yani sadece açıklığa kavuşturmak için ... pasta iyi mi?
Igby Largeman

4
Listede sıfır sayısı olan bir pasta tutmak kabul edilebilir mi? Eğer yaparsan buy 1 appleve sell 1 apple. Peki bunun yerine count applegeri dönmek geçerli midir? 0There is no apple pie!
Igby Largeman

@IgbyLargeman Lanet olsun, her şeyi açıklığa kavuşturduğumu sanıyordum! : P Ek açıklamalara yeni test örneği eklendi
Kapı tokmağı

Heyecan! Ben sonuncusu satıldıktan sonra "elmalı turta yok" çıktı.
John Dvorak

@ JanDvorak Tamam, her iki şekilde de işe yarayacağını düşünüyorum. Tekrar güncellendi
Kapı Tokmağı

Yanıtlar:


3

Yakut, 335 330

h=Hash.new 0
loop{$><<"> "
puts case gets when/^list/
h.map{|x|?|+" %%%ds |"%h.flatten.map{|e|e.to_s.size}.max*2%x}when/^count (.*)/
h[$1]!=0?h[$1]:"There is no #{$1} pie!"when/^buy#{m=" (.*)"*2}/
h[$2]+=$1.to_i when/^sell#{m}/
h[$2]-=$1.to_i when/^exit/
puts"The pie store has closed!"
break else"That's not a valid command."end}

Burada bazı püf noktaları:

?|+" %%%ds |"%[*h].flatten.map{|e|e.to_s.size}.max*2%x

Doorknob'un bir formatlayıcı kullanma fikri, tam anlamıyla burada bir adım daha ileri götürülmektedir. İlk olarak, tüm anahtarlar ve değerler arasındaki karmadaki en uzun dize, " %%%ds |"benzer bir dize üretmek için kullanılarak biçimlendirilir " %6s |". Evet, her sütunu ayrı olarak daraltmak yok. Asla gerek yoktu. Tek beden herkese uyar. Daha sonra bu dize çoğaltılır ve geçerli satırı içeren iki öğeli dizi için biçimlendirme dizesi olarak kullanılır. Son olarak, +yakın başlangıç ​​sözünü alır ve tek bir önde gelen boruyu hazırlar. Oh, ve putsdizileri güzel bir şekilde ele alıyor.

Ruby normal ifadelerde enterpolasyona sahiptir. Sıkı bir tasarruf ancak biraz tasarruf sağlıyor.

Ruby, whenifadeden sonra noktalı virgül gerektirir , ancak anahtar kelimeden önce gerekmez. Noktalı virgül bir satırsonu ile değiştirildiğinde tuhaf bir oluşturma yapaylığına yol açar.

Ve elbette, sihirli küreseller olarak bilinen perlizm ve regex değişmezlerinin onlara karşı otomatik olarak eşleştirilmesi.

Ayrıca, çoğu ifade caseifadedir.


Çok akıllı numaralar! +1
Kapı Tokmağı

Hmm, ama neden Hash.new(0)yerine {}?
Kapı Tokmağı

1
> Değer) ya geçemiyor, varsayılan değerdir -. @Doorknob Ruby'nin karmaları sen (anahtar, karma bir blok geçirirseniz (hatta jeneratörler (Bir nesneyi geçirirseniz) varsayılan değerleri olabilir nildeğil ki ( Değişmez nildeğer varsayılan değer olarak kullanılır
John Dvorak

h=Hash.new(0)=> h=Hash.new 0, print"> "=> İle birkaç karakter kaydedebilir $><<'> 've bence [*h]sadece olabilir h. Tüm bu metraj metni metni gerçekten eklediğinden, anahtar deyimi olmayan bir sürümü bir araya getirmeyi denedim: gist.github.com/chron/6315218 . Bir şeylerin çalışmasını sağlamaya çalışıyordum ruby -apama bilgi istemi zorlaştırıyor: <
Paul Prestidge

@chron teşekkürler! İlkini özlediğime inanamıyorum ve neden $><<yeni bir satır yazdırdığımı bilmiyorum . Son öneriye gelince ... maalesef, karmaların "düzleştir" yöntemi yoktur.
John Dvorak

3

Ruby, 427384 karakter

alias x puts
p={}
loop{
print'> '
case(u=gets.chop.split)[0]when'exit'
x'The pie store has closed!'
exit
when'list'
p.each{|k,v|printf"| %-#{p.keys.map(&:size).max}s | %-#{p.map{|e,a|a.to_s.size}.max}s |\n",k,v}
when'count'
x p[t=u[1]]||"There is no #{t} pie!"
when/sell|buy/
m=(u[0]<?s?1:-1)*u[1].to_i
if p[t=u[2]]
x p[t]+=m
else
x p[t]=m
end
else x"That's not a valid command."
end}

Jan Dvorak'a 427'den 384'e kadar büyük gelişme sayesinde (!)


Bunun loop{...}yerine kullanabilirsiniz while 1do...end.
John Dvorak

splitOnun argümanı olmadan kullanabilirsiniz . Varsayılan olarak, boşluk (veya $;ayarlanmışsa) tarafından bölünür
John Dvorak

p.keys.group_by(&:size).max[0]- arıyorsunuz p.keys.map(&:size).maxya da p.map{|x,_|x.size}.max? Burada [(t=p.values).max.to_s.size,t.min.to_s.size].maxmı arıyorsunuz p.map{|_,x|x.to_s.size}.max? Fikrinizi alacağım ve formatlayıcıyı kötüye
kullanacağım

p[t]=p[t]+meşittir p[t]+=m(hariç p[t]bir kez yerine iki kez değerlendirilir) ve daha uzun. İkincisini kullanın.
John Dvorak

@ JanDvorak Oooh, tüm ipuçları için teşekkürler: DI, Ruby'nin bir +=operatörü olmadığını düşündü ; bu yüzden kullanmadım. Belki bu sadece ++.
Yazımı en

3

piton Pasta 437 -thon

Eminim ikinci son satırda biraz gevşeklik var, ama hem pasta türü hem de sayı için çubukları hizalama gereksinimi doozy.

p,C,l={},"count",len
while 1:
 a=raw_input("> ").split();c=a.pop(0)
 if"exit"==c:print"The pie store has closed!";break
 if"sell"==c:a[0]=int(a[0])*-1
 if c in[C,"buy","sell"]:
  y=a[-1]
  if c!=C:p[y]=p.get(y,0)+int(a[0])
  print p.get(y,"There is no %s pie!"%y)
 elif"list"==c:
  for i in p:print"| %s | %s |"%(i.ljust(l(max(p.keys(),l))),str(p[i]).rjust(max([l(str(x)) for x in p.values()])))
 else:print"That's not a valid command."

Igby Largeman yorumuna gereğince kural var ne yapmanız gerektiği etrafında belirsiz oldu Belirli bir türde bir pasta, ama orada 0şimdi. Ben de bunu kendi lehime yorumladım.

Örnek çıktı:

> buy 10 apple
10
> sell 1 blueberry
-1
> buy 1 keylime
1
> sell 3 apple
7
> buy 5 blueberry
4
> list
| keylime   | 1 |
| apple     | 7 |
| blueberry | 4 |
> sell 1 keylime
0
> count keylime
0

Üzgünüz, ama bunun yerine > count potatoüretirThat's not a valid command.There is no potato pie!
Kapı Tokmağı

@Doorknob IDLE'de mi çalıştırıyorsunuz?

Evet. Ben bir dosyada deneyeceğim
Kapı tokmağı

Aslında, sayım hiç çalışmıyor gibi görünüyor . Aslında bazen çalışıyor ama bazen çalışmıyor. Çok tuhaf ...
Kapı tokmağı

3
Hehe, bunun bir tür adlandırma çatışması olduğunu biliyordum: P +1 Oh ve ayrıca, programınız için pie.py
dosyamın

3

C # - 571 568 559

Umutsuzca ayrıntılı C # ile arka her zamanki gibi getirmek.

using C=System.Console;class Z{static void Main(){var P=new 
System.Collections.Generic.Dictionary<string,int>();int i=0,n;a:C.Write
("> ");var I=C.ReadLine().Split(' ');var c=I[0];object s=c=="exit"?
"The pie store has closed!":"That's not a valid command.";if(c==
"count")try{s=P[c=I[1]];}catch{s="There is no "+c+" pie!";}if(c==
"buy"||c=="sell"){n=int.Parse(I[1]);n=c=="sell"?-n:n;try{n+=P[c=
I[2]];}catch{}s=P[c]=n;i=(n=c.Length)>i?n:i;}if(c=="list")foreach(
var p in P.Keys)C.Write("| {0,"+-i+"} | {1,11} |\n",p,P[p]);else C.
WriteLine(s);if(c!="exit")goto a;}}

resim açıklamasını buraya girin

Liste çıktısı kuralıyla biraz özgürlük aldım. Bazı karakterleri kaydetmek için sayım sütununun genişliğini bir tamsayı değerinin maksimum genişliğine kodladım. (Kurallar fazladan boşluğa izin verilmediğini söylemedi.)

biçimlendirilmiş:

using C = System.Console;
class Z
{
    static void Main()
    {
        var P = new System.Collections.Generic.Dictionary<string, int>();
        int i = 0, n;
    a:
        C.Write("> ");
        var I = C.ReadLine().Split(' ');
        var c = I[0];
        object s = c == "exit" ? "The pie store has closed!" 
                               : "That's not a valid command.";

        // allow Dictionary to throw exceptions; cheaper than using ContainsKey()
        if (c == "count")
            try { s = P[c = I[1]]; }
            catch { s = "There is no " + c + " pie!"; }

        if (c == "buy" || c == "sell")
        {
            n = int.Parse(I[1]);
            n = c == "sell" ? -n : n;

            try { n += P[c = I[2]]; }
            catch { }

            s = P[c] = n;
            i = (n = c.Length) > i ? n : i;
        }

        if (c == "list")
            foreach (var p in P.Keys) 
                C.Write("| {0," + -i + "} | {1,11} |\n", p, P[p]);
        else
            C.WriteLine(s);

        if (c != "exit") goto a; // goto is cheaper than a loop
    }
}

1
+1, böyle ayrıntılı bir dille çok düşük bir karakter sayısı elde edebildiğiniz için şaşırdım: D
Doorknob

Java ile amacım sadece C # uygulamasını yenmektir. Haha. Bununla iyi iş çıkardın.
asteri

2

Python 3, 310

p={}
c=G=p.get
while c:
 l=("exit list buy count sell "+input("> ")).split();c=l.index(l[5]);*_,n=l
 if~-c%2*c:p[n]=(3-c)*int(l[6])+G(n,0)
 print(["The pie store has closed!","\n".join("| %*s | %9s |"%(max(map(len,p)),k,p[k])for k in p),G(n),G(n,"There is no %s pie!"%n),G(n),"That's not a valid command."][c])

1

Java - 772 751 739 713 666 619

Yarışmayı kazanmadığını biliyorum, ama sadece eğlence için!

import java.util.*;class a{static<T>void p(T p){System.out.print(p);}public static
 void main(String[]s){z:for(Map<String,Long>m=new HashMap();;){p("> ");s=new
 Scanner(System.in).nextLine().split(" ");switch(s[0]){case"list":for(Map.Entry 
e:m.entrySet())System.out.printf("|%12s|%6s|\n",e.getKey(),e.getValue());break;
case"count":p(m.get(s[1])!=null?m.get(s[1]):"There is no "+s[1]+" pie!\n");break;
case"buy":case"sell":long r=(s[0].length()==3?1:-1)*new Long(s[1])+(m.get(s[2])!=null?
m.get(s[2]):0);p(r+"\n");m.put(s[2],r);break;case"exit":p("The pie store has
 closed!");break z;default:p("That's not a valid command.\n");}}}}

Satır kesmeleri ve sekmelerle:

import java.util.*;

class a{

    static<T>void p(T p){
        System.out.print(p);
    }

    public static void main(String[]s){
        z:for(Map<String,Long>m=new HashMap();;){
            p("\n> ");
            s=new Scanner(System.in).nextLine().split(" ");
            switch(s[0]){
            case"list":
                for(Map.Entry e:m.entrySet())
                    System.out.printf("|%12s|%6s|\n",e.getKey(),e.getValue());
                break;
            case"count":
                p(m.get(s[1])!=null?m.get(s[1]):"There is no "+s[1]+" pie!");
                break;
            case"buy":
            case"sell":
                long r=(s[0].length()==3?1:-1)*new Long(s[1])+(m.get(s[2])!=null?m.get(s[2]):0);
                p(r);
                m.put(s[2],r);
                break;
            case"exit":
                p("The pie store has closed!");
                break z;
            default:
                p("That's not a valid command.");
            }
        }
    }

}

1
Geleneksel olmayan bir golf dili için +1 :). C # ile, {} derlerse switch deyiminin basitten daha pahalı olduğunu gördüm. Bu Java için de geçerli olmalıdır.
Igby Largeman

@IgbyLargeman Evet, if/elsedaha ucuz olmaya çalışıyordum , ancak s[0]=s[0].intern()karşılaştırmak için yapmam gerekmesi nedeniyle ==, her zaman daha fazla oluyor . Biliyorum, çok mantıksız.
asteri
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.