Puzzle dzbanek o pojemności 3 i 5 litrów

14

Być może widziałeś to w Die Hard: With a Vengeance ... To pytanie jest oparte na słynnej 3 i 5-litrowej dzbanku, ale z nieco innym kątem.

Zdobądź kod, który po podaniu liczby całkowitej od 1 do 100 dostarczy ci najszybszych instrukcji, jak odmierzyć do zbiornika odpowiednią liczbę litrów wody z fontanny, używając 3-litrowego dzbanka i 5-litrowego dzbanka.

Nie ma gradacji w żadnym z dzbanków; fontanna jest bogata w wodę i zakłada się, że zbiornik jest opróżniany na początku każdego wykonania kodu.

Nie można uzyskać dostępu do wody ze zbiornika, gdy trafi ona do zbiornika.

Format wykonania jest następujący:

Wejście:

4 na przykład.

Wynik

Wyjmij każdy numerowany krok, jak pokazano, a następnie sumę objętości dzbanka 5L, dzbanka 3L i zbiornika. Format Tally pokazano również poniżej. Liczba kroków musi być również wyprowadzona na końcu kroków.

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

Przykład 2

Wejście: 8

Wynik:

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

Konwencje

  1. Fill xL jug - napełnia powiązany dzbanek do góry z fontanny
  2. Empty xL jug - opróżnia zawartość powiązanego dzbanka do fontanny
  3. Pour from xL jug into yL jug - Wlewa zawartość dzbanka xL do dzbanka yL
  4. Pour from xL jug into tank - Wlewa zawartość dzbanka xL do zbiornika

Najkrótszy kod wygrywa.

WallyWest
źródło
możliwy duplikat problemu Wiadro
Howard
4
@Howard, stare pytanie jest źle określone (nie ma kryteriów wygranej) i zostało porzucone, więc myślę, że to jest lepsze i nie powinno być zamknięte.
Victor Stafusa
Nazywaj mnie szalonym, ale czy nie będzie to optymalne rozwiązanie 1. Dodaj tyle 5L, ile to możliwe, 2. Dodaj 3L, jeśli to konieczne, 3. Dodaj już rozwiązaną część 2L lub 1L, jeśli to konieczne?
1
@LegoStormtroopr Gdy wszystko sprowadza się, to prawda. Ale spodziewam się, że będzie odpowiednio golfowany.
WallyWest
3
@LegoStormtroopr Też tak myślałem, ale czy nie ma 6 i 9 kontrprzykładów?
Paul Prestidge

Odpowiedzi:

6

Rubin, 407 376 365 331 324 323

Trudno to odczytać ...

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"

Pobiera dane wejściowe na STDIN. Przykładowy przebieg dla 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
Paul Prestidge
źródło
2
„Trudno to odczytać ...” - Koleś, czy nie o to chodzi w golfie kodowym…? ;)
WallyWest
4
@WallyWest Nope. Dla tych osób mamy tag [zaciemnianie]! Moja skromna opinia byłaby taka, że ​​jeśli chodzi o dwa rozwiązania dla kundla o tej samej długości, najbardziej czytelne byłoby najlepsze.
Pan Lister
@MrLister Wystarczająco sprawiedliwe, ale czasami zaciemnianie jest jedynym sposobem na osiągnięcie pożądanego skurczu ...
WallyWest
5

T-SQL 2012: 1410 1302

Kolejna quiksotyczna próba pytania w SQL, ale ta oferowała przyjemną okazję do zabawy z niektórymi nowymi opcjami funkcji okna w wersji 2012. Ponadto wykorzystuje rekurencyjne CTE, które mogą nie być imponujące w większości języków programowania, ale rekurencja w SQL jest jak przejście z konia i buggy na Ferrari.

Silnik w centrum tego jest w liniach 5-12, który wykorzystuje rekurencyjną CTE i funkcję okna do zbudowania tabeli zawierającej większość liczb potrzebnych do rozwiązania problemu. Zwróć uwagę w szczególności na test 3, 4, 6 lub 9, który zapewnia optymalne podejście do rozwiązania o 3 sekundy od tych liczb. (Technicznie rzecz biorąc, jest remis dla 4 między podejściem 3-1 i 2-2, ale w ten sposób grałem w golfa dla wielu postaci.) Następnie łatwo jest dołączyć do tabeli przeglądowej optymalnych kroków dla różnych części problemu i użyj innej funkcji okna, aby poprawnie ponumerować kroki.

Jeśli nie masz MS SQL leżącego, baw się nim na 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

Wyniki dla danych wejściowych 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 

Edytować:

Grał w golfa przyzwoitą poprawę wyniku przez

  • eliminując niepotrzebne +5 w pierwszym rzędzie CTE, i wymagała tego klauzula WHERE
  • wstawianie do tabel VALUES, oszczędzając kosztownych instrukcji DECLARE
  • pamiętając, aby tym razem przekonwertować dwubajtowe listy CRLF Windows na styl Unix.
Jonathan Van Matre
źródło
+1 za odwagę, koleś ... Bardzo imponujące i dziękuję za link do MS SQL!
WallyWest,
1
Haha, dzięki stary! Naprawdę wierzyłem, że ten można wygrać, kiedy zacząłem i miałem rekursywne podstawowe zapytanie. Ale nawet przy rozległym golfie strunowym gadatliwość dodania całego niezbędnego tekstu skazała moje ostateczne rozwiązanie. :)
Jonathan Van Matre
Gdybym mógł zrobić „najbardziej kreatywną” nagrodę,
dostałbyś
+1 za zrobienie ze mnie LOL. T-SQL jest z pewnością dziwnym kijem do noszenia w torbie golfowej.
Komintern
5

JavaScript: 481

Doceniona pierwsza próba gry w golfa

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

Bałagan z niektórymi liczbami, ponieważ nie sprawdza, czy lepiej jest wlać 3 lub 5, przykład: 9 daje 9 obrotów zamiast 6, mogę to naprawić później

Wklej to w konsoli

Od 553 do 481 dzięki @WallyWest

Sam
źródło
1
Możesz spróbować: 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") dla 481 znaków ...
WallyWest
@WallyWest dzięki, nie pomyślałem o użyciu operatorów logicznych zamiast 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))}}

Wziąłem rozwiązanie Sumedh i golfa. Chciałem umieścić to w komentarzach, ale moja reputacja to za mało :(. To o 40% mniej, myślę, że przynajmniej należy się tym podzielić. Nadal jednak daleko od pierwszego ...

Oto nie golfista:

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

Uwaga: działa tylko przy pierwszym uruchomieniu. Uruchom go ponownie, a wynik będzie niepoprawny (ze względu na zmienną globalną).

Następująca wersja jest bezpieczna, ale tracimy 2 znaki, przechodząc z 610 do 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));
    }
}

Przykładowe dane wyjściowe dla 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
Narmer
źródło
2

Java: 984

Oto kod

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

Dane wejściowe pochodzą z wiersza poleceń. na przykład: java X 4

Sumedh
źródło
Nie mogę komentować nigdzie indziej, więc komentuję tutaj. @ Lego Stormtroopr, istnieje alternatywne optymalne rozwiązanie, w którym dla pozostałych 4L możesz zrobić to samo dla 2L (3 kroki), a następnie opróżnić dzbanek 3L, a następnie powtórzyć dla pozostałego 2L, dzięki czemu jest on ukończony w 7 krokach ... to samo dotyczy twojego rozwiązania, w którym 4L jest podzielone na: 3L do zbiornika (2 kroki) i 5-krokową metodę dla pozostałej 1L.
Sumedh
@ Chron, czy twój kod działa dla wartości N, gdzie N% 5 to 1 lub 4? Nie rozumiem rubinu, dlatego sam nie mogłem go przetestować ...
Sumedh
powinien na przykład spojrzeć tutaj na N = 11: ideone.com/3ZDuOS Możesz nacisnąć edycję w lewym górnym rogu i zmienić STDIN na inne wartości, jeśli chcesz to sprawdzić.
Paul Prestidge
Wow, masz bardziej optymalne rozwiązanie niż moje .... jak decydujesz, kiedy przestać 5L i zamiast tego użyć 3L? To znaczy, jeśli wejście wynosi 81, to dostajesz do 75L za pomocą 5L, a następnie używasz 3L. jeśli ip wynosi 89, to 5L jest używane do 80L, a pozostałe to 3L.
Sumedh
Zaoszczędzić kilka znaków: main(String[]s), int n=Integer.parseInt(s[0]),t=0,c=0;, java.io.PrintStream q=System.out;. Ponadto może być możliwe napisanie pierwszego whilejako jednego lub dwóch znaków krótszych for. Co więcej, twoje Stringsą powtarzalne, możesz próbować przechowywać powtarzalne części w zmiennych lub tworzyć funkcje, które budują je przy użyciu tylko jednego prefabrykatu String.
Victor Stafusa
2

Python 2.7 - 437

Nie jest to najkrótszy kod, ale myślę, że jest to najbardziej optymalny sposób rozwiązania tego problemu.

Jak stwierdziłem w komentarzach, najbardziej optymalny sposób na obliczenie tego:

  1. Weź jak najwięcej porcji 5L, jak to możliwe divmod(amount,5). Otrzymasz jedną z 4,3,2,1 jako pozostałą część.
  2. Weź 3 (jeśli to możliwe) z reszty.
  3. Który pozostawia 1 lub 2 jako resztę. Skorzystaj z optymalnego rozwiązania, które może być znane z góry jako:

    1. 1L, 5 kroków: 3L -> 5L, 3L -> 5L, pozostawiając 1L w 3L, 3L (trzymając 1L) -> zbiornik
    2. 2L, 3 kroki: 5L -> 3L, pozostawia 2L w 5L, 5L (trzymając 2L) -> zbiornik

