จิ๊กซอว์เหยือก 3 และ 5 ลิตร


14

คุณอาจเคยเห็นสิ่งนี้ในDie Hard: With Vengeance ... คำถามนี้มีพื้นฐานมาจากปริศนาเหยือก 3 และ 5 ลิตรที่โด่งดัง แต่มีความแตกต่างเล็กน้อย

หารหัสบางส่วนที่ให้จำนวนเต็มตั้งแต่ 1 ถึง 100 จะให้คำแนะนำที่รวดเร็วที่สุดในการวัดลงในถังน้ำจำนวนลิตรที่สอดคล้องกันจากน้ำพุโดยใช้เหยือก 3 ลิตรและเหยือก 5 ลิตร

ไม่มีการไล่ระดับสีบนเหยือกอย่างใดอย่างหนึ่ง น้ำพุนั้นมีน้ำมากและถังนั้นก็จะถูกปล่อยออกไปเมื่อเริ่มต้นการประมวลผลของรหัสแต่ละครั้ง

คุณไม่สามารถเข้าถึงน้ำจากถังเมื่อเข้าไปในถัง

รูปแบบของการดำเนินการเป็นดังนี้:

การป้อนข้อมูล:

4 ตัวอย่างเช่น.

เอาท์พุต

เอาท์พุทแต่ละขั้นตอนที่มีหมายเลขตามที่แสดงแล้วตามด้วยปริมาณของเหยือก 5L เหยือก 3L และถัง รูปแบบการนับยังแสดงด้านล่าง จำนวนขั้นตอนจะต้องถูกส่งออกในตอนท้ายของขั้นตอน

1) Fill 5L jug

5L: 5, 3L: 0, T: 0

2) Pour from 5L jug into 3L jug

5L: 2, 3L: 3, T: 0

3) Empty 3L jug

5L: 2, 3L: 0, T: 0

4) Pour from 5L jug into 3L jug

5L: 0, 3L: 2, T: 0

5) Fill 5L jug

5L: 5, 3L: 2, T: 0

6) Pour from 5L jug into 3L jug

5L: 4, 3L: 3, T: 0

7) Pour from 5L jug into tank

5L: 0, 3L: 3, T: 4

Volume measured out in 7 turns

ตัวอย่างที่ 2

การป้อนข้อมูล: 8

เอาท์พุท:

1) Fill 5L jug

5L: 5, 3L: 0, T: 0

2) Pour from 5L jug into tank

5L: 0, 3L: 0, T: 5

3) Fill 3L jug

5L: 0, 3L: 3, T: 5

4) Pour from 3L jug into tank

5L: 0, 3L: 0, T: 8

Volume measured out in 4 turns

การประชุม

  1. Fill xL jug - เติมเหยือกที่เกี่ยวข้องไปด้านบนจากน้ำพุ
  2. Empty xL jug - เททิ้งเหยือกที่เกี่ยวข้องลงในน้ำพุ
  3. Pour from xL jug into yL jug - เทเนื้อหาของเหยือก xL ลงในเหยือก yL
  4. Pour from xL jug into tank - เทเนื้อหาของเหยือก xL ลงในถัง

รหัสที่สั้นที่สุดชนะ


ความซ้ำซ้อนของปัญหา Water-Bucket ที่
Howard

4
@Howard คำถามเก่าไม่ถูกต้อง (ไม่มีเกณฑ์การชนะ) และถูกทอดทิ้งดังนั้นฉันคิดว่าคำถามนี้ดีกว่าและไม่ควรปิด
Victor Stafusa

โทรหาฉันบ้า แต่ไม่ใช่ทางออกที่ดีที่สุดที่จะเป็น 1 เพิ่ม 5L ให้ได้มากที่สุด 2 เพิ่ม 3L ถ้าจำเป็น 3 เพิ่มส่วน 2L หรือ 1L ที่แก้ไขแล้วตามที่ต้องการหรือไม่

1
@LegoStormtroopr เมื่อทุกอย่างเดือดลงจริง แต่ฉันคาดหวังว่ามันจะเป็นรหัสกอล์ฟ
WallyWest

3
@ LegoStormtroopr ฉันคิดเช่นกัน แต่ไม่ใช่ 6 และ 9 ตัวอย่าง
Paul Prestidge

คำตอบ:


6

ทับทิม, 407 376 365 331 324 323

นี่เป็นการยากที่จะอ่าน ...

x=y=n=d=0
g=gets.to_i
"#{[43435,102,t=45,t,12,t,12,t,t][g+~d]||12}".chars{|c|n+=1
puts [eval(["x-=t=[3-y,x].min;y+=t"+t=";'Pour from 5L jug into 3L jug'","x=5;'Fill 5L jug'","d+=x;x=0"+t.sub(/3.+/,"tank'")][c.ord%3].tr t='35xy',c<?3?t:'53yx'),"5L: #{x}, 3L: #{y}, T: #{d}"]}while g>d
$><<"Volume measured out in #{n} turns"

ใช้อินพุตบน STDIN ตัวอย่างรันสำหรับ N = 10:

Fill 5L jug
5L: 5, 3L: 0, T: 0
Pour from 5L jug into tank
5L: 0, 3L: 0, T: 5
Fill 5L jug
5L: 5, 3L: 0, T: 5
Pour from 5L jug into tank
5L: 0, 3L: 0, T: 10
Volume measured out in 4 turns

2
"นี่มันยากที่จะอ่าน ... " - Dude ไม่ได้เป็นจุดของรหัสกอล์ฟ ... ? ;)
WallyWest

4
@WallyWest Nope เรามีแท็ก [ทำให้งงงวย] สำหรับแท็กเหล่านั้น! ความเห็นอันถ่อมตนของฉันน่าจะเป็นเพราะวิธีแก้ปัญหา codegolf สองตัวที่มีความยาวเท่ากันคนที่อ่านง่ายที่สุดจะดีที่สุด
นาย Lister

@MrLister ยุติธรรมพอ แต่บางครั้งการทำให้งงงวยเป็นวิธีเดียวที่จะบรรลุการหดตัวที่ต้องการ ...
WallyWest

5

T-SQL 2012: 1410 1302

ความพยายามอีกครั้งของคำถามใน SQL แต่สิ่งนี้นำเสนอโอกาสที่สนุกสนานในการเล่นกับตัวเลือกฟังก์ชั่นหน้าต่างใหม่ในเวอร์ชั่น 2012 นอกจากนี้ยังใช้ประโยชน์จาก CTE แบบเรียกซ้ำซึ่งอาจไม่น่าประทับใจในภาษาการเขียนโปรแกรมส่วนใหญ่ ใน SQL นั้นเหมือนกับการเปลี่ยนจากม้าและรถม้าเป็นเฟอร์รารี

เครื่องยนต์ที่เป็นหัวใจของสิ่งนี้อยู่ในบรรทัดที่ 5-12 ซึ่งใช้ CTE แบบเรียกซ้ำและฟังก์ชั่นหน้าต่างเพื่อสร้างตารางของตัวเลขส่วนใหญ่ที่จำเป็นในการแก้ปัญหา หมายเหตุโดยเฉพาะอย่างยิ่งการทดสอบสำหรับ 3, 4, 6 หรือ 9 ซึ่งช่วยให้มั่นใจว่าวิธีการที่เหมาะสมในการแก้ปัญหาโดย 3s จากตัวเลขเหล่านั้นเป็นต้นไป (ในทางเทคนิคแล้วมันจะผูกกัน 4 ตัวระหว่าง 3-1 ​​และ 2-2 แต่ทำอย่างนี้ทำให้ฉันมีตัวละครเยอะมาก) จากนั้นมันเป็นเรื่องง่ายที่จะเข้าร่วมกับตารางการค้นหาของขั้นตอนที่เหมาะสมที่สุดสำหรับคนละคน กลุ่มของปัญหาและใช้ฟังก์ชันหน้าต่างอื่นเพื่อกำหนดจำนวนขั้นตอนอย่างเหมาะสม

หากคุณไม่มี MS SQL โกหกให้เล่นกับมันบน SQLFiddle

