You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							107 lines
						
					
					
						
							3.8 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							107 lines
						
					
					
						
							3.8 KiB
						
					
					
				
								/* A solver for the Japanese number-puzzle Shikaku
							 | 
						|
								 * http://en.wikipedia.org/wiki/Shikaku
							 | 
						|
								 *
							 | 
						|
								 * Sebastian Nowozin <nowozin@gmail.com>, 27th January 2009
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								param ndim := 10;
							 | 
						|
								set rows := 1..ndim;
							 | 
						|
								set rows1 := 1..(ndim+1);
							 | 
						|
								set cols := 1..ndim;
							 | 
						|
								set cols1 := 1..(ndim+1);
							 | 
						|
								param givens{rows, cols}, integer, >= 0, default 0;
							 | 
						|
								
							 | 
						|
								/* Set of vertices as (row,col) coordinates */
							 | 
						|
								set V := { (i,j) in { rows, cols }: givens[i,j] != 0 };
							 | 
						|
								
							 | 
						|
								/* Set of all feasible boxes of the right size: only this boxes are possible.
							 | 
						|
								 * The box contains (i,j) and ranges from (k,l) to (m,n)
							 | 
						|
								 */
							 | 
						|
								set B := { (i,j,k,l,m,n) in { V, rows, cols, rows1, cols1 }:
							 | 
						|
								    i >= k and i < m and j >= l and j < n and   /* Contains (i,j) */
							 | 
						|
								    ((m-k)*(n-l)) = givens[i,j] and /* Right size */
							 | 
						|
								    card({ (s,t) in V: s >= k and s < m and t >= l and t < n }) = 1
							 | 
						|
								        /* Contains only (i,j), no other number */
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								var x{B}, binary;
							 | 
						|
								
							 | 
						|
								/* Cover each square exactly once */
							 | 
						|
								s.t. cover_once{ (s,t) in { rows, cols } }:
							 | 
						|
								    sum{(i,j,k,l,m,n) in B: s >= k and s < m and t >= l and t < n}
							 | 
						|
								        x[i,j,k,l,m,n] = 1;
							 | 
						|
								
							 | 
						|
								minimize cost: 0;
							 | 
						|
								
							 | 
						|
								solve;
							 | 
						|
								
							 | 
						|
								/* Output solution graphically */
							 | 
						|
								printf "\nSolution:\n";
							 | 
						|
								for { row in rows1 } {
							 | 
						|
								    for { col in cols1 } {
							 | 
						|
								        printf{0..0: card({(i,j,k,l,m,n) in B:
							 | 
						|
								                col >= l and col <= n and (row = k or row = m) and
							 | 
						|
								                x[i,j,k,l,m,n] = 1}) > 0 and
							 | 
						|
								            card({(i,j,k,l,m,n) in B:
							 | 
						|
								                row >= k and row <= m and (col = l or col = n) and
							 | 
						|
								                x[i,j,k,l,m,n] = 1}) > 0} "+";
							 | 
						|
								        printf{0..0: card({(i,j,k,l,m,n) in B:
							 | 
						|
								                col >= l and col <= n and (row = k or row = m) and
							 | 
						|
								                x[i,j,k,l,m,n] = 1}) = 0 and
							 | 
						|
								            card({(i,j,k,l,m,n) in B:
							 | 
						|
								                row >= k and row <= m and (col = l or col = n) and
							 | 
						|
								                x[i,j,k,l,m,n] = 1}) > 0} "|";
							 | 
						|
								        printf{0..0: card({(i,j,k,l,m,n) in B:
							 | 
						|
								                row >= k and row <= m and (col = l or col = n) and
							 | 
						|
								                x[i,j,k,l,m,n] = 1}) = 0 and
							 | 
						|
								            card({(i,j,k,l,m,n) in B:
							 | 
						|
								                col >= l and col <= n and (row = k or row = m) and
							 | 
						|
								                x[i,j,k,l,m,n] = 1}) > 0} "-";
							 | 
						|
								        printf{0..0: card({(i,j,k,l,m,n) in B:
							 | 
						|
								                row >= k and row <= m and (col = l or col = n) and
							 | 
						|
								                x[i,j,k,l,m,n] = 1}) = 0 and
							 | 
						|
								            card({(i,j,k,l,m,n) in B:
							 | 
						|
								                col >= l and col <= n and (row = k or row = m) and
							 | 
						|
								                x[i,j,k,l,m,n] = 1}) = 0} " ";
							 | 
						|
								
							 | 
						|
								        printf{0..0: card({(i,j,k,l,m,n) in B:
							 | 
						|
								            col >= l and col < n and (row = k or row = m) and
							 | 
						|
								            x[i,j,k,l,m,n] = 1}) > 0} "---";
							 | 
						|
								        printf{0..0: card({(i,j,k,l,m,n) in B:
							 | 
						|
								            col >= l and col < n and (row = k or row = m) and
							 | 
						|
								            x[i,j,k,l,m,n] = 1}) = 0} "   ";
							 | 
						|
								    }
							 | 
						|
								    printf "\n";
							 | 
						|
								
							 | 
						|
								    for { (col,p) in { cols, 1 }: card({ s in rows: s = row }) = 1 } {
							 | 
						|
								        printf{0..0: card({(i,j,k,l,m,n) in B:
							 | 
						|
								            row >= k and row < m and (col = l or col = n) and
							 | 
						|
								            x[i,j,k,l,m,n] = 1}) > 0} "|";
							 | 
						|
								        printf{0..0: card({(i,j,k,l,m,n) in B:
							 | 
						|
								            row >= k and row < m and (col = l or col = n) and
							 | 
						|
								            x[i,j,k,l,m,n] = 1}) = 0} " ";
							 | 
						|
								        printf{0..0: card({ (i,j) in V: i = row and j = col}) > 0} " %2d", givens[row,col];
							 | 
						|
								        printf{0..0: card({ (i,j) in V: i = row and j = col}) = 0} "  .";
							 | 
						|
								    }
							 | 
						|
								    printf{0..0: card({ r in rows: r = row }) = 1} "|\n";
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								data;
							 | 
						|
								
							 | 
						|
								/* This Shikaku is from
							 | 
						|
								 * http://www.emn.fr/x-info/sdemasse/gccat/KShikaku.html#uid5449
							 | 
						|
								 */
							 | 
						|
								param givens : 1 2 3 4 5 6 7 8 9 10 :=
							 | 
						|
								           1   9 . . . 12 . . 5 . .
							 | 
						|
								           2   . . . . . . . . . .
							 | 
						|
								           3   . . . . . . . . . 6
							 | 
						|
								           4   8 . 6 . 8 . . . . .
							 | 
						|
								           5   . . . . . . . . . .
							 | 
						|
								           6   . . . . . . . . . .
							 | 
						|
								           7   . . . . . 6 . 8 . 12
							 | 
						|
								           8   4 . . . . . . . . .
							 | 
						|
								           9   . . . . . . . . . .
							 | 
						|
								          10   . . 3 . . 9 . . . 4
							 | 
						|
								           ;
							 | 
						|
								
							 | 
						|
								end;
							 |