Kod:

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)

I wyjście dla 4L w 7 krokach:

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

źródło
Przypisujesz int do o, a następnie próbujesz dodać listę. Myślę, że chciałeś przypisać o, t = [], f * 5 w linii 5.
psion5mx
1
Strać te dla instrukcji, zakresu i if, a możesz sprowadzić ją do 399 w jednym wierszu: j, T = "dzbanek% dL", "tank"; A = "\ n5L:% d, 3L:% d, T :% d "; F, P =" Fill "+ j + A," Wlać z "+ j +" do% s "+ A; f, r = divmod (input (), 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, t +1)] * (rw [1,4]); wydrukuj „\ n” .join (o), „\ nWolumen zmierzony w% d zwojach”% len (o)
psion5mx
1
Imponująca manipulacja ... @ psion5mx Nie sądziłem, że tego rodzaju programowanie jest możliwe w Pythonie? Brak zasięgu, rekurencja lub jeśli stwierdzenia?
WallyWest
Moc list. Pomnożenie listy przez liczbę całkowitą zastępuje „pętle”. Mnożenie przez wartość logiczną zastępuje „ifs”.
psion5mx
Ponadto - udało mi się sprowadzić go do pojedynczego pola (poza cudzysłowami), ale mogłem wyeliminować wszystkie pola kosztem postaci, zastępując (rw [1,4]) przez (r% 5in [1,4] ) w tym przypadku.
psion5mx
2

Smalltalk (Smalltalk / X), 568560 516

wejście in:

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

to zdecydowanie najbardziej zaciemniony program, jaki kiedykolwiek napisałem ...

Edycja: Niektóre inne Smalltalks mogą nie zezwalać na deklarowane automatycznie zmienne obszaru roboczego i będziesz musiał przygotować deklaracje. Również bindWith: może być inny (expandWith: '<p>').

przykładowe wyjście dla 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
blabla999
źródło
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);}

poprzednia nieprawidłowa wersja:

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

a oto kod odśluzowany:

#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);
}
VX
źródło
Nie daje to optymalnego rozwiązania dla 9 (8 tur, powinno być 6 - napełnij i opróżnij 3L 3 razy).
Komintern
Również nie działa w przypadku wejścia 1.
Comintern
Nie działa dla 1? Szkoda ... Ale godny podziwu wysiłek ... :)
WallyWest
tak, jest kilka błędów i rozwiązanie nie zawsze jest optymalne. ale daje 1 L w 8 krokach ...
VX
Kilka wskazówek golfowych - Możesz zaoszczędzić 6 bajtów, zastępując int N, T, i; z N, T, i, a, b; i int a = 0, b = 0; przy a = b = 0 ;. Dostajesz również 3 bajty, dodając (do definicji printf. Myślę, że największym zyskiem byłoby zmniejszenie instrukcji switch do zagnieżdżonej trójki - instrukcje case i break naprawdę się sumują.
Comintern
2

C ( 480 465 bajtów)

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

Wersja optymalna (dodaje 10 bajtów)

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

Prawdopodobnie można tu grać w golfa - zabijały mnie funkcje wyjściowe. To powinno dać optymalne rozwiązanie (najmniejszą liczbę kroków). Podobnie jak w innym kodzie tutaj, wypełnia i opróżnia dzbanki 5L, aż osiągnie poziom poniżej 5, a następnie przełączy się na dzbanki 3L. Testuje 2 specjalne przypadki (6 i 9) i jeśli je znajdzie, przełącza się na dzbanki 3L. Instrukcje uzyskania 1L i 2L są zakodowane na stałe.

Bardziej czytelna wersja:

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

Edycje:

  • Usunięto 10 bajtów, które dały optymalną wydajność dla wersji punktowanej na podstawie wyjaśnienia PO.
  • Ogol 5 bajtów, przekształcając funkcję w definicję.

Wyjście testowe dla n = 11 (wersja optymalna):

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
Komintern
źródło
Dlaczego nie liczysz 11 jako specjalnego przypadku? Co robisz dla 14 lat? Jedna pięć, trzy trójki (8) pokona dwie piątki i uzupełni pozostałe cztery litry (czego nie da się zrobić w czterech turach).
Bill Woodger
11 i 14 obejmują przypadki szczególne. Po odjęciu pierwszych 5 litrów pozostawiają odpowiednio 6 i 9, a są one obsługiwane przez specjalne przypadki. 9 jest największą liczbą, którą można wykonać w mniejszej liczbie kroków, używając tylko dzbanka o pojemności 3 litrów. Wejście 14 daje rozwiązanie 8 kroków, wyjście dla 11 jest powyżej.
Komintern
2

T-SQL (2012): 794 689 580

Zainspirowany odpowiedzią T-SQL @ Jonathan-Van-Matre w połączeniu z algorytmem @ Lego-Stormtroopr . Chciałem to zrobić, ponieważ podobało mi się 99 butelek piwa wyzwanie .

Próbowałem zachować okno (OVER do minimum funkcje ) zamiast funkcji matematycznych / boolowych.

SQLFiddle jest tutaj .

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

Wejście: 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

Czytelny dla człowieka:

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
comfortlydrei
źródło
Czy masz jakieś próbki wyjściowe?
Bill Woodger
@BillWoodger dodał wyjście dlainput = 8
komfortowodrei
Dzięki. 8 jest dość łatwe. Od 1 do 11 kod jest dobry :-) Jestem entuzjastycznie nastawiony, więc nie wracaj i nie mów mi, że to nie działa.
Bill Woodger
@Bill Thanks. Zmieniono nainput = 11
komfortowodrei
@comfortablydrei Niesamowite rzeczy przy użyciu T-SQL ... Biorąc stronę z książki Jonathona ...
WallyWest
1