DECLARE @i INT=42,@l VARCHAR(9)='L jug ',@k VARCHAR(99)='into tank
5L: 0, 3L: 0, T: ',@o VARCHAR(99)='
5L: 5, 3L: 0, T: ',@n CHAR(1)='
',@5 VARCHAR(99)=') Pour from 5',@3 VARCHAR(99)=') Pour from 3'
;WITH t AS (SELECT @i i,(@i-@i%5)%5 j
UNION ALL
SELECT i-5,(i-i%5)%5+5 FROM t WHERE i>=5 AND i NOT IN(6,9)
UNION ALL
SELECT i-3,3FROM t WHERE i in(3,4,6,9)
UNION ALL
SELECT i-i,i FROM t WHERE i<3 AND i>0)
SELECT t.i,t.j,v.s,ROW_NUMBER()OVER(PARTITION BY t.j ORDER BY t.i DESC)x,SUM(t.j)OVER(ORDER BY t.i DESC ROWS UNBOUNDED PRECEDING)y INTO #q FROM(VALUES(1,5),(2,3),(3,2),(5,2))v(i,s) JOIN t ON t.j = v.i
SELECT z.b FROM(SELECT ROW_NUMBER()OVER(ORDER BY q.i DESC,w.s)a,CAST(ROW_NUMBER()OVER(ORDER BY q.i DESC,w.s)AS VARCHAR)+w.v+CAST(y-CASE WHEN q.s!=w.s THEN q.j ELSE 0 END AS VARCHAR)b
FROM(VALUES(5,1,') Fill 5'+@l+@o),(5,2,@5+@l+@k),(3,1,') Fill 3'+@l+@n+'5L: 0, 3L: 3, T: '),(3,2,@3+@l+@k),(2,1,') Fill 5'+@l+@o),(2,2,@5+@l+' into 3'+@l+@n+'5L: 2, 3L: 3, T: '),(2,3,@5+@l+@k),(1,1,') Fill 3'+@l+@n+'5L: 0, 3L: 3, T: '),(1,2,@3+@l+'into 5'+@l+@n+'5L: 3, 3L: 0, T: '),(1,3,') Fill 3'+@l+@n+'5L: 3, 3L: 3, T: '),(1,4,@3+@l+'into 5'+@l+@n+'5L: 5, 3L: 1, T: '),(1,5,@3+@l+'into tank'+@o))w(i,s,v)JOIN #q q ON w.i=q.j
UNION
SELECT 99,'Volume measured out in '+CAST(COUNT(*)AS VARCHAR)+' turns'
FROM #q)z

ผลลัพธ์สำหรับอินพุต 42:

1) Fill 5L jug 
5L: 5, 3L: 0, T: 0
2) Pour from 5L jug into tank
5L: 0, 3L: 0, T: 5
3) Fill 5L jug 
5L: 5, 3L: 0, T: 5
4) Pour from 5L jug into tank
5L: 0, 3L: 0, T: 10 
5) Fill 5L jug 
5L: 5, 3L: 0, T: 10 
6) Pour from 5L jug into tank
5L: 0, 3L: 0, T: 15 
7) Fill 5L jug 
5L: 5, 3L: 0, T: 15 
8) Pour from 5L jug into tank
5L: 0, 3L: 0, T: 20 
9) Fill 5L jug 
5L: 5, 3L: 0, T: 20 
10) Pour from 5L jug into tank
5L: 0, 3L: 0, T: 25 
11) Fill 5L jug 
5L: 5, 3L: 0, T: 25 
12) Pour from 5L jug into tank
5L: 0, 3L: 0, T: 30 
13) Fill 5L jug 
5L: 5, 3L: 0, T: 30 
14) Pour from 5L jug into tank
5L: 0, 3L: 0, T: 35 
15) Fill 5L jug 
5L: 5, 3L: 0, T: 35 
16) Pour from 5L jug into tank
5L: 0, 3L: 0, T: 40 
17) Fill 5L jug 
5L: 5, 3L: 0, T: 40 
18) Pour from 5L jug  into 3L jug 
5L: 2, 3L: 3, T: 40 
19) Pour from 5L jug into tank
5L: 0, 3L: 0, T: 42 
Volume measured out in 9 turns 

แก้ไข:

ทำคะแนนปรับปรุงได้ดีโดย

  • กำจัด +5 ที่ไม่จำเป็นในแถวแรกของ CTE และประโยคที่จำเป็น
  • ในตารางค่า VALUES การบันทึกคำสั่ง DECLARE ราคาแพง
  • ความทรงจำในการแปลง CRLF แบบไบต์คู่ของ Windows เป็นรูปแบบ Unix ในครั้งนี้

+1 สำหรับความกล้าหาญเพื่อน ... น่าประทับใจมากและขอบคุณสำหรับลิงค์ซอฟท์แวร์ MS SQL!
WallyWest

1
ฮ่าฮ่าขอบคุณมาก! ฉันเชื่อจริง ๆ ว่าสิ่งนี้อาจชนะได้เมื่อฉันเริ่มและมีคิวรีแบบเรียกซ้ำ แต่ถึงแม้จะมีการตีกอล์ฟจำนวนมาก แต่ความฟุ้งซ่านของการเพิ่มข้อความที่จำเป็นทั้งหมดถึงวาระสุดท้ายของฉัน :)
Jonathan Van Matre

ถ้าฉันสามารถทำเงินรางวัล "สร้างสรรค์มากที่สุด" คุณจะได้รับ ...
WallyWest

+1 ที่ทำให้ฉัน LOL T-SQL เป็นคลับที่น่าแปลกใจที่พกพากระเป๋ากอล์ฟของคุณ
Comintern

5

Javascript: 481

ความพยายามครั้งแรกที่การเล่นกอล์ฟคำแนะนำชื่นชม

n=["3L jug","5L jug","tank"];l=[0,0,0];t=[3,5,0];h=0;c=console;function e(d){l[d]=t[d];c.log(++h+") Fill "+n[d]);k()}function m(d,g){s=l[d];f=l[g];b=s+f>t[g];l[g]=b?t[g]:f+s;l[d]=b?s-(t[g]-f):0;c.log(++h+") Pour from "+n[d]+" into "+n[g]);k()}function k(){c.log("5L: "+l[1]+", 3L: "+l[0]+", T: "+l[2])}a=prompt();for(t[2]=a;4<a;)e(1),m(1,2),a-=5;2<a&&(e(0),m(0,2),a-=3);1<a&&(e(1),m(1,0),m(1,2),a=0);0<a&&(e(0),m(0,1),e(0),m(0,1),m(0,2));c.log("Volume measured out in "+h+" turns")

มันยุ่งกับตัวเลขเพราะไม่ได้ตรวจสอบว่าจะดีกว่าที่จะเท 3 หรือ 5 ตัวอย่างเช่น: 9 ให้ 9 ผลัดแทนที่จะเป็น 6 ฉันอาจแก้ไขได้ในภายหลัง

วางไว้ในคอนโซล

จาก 553 ถึง 481 ต้องขอบคุณ @WallyWest


1
คุณสามารถลอง: n=["3L jug","5L jug","tank"];l=[0,0,0];t=[3,5,0];h=0;c=console;function e(d){l[d]=t[d];c.log(++h+") Fill "+n[d]);k()}function m(d,g){s=l[d];f=l[g];b=s+f>t[g];l[g]=b?t[g]:f+s;l[d]=b?s-(t[g]-f):0;c.log(++h+") Pour from "+n[d]+" into "+n[g]);k()}function k(){c.log("5L: "+l[1]+", 3L: "+l[0]+", T: "+l[2])}a=prompt();for(t[2]=a;4<a;)e(1),m(1,2),a-=5;2<a&&(e(0),m(0,2),a-=3);1<a&&(e(1),m(1,0),m(1,2),a=0);0<a&&(e(0),m(0,1),e(0),m(0,1),m(0,2));c.log("Volume measured out in "+h+" turns") สำหรับ 481 ตัวอักษร ...
WallyWest

@WallyWest ขอบคุณไม่คิดที่จะใช้ตัวดำเนินการเชิงตรรกะแทนifs
Sam

3

Java, 610

