Advertisement
Guest User

Kody 3

a guest
Jan 15th, 2019
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 14.16 KB | None | 0 0
  1. open List;;
  2. open Find_Union;;
  3. open Fifo;;
  4.  
  5. let buduj_permutacje ll =
  6.     fold_left
  7.         (fun f l -> if l = [] then f else
  8.             fold_left
  9.                 (fun (f, prev) a ->
  10.                     (fun x ->
  11.                         if x = prev then a
  12.                         else f x
  13.                     ), a
  14.                 )
  15.             (f, hd (rev l)) l |> fst
  16.         )
  17.         (fun x -> x) ll
  18.  
  19. (***** 19.11.2018 *****)
  20.  
  21. (* zadanie słupki (tzw Rolki papieru) *)
  22.  
  23. let slupki l =
  24.     let l = List.sort compare l in
  25.     let m = List.nth l ((length l) / 2) in
  26.     fold_left (fun a x -> a + abs (m - x)) 0 l
  27.  
  28. (* to nie wiem jakie zadanie *)
  29.  
  30. let element lx ly =
  31.     let rec chodz i lx lyj a =
  32.         match lyj with
  33.         | [] -> a
  34.         | (y, j)::tyj ->
  35.             if i = y then
  36.                 chodz i lx ((j, hd lx)::a) tyj
  37.             else (
  38.                 assert (i < y);
  39.                 chodz (i + 1) (tl lx) a lyj )
  40.     in ly |> mapi (fun j y -> (y, j)) |> sort compare |> chodz 0 lx [] |> sort compare |> map snd
  41.  
  42. (* zadanie oi, czy istnieje trojka indeksow parami roznych i,j,k ze xi, xj, xk spelniaja nierownosc trojkata *)
  43. (* posortowac i sprawdzac kolejne trzy *)
  44.  
  45. (***** 26.11.2018 *****)
  46.  
  47. (* zadanie katastrofy lotnicze (??) *)
  48.  
  49. let katastrofy l =
  50.     let rec pom l i s a = (* lista, indeks y_i, schodki, rev lista k_i *)
  51.         match l with
  52.         | [] -> rev a
  53.         | xi::tl ->
  54.             let e = (i, xi) in
  55.             match s with
  56.             | [] -> pom tl (i + 1) (e::s) (i::a)
  57.             | (j, xj)::ts ->
  58.                 if xi < xj then
  59.                     pom tl (i + 1) (e::s) ((i - j)::a)
  60.                 else pom l i ts a
  61.     in pom l 1 [] []
  62.  
  63. (* 28.11.2018 *)
  64.  
  65. type 'a option = None | Some of 'a
  66. type 'a elem = {v : 'a; mutable next : 'a lista}
  67. and 'a lista = 'a elem option
  68.  
  69. let x = Some {v = 0; next = None}
  70.  
  71. (* petla : 'a lista -> unit *)
  72.  
  73. let petla l =
  74.     if l = None then ()
  75.     else
  76.         let get o =
  77.             match o with
  78.             | Some x -> x
  79.             | None -> assert false in
  80.         let cur = ref l in
  81.         let next = ref ((get l).next) in
  82.         while !next <> None do
  83.             let e = get !next in
  84.             let n = e.next in
  85.             e.next <- !cur;
  86.             cur := !next;
  87.             next := n
  88.         done;
  89.         (get l).next <- !cur
  90.  
  91. (* module counter, cos w nim nie dziala 100 linijka  *)
  92.  
  93. (*
  94. module type COUNTER =
  95. sig
  96.     type counter
  97.     val make : unit -> counter
  98.     val inc : counter -> int
  99.     val reset : unit -> unit
  100. end
  101. module Counter : COUNTER =
  102. struct
  103.     let time = ref 0 in
  104.     type counter = {mutable value : int; mutable update_time : int}
  105.     let make () = {value = 0; update_time = !time}
  106.     let reset () = incr time
  107.     let inc c =
  108.         if c.update_time <> !time then
  109.             (c.value <- 1; c.update_time <- !time)
  110.         else
  111.             c.value <- c.value + 1;
  112.         c.value
  113. end
  114. *)
  115.  
  116. (***** 3.12.2018 *****)
  117.  
  118. (* zadanie bitfony *)
  119. (* cykl : int array -> int *)
  120.  
  121. let cykl p =
  122.     let n = Array.length p in
  123.     let v = Array.make n false in
  124.     let rec obejdz i dl =
  125.         if v.(i) then dl else (v.(i) <- true; obejdz p.(i) (dl + 1)) in
  126.     let max_dl = ref 0 in (
  127.     for i = 0 to n - 1 do
  128.         max_dl := max (obejdz i 0) (!max_dl)
  129.     done;
  130.     !max_dl)
  131.  
  132. (* zadanie fastrygi (??) *)
  133. (* fastryguj : 'a drzewo -> unit *)
  134. (* chodzi chyba o to zeby zrobic przejscie in order *)
  135.  
  136. type 'a drzewo =
  137.     | Puste
  138.     | Wezel of 'a drzewo * 'a * 'a drzewo * 'a drzewo ref
  139.  
  140. let ignore x = let _ = x in ()
  141.  
  142. let fastryguj t =
  143.     let rec pom t next =
  144.         match t with
  145.         | Puste -> next
  146.         | Wezel (l, _, p, r) -> (
  147.             r := pom p next;
  148.             pom l t
  149.         )
  150.     in ignore (pom t Puste)
  151.  
  152. (* tu cos nie dziala *)
  153.  
  154.  
  155. let fastryguj t =
  156.     let next = ref Puste in
  157.     let rec invinfix t =
  158.         match t with
  159.         | Puste -> ()
  160.         | Wezel (l, _, p, r) -> (
  161.             invinfix p;
  162.             r := !next;
  163.             next := t;
  164.             invinfix l
  165.         )
  166.     in invinfix t
  167.  
  168.  
  169. (* Napisz funkcję fastryga 'a drzewo -> unit, która poustawia referencje w wierzchołkach tak,
  170.    aby wierzchołki o tej samej wartości tworzyły listę cykliczną. *)
  171.  
  172. type 'a drzewo =
  173.     | Puste
  174.     | Wezel of 'a drzewo * 'a * 'a drzewo * 'a drzewo ref
  175.  
  176. (*
  177. let fastryga t =
  178.     let poprz = ref Puste in
  179.     let rec infix t =
  180.         match t with
  181.         | Puste -> ()
  182.         | Wezel (l, x, p, r) ->
  183.             infix l;
  184.             (match !poprz with
  185.             | Puste -> r := t
  186.             | Wezel (_, y, _, s) ->
  187.                 if x = y then
  188.                     (r := !s; s := t)
  189.                 else
  190.                     r := t;)
  191.             poprz := t;
  192.             infix p;
  193.     in infix t
  194. *)
  195.  
  196. (***** 5.12.2018 *****)
  197.  
  198. (* zadanie skarbonki *)
  199.  
  200. (* n skarbonek z kluczykami o numerach 0, ..., n - 1                                *)
  201. (* a - tablica rozmiaru n                                                           *)
  202. (* a.(i) - numer skarbonki, w której znajduje się kluczyk do skarbonki i          *)
  203. (* Oblicz minimalną liczbę skarbonek, które trzeba rozbić, aby otrzymać wszystkie  *)
  204. (* jakies proste find & union, liczba spojnych składowych                          *)
  205.  
  206. let skarbonki a =
  207.     let n = Array.length a in
  208.     let s = Array.init n (fun i -> make_set i) in
  209.     for i = 0 to n - 1 do
  210.         union s.(i) s.(a.(i))
  211.     done;
  212.     n_of_sets ()
  213.  
  214. (* zadanie wieże *)
  215.  
  216. (* chyba (int * int) list zmieniamy na (int * int) * ((int * int) set) *)
  217. (* jakieś kolejne na find & union *)
  218. (* wieże różnych kolorów nie mogą się ze sobą szachować *)
  219.  
  220. let kolory l =
  221.     let p = map (fun w -> (w, make_set w)) l in
  222.     let lacz sel =
  223.         let p = List.sort (fun a b -> compare (a |> fst |> sel) (b |> fst |> sel)) p in
  224.         let rec pom p =
  225.             match p with
  226.             | (wa, sa)::(wb, sb)::_ ->
  227.                 if sel wa = sel wb then
  228.                     union sa sb;
  229.                     pom (tl p)
  230.             | _ -> () in
  231.         pom p in
  232.     lacz fst;
  233.     lacz snd;
  234.     n_of_sets ()
  235.  
  236. (***** 10.12.2018 *****)
  237.  
  238. (* jakieś zadanie na imperatywne                                                       *)
  239. (* jest jakiś kod i zobaczyć co on robi                                               *)
  240. (* zwraca pierwszą większą liczbę fibonnaciego od [n], która jest na parzystym miejscu     *)
  241.  
  242. let coto n =
  243.     let x = ref 0 in
  244.     let y = ref 1 in
  245.     while !y <= n do
  246.         x := !x - !y;
  247.         y := !y - !x
  248.     done;
  249.     !y
  250.  
  251. (* zadanie na grafy, jest plansza m x n ze skrzyżowaniami na przecięciach     *)
  252. (* nie można skręcać w lewo                                              *)
  253.  
  254. let kpk ulice =
  255.     let north = 0 and east = 1 and south = 2 and west = 3 in
  256.     let m = Array.length ulice in
  257.     let n = Array.length ulice.(0) in
  258.     let kier = [|(0, 1); (1, 0); (0, -1); (-1, 0)|] in
  259.     let (++) (x, y) (a, b) = (x + a, y + b) in
  260.     let visited = Array.init m
  261.         (fun _ -> Array.init n (fun _ -> Array.make 4 (-1))) in
  262.     let fifo = ref empty in
  263.     fifo := insert !fifo (0, 0, 0);
  264.     visited.(0).(0).(0) <- 0;
  265.     while not (is_empty !fifo) do
  266.         let (i, j, k) = front !fifo in
  267.         fifo := remove !fifo;
  268.         for d = 0 to 1 do
  269.             let k' = (k + d) mod 4 in
  270.             let (i', j') = (i, j) ++ kier.(k') in
  271.             if visited.(i').(j').(k') < 0 then (
  272.                 visited.(i').(j').(k') <- visited.(i).(j).(k) + 1;
  273.                 fifo := insert !fifo (i', j', k'))
  274.         done
  275.     done;
  276.     visited.(m - 1).(n - 1).(east)
  277.  
  278. (***** 12.12.2018 *****)
  279.  
  280. (*
  281.     A - amortyzowane
  282.     B - referencje, tablice, proste imperatywne
  283.     C - struktury wskaźnikowe
  284.     D - fastrygi na drzewie
  285.     E - find-union
  286.     F - logika
  287. *)
  288.  
  289. (* zadanie rejs, ktos chce poplynac na [k] dni                      *)
  290. (* jakis kolega ma wolny czas w przedziale a_i, b_i                 *)
  291. (* kiedy wyruszyć w rejs żeby mogli żeglować jak największą grupą    *)
  292.  
  293.  
  294. (*
  295. type zdarzenie =
  296.     | Pocz
  297.     | Kon
  298.  
  299. let rejs k l =
  300.     let lz = (* lista zdarzeń *)
  301.         map (fun (a, b) -> [(a, Pocz); (b, Kon)]) l |> flatten |> sort compare in (* flatten [[x, y, z];[a, b, c]] = [x, y, z, a, b, c] *)
  302.     let sprawdz r = (* czy >= r kolegów da się zabrać *)
  303.         let rec pom lz ilu ost_t = (* ost_t od ost_t mamy r kolegów - int option *)
  304.             match lz with
  305.             | [] -> false
  306.             |
  307.  
  308.  
  309. (* binsercz *)
  310.  
  311. let l = ref 0
  312. and p = ref (length l) in
  313. while !l < !p do
  314.     let m = (!l + !p) / 2 in
  315.     if sprawdz m then l := m
  316.     else p := m - 1
  317. done;
  318. !l
  319. *)
  320.  
  321.  
  322. (* zadanie jakies z teorii gier na f&u) *)
  323. (* hex : int -> (int * int) list -> (int * bool), kiedy i kto wygrał *)
  324.  
  325.  
  326. (***** 17.12.2018 *****)
  327.  
  328. (*  8. Dany jest acykliczny graf skierowany (DAG). Jego wierzchołki są ponumerowane od 0 do n,           *)
  329. (*  a krawędzie są dane w postaci tablicy sąsiedztwa (kwadratowej tablicy e wartości logicznych;        *)
  330. (*  w grafie mamy krawędź u→v wtw., gdy e.(u).(v) ). Powiemy, że wierzchołek u dominuje wierzchołek v,    *)
  331. (*  jeżeli dla każdego wierzchołka w, z którego można dojść do v, z u można dojść do w.                  *)
  332. (*                                                                                                      *)
  333. (*  Napisz procedurę zdominowani : bool array array -> int, która na podstawie tablicy opisującej graf    *)
  334. (*  obliczy liczbę wierzchołków, dla których istnieją wierzchołki je dominujące.                        *)
  335.  
  336. open Array;;
  337.  
  338. let zdominowani e =
  339.     let n = length e in
  340.     let indeg v =
  341.         let wyn = ref 0 in
  342.         for u = 0 to n - 1 do
  343.             if e.(u).(v) then incr wyn
  344.         done;
  345.         !wyn in
  346.     let visited = make n 0 in
  347.     let rec dfs v =
  348.         if visited.(v) < 2 then begin
  349.             visited.(v) <- visited.(v) + 1;
  350.             for u = 0 to n - 1 do
  351.                 if e.(v).(u) then dfs u
  352.             done
  353.         end in
  354.     for v = 0 to n - 1 do
  355.         if indeg v = 0 then dfs v
  356.     done;
  357.     fold_left (fun acc x -> if x < 2 then acc + 1 else acc) 0 visited
  358.  
  359. (* T(n) = 0(n^2) *)
  360. (* M(n) = 0(n) *)
  361.  
  362.  
  363. (***** 19.12.2018 *****)
  364.  
  365. (*  10. [XIV OI, zadanie Powódź] Dana jest mapa topograficzna miasta położonego w kotlinie,                      *)
  366. (*  w postaci prostokątnej tablicy typu (int * bool) array array. Liczby określają wysokość                       *)
  367. (*  kwadratów jednostkowych, a wartości logiczne określają, czy dany kwadrat należy do terenu miasta.         *)
  368. (*  Przyjmujemy, że teren poza mapą jest położony wyżej niż jakikolwiek kwadrat na mapie.                        *)
  369. (*  Miasto zostało całkowicie zalane. Żeby je osuszyć należy w kotlinie rozmieścić pewną liczbę pomp.           *)
  370. (*  Każda z pomp wypompowuję wodę aż do osuszenia kwadratu jednostkowego, na którym się znajduje.               *)
  371. (*  Osuszenie dowolnego kwadratu pociąga za sobą obniżenie poziomu wody lub osuszenie kwadratów jednostkowych,  *)
  372. (*  z których woda jest w stanie spłynąć do kwadratu, na którym znajduje się pompa.                              *)
  373. (*  Woda może przepływać między kwadratami, które stykają się bokami.                                          *)
  374. (*                                                                                                              *)
  375. (*  Wyznacz minimalną liczbę pomp koniecznych do osuszenia miasta.                                              *)
  376. (*  Teren nie należący do miasta nie musi być osuszony. Miasto nie musi tworzyć spójnego obszaru.             *)
  377.  
  378.  
  379. (*
  380. let powodz teren =
  381.     let m = length teren in
  382.     let n = length teren.(0) in
  383.     let l = ref [] in
  384.     for i = 0 to m - 1 do
  385.         for j = 0 to n - 1 do
  386.             if snd teren.(i).(j) then
  387.                 l := (fst teren.(i).(j), (i, j))::!l
  388.         done
  389.     done;
  390.     l := List.sort compare !l;
  391.     let spompowane = make_matrix m n false in
  392.     let kolejka = ref Leftist.empty in
  393.     let pompy = ref [] in
  394.     while !l <> [] do
  395.         if Leftist.is_empty !kolejka || fst (Leftist.get_min !kolejka) > fst (hd !l) then begin
  396.             let (wys, (i, j)) = hd !l in
  397.             l := tl !l;
  398.             if not spompowane.(i).(j) then begin
  399.                 pompy := (i, j)::(!pompy);
  400.                 spompowane.(i).(j) <- true;
  401.                 kolejka := Leftist.add (wys, (i, j)) !kolejka
  402.             end
  403.         end
  404.         else begin
  405.             let (wys, (i, j)) = Leftist.get_min !kolejka in
  406.             kolejka := Leftist.remove_min !kolejka;
  407.             if not spompowane.(i).(j) then
  408.                 spompowane.(i).(j) <- true;
  409.         end
  410.         let splywaj i' j' wys =
  411.             if not spompowane.(i').(j') then begin
  412.                 if not snd teren.(i').(j') || fst teren.(i').(j') >= wys then
  413.                     kolejka := Leftist.add (max wys (fst teren.(i').(j'), (i', j'))) !kolejka
  414.             end in
  415.         if i > 0 then splywaj (i - 1) j wys;
  416.         if i < m - 1 then splywaj (i + 1) j wys;
  417.         if j > 0 then splywaj i (j - 1) wys;
  418.         if j < n - 1 then splywaj i (j + 1) wys;
  419.     done;
  420.     !pompy
  421. *)
  422.  
  423. (* Zadanie jakieś na BackTracka, jest plansza [m] x [n], jest skoczek i jakies skoki jego *)
  424.  
  425. let skoczek m n =
  426.     let d = [|(2, 1); (2, -1); (-2, 1); (-2, -1); (1, 2); (1, -2); (-1, 2); (-1, -2)|] in
  427.     let a = make_matrix m n (-1) in
  428.     let rec bt x y k =
  429.         if 0 <= x && x < m && 0 <= y && y < n then
  430.             if k = m * n && x = 0 && y = 0 then
  431.                 failwith "Yeah!"
  432.             else if a.(x).(y) < 0 then begin
  433.                 a.(x).(y) <- k;
  434.                 Array.iter (fun (dx, dy) -> bt (x + dx) (y + dy) (k + 1)) d;
  435.                 a.(x).(y) <- -1
  436.         end in
  437.     try
  438.         bt 0 0 0; a
  439.     with _ -> a
  440.  
  441. (***** 7.01.2019 *****)
  442.  
  443. (* Chyba zwykły problem wydawania reszty *)
  444.  
  445. let reszta n l =
  446.     let a = Array.init (n + 1) (fun i -> if i = 0 then 0 else n + 1) in
  447.     List.iter
  448.         (fun b ->
  449.             for i = b to n do
  450.                 a.(i) <- min a.(i) (a.(i - b) + 1)
  451.             done
  452.         ) l;
  453.     a.(n)
  454.  
  455. (* T(n, m) = O(n * m)   *)
  456. (* M(n, m) = O(n)       *)
  457.  
  458. (* Na ile sposobów możemy wydać daną resztę *)
  459.  
  460. let reszta n l =
  461.     let a = Array.init (n + 1) (fun i -> if i = 0 then 1 else 0) in
  462.     List.iter
  463.         (fun b ->
  464.             for i = b to n do
  465.                 a.(i) <- a.(i) * a.(i - b) (* na tablicy był tu + ??? *)
  466.             done
  467.         ) l;
  468.     a.(n)
  469.  
  470. (*
  471. let banknot n l =
  472.     let a = Array.init (n + 1) (fun i -> if i = 0 then 0 else n + 1) in
  473.     List.iter
  474.         (fun (b, c) ->
  475.             for r = 0 to b - 1 do
  476.                 let kolejka = ref KMinQ.init c in
  477.                 for q = 1 to (n - r) / b do
  478.                     kolejka := KMinQ.add (a.(q + b + r) - q) !kolejka;
  479.                     a.(q * b + r) <- (KMinQ.get_min !kolejka) + q
  480.                 done
  481.             done
  482.         ) l;
  483.     a.(n)
  484. *)
  485.  
  486. (* T(n, m) = O(n * m)   *)
  487. (* M(n, m) = O(n)       *)
  488.  
  489. (***** 9.01.2019 *****)
  490.  
  491. let klej l =
  492.     let x = Array.of_list l in
  493.     let n = Array.length x in
  494.     let s = Array.make (n + 1) 0 in
  495.     for i = 1 to n do
  496.         s.(i) <- s.(i - 1) + x.(i - 1)
  497.     done;
  498.     let dl a b =
  499.         s.(b + 1) - s.(a) in
  500.     let m = Array.make_matrix n n max_int in
  501.     for a = 0 to n - 1 do
  502.         m.(a).(a) <- 0
  503.     done;
  504.     for d = 1 to n - 1 do
  505.         for a = 0 to n - d - 1 do
  506.             let b = a + d in (* m.(a).(b) *)
  507.             for i = a to b - 1 do
  508.                 m.(a).(b) <- min m.(a).(b) (m.(a).(i) + m.(i + 1).(b) + max (dl a i) (dl (i + 1) b))
  509.             done
  510.         done
  511.     done;
  512.     m.(0).(n - 1)
  513.  
  514. (* T(n) = O(n^3) *)
  515. (* M(n) = O(n^2) *)
  516.  
  517. type drzewo =
  518.     | Node of int * drzewo * drzewo
  519.     | Leaf
  520.  
  521. (* Nie działa intersect *)
  522. (*
  523. let rownowaga t =
  524.     let przetnij a b =
  525.         let rec pom a b acc =
  526.             match a, b with
  527.             | x::t, y::s ->
  528.                 if x < y then pom t b acc
  529.                 else if x > y then pom a s acc
  530.                 else pom t s (x::acc)
  531.             | _ -> rev acc in
  532.         pom a b [] in
  533.     let rec dynamik t =
  534.         match t with
  535.         | Leaf -> (0, [0])
  536.         | Node (w, l, p) ->
  537.             let (u, a) = dynamik l in
  538.             let (v, b) = dynamik p in
  539.             let uv =
  540.                 if u >= 0 && v >= 0 && u = v then u + v + 1
  541.                 else -1 in
  542.             let c = intersect a b |> map (fun x -> x + w + 1) in (* map ((+) (w + 1)) *)
  543.             (uv, if uv >= 0 then uv::c else c) in
  544.     (dynamik t |> snd) <> []
  545.  
  546. *)
  547.  
  548. (* nlog n czas i pamiec *)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement