3 und 5 Liter Krug Puzzle

14

Vielleicht haben Sie diese in Die Hard: With a Vengeance ... gesehen. Diese Frage basiert auf dem berühmten 3-Liter- und 5-Liter-Krug-Puzzle, aber mit einer etwas anderen Neigung.

Spielen Sie einen Code nach, der Ihnen bei einer Ganzzahl zwischen 1 und 100 die schnellste Anleitung bietet, um die entsprechende Anzahl von Litern Wasser aus einem Springbrunnen mit einem 3-Liter-Krug und einem 5-Liter-Krug in einen Tank zu füllen.

Auf keinem der Krüge sind Abstufungen; Der Brunnen ist reichlich mit Wasser versorgt, und es wird angenommen, dass der Tank zu Beginn jeder Ausführung des Codes geleert wird.

Sie können nicht auf das Wasser aus dem Tank zugreifen, wenn es erst einmal in den Tank gelangt ist.

Das Format der Ausführung ist wie folgt:

Eingang:

4 beispielsweise.

Ausgabe

Geben Sie jeden nummerierten Schritt wie gezeigt aus, gefolgt von einer Auflistung der Volumina der 5-Liter-Kanne, der 3-Liter-Kanne und des Tanks. Tally-Format auch unten gezeigt. Die Anzahl der Schritte muss auch am Ende der Schritte ausgegeben werden.

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

Beispiel 2

Eingang: 8

Ausgabe:

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

Konventionen

  1. Fill xL jug - Füllt den dazugehörigen Krug bis zum Rand vom Brunnen
  2. Empty xL jug - entleert den Inhalt der zugehörigen Kanne in den Brunnen
  3. Pour from xL jug into yL jug - Gießt den Inhalt der xL-Kanne in die yL-Kanne
  4. Pour from xL jug into tank - Gießt den Inhalt der xL-Kanne in den Tank

Kürzester Code gewinnt.

WallyWest
quelle
Mögliches Duplikat des Water-Bucket-Problems
Howard
4
@Howard, die alte Frage ist falsch spezifiziert (hat keine Gewinnkriterien) und wurde aufgegeben, daher denke ich, dass diese besser ist und nicht geschlossen werden sollte.
Victor Stafusa
Nennen Sie mich verrückt, aber es ist nicht die optimale Lösung: 1. Fügen Sie so viele 5 l wie möglich hinzu, 2. Fügen Sie bei Bedarf 3 l hinzu, 3. Fügen Sie je nach Bedarf eine bereits gelöste 2 l- oder 1 l-Portion hinzu?
1
@LegoStormtroopr Wenn alles gut läuft, stimmt das. Aber ich erwarte, dass es dementsprechend codegolfing ist.
WallyWest
3
@LegoStormtroopr Das dachte ich auch, aber sind das nicht 6 und 9 Gegenbeispiele?
Paul Prestidge

Antworten:

6

Rubin, 407 376 365 331 324 323

Dies wird immer schwieriger zu lesen ...

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"

Übernimmt die Eingabe für STDIN. Beispiellauf für 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
quelle
2
"Das wird immer schwieriger zu lesen ..." - Alter, ist das nicht der Sinn von Code-Golf ...? ;)
WallyWest
4
@WallyWest Nope. Wir haben einen [Verschleierungs] -Tag für diese! Meine bescheidene Meinung wäre, dass von zwei Codegolf-Lösungen der gleichen Länge die am besten lesbare die beste wäre.
Mr Lister
@ MrLister Fair genug, aber manchmal ist Verschleierung der einzige Weg, um die gewünschte Schrumpfung zu erreichen ...
WallyWest
5

T-SQL 2012: 1410 1302

Ein weiterer quixotischer Versuch, eine Frage in SQL zu beantworten, aber dieser bot eine erfreuliche Gelegenheit, mit einigen der neuen Fensterfunktionsoptionen in Version 2012 zu spielen. Außerdem werden rekursive CTEs ausgenutzt, die in den meisten Programmiersprachen nicht beeindruckend sind, sondern Rekursion in SQL ist wie der Wechsel von Pferd und Buggy zu einem Ferrari.