class X{int n,c=0,t=0;public void static main(String[]a){n=Integer.parseInt(a[0]);String s,b,f,k,m,u;b="5L";s="3L";k="tank";u="Fill %s jug\n5L: %d, 3L: %d, T: %d";m="\nPour from %s jug into %s\n5L: %d, 3L: %d, T: %d";f=u+m;for(;n>4;)z(f,2,5,b,5,0,t,b,k,0,0,t+=5);while(n!=0){if(n==1)z(f+f+m,5,1,s,0,3,t,s,b,3,0,t,s,3,3,t,s,b,5,1,t,s,k,5,0,t+1);if(n==3)z(f,2,3,s,0,3,t,s,k,0,0,t+3);z(f+m,3,2,b,5,0,t,b,s,2,3,t,b,k,0,3,t+=2);if(n==2)z("Empty 3L jug\n5L: 0, 3L: 0,T: %d",1,0,t)}z("Volume measured out in %d turns",0,0,c)}void z(String s,int o,int w,Object...a){c+=o;n-=w;System.out.println(String.format(s,a))}}

ฉันใช้วิธีแก้ปัญหาของSumedhและเล่นกอล์ฟ ฉันต้องการที่จะใส่มันลงในความคิดเห็น แต่ชื่อเสียงของฉันไม่เพียงพอ :( มันน้อยกว่า 40% ฉันคิดว่าอย่างน้อยก็ควรแบ่งปันให้กัน แต่ยังห่างไกลจากตอนแรกแม้ว่า ...

นี่คือ ungolfed:

    class X{
    int n,c=0,t=0;
    public void static main(String[] a){
        n=Integer.parseInt(a[0]);
        String s,b,f,k,m,u;
        b="5L";
        s="3L";
        k="tank";
        u="Fill %s jug\n5L: %d, 3L: %d, T: %d";
        m="\nPour from %s jug into %s\n5L: %d, 3L: %d, T: %d";
        f=u+m;
        for(;n>4;)z(f,2,5,b,5,0,t,b,k,0,0,t+=5);
        while(n!=0)
        {
            if(n==1)z(f+f+m,5,1,s,0,3,t,s,b,3,0,t,s,3,3,t,s,b,5,1,t,s,k,5,0,t+1);
            if(n==3)z(f,2,3,s,0,3,t,s,k,0,0,t+3); 
            z(f+m,3,2,b,5,0,t,b,s,2,3,t,b,k,0,3,t+=2);
            if(n==2)z("Empty 3L jug\n5L: 0, 3L: 0,T: %d",1,0,t);
        }
        z("Volume measured out in %d turns",0,0,c);
    }
    void z(String s,int o, int w,Object... a){
        c+=o;
        n-=w;
        System.out.println(String.format(s,a));
    }
}

หมายเหตุ:มันทำงานเฉพาะในการเรียกใช้ครั้งแรก เรียกใช้อีกครั้งและผลลัพธ์จะผิด (เนื่องจากตัวแปรทั่วโลก)

รุ่นต่อไปนี้ปลอดภัย แต่เราเสีย 2 ถ่านไปจาก 610 เป็น 612:

    class X{
    int n,c,t;
    public void static main(String[] a){
        n=Integer.parseInt(a[0]);
        String s,b,f,k,m,u;
        t=c=0;
        b="5L";
        s="3L";
        k="tank";
        u="Fill %s jug\n5L: %d, 3L: %d, T: %d";
        m="\nPour from %s jug into %s\n5L: %d, 3L: %d, T: %d";
        f=u+m;
        for(;n>4;)z(f,2,5,b,5,0,t,b,k,0,0,t+=5);
        while(n!=0)
        {
            if(n==1)z(f+f+m,5,1,s,0,3,t,s,b,3,0,t,s,3,3,t,s,b,5,1,t,s,k,5,0,t+1);
            if(n==3)z(f,2,3,s,0,3,t,s,k,0,0,t+3); 
            z(f+m,3,2,b,5,0,t,b,s,2,3,t,b,k,0,3,t+=2);
            if(n==2)z("Empty 3L jug\n5L: 0, 3L: 0,T: %d",1,0,t);
        }
        z("Volume measured out in %d turns",0,0,c);
    }
    void z(String s,int o, int w,Object... a){
        c+=o;
        n-=w;
        System.out.println(String.format(s,a));
    }
}

เอาต์พุตตัวอย่างสำหรับ N = 69:

Fill 5L jug
5L: 5, 3L: 0, T: 0
Pour from 5L jug into tank
5L: 0, 3L: 0, T: 5
Fill 5L jug
5L: 5, 3L: 0, T: 5
Pour from 5L jug into tank
5L: 0, 3L: 0, T: 10
Fill 5L jug
5L: 5, 3L: 0, T: 10
Pour from 5L jug into tank
5L: 0, 3L: 0, T: 15
Fill 5L jug
5L: 5, 3L: 0, T: 15
Pour from 5L jug into tank
5L: 0, 3L: 0, T: 20
Fill 5L jug
5L: 5, 3L: 0, T: 20
Pour from 5L jug into tank
5L: 0, 3L: 0, T: 25
Fill 5L jug
5L: 5, 3L: 0, T: 25
Pour from 5L jug into tank
5L: 0, 3L: 0, T: 30
Fill 5L jug
5L: 5, 3L: 0, T: 30
Pour from 5L jug into tank
5L: 0, 3L: 0, T: 35
Fill 5L jug
5L: 5, 3L: 0, T: 35
Pour from 5L jug into tank
5L: 0, 3L: 0, T: 40
Fill 5L jug
5L: 5, 3L: 0, T: 40
Pour from 5L jug into tank
5L: 0, 3L: 0, T: 45
Fill 5L jug
5L: 5, 3L: 0, T: 45
Pour from 5L jug into tank
5L: 0, 3L: 0, T: 50
Fill 5L jug
5L: 5, 3L: 0, T: 50
Pour from 5L jug into tank
5L: 0, 3L: 0, T: 55
Fill 5L jug
5L: 5, 3L: 0, T: 55
Pour from 5L jug into tank
5L: 0, 3L: 0, T: 60
Fill 5L jug
5L: 5, 3L: 0, T: 60
Pour from 5L jug into tank
5L: 0, 3L: 0, T: 65
Fill 5L jug
5L: 5, 3L: 0, T: 65
Pour from 5L jug into 3L
5L: 2, 3L: 3, T: 65
Pour from 5L jug into tank
5L: 0, 3L: 3, T: 67
Empty 3L jug
5L: 0, 3L: 0,T: 67
Fill 5L jug
5L: 5, 3L: 0, T: 67
Pour from 5L jug into 3L
5L: 2, 3L: 3, T: 67
Pour from 5L jug into tank
5L: 0, 3L: 3, T: 69
Volume measured out in 33 turns

2

Java: 984

นี่คือรหัส

class X{public static void main(String[] s){int n=Integer.parseInt(s[0]);int t=0;int c=0;while(n>4){n-=5;System.out.println("Fill 5L jug\n5L: 5, 3L: 0, T: "+t+"\nPour from 5L jug into tank\n5L: 0, 3L: 0, T: "+(t+5));t+=5;c+=2;}while(n!=0){switch(n){case 1:System.out.println("Fill 3L jug\n5L: 0, 3L: 3, T: "+t+"\nPour from 3L jug into 5L jug\n5L: 3, 3L: 0, T: "+t+"\nFill 3L jug\n5L: 3, 3L: 3, T: "+t+"\nPour from 3L jug into 5L jug\n5L: 5, 3L: 1, T: "+t+"\nPour from 3L jug into tank\n5L: 5, 3L: 0, T: "+(t+1));n=0;c+=5;break;case 3:System.out.println("Fill 3L jug\n5L: 0, 3L: 3, T: "+t+"\nPour from 3L jug into tank\n5L: 0, 3L: 0, T: "+(t+3));n=0;c+=2;break;default:System.out.println("Fill 5L jug\n5L: 5, 3L: 0, T: "+t+"\nPour from 5L jug into 3L jug\n5L: 2, 3L: 3, T: "+t+"\nPour from 5L jug into tank\n5L: 0, 3L: 0, T: "+(t+2));n-=2;c+=3;t+=2;if(n==2){System.out.println("Empty 3L jug\n5L: 0, 3L: 0,T: "+t);c++;}break;}}System.out.println("Volume measured out in "+c+" turns");}}

อินพุตมาจากบรรทัดคำสั่ง ตัวอย่างเช่น: java X 4


ฉันไม่สามารถแสดงความคิดเห็นได้ทุกที่ดังนั้นฉันจึงแสดงความคิดเห็นที่นี่ @Lego Stormtroopr มีทางออกที่ดีที่สุดสำรองที่เหลือ 4L คุณสามารถทำเช่นเดียวกับ 2L (3 ขั้นตอน) จากนั้นจึงว่างเหยือก 3L แล้วทำซ้ำสำหรับ 2L ที่เหลืออยู่ทำให้เสร็จสมบูรณ์ใน 7 ขั้นตอน ... ซึ่งเหมือนกันสำหรับโซลูชันของคุณโดยที่ 4L แบ่งออกเป็น: 3L เป็นถัง (2 ขั้นตอน) และวิธี 5 ขั้นตอนสำหรับ 1L ที่เหลืออยู่
Sumedh

@ Chron รหัสของคุณทำงานกับค่า N ได้หรือไม่โดยที่ N% 5 เป็น 1 หรือ 4 ฉันไม่เข้าใจทับทิมนั่นเป็นเหตุผลว่าทำไมฉันถึงทดสอบตัวเองไม่ได้ ...
Sumedh

ตัวอย่างเช่นควรดูที่นี่ที่ N = 11: ideone.com/3ZDuOSคุณสามารถกดแก้ไขที่ด้านบนซ้ายและเปลี่ยน STDIN เป็นค่าอื่น ๆ หากคุณต้องการตรวจสอบ
Paul Prestidge

ว้าวคุณมีทางออกที่ดีที่สุดมากกว่าของฉัน .... คุณตัดสินใจอย่างไรเมื่อหยุด 5L และใช้ 3L แทน? ฉันหมายความว่าถ้าอินพุทคือ 81 คุณจะได้รับสูงถึง 75L โดยใช้ 5L แล้วใช้ 3L ถ้า ip เป็น 89 จะใช้ 5L สูงสุด 80L และที่เหลือคือ 3L
Sumedh

บันทึกตัวอักษรบางตัว: main(String[]s)บันทึกตัวอักษรบาง:int n=Integer.parseInt(s[0]),t=0,c=0; , java.io.PrintStream q=System.out;, นอกจากนี้ก็อาจจะเป็นไปได้ที่จะเขียนเป็นครั้งแรกในฐานะที่เป็นหนึ่งหรือสองตัวละครสั้นwhile forนอกจากนี้คุณStrings จะซ้ำ ๆ คุณอาจจะพยายามเก็บชิ้นส่วนที่ซ้ำ ๆ Stringในตัวแปรหรือสร้างฟังก์ชั่นที่สร้างพวกเขาใช้เพียงหนึ่งรูปแบบสำเร็จรูป
Victor Stafusa

2

Python 2.7 - 437

ไม่ใช่รหัสที่สั้นที่สุด แต่ฉันคิดว่านี่เป็นวิธีที่ดีที่สุดในการแก้ปัญหานี้

ตามที่ฉันระบุไว้ในความคิดเห็นวิธีที่ดีที่สุดในการคำนวณนี้:

  1. รับชิ้นส่วน 5 ลิตรให้ได้มากที่สุด - divmod(amount,5). นี่จะให้หนึ่งใน 4,3,2,1 เป็นส่วนที่เหลือ
  2. ใช้ 3 (ถ้าเป็นไปได้) จากส่วนที่เหลือ
  3. ซึ่งเหลือ 1 หรือ 2 เป็นส่วนที่เหลือ ใช้วิธีแก้ปัญหาที่ดีที่สุดสำหรับสิ่งที่สามารถทราบล่วงหน้าเป็น:

    1. 1L, 5 ขั้นตอน: 3L -> 5L, 3L -> 5L, ทิ้ง 1L ใน 3L, 3L (โฮลดิ้ง 1L) -> ถัง
    2. 2L, 3 ขั้นตอน: 5L -> 3L, ทิ้ง 2L ใน 5L, 5L (ถือ 2L) -> ถัง

รหัส:

j,T="%dL jug","tank"
A="\n5L: %d, 3L: %d, T: %d"
F,P="Fill "+j+A,"Pour from "+j+" into %s"+A
f,r=divmod(input(),5)
o,t=f*5,[]
for i in range(f):o+=[F%(5,5,0,5*i),P%(5,T,0,0,5*i+5)]
if r>2:o+=[F%(3,0,3,t),P%(3,T,0,0,t+3)];r-=3;t+=3
if r==2:o+=[F%(5,5,0,t),P%(5,j%3,2,3,t),P%(5,T,0,3,t+2)]
if r==1:o+=[F%(3,0,3,t),P%(3,j%5,3,0,t),F%(3,3,3,t),P%(3,j%5,5,1,t),P%(3,T,5,0,t+1)]
print"\n".join(o),'\n',"Volume measured out in %d turns"%len(o)

และเอาต์พุตสำหรับ 4L ใน 7 ขั้นตอน:

Fill 3L jug
5L: 0, 3L: 3, T: 0
Pour from 3L jug into tank
5L: 0, 3L: 0, T: 3
Fill 3L jug
5L: 0, 3L: 3, T: 3
Pour from 3L jug into 5L jug
5L: 3, 3L: 0, T: 3
Fill 3L jug
5L: 3, 3L: 3, T: 3
Pour from 3L jug into 5L jug
5L: 5, 3L: 1, T: 3
Pour from 3L jug into tank
5L: 5, 3L: 0, T: 4
Volume measured out in 7 turns

คุณกำลังกำหนด int ถึง o จากนั้นลองเพิ่มรายการ ฉันคิดว่าคุณตั้งใจจะมอบหมาย o, t = [], f * 5 ในบรรทัดที่ 5
psion5mx

1
ลดคำสั่งสำหรับ range และ if และคุณสามารถลดลงได้ถึง 399 ในหนึ่งบรรทัด: j, T = "% dL jug", "tank"; A = "\ n5L:% d, 3L:% d, T :% d "; F, P =" เติม "+ j + A," เทจาก "+ j +" ลงใน% s "+ A; f, r = divmod (อินพุต (), 5); t, o = f * 5 []; o = [F% (5,5,0,5 * i), P% (5, T, 0,0,5 * i + 5)] * f + [F% (3,0, 3, t) P% (3, T, 0,0, T + 3)] * (R> 2) + [F% (5,5,0, t) P% (5, J% 3, 2,3, t) P% (5, T, 0,3, T + 2)] * (R == 2) + [F% (3,0,3, t) P% (3, J % 5,3,0, t) F% (3,3,3, t) P% (3, J% 5,5,1, t) P% (3, T, 5,0, เสื้อ +1)] * (r ใน [1,4]); พิมพ์ "\ n". เข้าร่วม (o), "\ n ปริมาณที่วัดได้ใน% d รอบ"% len (o)
psion5mx

1
การจัดการที่น่าประทับใจ ... @ psion5mx ฉันไม่คิดว่าการเขียนโปรแกรมแบบนี้เป็นไปได้ใน Python? ไม่มีช่วงการสอบถามซ้ำหรือหากมีคำสั่ง
WallyWest

พลังของรายการ การคูณรายการด้วยจำนวนเต็มแทนที่ 'loops' การคูณด้วยบูลีนแทนที่ 'ifs'
psion5mx

นอกจากนี้ - ฉันจัดการเพื่อให้มันลงในช่องว่างเดียว (นอกเครื่องหมายคำพูด) แต่สามารถกำจัดช่องว่างทั้งหมดด้วยราคาของอักขระโดยแทนที่ (r ใน [1,4]) ด้วย (r% 5in [1,4] ) ในกรณีนี้.
psion5mx

2

Smalltalk (Smalltalk / X), 568 560 516

อินพุตใน n:

    T:=j:=J:=c:=0.m:={'Pour from'.' into'.' 3L jug'.' 5L jug'.[j:=j+3.'Fill'].[J:=J+5.'Fill'].[t:=j.j:=0.''].[t:=J.J:=0.''].[r:=j min:5-J.j:=j-r.J:=J+r.''].[r:=J min:3-j.J:=J-r.j:=j+r.''].[T:=T+t.' into tank'].[c:=c+1.'\5L: %1 3L: %2 T: %3\'bindWith:J with:j with:T].['Volume measured out in %1 turns'bindWith:c]}.[n>=0]whileTrue:[s:=n.n:=0.(s caseOf:{0->[n:=-1.'<'].1->'42;02813;42;02813;062:;'.2->'53;03912;073:;'.3->'42;062:;'.4->[n:=1.'42;062:;']}otherwise:[n:=s-5.'53;073:;'])do:[:c|(m at:c-$/)value withCRs print]]

เด็กชายนี่เป็นโปรแกรมที่น่าสะพรึงกลัวที่สุดที่ฉันเคยเขียน ...

แก้ไข: Smalltalks อื่น ๆ อาจไม่อนุญาตให้ใช้ตัวแปรพื้นที่ทำงานแบบประกาศอัตโนมัติและคุณจะต้องเตรียมการประกาศล่วงหน้า นอกจากนี้ bindWith: อาจแตกต่างกัน (ขยายด้วย: '<p>')

เอาต์พุตตัวอย่างสำหรับ n = 17:

Fill 5L jug 
5L: 5, 3L: 0, T: 0
Pour from 5L jug into tank
5L: 0, 3L: 0, T: 5
Fill 5L jug 
5L: 5, 3L: 0, T: 5
Pour from 5L jug into tank
5L: 0, 3L: 0, T: 10
Fill 5L jug 
5L: 5, 3L: 0, T: 10
Pour from 5L jug into tank
5L: 0, 3L: 0, T: 15
Fill 5L jug 
5L: 5, 3L: 0, T: 15
Pour from 5L jug into 3L jug 
5L: 2, 3L: 3, T: 15
Pour from 5L jug into tank
5L: 0, 3L: 3, T: 17
Volume measured out in 9 turns

2

C, 567 609

#define r printf
#define l r("5L: %d, 3L: %d, T: %d\n", a, b, T);
#define j(x,y,z,w) r("%d) "#x" %dL jug\n", i++, y),z=w,l
#define e j(Empty,3,b,0)
#define f j(Fill,5,a,5)
#define g j(Fill,3,b,3)
#define o(x,y,z,w) r("%d) Pour from %dL jug into "x"\n", i++, y,z),w;l
#define t(x,y) T+=x,o("tank",y,0,x=0)
#define p(x) o("%dL jug",5,3,(a-=x,b+=x))
int N,T,i;q(x){int a=0,b=0;switch(x){case 5:f t(a,5) break;case 3:g t(b,3) break;case 1:case 2:case 4:f if(x-2){e p(2)f p(1)if(x-4){e p(3)}}t(a,5)}N-=x;}main(){T=0,i=1,scanf("%d",&N);while(N>5)q((N-6)&&(N-9)?5:3);q(N);r("Volume measured out in %d turns",i-1);}

รุ่นที่ไม่ถูกต้องก่อนหน้านี้:

#define r printf
#define l r("5L: %d, 3L: %d, T: %d\n", a, b, T);
#define j(x,y,z,w) r("%d) "#x" %dL jug\n", i++, y),z=w,l
#define e j(Empty,3,b,0)
#define f j(Fill,5,a,5)
#define g j(Fill,3,b,3)
#define o(x,y,z,w) r("%d) Pour from %dL jug into "x"\n", i++, y,z),w;l
#define t o("tank",5,0,a=0)
#define p(x) o("%dL jug",5,3,(a-=x,b+=x))
int N,T,i;q(x){int a=0,b=0;switch(x){case 5:f t break;case 3:g t break;case 1:case 2:case 4:f if(x-2){e p(2)f p(1)if(x-4){e p(3)}}t}N-=x;}main(){T=0,i=1,scanf("%d",&N);while(N>5)q(5);q(N);r("Volume measured out in %d turns",i-1);}

และนี่คือรหัส degolfed:

#define r printf
#define l r("5L: %d, 3L: %d, T: %d\n", a, b, T);
#define j(x,y,z,w) r("%d) "#x" %dL jug\n", i++, y),z=w,l
#define e j(Empty,3,b,0)
#define f j(Fill,5,a,5)
#define g j(Fill,3,b,3)
#define o(x,y,z,w) r("%d) Pour from %dL jug into "x"\n", i++, y,z),w;l
#define t o("tank",5,0,a=0)
#define p(x) o("%dL jug",5,3,(a-=x,b+=x))
int N,T,i;
q(x)
{
    int a=0,b=0;
    switch(x)
    {
        case 5:
            f
            t 
            break;
        case 3:
            g
            t
            break;
        case 1:
        case 2:
        case 4:
            f
            if(x-2)
            {
                e
                p(2)
                f
                p(1)
                if(x-4)
                {
                    e
                    p(3)
                }
            }
            t
    }
    N-=x;
}
main()
{
    T=0,i=1,scanf("%d",&N);
    while(N&gt;
    5)q(5);
    q(N);
    r("Volume measured out in %d turns",i-1);
}

สิ่งนี้ไม่ได้ให้ทางออกที่ดีที่สุดสำหรับ 9 (8 ตาควรเป็น 6 - เติมและล้าง 3L 3 ครั้ง)
Comintern

ยังไม่ทำงานเลยสำหรับการป้อน 1
Comintern

ใช้งานไม่ได้กับ 1 ใช่ไหม สงสาร ... แต่ความพยายามที่น่าชื่นชม ... :)
WallyWest

ใช่มีข้อบกพร่องบางอย่างและการแก้ปัญหาไม่ได้เป็นสิ่งที่ดีที่สุด แต่มันทำให้ 1 L ใน 8 ขั้นตอน ...
VX

เคล็ดลับกอล์ฟคู่ - คุณสามารถบันทึก 6 ไบต์โดยแทนที่ int N, T, i; กับ N, T, i, a, b; และ int a = 0, b = 0; ด้วย a = b = 0; คุณยังได้รับ 3 ไบต์ด้วยการเพิ่ม (ลงในคำจำกัดความ printf ของคุณฉันคิดว่ากำไรที่ยิ่งใหญ่ที่สุดคือการลดคำสั่ง switch ให้เป็น ternary ซ้อนกัน - กรณีและคำสั่ง break เพิ่มขึ้นจริงๆ
Comintern

2

C ( 480 465 ไบต์)

#define P printf(
#define O(x) P"%d) Pour from %dL jug into "x"\n"
#define S P"5L: %d, 3L: %d, T: %d\n",F,H,g);}
F,H,s,g,x;l(j){P"%d) Fill %dL jug\n",++s,j);St(j,o,m){O("%dL jug"),++s,j,(j^5)?5:3);Se(j,i){O("tank"),++s,j);Smain(){scanf("%d",&x);while(x>4){x-=5;l(F=5);g+=5;e(5,F=0);}while(x>2){x-=3;l(H=3);g+=3;e(3,H=0);}(x^2)?(x^1)?0:(l(H=3),t(3,H=0,F=3),l(H=3),t(3,H=1,F=5),g++,e(3,H=0)):(l(F=5),t(5,F=2,H=3),g+=2,e(5,F=0));P"Volume measured out in %d turns",s);}

รุ่นที่เหมาะสมที่สุด (เพิ่ม 10 ไบต์)

#define P printf(
#define O(x) P"%d) Pour from %dL jug into "x"\n"
#define S P"5L: %d, 3L: %d, T: %d\n",F,H,g);}
F,H,s,g,x;l(j){P"%d) Fill %dL jug\n",++s,j);St(j,o,m){O("%dL jug"),++s,j,(j^5)?5:3);Se(j,i){O("tank"),++s,j);Smain(){scanf("%d",&x);while(x>4&&x^6&&x^9){x-=5;l(F=5);g+=5;e(5,F=0);}while(x>2){x-=3;l(H=3);g+=3;e(3,H=0);}(x^2)?(x^1)?0:(l(H=3),t(3,H=0,F=3),l(H=3),t(3,H=1,F=5),g++,e(3,H=0)):(l(F=5),t(5,F=2,H=3),g+=2,e(5,F=0));P"Volume measured out in %d turns",s);}

มีโอกาสเล่นกอล์ฟมากกว่านี้ที่นี่ - ฟังก์ชั่นเอาท์พุทฆ่าฉัน สิ่งนี้จะให้ทางออกที่ดีที่สุด (จำนวนขั้นตอนน้อยที่สุด) คล้ายกับรหัสอื่น ๆ ที่นี่มันเติมและเทเหยือก 5L จนได้ต่ำกว่า 5 แล้วจึงสลับไปที่เหยือก 3L มันทดสอบ 2 กรณีพิเศษ (6 และ 9) และหากพบว่ามันเปลี่ยนเป็นเหยือก 3L คำแนะนำในการรับ 1L และ 2L นั้นเป็นรหัสฮาร์ด

รุ่นที่อ่านเพิ่มเติมได้:

#define P printf(
#define O(x) P"%d) Pour from %dL jug into "x"\n"
#define S P"5L: %d, 3L: %d, T: %d\n",F,H,g);}
F,H,s,g,x;
l(j)
{
    P"%d) Fill %dL jug\n",++s,j);S

t(j,o,m)
{
    O("%dL jug"),++s,j,(j^5)?5:3);S

e(j,i)
{
    O("tank"),++s,j);S

main()
{
    scanf("%d",&x);
    //while(x>4&&x^6&&x^9)     <--optimal version
    while(x>4)
    {
        x-=5;l(F=5);g+=5;e(5,F=0);
    }
    while(x>2)
    {
        x-=3;l(H=3);g+=3;e(3,H=0);
    }
    (x^2)?
        (x^1)?  
            0
             :
            (l(H=3),t(3,H=0,F=3),l(H=3),t(3,H=1,F=5),g++,e(3,H=0))
             :(l(F=5),t(5,F=2,H=3),g+=2,e(5,F=0));
    P"Volume measured out in %d turns",s);
}

