จัดการร้านพาย!


12

สรุป

รหัสกอล์ฟเป็นสิ่งที่ดี พายเป็นสิ่งที่ดี เมื่อคุณรวมสองสิ่งเข้าด้วยกันสิ่งที่ดีเท่านั้นที่จะเกิดขึ้นได้

ข้อมูลจำเพาะ

ในการท้าทายนี้คุณจะจัดการร้านพาย ผู้ใช้จะสามารถป้อนข้อมูลห้าคำสั่งแตกต่างกัน: list, count, buy, และsell exitนี่คือข้อกำหนดสำหรับแต่ละ:

  • list

    • พิมพ์รายการของพายทั้งหมดที่เป็นเจ้าของและจำนวน คั่นด้วย|และ pad ด้วยช่องว่างทั้งสองด้าน |ต้องจัดตำแหน่ง จำนวนพายอาจเป็นค่าลบ (นั่นหมายความว่าคุณเป็นหนี้กับใครบางคน:() ตัวอย่างเช่น:

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

    • พิมพ์จำนวน{{type}}พายที่มี พิมพ์ "ไม่มี{{type}}พาย!" ถ้าไม่มี {{type}}จะตรงกับ regex เสมอ\w+(เช่นจะเป็นคำเดียวเสมอ) ตัวอย่างเช่นถ้าฉันมีจำนวนของพายที่แสดงในรายการตัวอย่างข้างต้นแล้ว

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

    • เพิ่ม{{n}}ลงในจำนวนของ{{type}}วงกลมและพิมพ์ สร้าง{{type}}วงกลมหากไม่มีอยู่ {{n}}จะตรงกับ regex เสมอ[0-9]+(กล่าวคือจะเป็นตัวเลขเสมอ) นี่เป็นอีกตัวอย่างหนึ่ง (ที่มีคลังโฆษณาพายเหมือนกับตัวอย่างก่อนหน้านี้):

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

    • ลบ{{n}}ออกจากการนับจำนวนของ{{type}}วงกลมและพิมพ์ สร้าง{{type}}วงกลมหากไม่มีอยู่ พายอาจเป็นลบได้ (โอ้ไม่นั่นหมายความว่าคุณเป็นหนี้คนพาย!)

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

    • พิมพ์ "ร้านพายปิดแล้ว!" และออกจากโปรแกรม

      > exit
      The pie store has closed!
      

ชี้แจงเพิ่มเติม

  • หากมีการเรียกใช้ฟังก์ชันที่ไม่มีอยู่ (คำแรก) ให้พิมพ์ "นั่นไม่ใช่คำสั่งที่ถูกต้อง"
  • หากมีการเรียกใช้ฟังก์ชันที่มีอยู่ด้วยอาร์กิวเมนต์ที่ไม่ถูกต้อง (คำถัดจากคำแรก) โปรแกรมของคุณจะทำงานอย่างไร "การขัดแย้งที่ไม่ถูกต้อง" รวมถึงการขัดแย้งมากเกินไปการโต้แย้งน้อยเกินไป{{n}}ไม่เป็นตัวเลข ฯลฯ
  • พายเป็นสิ่งที่ดี
  • ข้อมูลของคุณจะต้องแตกต่างจากผลลัพธ์ของคุณ หากคุณกำลังรันโปรแกรมบนบรรทัดคำสั่ง / เทอร์มินัล / เชลล์ / ข้อความอื่น ๆ คุณต้องใส่คำนำหน้าด้วยเครื่องหมาย " > ​"(" มากกว่า "เครื่องหมายและช่องว่าง) หรือคำนำหน้าอินพุตเชลล์อื่น ๆ
  • พายเป็นสิ่งที่ดี
  • หากคำอธิบายทั้งหมดนี้ไม่ดีพอนี่คือตัวอย่างผลลัพธ์:

    > 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!
    
  • หากคุณซื้อ / ขายพายและนับสุทธิจะกลายเป็น0คุณสามารถอย่างใดอย่างหนึ่งเก็บไว้ในlistหรือไม่และคุณสามารถอย่างใดอย่างหนึ่งกลับ0หรือThere is no {{type}} pie!เมื่อคุณcountมัน

  • นี่คือ ; รหัสที่สั้นที่สุดชนะ
  • ฉันพูดถึงว่าพายนั้นดีหรือไม่?

3
ดังนั้นเพื่อชี้แจง ... เป็นสิ่งที่ดีพาย?
Igby Largeman

4
เป็นที่ยอมรับหรือไม่ที่จะเก็บวงกลมไว้ในรายการด้วยการนับศูนย์? เช่นถ้าคุณทำและbuy 1 apple sell 1 appleและมันจะถูกต้องสำหรับcount appleการส่งคืน0แทนThere is no apple pie!หรือไม่?
Igby Largeman

@IgbyLargeman แย่แล้วฉันคิดว่าฉันชี้แจงทุกอย่าง! : P เพิ่มกรณีทดสอบใหม่เพื่อความกระจ่างเพิ่มเติม
Doorknob

@ Doorknob เฮ้! ฉันกำลังแสดงผล "ไม่มีพายแอปเปิ้ล" หลังจากที่ขายครั้งสุดท้ายแล้ว
John Dvorak

@JanDvorak เอาล่ะฉันคิดว่าจะใช้วิธีใดก็ได้ อัปเดตอีกครั้ง
Doorknob

คำตอบ:


3

ทับทิม, 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}