Die Engine, die das Herzstück bildet, befindet sich in den Zeilen 5-12, in denen mithilfe eines rekursiven CTE und einer Fensterfunktion eine Tabelle mit den meisten zur Lösung des Problems erforderlichen Zahlen erstellt wird. Beachten Sie insbesondere den Test für 3, 4, 6 oder 9, der ab diesen Zahlen eine optimale Annäherung an die Lösung um 3s sicherstellt. (Technisch gesehen ist es ein Unentschieden zwischen dem 3: 1-Ansatz und dem 2: 2-Ansatz, aber auf diese Weise habe ich viele Charaktere golfen.) Dann ist es ganz einfach, eine Nachschlagetabelle mit den optimalen Schritten für verschiedene zu erstellen Teile des Problems und verwende eine andere Fensterfunktion, um die Schritte richtig zu nummerieren.

Wenn Sie nicht über MS SQL verfügen, spielen Sie mit 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

Ergebnisse für die Eingabe 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 

Bearbeiten:

Golfte eine ordentliche Punktzahlverbesserung durch

  • Eliminieren einer unnötigen +5 in der ersten Zeile des CTE und der dazu erforderlichen WHERE-Klausel
  • Einbetten der VALUES-Tabellen, wodurch teure DECLARE-Anweisungen eingespart werden
  • Denken Sie daran, dieses Mal Windows-Doppelbyte-CRLFs in Unix-Format umzuwandeln.
Jonathan Van Matre
quelle
+1 für Mut, Alter ... Sehr beeindruckend und danke für den MS SQL Fiddle Link!
WallyWest
1
Haha, danke Mann! Ich habe tatsächlich geglaubt, dass dies ein Gewinn sein könnte, als ich anfing und die rekursive Kernabfrage hatte. Aber selbst bei ausgiebigem Saiten-Golfen war die Ausführlichkeit des Hinzufügens des gesamten erforderlichen Textes meine endgültige Lösung zum Scheitern verurteilt. :)
Jonathan Van Matre
Wenn ich ein "kreativstes" Kopfgeld machen könnte, würden Sie es bekommen ...
WallyWest
+1 für mich LOL machen. T-SQL ist mit Sicherheit ein ungewöhnlicher Club, den Sie in Ihrer Code-Golftasche mitnehmen können.
Komintern
5

Javascript: 481

Erster Golfversuch, Beratung erwünscht

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

Es bringt einige Zahlen durcheinander, weil es nicht überprüft, ob es besser ist, 3 oder 5 zu gießen. Beispiel: 9 gibt 9 Runden statt 6, ich kann es später korrigieren

Füge es in die Konsole ein

Von 553 auf 481 dank @WallyWest

Sam
quelle
1
Sie könnten versuchen: 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") für 481 Zeichen ...
WallyWest
@WallyWest danke, habe nicht daran gedacht, logische Operatoren anstelle von ifs zu verwenden
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))}}

Ich nahm die Lösung von Sumedh und spielte Golf. Ich wollte es in die Kommentare aufnehmen, aber mein Ruf ist nicht genug :(. Es ist 40% weniger, ich denke, es sollte zumindest geteilt werden. Trotzdem noch weit davon entfernt, zuerst ...

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

NB: Es funktioniert nur beim ersten Durchlauf. Führen Sie es erneut aus, und das Ergebnis ist falsch (aufgrund einer globalen Variablen).

Die folgende Version ist sicher, aber wir verlieren 2 Zeichen von 610 auf 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));
    }
}

Beispielausgabe für 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
quelle
2

Java: 984

Hier ist der Code

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

Die Eingabe erfolgt über die Befehlszeile. Zum Beispiel: Java X 4