การแก้ไข:

  • ลบ 10 ไบต์ที่ให้ประสิทธิภาพสูงสุดสำหรับเวอร์ชั่นที่ได้คะแนนตามการชี้แจงของ OP
  • โกน 5 ไบต์ด้วยการแปลงฟังก์ชั่นเป็นคำจำกัดความ

ทดสอบเอาต์พุตสำหรับ n = 11 (เวอร์ชันที่ดีที่สุด):

11
1) Fill 5L jug
5L: 5, 3L: 0, T: 0
2) Pour from 5L jug into tank
5L: 0, 3L: 0, T: 5
3) Fill 3L jug
5L: 0, 3L: 3, T: 5
4) Pour from 3L jug into tank
5L: 0, 3L: 0, T: 8
5) Fill 3L jug
5L: 0, 3L: 3, T: 8
6) Pour from 3L jug into tank
5L: 0, 3L: 0, T: 11
Volume measured out in 6 turns

ทำไมคุณไม่นับ 11 เป็นกรณีพิเศษ? คุณทำอะไรเพื่ออายุ 14 หนึ่งห้าสามสาม (8) กำลังจะตีห้าสองและทำอีกสี่ลิตร (ซึ่งไม่สามารถทำได้ในสี่ตา)
Bill Woodger

11 และ 14 ทั้งสองรวมถึงกรณีพิเศษ หลังจากคุณลบ 5L แรกพวกเขาจะเหลือ 6 และ 9 ตามลำดับและจะถูกจัดการโดยกรณีพิเศษ 9 เป็นจำนวนมากที่สุดที่สามารถทำได้ในขั้นตอนน้อยลงโดยใช้เพียง 3L เหยือก อินพุต 14 ให้โซลูชัน 8 ขั้นตอนเอาต์พุต 11 ขึ้นไป
Comintern

