MODULE Puzzle; IMPORT Disk, Baseboard, RealDisk, MasterDisk, Strings, IntStr, Out; CONST Disks = 3; GoodText = "E=mc2"; VAR b : Baseboard.P; d : ARRAY Disks OF RealDisk.P; m : MasterDisk.P; i : INTEGER; is : ARRAY 2 OF CHAR; fn : ARRAY 32 OF CHAR; next : Disk.P; sides : ARRAY Disks + 1 OF INTEGER; order : ARRAY Disks OF INTEGER; good : BOOLEAN; PROCEDURE Permute () : BOOLEAN; VAR temp, i, j : INTEGER; BEGIN i := Disks - 1; REPEAT DEC ( i ); UNTIL ( i < 0 ) OR ( order [ i ] < order [ i + 1 ] ); IF i < 0 THEN RETURN FALSE; END; (* IF *) j := Disks; REPEAT DEC ( j ); UNTIL order [ j ] > order [ i ]; temp := order [ j ]; order [ j ] := order [ i ]; order [ i ] := temp; FOR i := i + 1 TO Disks - 2 DO FOR j := i + 1 TO Disks - 1 DO IF order [ i ] > order [ j ] THEN temp := order [ j ]; order [ j ] := order [ i ]; order [ i ] := temp; END; (* IF *) END; (* FOR *) END; (* FOR *) RETURN TRUE; END Permute; PROCEDURE Flip () : BOOLEAN; VAR i : INTEGER; BEGIN i := Disks + 1; REPEAT DEC ( i ); sides [ i ] := 1 - sides [ i ]; UNTIL ( sides [ i ] = 1 ) OR ( i = 0 ); RETURN sides [ i ] = 1; END Flip; BEGIN FOR i := 0 TO Disks - 1 DO order [ i ] := i; sides [ i ] := 0; END; (* FOR *) sides [ Disks ] := 0; Strings.Assign ( " ", is ); NEW ( b ); Baseboard.Init ( b, NIL, "Baseboard" ); REPEAT REPEAT Out.String ( "Disks: " ); FOR i := 0 TO Disks - 1 DO Out.Char ( CHR ( order [ i ] + ORD ( 'A' ))); Out.Int ( sides [ i ] + 1, 0 ); Out.Char ( ' ' ); END; (* FOR *) Out.Char ( 'M' ); Out.Int ( sides [ Disks ] + 1, 0 ); Out.Ln; next := b; FOR i := 0 TO Disks - 1 DO Strings.Assign ( "Disk_", fn ); is [ 0 ] := CHR ( order [ i ] + ORD ( 'A' )); Strings.Append ( is , fn ); Strings.Append ( "_Side_", fn ); is [ 0 ] := CHR ( sides [ i ] + ORD ( '1' )); Strings.Append ( is, fn ); NEW ( d [ i ] ); RealDisk.Init ( d [ i ], next, fn ); next := d [ i ]; END; (* FOR *) Strings.Assign ( "Master_Disk_Side_", fn ); is [ 0 ] := CHR ( sides [ Disks ] + ORD ( '1' )); Strings.Append ( is, fn ); NEW ( m ); MasterDisk.Init ( m, next, fn ); REPEAT good := m.CheckText ( GoodText ) & m.CheckColors (); UNTIL good OR ~ m.Rotate (); UNTIL good OR ~ Flip (); UNTIL good OR ~ Permute (); IF good THEN m.WriteAllCellNum; END; (* IF *) END Puzzle.