Add a pretty printer for the solution.
This lets us validate the solution more easily, and gives us what we actually want which is a pretty picture of the layout.
This commit is contained in:
96
bin/main.ml
96
bin/main.ml
@@ -1,4 +1,4 @@
|
|||||||
let debugf = Format.ifprintf Format.std_formatter
|
(*let debugf = Format.ifprintf Format.std_formatter*)
|
||||||
|
|
||||||
let pp_card out ((x, y), n) = Format.fprintf out "((%d, %d), %d)" x y n
|
let pp_card out ((x, y), n) = Format.fprintf out "((%d, %d), %d)" x y n
|
||||||
|
|
||||||
@@ -36,31 +36,31 @@ let next_pos size (x, y) cards =
|
|||||||
in
|
in
|
||||||
impl (x + 1) y
|
impl (x + 1) y
|
||||||
|
|
||||||
let pp_pos out (x, y) = Format.fprintf out "(@[%d,@ %d@])" x y
|
(*let pp_pos out (x, y) = Format.fprintf out "(@[%d,@ %d@])" x y*)
|
||||||
|
|
||||||
let rec find_solutions_impl cards size n idx current_alloc current_pos = begin
|
let rec find_solutions_impl cards size n idx current_alloc current_pos =
|
||||||
debugf "find_solutions_impl:@ @[<hov>%a@ %d@ %d@ %d@ %a@ %a@]@;@?"
|
begin
|
||||||
|
(*debugf "find_solutions_impl:@ @[<hov>%a@ %d@ %d@ %d@ %a@ %a@]@;@?"
|
||||||
(Format.pp_print_array Format.pp_print_int) cards
|
(Format.pp_print_array Format.pp_print_int) cards
|
||||||
size n idx
|
size n idx
|
||||||
(Format.pp_print_list pp_card) current_alloc
|
(Format.pp_print_list pp_card) current_alloc
|
||||||
pp_pos current_pos;
|
pp_pos current_pos;*)
|
||||||
|
if current_pos = (0, size) then current_alloc
|
||||||
if current_pos = (0, size) then current_alloc
|
else if idx = 0 then []
|
||||||
else if idx = 0 then []
|
else if cards.(idx) = 0 then
|
||||||
else if cards.(idx) = 0 then
|
find_solutions_impl cards size n (idx - 1) current_alloc current_pos
|
||||||
find_solutions_impl cards size n (idx - 1) current_alloc current_pos
|
else if card_fits size idx current_alloc current_pos then begin
|
||||||
else if card_fits size idx current_alloc current_pos then begin
|
Array.set cards idx (cards.(idx) - 1);
|
||||||
Array.set cards idx (cards.(idx) - 1);
|
let new_alloc = (current_pos, idx) :: current_alloc in
|
||||||
let new_alloc = (current_pos, idx) :: current_alloc in
|
let new_pos = next_pos size current_pos new_alloc in
|
||||||
let new_pos = next_pos size current_pos new_alloc in
|
let alloc = find_solutions_impl cards size n n new_alloc new_pos in
|
||||||
let alloc = find_solutions_impl cards size n n new_alloc new_pos in
|
Array.set cards idx (cards.(idx) + 1);
|
||||||
Array.set cards idx (cards.(idx) + 1);
|
if List.is_empty alloc then
|
||||||
if List.is_empty alloc then
|
find_solutions_impl cards size n (idx - 1) current_alloc current_pos
|
||||||
find_solutions_impl cards size n (idx - 1) current_alloc current_pos
|
else alloc
|
||||||
else alloc
|
end
|
||||||
|
else find_solutions_impl cards size n (idx - 1) current_alloc current_pos
|
||||||
end
|
end
|
||||||
else find_solutions_impl cards size n (idx - 1) current_alloc current_pos
|
|
||||||
end
|
|
||||||
|
|
||||||
let find_solutions cards size =
|
let find_solutions cards size =
|
||||||
find_solutions_impl cards size
|
find_solutions_impl cards size
|
||||||
@@ -68,6 +68,59 @@ let find_solutions cards size =
|
|||||||
(Array.length cards - 1)
|
(Array.length cards - 1)
|
||||||
[] (0, 0)
|
[] (0, 0)
|
||||||
|
|
||||||
|
exception Overlapping_value
|
||||||
|
|
||||||
|
let print_solution size cards =
|
||||||
|
let array = Array.make (size * size) '.' in
|
||||||
|
let set_pos x y c =
|
||||||
|
if array.(x + (y * size)) <> '.' then raise Overlapping_value
|
||||||
|
else Array.set array (x + (y * size)) c
|
||||||
|
in
|
||||||
|
let rec write_size x y n =
|
||||||
|
if n = 0 then ()
|
||||||
|
else begin
|
||||||
|
Array.set array (x + (y * size)) (Char.chr (48 + (n mod 10)));
|
||||||
|
write_size (x - 1) y (n / 10)
|
||||||
|
end
|
||||||
|
in
|
||||||
|
let rec impl cards =
|
||||||
|
match cards with
|
||||||
|
| [] -> ()
|
||||||
|
| ((x, y), n) :: t -> begin
|
||||||
|
if n = 1 then set_pos x y '*'
|
||||||
|
else if n = 2 then begin
|
||||||
|
set_pos x y '+';
|
||||||
|
set_pos (x + 1) y '+';
|
||||||
|
set_pos x (y + 1) '+';
|
||||||
|
set_pos (x + 1) (y + 1) '+'
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
set_pos x y '+';
|
||||||
|
set_pos (x + n - 1) y '+';
|
||||||
|
set_pos x (y + n - 1) '+';
|
||||||
|
set_pos (x + n - 1) (y + n - 1) '+';
|
||||||
|
for a = 1 to n - 2 do
|
||||||
|
set_pos (x + a) y '-';
|
||||||
|
set_pos (x + a) (y + n - 1) '-';
|
||||||
|
for b = 1 to n - 2 do
|
||||||
|
set_pos (x + a) (y + b) ' '
|
||||||
|
done;
|
||||||
|
set_pos x (y + a) '|';
|
||||||
|
set_pos (x + n - 1) (y + a) '|'
|
||||||
|
done;
|
||||||
|
write_size (x + n - 2) (y + 1) n
|
||||||
|
end;
|
||||||
|
impl t
|
||||||
|
end
|
||||||
|
in
|
||||||
|
impl cards;
|
||||||
|
for y = 0 to size - 1 do
|
||||||
|
for x = 0 to size - 1 do
|
||||||
|
Format.printf "%c" array.(x + (y * size))
|
||||||
|
done;
|
||||||
|
Format.printf "\n"
|
||||||
|
done
|
||||||
|
|
||||||
let n = 8
|
let n = 8
|
||||||
let tri_n = (n + 1) * n / 2
|
let tri_n = (n + 1) * n / 2
|
||||||
|
|
||||||
@@ -79,3 +132,4 @@ let cards = Array.init (n + 1) Fun.id
|
|||||||
let soln = find_solutions cards tri_n
|
let soln = find_solutions cards tri_n
|
||||||
let () = Format.printf "@[<hov>Base number: %d,@;side length: %d@;" n tri_n
|
let () = Format.printf "@[<hov>Base number: %d,@;side length: %d@;" n tri_n
|
||||||
let () = Format.printf "Solution: %a@]@\n" (Format.pp_print_list pp_card) soln
|
let () = Format.printf "Solution: %a@]@\n" (Format.pp_print_list pp_card) soln
|
||||||
|
let () = print_solution tri_n soln
|
||||||
|
|||||||
Reference in New Issue
Block a user