2

T-SQL (2012): 794 689 580

แรงบันดาลใจจากคำตอบ T-SQL ของ@ Jonathan-Van-Matreร่วมกับอัลกอริทึมของ@ Lego-Stormtroopr ฉันต้องการทำเช่นนี้เพราะฉันชอบเบียร์ 99 ขวดมาก

ฉันพยายามเก็บหน้าต่าง (OVERฟังก์ชั่น ) อย่างน้อยที่สุดในการตั้งค่าฟังก์ชั่นทางคณิตศาสตร์ / บูล

SQLFiddle เป็นที่นี่

WITH n AS(SELECT 11 n UNION ALL SELECT n-IIF(n>4,5,3)FROM n WHERE n>2)SELECT n, a,LEN(a)L,i=IDENTITY(INT,1,1),'L jug'j INTO #t FROM n JOIN(VALUES(3303),(33900),(5550),(55900),(2550),(259323),(25903),(1303),(139530),(1333),(139551),(13950))x(a)ON RIGHT(LEFT(12335,n),1)=LEFT(a,1)ORDER BY n DESC SELECT LTRIM(i)+') '+REPLACE(IIF(L=4,'Fill ','Pour ')+RIGHT(a/100,L-3),9,j+' into ')+IIF(L=5,'tank',j)  +'
5L: '+LTRIM((A%100)/10)+', 3L: '+LTRIM(A%10)+', T: '+LTRIM(SUM(IIF(L=5,LEFT(a,1),0))OVER(ORDER BY i))FROM #t UNION SELECT 'Volume measured out in ' +LTRIM(MAX(i))+' turns'FROM #t

การป้อนข้อมูล: 11

1) Fill 5L jug
5L: 5, 3L: 0, T: 0
2) Pour from 5L jug into tank
5L: 0, 3L: 0, T: 5
3) Fill 5L jug
5L: 5, 3L: 0, T: 5
4) Pour from 5L jug into tank
5L: 0, 3L: 0, T: 10
5) Fill 3L jug
5L: 0, 3L: 3, T: 10
6) Pour from 3L jug into
5L jug 5L: 0, 3L: 3, T: 10
7) Fill 3L jug
5L: 3, 3L: 3, T: 10
8) Pour from 3L jug into 5L jug
5L: 5, 3L: 1, T: 10
9) Pour from 3L jug into tank
5L: 5, 3L: 0, T: 11
Volume measured out in 9 turns

มนุษย์สามารถอ่านได้:

WITH n AS(
  SELECT 11 n
    UNION ALL
  SELECT n-IIF(n>4,5,3)
  FROM n
  WHERE n>2
)
SELECT n, a,LEN(a) L, i = IDENTITY(INT,1,1), 'L jug'j
INTO #t
FROM n
JOIN(VALUES
     (3303),(33900),
     (5550),(55900),
     (2550),(259323),(25903),
     (1303),(139530),(1333),(139551),(13950)
    )x(a)
ON RIGHT(LEFT(12335,n),1) = LEFT(a,1)
ORDER BY n DESC

 SELECT LTRIM(i)+') '
  + REPLACE(IIF(L=4,'Fill ','Pour ')
  + RIGHT(a/100,L-3),9,j+' into ')+IIF(L=5,'tank',j)
  +'
5L: ' + LTRIM((A%100)/10) + ', 3L: ' + LTRIM(A%10) + ', T: '
  + LTRIM(SUM(IIF(L=5,LEFT(a,1),0))OVER(ORDER BY i)) FROM #t
UNION ALL
 SELECT 'Volume measured out in ' +LTRIM(MAX(i))+' turns'FROM #t
 DROP TABLE #t

คุณมีตัวอย่างผลลัพธ์หรือไม่?
Bill Woodger

@BillWoodger เพิ่มการส่งออกสำหรับinput = 8
สบาย ๆ

ขอบคุณ 8 ค่อนข้างง่าย หนึ่งถึง 11 ให้รหัสดี :-) ฉัน upvoting ดังนั้นอย่ากลับมาและบอกฉันว่ามันไม่ทำงาน
Bill Woodger

@ การเรียกเก็บเงินขอบคุณ เปลี่ยนเป็นinput = 11
comfortabledrei

@comfortablydrei สิ่งที่น่าอัศจรรย์โดยใช้ T-SQL ... รับหน้าจากหนังสือของ Jonathon ...
WallyWest

1

Python 3 (417 ตัวอักษร)

P=print
D=divmod
N=['3L jug','5L jug','tank',0]
M=999
R=[0,0,0,M]
F=[3,5,M,M]
def o(a,b):k=a==3;P(['Pour from %s into %s','Empty %s','Fill %s'][k*2+(b==3)]%[(N[a],N[b]),(N[b])][k]);d=min(R[a],F[b]-R[b]);R[a]-=d;R[b]+=d;P('5L:',R[1],'3L:',R[0],'T:',R[2]);N[3]+=1
k,r=D(int(input()),5)
for i in'0'*k:o(3,1);o(1,2)
for x in['','c1c12','d46','c2','d434d46'][r]:o(*D(int(x,16),4))
P('Volume measured out in',N[3],'turns')

อธิบาย

โปรดทราบว่าเรามีวัตถุ 4 รายการ ได้แก่ เหยือก 3L เหยือก 5L ถังและ foutain การดำเนินการเดียวที่เราทำได้คือย้ายน้ำจากวัตถุหนึ่งaไปยังอีกวัตถุbหนึ่ง นี่คือฟังก์ชั่นอะไรo(a, b)ทำในรหัสของฉันมันจะย้ายน้ำและพิมพ์และนับต่อไป