Sumedh
quelle
Ich kann nirgendwo anders kommentieren, also kommentiere ich hier. @Lego Stormtroopr, es gibt eine alternative optimale Lösung, bei der Sie für 4 l die gleichen Schritte ausführen können wie für 2 l (3 Schritte), dann den 3 l-Krug leeren und dann für die verbleibenden 2 l wiederholen, wodurch der Vorgang in 7 Schritten abgeschlossen wird. Dies gilt auch für Ihre Lösung, bei der 4 l unterteilt sind in: 3 l in einen Tank (2 Schritte) und eine 5-Stufen-Methode für die verbleibenden 1 l.
Sumedh
@ Chron, funktioniert Ihr Code für Werte von N, wobei N% 5 1 oder 4 ist? Ich verstehe Rubin nicht, deshalb konnte ich es nicht selbst testen ...
Sumedh
Es sollte zum Beispiel hier bei N = 11 aussehen: ideone.com/3ZDuOS Sie können oben links auf Bearbeiten klicken und STDIN in andere Werte ändern, wenn Sie dies überprüfen möchten.
Paul Prestidge
Wow, Sie haben eine optimalere Lösung als meine ... Wie entscheiden Sie, wann Sie 5L abbrechen und stattdessen 3L verwenden? Ich meine, wenn der Eingang 81 ist, dann bekommst du bis zu 75L mit 5L und dann 3L. Wenn ip 89 ist, werden 5L bis zu 80L verwendet, und die verbleibenden 3L.
Sumedh
Speichern Sie einige Zeichen: main(String[]s), int n=Integer.parseInt(s[0]),t=0,c=0;, java.io.PrintStream q=System.out;. Es kann auch möglich sein, das erste whileZeichen ein oder zwei Zeichen kürzer zu schreiben for. Ferner Ihre Strings repetitiv sind, können Sie versuchen , sich wiederholende Teile in Variablen oder erstellen Funktionen zu speichern , dass sie nur ein Fertighaus bauen mit String.
Victor Stafusa
2

Python 2.7 - 437

Nicht der kürzeste Code, aber ich denke, dies ist der optimalste Weg, dies zu lösen.

Wie ich in den Kommentaren ausgeführt habe, ist dies der beste Weg, dies zu berechnen:

  1. Nehmen Sie so viele 5L-Stücke wie möglich - divmod(amount,5) . Dies gibt Ihnen einen von 4,3,2,1 als Rest.
  2. Nimm 3 (wenn möglich) vom Rest.
  3. Wobei entweder 1 oder 2 übrig bleiben. Verwenden Sie die optimale Lösung für beide, die im Voraus bekannt sein können als:

    1. 1L, 5 Schritte: 3L -> 5L, 3L -> 5L, 1L bleibt im 3L, 3L (1L halten) -> Tank
    2. 2 l, 3 Schritte: 5 l -> 3 l, 2 l verbleiben im 5 l, 5 l (2 l halten) -> Tank

Der Code:

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)

Und eine Ausgabe für 4L in 7 Schritten:

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

quelle
Sie weisen o ein int zu und versuchen dann, eine Liste hinzuzufügen. Ich denke, Sie
wollten
1
Verlieren Sie diese Anweisungen für, range und if, und Sie können sie in einer Zeile auf 399 setzen: j, T = "% dL jug", "tank"; A = "\ n5L:% d, 3L:% d, T :% d "; F, P =" Füllen "+ j + A," Gießen von "+ j +" in% s "+ A; f, r = divmod (Eingabe (), 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)] * (r in [1,4]); drucke "\ n" .join (o), "\ nVolumen gemessen in% d Umdrehungen"% len (o)
psion5mx
1
Beeindruckende Manipulation ... @ psion5mx Ich hätte nicht gedacht, dass diese Art der Programmierung auf Python möglich ist? Kein Bereich, Rekursion oder if-Anweisungen?
WallyWest
Die Macht der Listen. Das Multiplizieren einer Liste mit einer Ganzzahl ersetzt die 'Schleifen'. Das Multiplizieren mit einem Booleschen Wert ersetzt das Wenn.
psion5mx
Außerdem habe ich es geschafft, es auf ein einzelnes Leerzeichen (außerhalb von Anführungszeichen) zu beschränken, konnte jedoch alle Leerzeichen auf Kosten eines Zeichens entfernen, indem ich (r in [1,4]) durch (r% 5in [1,4] ersetzte. ) in diesem Fall.
psion5mx
2

