PROC report (INT CONST a, TEXT CONST msg): put (a); put (msg) ENDPROC report; PROC position queens from (INT CONST this row): IF this row > n THEN report solution ELSE INT VAR i; FOR i UPTO n REP IF location i unchallenged THEN take location i; position queens from (this row + 1); free location i FI ENDREP FI. take location i: queen column [this row] := i. free location i:. location i unchallenged: INT VAR j :: 1; WHILE j < this row REP IF jth queen threatens i THEN LEAVE location i unchallenged WITH false FI; j INCR 1 ENDREP; true. jth queen threatens i: INT CONST that column :: queen column [j]; IF same column THEN true ELIF same diagonal to the right THEN true ELSE same diagonal to the left FI. same column: that column = i. same diagonal to the right: that column - i = this row - j. same diagonal to the left: that column - i = j - this row. report solution: page; display chessboard; line; INT CONST time :: exectime; total time INCR time; number of solutions INCR 1; report (number of solutions, " solutions in"); report (total time, " miliseconds."); line. ENDPROC position queens from; PROC display chessboard: INT VAR k; FOR k UPTO n REP display row; line ENDREP. display row: INT VAR l; FOR l UPTO n REP display position ENDREP. display position: TEXT CONST colour :: IF odd (k + l) THEN ""176"" ELSE ""219"" FI; IF l = queen column [k] THEN put (colour + "Q" + colour) ELSE put (3 * colour) FI. ENDPROC display chessboard; program: how many queens; start counting; position queens from (1); those were all solutions. how many queens: put ("n Queens problem"); INT VAR n; REP line; put ("How many queens (1<=n<10)? "); get (n) UNTIL n >= 1 AND n <= 10 ENDREP; ROW 10 INT VAR queen column. start counting: INT VAR total time :: 0, number of solutions :: 0. those were all solutions: line; put ("Those are all solutions.").