เล่นกล

  • N=['3L jug','5L jug','tank',0]. IndexErrorนี่ฉันต้ององค์ประกอบสุดท้ายที่จะหลีกเลี่ยง นอกจากนี้ยังสามารถใช้เป็นตัวแปรการนับทั่วโลกได้โดยไม่ต้องใช้globalคำหลักที่กว้างขวาง ตัวอย่างเช่น,N[3] += 1

  • เนื่องจาก0 <= a < 4, 0 <= b < 4ในการทำงานของo(a, b)เราสามารถเข้ารหัส(a, b)เป็นฐานสิบหกหลักโดยใช้และถอดรหัสโดยใช้(a << 2) | b divmod(x, 4)ด้วยเคล็ดลับนี้ทั้ง 5 โซลูชั่น ( reminder=0, 1, 2, 3, 4) สามารถเข้ารหัสเป็นอาร์เรย์['','c1c12','d46','c2','d434d46']ซึ่งสั้นกว่าแบบเดิมเล็กน้อย:

    A=[ (), ((3,0),(0,1),(3,0),(0,1),(0,2)), ((3,1),(1,0),(1,2)), ((3,0),(0,2)), ((3,1),(1,0),(0,3),(1,0),(3,1),(1,0),(1,2)) ]

ตัวอย่างผลลัพธ์ (n = 17)

17
Fill 5L jug
5L: 5 3L: 0 T: 0
Pour from 5L jug into tank
5L: 0 3L: 0 T: 5
Fill 5L jug
5L: 5 3L: 0 T: 5
Pour from 5L jug into tank
5L: 0 3L: 0 T: 10
Fill 5L jug
5L: 5 3L: 0 T: 10
Pour from 5L jug into tank
5L: 0 3L: 0 T: 15
Fill 5L jug
5L: 5 3L: 0 T: 15
Pour from 5L jug into 3L jug
5L: 2 3L: 3 T: 15
Pour from 5L jug into tank
5L: 0 3L: 3 T: 17
Volume measured out in 9 turns

1

COBOL (IBM Enterprise COBOL) 192 บรรทัดความยาว 72 อักขระ

นี่คือข้อพิสูจน์แนวคิดสำหรับคำถามและจุดเริ่มต้นของคำถามสำหรับ Golf-COBOL :-)

คำถามถามหาเร็วที่สุด ดังนั้นใช้ขนาน แม้แต่คนเดียวก็สามารถเติมเหยือก 3L หนึ่งอันและเหยือก 5 ลิตรได้ในเวลาเดียวกัน

เพียงแค่หารอินพุทด้วยแปดก็เหลือส่วนที่เหลือ ทำบางอย่างรวดเร็ว 5L / 3L เติมจำนวนครั้งที่แปดพอดีพอดีแล้วจัดการกับหนึ่งถึงเจ็ดลิตรที่เหลืออยู่

สิ่งที่น่าสนใจที่สุดสำหรับสี่ลิตร การทำเช่นเดียวกับหนึ่งลิตรบวกสามลิตรทำให้มีน้ำน้อยลงมากเพียง 18 ลิตรต่อ 23 สำหรับความเป็นไปได้อื่น ๆ

รหัส (ทำงาน)

   ID DIVISION
   PROGRAM-ID
   DATA DIVISION
   WORKING-STORAGE SECTION
   1.
   88 g1 VALUE ' '.
   2  PIC X
   88 H VALUE 'F'.
   88 I VALUE 'E'.
   88 J VALUE 'T'.
   2 PIC X
   88 K VALUE 'F'.
   88 L VALUE 'E'.
   88 M VALUE 'T'.
   1 R
   2 A1 PIC 999
   2 B PIC 99
   2 C PIC 9
   1 E
   2 e2 PIC X(120) VALUE "  ) Fill both jugs"
   2 e3 PIC X(120)
   88 O VALUE "5L: 0, 3L: 0, T: 000".
   2 e4 PIC X(120) VALUE "  ) Empty both jugs"
   2 e5 PIC X(120)
   2 e1 occurs 32 depending on p pic x(240)
   2 e6 pic x(99)
   1 F PIC 999 VALUE 0
   1 P PIC 99 VALUE 0
   1 P1 PIC 99
   PROCEDURE DIVISION
   ACCEPT A1
   DIVIDE A1 BY 8 GIVING B REMAINDER C
   set o to true
   move e3 to e5
   move 5 to e3(5:1)
   move 3 to e3(12:1)
   PERFORM D1 B TIMES
   EVALUATE C
   WHEN 1
   MOVE ZERO TO R
   SET K TO TRUE
   PERFORM N
   SET M TO TRUE
   PERFORM N
   SET K TO TRUE
   PERFORM N
   SET M TO TRUE
   PERFORM N
   SET L TO TRUE
   PERFORM N
   WHEN 2
   MOVE ZERO TO R
   SET H TO TRUE
   PERFORM N
   SET J TO TRUE
   PERFORM N
   SET I TO TRUE
   PERFORM N
   WHEN 3
   MOVE ZERO TO R
   SET K TO TRUE
   PERFORM N
   SET L TO TRUE
   PERFORM N
   WHEN 4
   MOVE ZERO TO R
   SET K TO TRUE
   PERFORM N
   SET M TO TRUE
   PERFORM N
   SET K TO TRUE
   PERFORM N
   SET M TO TRUE
   PERFORM N
   SET L TO TRUE
   PERFORM N
   SET K TO TRUE
   PERFORM N
   SET L TO TRUE
   PERFORM N
   WHEN 5
   MOVE ZERO TO R
   SET H TO TRUE
   PERFORM N
   SET I TO TRUE
   PERFORM N
   WHEN 6
   MOVE ZERO TO R
   SET K TO TRUE
   PERFORM N
   SET L TO TRUE
   PERFORM N
   SET K TO TRUE
   PERFORM N
   SET L TO TRUE
   PERFORM N
   WHEN 7
   MOVE ZERO TO R
   SET H TO TRUE
   PERFORM N
   SET I TO TRUE
   PERFORM N
   SET H TO TRUE
   PERFORM N
   SET J TO TRUE
   PERFORM N
   SET I TO TRUE
   PERFORM N
   END-EVALUATE
   string "Volume measured out in " delimited size P " turns"
   delimited size into e6
   if  e6(24:1) = 0
   move e6(25:) to e6 (24:)
   end-if
   move p to p1
   perform d2 p times
   DISPLAY E(481:)
   GOBACK
   D1
   ADD 1 TO P
   MOVE P TO E(1:2)
   move e2 to e1(p)
   move e3 to e1(p)(121:)
   ADD 1 TO P
   MOVE P TO E(241:2)
   ADD 8 TO F
   MOVE F TO E(378:3)
   move e4 to e1(p)
   move e5 to e1(p)(121:)
   MOVE F TO E(138:3)
   N
   ADD 1 TO P
   SET O TO TRUE
   EVALUATE TRUE
   WHEN K

   MOVE 3 TO B
   string p delimited size ") Fill 3L jug" delimited by size
   into e1(p)
   WHEN M
   COMPUTE C = C + B
   IF  C > 5
   COMPUTE B = C - 5
   MOVE 5 TO C
   ELSE
   MOVE 0 TO B
   END-IF
   string  P delimited size ") Pour from 3L jug into 5L jug"
   delimited size into e1(p)
   WHEN L
   ADD B TO F
   MOVE 0 TO B
   string  P delimited size ") Empty 3L jug into tank"
   delimited size into e1(p)
   END-EVALUATE
   EVALUATE TRUE
   WHEN H
   MOVE 5 TO C
   string  P delimited size ") Fill 5L jug"
   delimited size into e1(p)
   WHEN J
   COMPUTE B = C + B
   IF  B > 3
   COMPUTE C = B - 3
   MOVE 3 TO B
   ELSE
   MOVE 0 TO C
   END-IF
   string  P delimited size ") Pour from 5L jug into 3L jug"
   delimited size into e1(p)
   WHEN I
   ADD C TO F
   MOVE 0 TO C
   string  P delimited size ") Empty 5L jug into tank"
   delimited size into e1(p)
   END-EVALUATE
   string  "5L: " delimited size
       C delimited size ", 3L: " delimited size B(2:)
   ", T: " delimited size F delimited size
   into e1(p)(121:)
   SET g1 TO TRUE
   d2
   perform d3 2 times
   if  e1(p1)(1:1) = 0
   move e1(p1)(2:) to e1(p1)(1:120)
   end-if
   subtract 1 from p1
   d3
   if  e1(p1)(138:1) = 0
   move e1(p1)(139:) to e1(p1)(138:)
   end-if