Smalltalk (Smalltalk / X), 568 560 516

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

Junge, das ist definitiv das verschleierteste Programm, das ich je geschrieben habe ...

Bearbeiten: Einige andere Smalltalks erlauben möglicherweise keine automatisch deklarierten Arbeitsbereichsvariablen und Sie müssen Deklarationen voranstellen. Auch bindWith: kann unterschiedlich sein (expandWith: '<p>').

Beispielausgabe für 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
quelle
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);}

vorherige ungültige Version:

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

und hier ist der Code entgolfet:

#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
quelle
Dies ergibt nicht die optimale Lösung für 9 (8 Umdrehungen sollten 6 sein - 3-mal 3L füllen und leeren).
Komintern
Funktioniert auch überhaupt nicht für eine Eingabe von 1.
Komintern
Funktioniert nicht für 1? Schade ... Aber bewundernswerte Anstrengung ... :)
WallyWest
Ja, es gibt einige Fehler und die Lösung ist nicht immer optimal. aber es macht 1 L in 8 Schritten ...
VX
Paar Golftipps - Sie können 6 Bytes sparen, indem Sie int N, T, i ersetzen. mit N, T, i, a, b; und int a = 0, b = 0; mit a = b = 0 ;. Sie erhalten auch 3 Bytes durch die Zugabe von (zu Ihrer printf Definition Ich denke , der größte Gewinn zu einem verschachtelten ternären die switch - Anweisung würde reduziert , obwohl -. Der Fall ist und break - Anweisungen wirklich oben hinzufügen.
Komintern
2

C ( 480 465 Bytes)

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

Optimale Version (fügt 10 Bytes hinzu)

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

Wahrscheinlich wird hier mehr Golf gespielt - die Ausgabefunktionen haben mich umgebracht. Dies sollte die optimale Lösung ergeben (geringste Anzahl von Schritten). Ähnlich wie bei anderen Codes werden hier 5-Liter-Krüge gefüllt und geleert, bis sie unter 5 fallen, und dann auf 3-Liter-Krüge umgeschaltet. Es prüft auf 2 Sonderfälle (6 und 9) und schaltet auf 3-Liter-Kannen um, wenn es diese findet. Die Anweisungen zum Erhalten von 1L und 2L sind fest codiert.

Mehr lesbare Version:

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

Bearbeitungen:

  • 10 Bytes entfernt, die aufgrund der Klarstellung des OP die optimale Leistung für die bewertete Version ergaben.
  • Rasieren Sie 5 Bytes, indem Sie die Funktion in die Definition konvertieren.

Testausgabe für n = 11 (optimale Version):

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
quelle
Warum zählen Sie nicht 11 als Sonderfall? Was machst du für 14? Ein Fünf-Dreier-Dreier (8) schlägt zwei Fünfer und macht die anderen vier Liter aus (was nicht in vier Runden möglich ist).
Bill Woodger
11 und 14 enthalten beide Sonderfälle. Nachdem Sie die ersten 5 L abgezogen haben, bleiben 6 bzw. 9 übrig, und diese werden von den Sonderfällen behandelt. 9 ist die größte Zahl, die mit nur einem 3-Liter-Krug in weniger Schritten ausgeführt werden kann . Eingabe von 14 ergibt die 8-Stufen-Lösung, Ausgabe von 11 ist oben.
Komintern
2

T-SQL (2012): 794 689 580

Inspiriert von @ Jonathan-Van-Matres T-SQL-Antwort in Kombination mit @ Lego-Stormtrooprs Algorithmus. Ich wollte das machen, weil ich die 99 Flaschen Bier genossen habe Herausforderung so gut gefallen hat.

Ich habe versucht, Fenster zu halten (OVER ) - Funktionen auf ein Minimum zu beschränken, anstatt die mathematischen / bool-Funktionen zu verwenden.

SQLFiddle ist da .

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

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

Für Menschen lesbar:

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
bequemdrei
quelle
Haben Sie eine Beispielausgabe?
Bill Woodger
@ BillWoodger zusätzliche Ausgabe fürinput = 8
comfortablydrei
Vielen Dank. 8 ist ganz einfach. Eins bis 11 gibt dem Code eine gute Ausdehnung :-) Ich stimme zu, also komm nicht zurück und sag mir, dass es nicht funktioniert.
Bill Woodger
@ Rechnung Danke. Geändert zuinput = 11
comfortablydrei
@comfortablydrei Tolles Zeug mit T-SQL ... Eine Seite aus Jonathons Buch ...
WallyWest
1

