Browse Source

Solution day 4 part 2

AbdoFizzy 6 tháng trước cách đây
mục cha
commit
a47d3cb679
2 tập tin đã thay đổi với 51 bổ sung52 xóa
  1. 46 51
      4/solve_2.ml
  2. 5 1
      README.md

+ 46 - 51
4/solve_2.ml

@@ -1,66 +1,61 @@
 open Stdio
 open Str
 
-let get_instructions_byregexp re line =
-  let rec aux pos list_positions =
-    try
-      let start_pos = search_forward re line pos in
-      aux (match_end ()) (list_positions@[start_pos])
-    with Not_found -> list_positions
-  in
-  aux 0 []
+let input_info = 
+  let rec one_string inp nb_rows nb_columns = 
+    let line = In_channel.input_line In_channel.stdin in
+    match line with
+    | None -> (inp, (nb_rows, nb_columns))
+    | Some x -> one_string (inp ^ x) (nb_rows + 1) (String.length x)
+  in one_string "" 0 0
 ;;
 
-let active_regions x =
-  let list_dos_positions = get_instructions_byregexp (regexp {|do()|}) x in
-  let list_donts_positions = get_instructions_byregexp (regexp {|don't()|}) x in
-  let rec aux do_flag l_do l_dont pos res = 
-    if do_flag then 
-      (match l_do with
-      | hd::tl -> if (hd >= pos) then (aux false tl l_dont hd (res@[hd])) else (aux true tl l_dont pos res)
-      | [] -> res)  
-    else 
-      (match l_dont with
-      | hd::tl -> if (hd >= pos) then (aux true l_do tl hd (res@[hd])) else (aux false l_do tl pos res)
-      | [] -> res)
-  in
-  aux false list_dos_positions list_donts_positions 0 [0]
+let input = fst input_info;;
+let nb_rows = (fst (snd input_info));;
+let nb_columns = (snd (snd input_info));;
+
+
+let get_valid_indexes pos = 
+  let filter i = 
+  ( let up        = (if ((pos - i*nb_columns) >= 0) then (pos - nb_columns) else -99) in
+    let down      = (if ((pos + i*nb_columns) < nb_columns*nb_rows) then (pos + nb_columns) else -99) in
+    let upright   = (let is_valid_upright = ((((pos - i*(nb_columns - 1)) mod nb_columns) - (pos mod nb_columns)) == i) in
+                      if is_valid_upright then (up + 1) else -99) in
+    let upleft    = (let is_valid_upleft = (((pos mod nb_columns) - ((pos - i*(nb_columns + 1)) mod nb_columns)) == i) in
+                      if is_valid_upleft then (up - 1) else -99) in
+    let downright = (let is_valid_downright = ((((pos + i*(nb_columns + 1)) mod nb_columns) - (pos mod nb_columns)) == i) in
+                      if is_valid_downright then (down + 1) else -99) in
+    let downleft  = (let is_valid_downleft = (((pos mod nb_columns) - ((pos + i*(nb_columns - 1)) mod nb_columns)) == i) in
+                      if is_valid_downleft then (down - 1) else -99) in
+    List.filter (fun x -> (snd x) >= 0) [('R',upright);('L',upleft);
+                                         ('\\',downright);('/',downleft)]) in
+  
+    filter 1
 ;;
 
-let rec is_active_mul mul_pos = function
-| a :: b :: tl -> (if (a<= mul_pos) then
-                     (if (mul_pos <= b) then true 
-                   else is_active_mul mul_pos tl)
-                  else false)
-| [a] -> mul_pos >= a
-| []  -> false
+let valid_configs = [
+    [('R','S');('L','M');('\\','S');('/','M')];
+    [('R','M');('L','M');('\\','S');('/','S')];
+    [('R','S');('L','S');('\\','M');('/','M')];
+    [('R','M');('L','S');('\\','M');('/','S')];
+  ]
+;;
 
+let count_xmas pos =
+  let is_xmas pos = 
+    (let list_indexes = List.map (fun x -> (fst x, input.[snd x])) (get_valid_indexes pos) in
+    if ((List.length list_indexes) == 4) then 
+      (List.exists (fun x -> (compare list_indexes x) == 0) valid_configs) else false) in
+  if (is_xmas pos) then 1 else 0    
+;;
 
-let parse_mult_instruction line=
-  let active_regions_list = active_regions line in
-  let r = regexp {|mul( *\([0-9][0-9]?[0-9]?\) *, *\([0-9][0-9]?[0-9]?\) *)|} in 
+let solve = 
   let rec aux pos accum=
     try
-      let mul_pos = search_forward r line pos in
-      if (is_active_mul mul_pos active_regions_list) then
-        (let x = float_of_string (matched_group 1 line) in
-         let y = float_of_string (matched_group 2 line) in
-         aux (match_end ()) (accum + int_of_float (x *. y)))
-      else
-         aux (match_end ()) accum
+      let pos_a = search_forward (regexp "A") input pos in
+      aux (pos_a + 1) (accum + count_xmas pos_a)
     with Not_found -> accum
   in
     aux 0 0
 ;;
-
-let solve =
-  let rec one_string input = 
-    let line = In_channel.input_line In_channel.stdin in
-    match line with
-    | None -> input
-    | Some x -> one_string (input ^ x)
-  in 
-  parse_mult_instruction (one_string "")
-;;
-
-let () =  printf "Total: %d\n" (solve)
+let () =  printf "Total : %d\n" solve

+ 5 - 1
README.md

@@ -45,7 +45,11 @@ replace `<part_number>` with 1 for Part 1 or 2 for Part 2
 | 1   | ✅     | ✅     |
 | 2   | ✅     | ✅     |
 | 3   | ✅     | ✅     |
-| 4   | ✅     | ⬜     |
+| 4   | ✅     | ✅     |
+| 5   | ⬜     | ⬜     |
+| 6   | ⬜     | ⬜     |
+| 7   | ⬜     | ⬜     |
+| 8   | ⬜     | ⬜     |
 | ... | ...    | ...    |
 | 25  | ⬜     | ⬜     |