สิ่งนี้จะได้รับข้อความการวินิจฉัยที่สมบูรณ์สำหรับการเริ่มต้นรหัสในสถานที่ที่ไม่ถูกต้องและปัญหาการหยุดเต็มรูปแบบที่จำเป็น

ไม่มีการวินิจฉัยที่บ่งบอกถึงผลกระทบใด ๆ กับรหัสวัตถุ ดังนั้นแม้ว่ามันจะเป็น RC = 8 ที่ถูกจับฉันรู้ว่าวัตถุนั้นจะตกลงดังนั้นจึงเชื่อมโยงและวิ่ง

นี่คือผลลัพธ์สำหรับหนึ่งถึงแปดลิตร หลังจากนั้นผลลัพธ์ทั้งหมดสามารถใช้งานได้จริง 17 และ 100 รวมเป็นตัวอย่างของการขนาน

ยังมีอีกมากที่สามารถทำได้เพื่อบีบโปรแกรมลงในตัวอักษรผลลัพธ์ที่ถูกต้องคือสิ่งสำคัญก่อน การนับจำนวนตัวอักษรเมื่ออยู่บนเส้นที่มีความยาวคงที่เป็นอีกเรื่องหนึ่งโดยสิ้นเชิง

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

1) Fill 3L jug                 
5L: 0, 3L: 3, T: 0             
2) Pour from 3L jug into 5L jug
5L: 3, 3L: 0, T: 0             
3) Fill 3L jug                 
5L: 3, 3L: 3, T: 0             
4) Pour from 3L jug into 5L jug
5L: 5, 3L: 1, T: 0             
5) Empty 3L jug into tank      
5L: 5, 3L: 0, T: 1             
Volume measured out in 5 turns 

1) Fill 5L jug                 
5L: 5, 3L: 0, T: 0             
2) Pour from 5L jug into 3L jug
5L: 2, 3L: 3, T: 0             
3) Empty 5L jug into tank      
5L: 0, 3L: 3, T: 2             
Volume measured out in 3 turns

1) Fill 3L jug                 
5L: 0, 3L: 3, T: 0             
2) Empty 3L jug into tank      
5L: 0, 3L: 0, T: 3             
Volume measured out in 2 turns 

1) Fill 3L jug                 
5L: 0, 3L: 3, T: 0             
2) Pour from 3L jug into 5L jug
5L: 3, 3L: 0, T: 0             
3) Fill 3L jug                 
5L: 3, 3L: 3, T: 0             
4) Pour from 3L jug into 5L jug
5L: 5, 3L: 1, T: 0             
5) Empty 3L jug into tank      
5L: 5, 3L: 0, T: 1             
6) Fill 3L jug                 
5L: 5, 3L: 3, T: 1             
7) Empty 3L jug into tank      
5L: 5, 3L: 0, T: 4             
Volume measured out in 7 turns 

1) Fill 5L jug                
5L: 5, 3L: 0, T: 0            
2) Empty 5L jug into tank     
5L: 0, 3L: 0, T: 5            
Volume measured out in 2 turns

1) Fill 3L jug                 
5L: 0, 3L: 3, T: 0             
2) Empty 3L jug into tank      
5L: 0, 3L: 0, T: 3             
3) Fill 3L jug                 
5L: 0, 3L: 3, T: 3             
4) Empty 3L jug into tank      
5L: 0, 3L: 0, T: 6             
Volume measured out in 4 turns 

1) Fill 5L jug                  
5L: 5, 3L: 0, T: 0              
2) Empty 5L jug into tank       
5L: 0, 3L: 0, T: 5              
3) Fill 5L jug                  
5L: 5, 3L: 0, T: 5              
4) Pour from 5L jug into 3L jug 
5L: 2, 3L: 3, T: 5              
5) Empty 5L jug into tank       
5L: 0, 3L: 3, T: 7              
Volume measured out in 5 turns 



1) Fill both jugs               
5L: 5, 3L: 3, T: 0              
2) Empty both jugs              
5L: 0, 3L: 0, T: 8              
Volume measured out in 2 turns  

1) Fill both jugs               
5L: 5, 3L: 3, T: 0              
2) Empty both jugs              
5L: 0, 3L: 0, T: 8              
3) Fill both jugs               
5L: 5, 3L: 3, T: 8              
4) Empty both jugs              
5L: 0, 3L: 0, T: 16             
5) Fill 3L jug                  
5L: 0, 3L: 3, T: 16             
6) Pour from 3L jug into 5L jug 
5L: 3, 3L: 0, T: 16             
7) Fill 3L jug                  
5L: 3, 3L: 3, T: 16             
8) Pour from 3L jug into 5L jug 
5L: 5, 3L: 1, T: 16             
9) Empty 3L jug into tank       
5L: 5, 3L: 0, T: 17             
Volume measured out in 9 turns  



1) Fill both jugs  
5L: 5, 3L: 3, T: 0 
2) Empty both jugs 
5L: 0, 3L: 0, T: 8 
3) Fill both jugs  
5L: 5, 3L: 3, T: 8 
4) Empty both jugs 
5L: 0, 3L: 0, T: 16
5) Fill both jugs  
5L: 5, 3L: 3, T: 16
6) Empty both jugs 
5L: 0, 3L: 0, T: 24
7) Fill both jugs  
5L: 5, 3L: 3, T: 24
8) Empty both jugs 
5L: 0, 3L: 0, T: 32
9) Fill both jugs  
5L: 5, 3L: 3, T: 32
10) Empty both jugs
5L: 0, 3L: 0, T: 40
11) Fill both jugs 
5L: 5, 3L: 3, T: 40
12) Empty both jugs
5L: 0, 3L: 0, T: 48
13) Fill both jugs 
5L: 5, 3L: 3, T: 48
14) Empty both jugs
5L: 0, 3L: 0, T: 56
15) Fill both jugs 
5L: 5, 3L: 3, T: 56
16) Empty both jugs
5L: 0, 3L: 0, T: 64
17) Fill both jugs 
5L: 5, 3L: 3, T: 64
18) Empty both jugs
5L: 0, 3L: 0, T: 72
19) Fill both jugs               
5L: 5, 3L: 3, T: 72              
20) Empty both jugs              
5L: 0, 3L: 0, T: 80              
21) Fill both jugs               
5L: 5, 3L: 3, T: 80              
22) Empty both jugs              
5L: 0, 3L: 0, T: 88              
23) Fill both jugs               
5L: 5, 3L: 3, T: 88              
24) Empty both jugs              
5L: 0, 3L: 0, T: 96              
25) Fill 3L jug                  
5L: 0, 3L: 3, T: 96              
26) Pour from 3L jug into 5L jug 
5L: 3, 3L: 0, T: 96              
27) Fill 3L jug                  
5L: 3, 3L: 3, T: 96              
28) Pour from 3L jug into 5L jug 
5L: 5, 3L: 1, T: 96              
29) Empty 3L jug into tank       
5L: 5, 3L: 0, T: 97              
30) Fill 3L jug                  
5L: 5, 3L: 3, T: 97              
31) Empty 3L jug into tank       
5L: 5, 3L: 0, T: 100             
Volume measured out in 31 turns 

วิธีการที่น่าชื่นชม @BillWoodger; อย่างไรก็ตามฉันไม่ได้ตั้งค่าคำสั่ง "ใส่ทั้งเหยือก" ภายในคำแนะนำที่มีอยู่ ... งานที่ยอดเยี่ยมและอุปกรณ์ประกอบฉากสำหรับ a) โดยใช้ COBOL, b) ไปตามเส้นทางของวิธีที่เร็วที่สุด
WallyWest

1
@WallyWest ขอบคุณ หากฉันคิดว่าข้อมูลจำเพาะทางธุรกิจสามารถปรับปรุงได้ฉันจะทำเช่นนั้นเสมอ :-) ฉันไม่ต้องการ "ว่างในน้ำพุ" ดังนั้นทั้งสองใหม่และสองไม่ได้ใช้ - ความล้มเหลวสองครั้ง!
Bill Woodger
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.