เทคนิคบางอย่างที่นี่:

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

ความคิดของ Doorknob ในการใช้ตัวจัดรูปแบบเป็นขั้นตอนต่อไปที่นี่อย่างแท้จริง ครั้งแรกที่สตริงที่ยาวที่สุดในกัญชาในหมู่คีย์และค่าทั้งหมดที่มีรูปแบบที่ใช้ในการผลิตเช่นสตริง" %%%ds |" " %6s |"ใช่ไม่มีการลดขนาดการแยกแต่ละคอลัมน์ ไม่เคยมีความต้องการที่จะ ขนาดเดียวเหมาะกับทุกคน จากนั้นสตริงนี้จะทำซ้ำและใช้เป็นสตริงการจัดรูปแบบสำหรับอาร์เรย์สององค์ประกอบที่มีแถวปัจจุบัน ในที่สุด+ใกล้จุดเริ่มต้นจะได้รับคำพูดของมันและเสริมท่อนำหน้าเดียว โอ้และputsมีการจัดการอาร์เรย์ที่ดี

Ruby มีการแก้ไขในตัวอักษร regex มันประหยัดแน่น แต่ก็ประหยัดเล็กน้อย

Ruby ต้องการเซมิโคลอนหลังwhenนิพจน์ แต่ไม่ใช่ก่อนคำสำคัญ สิ่งนี้นำไปสู่การสร้างสิ่งประดิษฐ์แปลก ๆ เมื่ออัฒภาคถูกแทนที่ด้วยขึ้นบรรทัดใหม่

และแน่นอนว่า perlism รู้จักกันในนามของ globals เวทมนตร์และการจับคู่ regex ตัวอักษรอัตโนมัติกับพวกเขา

นอกจากนี้งบส่วนใหญ่รวมถึงcaseการแสดงออก


เทคนิคที่ฉลาดมาก! +1
Doorknob

อืม แต่ทำไมHash.new(0)แทน{}?
Doorknob

1
@Doorknob แฮชของรูบี้สามารถมีค่าเริ่มต้น (ถ้าคุณผ่านวัตถุ) หรือแม้กระทั่งเครื่องกำเนิดไฟฟ้า (ถ้าคุณผ่านบล็อก (คีย์, แฮช -> ค่า) หากคุณไม่ผ่านเช่นนั้นค่าเริ่มต้นคือnil(ซึ่งไม่ อนุญาตให้เพิ่ม) ตัวอักษรใช้nilเป็นค่าเริ่มต้น
John Dvorak

สามารถบันทึกไม่กี่ตัวอักษรที่มีh=Hash.new(0)=> h=Hash.new 0, print"> "=> $><<'> 'และผมคิดว่าเพียงแค่สามารถ[*h] hฉันพยายามร่วมกันวางรุ่นที่ไม่มีงบเปลี่ยนตั้งแต่ทั้งหมดที่ข้อความสำเร็จรูปจริงๆเพิ่มขึ้น: gist.github.com/chron/6315218 ฉันพยายามทำให้บางสิ่งทำงานด้วยruby -apแต่ข้อกำหนดสำหรับพรอมต์ทำให้มันยาก: <
Paul Prestidge

@ ประสานขอบคุณ! ไม่อยากจะเชื่อเลยว่าฉันพลาดคนแรกและฉันไม่แน่ใจว่าทำไมฉันจึงคิดว่า$><<พิมพ์บรรทัดใหม่ สำหรับข้อเสนอแนะล่าสุด ... น่าเสียดายที่แฮ็ชไม่มีวิธี "แบน"
John Dvorak

3

Ruby, 427 384 ตัวอักษร

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 ที่มีการพัฒนาอย่างมากจาก 427 เป็น 384 (!)


คุณสามารถใช้แทนloop{...} while 1do...end
John Dvorak

คุณสามารถใช้splitโดยไม่มีการโต้แย้ง โดยค่าเริ่มต้นมันแยกจากช่องว่าง (หรือ$;ถ้ามีการตั้งค่า)
จอห์น Dvorak

p.keys.group_by(&:size).max[0]- คุณกำลังมองหาp.keys.map(&:size).maxหรือp.map{|x,_|x.size}.max? ที่นี่: [(t=p.values).max.to_s.size,t.min.to_s.size].maxคุณกำลังมองหาp.map{|_,x|x.to_s.size}.max? ฉันจะใช้ความคิดของคุณและใช้ฟอร์แมตเตอร์ในทางที่ผิด :-)
John Dvorak