Python 3 (417 znaków)

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

Wyjaśniono

Zauważ, że mamy 4 przedmioty, a mianowicie dzbanek o pojemności 3 litrów, dzbanek o pojemności 5 litrów, zbiornik i foutain. Jedyne operacje, jakie możemy wykonać, to przenosić wodę z obiektu ana obiekt b. To jest funkcjao(a, b) robi w moim kodzie, przesuwa wodę i drukuje ją i wciąż liczy.

Wydziwianie

  • N=['3L jug','5L jug','tank',0]. Tutaj potrzebuję ostatniego elementu, którego należy unikać IndexError. Można go również używać jako globalnej zmiennej zliczającej, bez globalsłowa kluczowego ekspansywnego . Na przykład,N[3] += 1

  • Ponieważ 0 <= a < 4, 0 <= b < 4w funkcji o(a, b)możemy kodować(a, b) cyfrę szesnastkową za pomocą (a << 2) | bi zdekodować ją za pomocą divmod(x, 4). Dzięki tej sztuczce wszystkie 5 rozwiązań ( reminder=0, 1, 2, 3, 4) można zakodować w tablicy ['','c1c12','d46','c2','d434d46'], która jest nieco krótsza niż w oryginalnej formie:

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

Wyjście próbki (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
Promień
źródło
1

COBOL (IBM Enterprise COBOL) 192 linie 72 znaków

To jest dowód koncepcji na pytanie i początek jednego dla Golf-COBOL :-)

Pytanie wymaga najszybszego. Tak więc, wdrażaj równoległość. Nawet jedna osoba może z łatwością napełnić jednocześnie jeden dzbanek o pojemności 3 litrów i jeden dzbanek o pojemności 5 litrów.

Po prostu podziel dane wejściowe przez osiem, pozostawiając resztę. Wykonaj kilka szybkich napełnień 5L / 3L dokładnie tyle razy, ile osiem pasuje dokładnie, a następnie upuść jeden z pozostałych siedmiu litrów.

Najciekawsze z pozostałych to cztery litry. Robiąc to jako jeden litr plus trzy litry, przepycha o wiele mniej wody, tylko 18 litrów w porównaniu do 23 dla innych możliwości.

Kod (działa)

   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

W ten sposób uzyskuje się całkowity spadek komunikatów diagnostycznych dla kodu rozpoczynającego się w niewłaściwym miejscu i brak wymaganych kropek.

Żadna z diagnoz nie wskazuje żadnego wpływu na kod obiektu. Więc pomimo tego, że jest to błąd RC = 8, wiem, że obiekt będzie OK, więc połączyłem go i uruchomiłem.

Oto moce od jednego do ośmiu litrów. Następnie wszystkie wyniki mogą być intuicyjne. 17 i 100 podano jako przykłady równoległości.

Nadal można wiele zrobić, aby wycisnąć program z postaci, poprawne wyjście było najważniejsze. Liczenie znaków na liniach o stałej długości to zupełnie inna sprawa.

Przykładowe dane wyjściowe:

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 
Bill Woodger
źródło
Godne podziwu podejście @BillWoodger; Nie ustawiłem jednak polecenia „napełnij oba dzbanki” w dostępnych instrukcjach ... wygrywająca praca i rekwizyty dla a) przy użyciu COBOL, b) wybrania najszybszej metody .
WallyWest
1
@WallyWest Thanks. Jeśli uważam, że specyfikę biznesową można ulepszyć, zawsze to robię :-). Nie potrzebowałem też „pustego w fontannie”, więc dwa nowe i dwa nieużywane - podwójna awaria!
Bill Woodger