diff --git a/bin/main.ml b/bin/main.ml index fd99edc..3b84ffc 100644 --- a/bin/main.ml +++ b/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 @@ -36,31 +36,31 @@ let next_pos size (x, y) cards = in 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 - debugf "find_solutions_impl:@ @[%a@ %d@ %d@ %d@ %a@ %a@]@;@?" +let rec find_solutions_impl cards size n idx current_alloc current_pos = + begin + (*debugf "find_solutions_impl:@ @[%a@ %d@ %d@ %d@ %a@ %a@]@;@?" (Format.pp_print_array Format.pp_print_int) cards size n idx (Format.pp_print_list pp_card) current_alloc - pp_pos current_pos; - - if current_pos = (0, size) then current_alloc - else if idx = 0 then [] - else if cards.(idx) = 0 then - find_solutions_impl cards size n (idx - 1) current_alloc current_pos - else if card_fits size idx current_alloc current_pos then begin - Array.set cards idx (cards.(idx) - 1); - let new_alloc = (current_pos, idx) :: current_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 - Array.set cards idx (cards.(idx) + 1); - if List.is_empty alloc then - find_solutions_impl cards size n (idx - 1) current_alloc current_pos - else alloc + pp_pos current_pos;*) + if current_pos = (0, size) then current_alloc + else if idx = 0 then [] + else if cards.(idx) = 0 then + find_solutions_impl cards size n (idx - 1) current_alloc current_pos + else if card_fits size idx current_alloc current_pos then begin + Array.set cards idx (cards.(idx) - 1); + let new_alloc = (current_pos, idx) :: current_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 + Array.set cards idx (cards.(idx) + 1); + if List.is_empty alloc then + find_solutions_impl cards size n (idx - 1) current_alloc current_pos + else alloc + end + else find_solutions_impl cards size n (idx - 1) current_alloc current_pos end - else find_solutions_impl cards size n (idx - 1) current_alloc current_pos -end let find_solutions cards size = find_solutions_impl cards size @@ -68,6 +68,59 @@ let find_solutions cards size = (Array.length cards - 1) [] (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 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 () = Format.printf "@[Base number: %d,@;side length: %d@;" n tri_n let () = Format.printf "Solution: %a@]@\n" (Format.pp_print_list pp_card) soln +let () = print_solution tri_n soln