Python 3 (417 Zeichen)

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

Erklärt

Beachten Sie, dass wir 4 Objekte haben, nämlich den 3-Liter-Krug, den 5-Liter-Krug, den Tank und den Springbrunnen. Wir können nur Wasser von Objekt azu Objekt bewegen b. Das ist welche Funktiono(a, b) in meinem Code tun, es Wasser bewegen und drucken und weiterzählen.

Tricks

  • N=['3L jug','5L jug','tank',0]. Hier muss ich das letzte Element vermeiden IndexError. Sie kann auch als globale Zählvariable ohne das globalSchlüsselwort expansive verwendet werden . Beispielsweise,N[3] += 1

  • Da 0 <= a < 4, 0 <= b < 4in Funktion o(a, b), können wir mit (a, b)in eine hexadezimale Ziffer kodieren(a << 2) | b und mit dekodieren divmod(x, 4). Mit diesem Trick können alle 5 Lösungen ( reminder=0, 1, 2, 3, 4) in ein Array codiert werden ['','c1c12','d46','c2','d434d46'], das etwas kürzer als die ursprüngliche Form ist:

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

Beispielausgabe (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
Strahl
quelle
1

COBOL (IBM Enterprise COBOL) 192 Zeilen mit 72 Zeichen

Dies ist ein Proof of Concept für die Frage und der Beginn eines für Golf-COBOL :-)

Die Frage fragt nach dem schnellsten. Implementieren Sie also Parallelität. Selbst eine Person kann problemlos einen 3-Liter- und einen 5-Liter-Krug gleichzeitig füllen.

Teilen Sie einfach die Eingabe durch acht und lassen Sie den Rest übrig. Führen Sie einige schnelle 5-Liter- / 3-Liter-Füllungen durch, bis acht genau passen, und kümmern Sie sich dann um die verbleibenden sieben Liter.

Der interessanteste Rest ist für vier Liter. Wenn Sie einen Liter plus drei Liter einfüllen, wird viel weniger Wasser verbraucht, nur 18 Liter gegenüber 23 Litern für die anderen Möglichkeiten.

Der Code (funktioniert)

   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

Dies führt zu einer Unmenge von Diagnosemeldungen für Code, der an der falschen Stelle beginnt, und zu einem Mangel an erforderlichen Punkthaltestellen.

Keine der Diagnosen zeigt eine Auswirkung auf den Objektcode an. Also, obwohl es eine kaputte RC = 8 ist, weiß ich, dass das Objekt in Ordnung ist, also verknüpfe es und starte es.

Hier sind die Ausgänge für ein bis acht Liter. Danach können alle Ergebnisse eingesehen werden. 17 und 100 sind als Beispiele für die Parallelität enthalten.

Es gibt noch viel zu tun, um das Programm in Zeichen zu zerquetschen. Die richtige Ausgabe war das Wichtigste zuerst. Das Zählen der Zeichen in Zeilen mit fester Länge ist eine andere Sache.

Beispielausgabe:

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
quelle
Bewundernswerter Ansatz, @ BillWoodger; Ich habe jedoch nicht den Befehl "beide Kannen füllen" innerhalb der verfügbaren Anweisungen gesetzt ... wunderbare Arbeit und Requisiten für a) die Verwendung von COBOL, b) die schnellste Methode .
WallyWest
1
@WallyWest Danke. Wenn ich denke, dass die Geschäftsspezifikation verbessert werden kann, mache ich das immer so :-). Ich brauchte auch nicht das "In den Brunnen leeren", also zwei neue und zwei nicht benutzte - doppeltes Versagen!
Bill Woodger