p[t]=p[t]+mเทียบเท่ากับp[t]+=m(ยกเว้นp[t]ถูกประเมินสองครั้งแทนหนึ่งครั้ง) และนานกว่า ใช้หลัง
John Dvorak

@JanDvorak Oooh ขอบคุณสำหรับเคล็ดลับทั้งหมด: DI คิดว่า Ruby ไม่มี+=โอเปอเรเตอร์ นั่นเป็นเหตุผลที่ฉันไม่ได้ใช้มัน ++บางทีนั่นอาจจะเป็นเพียงสำหรับ ฉันจะแก้ไขโพสต์ของฉันในไม่ช้า
Doorknob

3

หลาม พาย -thon 437

ฉันแน่ใจว่ามีความหย่อนในบรรทัดสุดท้ายที่สอง แต่ความต้องการในการจัดแนวแท่งสำหรับทั้งประเภทพายและหมายเลขคือ 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 ของกฎระเบียบที่มีความชัดเจนรอบว่าจะทำอย่างไรถ้ามีเป็นพายประเภทที่เฉพาะเจาะจง แต่มี0ตอนนี้ ดังนั้นฉันจึงตีความมันในความโปรดปรานของฉัน

ตัวอย่างผลลัพธ์:

> 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

ขออภัยด้วยสิ่งนี้> count potatoผลิตThat's not a valid command.แทนThere is no potato pie!
Doorknob

@Doorknob คุณกำลังใช้งาน IDLE อยู่หรือเปล่า?

ใช่. ฉันจะลองเป็นไฟล์
Doorknob

ที่จริงแล้วการนับไม่ได้ผลเลย บางครั้งมันใช้งานได้จริง แต่บางครั้งก็ใช้ไม่ได้ มันแปลกมาก ...
Doorknob

3
Hehe ฉันรู้ว่ามันเป็นการปะทะกันของการตั้งชื่อบางอย่าง: P +1 โอ้และไฟล์ของฉันสำหรับโปรแกรมของคุณมีชื่อที่น่าขบขันpie.py:: P
Doorknob

3

C # - 571 568 559

ยกขึ้นด้านหลังตามปกติด้วย verbose อย่าง C #

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

ป้อนคำอธิบายรูปภาพที่นี่

ฉันเอาเสรีภาพบางอย่างกับกฎเกี่ยวกับรายการผลลัพธ์ เมื่อต้องการบันทึกอักขระบางตัวฉันฮาร์ดโค้ดความกว้างของคอลัมน์การนับเป็นความกว้างสูงสุดของค่าจำนวนเต็ม (กฎไม่ได้บอกว่าไม่อนุญาตให้เว้นวรรค)

จัดรูปแบบ:

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, ฉันประหลาดใจที่คุณสามารถนับจำนวนอักขระที่ต่ำด้วยภาษา verbose เช่นนี้: D
Doorknob

เป้าหมายของฉันกับ Java เป็นเพียงการเอาชนะการใช้งาน C # ฮ่าฮ่า ทำได้ดีมากกับสิ่งนี้
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

ฉันรู้ว่ามันไม่ชนะการแข่งขัน แต่เพื่อความสนุก!

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

ด้วยตัวแบ่งบรรทัดและแท็บ:

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
+1 สำหรับภาษากอล์ฟที่ไม่ใช่แบบดั้งเดิม :) ด้วย C # ฉันพบว่าคำสั่ง switch มีราคาแพงกว่าง่ายกว่าถ้า {} สร้าง นี่ควรเป็นจริงสำหรับ Java ด้วย
Igby Largeman

@IgbyLargeman ใช่ฉันเก็บไว้พยายามที่จะได้รับif/elseจะมีราคาแพงน้อยลง แต่เนื่องจากความจริงที่ว่าฉันต้องทำs[0]=s[0].intern()เพื่อที่จะเปรียบเทียบกับ==ก็มักจะสิ้นสุดขึ้นเป็นมากขึ้น ฉันรู้ว่าใช้ง่ายมาก
asteri
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.