Advertisement
Guest User

Untitled

a guest
Mar 8th, 2019
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 3.76 KB | None | 0 0
  1. #!/usr/bin/perl -w
  2. use strict;
  3. use warnings;
  4.  
  5. # Init
  6. my $K = 5;
  7. my @board;
  8. my @queen_placements;
  9.  
  10. =begin description
  11. Queens are randomly placed on the board. There's only one queen per row.
  12.  
  13. This array holds the overview of queens placements.
  14.  
  15. i.e.: Queen is placed in column 4 in row 2:
  16. $board[2] = 4;
  17. =cut
  18.  
  19.  
  20. # Generate board
  21. for (my $i = 0; $i < $K; $i++) {
  22.     for (my $j = 0; $j < $K; $j++) {
  23.         $board[$i][$j] = 0;
  24.     }
  25.     # generate random column
  26.     my $rand_val = int(rand($K));
  27.  
  28.     # place queen in randomized column
  29.     $board[$i][$rand_val] = 1;
  30.  
  31.     # update the overview
  32.     $queen_placements[$i] = $rand_val;
  33. }
  34.  
  35.  
  36.  
  37.  
  38. sub min_conflict
  39. {
  40.     my $max_steps = shift;
  41.  
  42.     while (is_solution())
  43.     {
  44.  
  45.         # run thorugh each rows
  46.         for (my $i = 0; $i < $K; $i++) {
  47.            
  48.             my $column_with_min_conflicts = 0;
  49.             my $conflicts = $K+1;
  50.  
  51.  
  52.             # run thorugh each columns
  53.             for (my $j = 0; $j < $K; $j++) {
  54.  
  55.                 # count conflicts for queen placements in each cell on given row
  56.                 my $counted_conflicts = (check_column($j, $i) + check_diagonal($i, $j));
  57.  
  58.                 # checks if current cell contains a queen
  59.                 if ($queen_placements[$i] == $j) {
  60.  
  61.                     # if queens current position is the best, then move on.
  62.                     if ($counted_conflicts == 0) {
  63.                         $column_with_min_conflicts = $j;
  64.                         $conflicts = $counted_conflicts;
  65.                         next;
  66.                     }
  67.                 }
  68.  
  69.                 # if checked column cell is better then the current best cell, update the cell information
  70.                 if ($counted_conflicts < $conflicts) {
  71.                     $column_with_min_conflicts = $j;
  72.                     $conflicts = $counted_conflicts;
  73.                 }
  74.  
  75.             }
  76.  
  77.  
  78.             # move the queen to new location
  79.             ## if queens current position is the best, then do nothing. TROR DENNE ØDELEGGER LITT NÅR DEN LÅSER SEG?!
  80.             if ( $queen_placements[$i] != $column_with_min_conflicts ) {
  81.                 move_queen($i, $column_with_min_conflicts);
  82.             }
  83.  
  84.         }
  85.  
  86.        
  87.     }
  88.  
  89.     0;
  90. }
  91.  
  92. sub move_queen
  93. {
  94.     my ($row, $column_with_min_conflicts) = @_;
  95.  
  96.     ### move queen away from old location
  97.     $board[$row][$queen_placements[$row]] = 0;
  98.  
  99.     ### place queen on new location
  100.     $board[$row][$column_with_min_conflicts] = 1;
  101.  
  102.     ### update queen placement overview
  103.     $queen_placements[$row] = $column_with_min_conflicts;
  104. }
  105.  
  106.  
  107.  
  108. sub is_solution
  109. {
  110.     my $count = 0;
  111.    
  112.     for (my $i = 0; $i < $K; $i++) {
  113.         $count += check_column($queen_placements[$i], $i) + check_diagonal($i, $queen_placements[$i]);
  114.     }
  115.  
  116.    
  117.    
  118.     return $count;
  119. }
  120.  
  121. # checks for conflicts diagonaly for given X and Y
  122. sub check_diagonal
  123. {
  124.     my ($x, $y) = @_;
  125.     my $counter = 0;
  126.  
  127.     for (my ($i, $j) = ($x+1, $y+1); $i < $K && $j < $K; $i++, $j++) {
  128.         if ($board[$i][$j]) {
  129.             $counter++;
  130.         }
  131.     }
  132.     for (my ($i, $j) = ($x-1, $y-1); $i >=0 && $j >= 0; $i--, $j--) {
  133.         if ($board[$i][$j]) {
  134.             $counter++;
  135.         }
  136.     }
  137.  
  138.     for (my ($i, $j) = ($x+1, $y-1); $i < $K && $j >= 0; $i++, $j--) {
  139.         if ($board[$i][$j]) {
  140.             $counter++;
  141.         }
  142.     }
  143.     for (my ($i, $j) = ($x-1, $y+1); $i >=0 && $j < $K; $i--, $j++) {
  144.         if ($board[$i][$j]) {
  145.             $counter++;
  146.         }
  147.     }
  148.  
  149.     return $counter;
  150. }
  151.  
  152.  
  153. sub check_column
  154. {
  155.     my ($y, $queen_x)   = @_;
  156.     my $counter         = 0;
  157.  
  158.     for (my $i = 0; $i < $K; $i++) { # row
  159.         if ($board[$i][$y] && $queen_x != $i) {
  160.             $counter++;
  161.         }
  162.     }
  163.  
  164.     return $counter;
  165. }
  166.  
  167.  
  168. sub print_solution
  169. {
  170.     for (my $i = 0; $i < $K; $i++) {
  171.         for (my $j = 0; $j < $K; $j++) {
  172.             if ($board[$i][$j]) {
  173.                 print " # ";
  174.             } else {
  175.                 print " O ";
  176.             }
  177.         }
  178.         print "\n";
  179.     }
  180.     print "\n";
  181. }
  182.  
  183.  
  184. ## Start program here =>
  185.  
  186. # print start position
  187. print "Given board:\n";
  188. for (my $i = 0; $i < $K; $i++) {
  189.     for (my $j = 0; $j < $K; $j++) {
  190.         if ($board[$i][$j]) {
  191.             print " # ";
  192.         } else {
  193.             print " O ";
  194.         }
  195.     }
  196.     print "\n";
  197. }
  198.  
  199. # run checks
  200. min_conflict();
  201.  
  202. # print solution
  203. print "\nSolution:\n";
  204. &print_solution;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement