Connect with us

Uncategorized

Cienie zdrady: droga do nowego szczęścia

Katarzyna często wyjeżdżała w delegacje. Raz w miesiącu na dwa, trzy dni udawała się do głównego biura firmy w sąsiednim mieście. Jakub przyzwyczaił się do jej nieobecności i nie protestował. Pracowali w różnych firmach, spotykali się wieczorami, spędzali razem weekendy – choć nie zawsze. Jakub miał swoje hobby – myślistwo. Często wyjeżdżał z przyjaciółmi na łono natury. Katarzyna nie miała nic przeciwko, rozumiejąc, że mężczyzna potrzebuje przestrzeni dla siebie.

Ży# CSCI 1102 Computer Science 2

### Fall 2017

## Lecture Notes
### Week 4: More Functions and First-Class Values

#### Topics

1. Binary Trees
2. Tail Recursion
3. Processing Pairs and Lists of Pairs

## 1. Binary Trees

Here’s a type for binary trees very similar to the type for lists:

„`ocaml
type 'a tree =
| Empty
| Node of 'a * 'a tree * 'a tree
„`

Let’s construct a sample tree:

„`ocaml
let t = Node (4,
Node (2,
Node (1, Empty, Empty),
Node (3, Empty, Empty)),
Node (6,
Node (5, Empty, Empty),
Node (7, Empty, Empty)))
„`

For a more compact representation, we can define a few helper functions:

„`ocaml
let lf x = Node (x, Empty, Empty)
let nd (x, l, r) = Node (x, l, r)
„`
Using these:

„`ocaml
let t = nd (4,
nd (2,
lf 1,
lf 3),
nd (6,
lf 5,
lf 7))
„`

In OCaml, trees are persistent data structures — they can’t be changed, i.e., they are *immutable*. For example, suppose we have:

„`ocaml
let t = Node (2, lf 1, lf 3)
„`

and would like to make a new tree by replacing the empty left subtree of `t` with the leaf `lf 4`, i.e., the result should be:

„`ocaml
Node (2, lf 4, lf 3)
„`

We can do this as follows:

„`ocaml
let newT =
match t with
| Empty -> failwith „empty”
| Node (x, _, r) -> Node (x, lf 4, r)
„`

### Processing Trees

Let’s write a function to compute the size of a tree, i.e., its number of non-empty nodes.

„`ocaml
let rec size tree =
match tree with
| Empty -> 0
| Node (_, l, r) -> 1 + size l + size r
„`

**Exercise.** Write a function `height : 'a tree -> int` to compute the height of a binary tree. For the purposes of this problem, we’ll take the height of the empty tree to be 0 and the height of a non-empty tree to be the length of the longest path from the root to a leaf.

„`ocaml
let rec height tree =
match tree with
| Empty -> 0
| Node (_, l, r) -> 1 + max (height l) (height r)
„`

Let’s write a function to compute the sum of the nodes of an `int tree`:

„`ocaml
let rec sum tree =
match tree with
| Empty -> 0
| Node (x, l, r) -> x + sum l + sum r
„`

All three of these functions are examples of tree folds.

**Exercise.** [Not required]. Can you write a general-purpose fold function for binary trees analogous to `fold_right` for lists? What would its type be?

### The Binary Search Tree (BST) Property

A binary tree is a BST if for any non-empty subtree `Node (x, l, r)`, the values in `l` are all less than `x` and the values in `r` are all greater than `x`. Here’s an OCaml predicate to test whether a tree satisfies the BST property.

„`ocaml
let rec isBST tree =
match tree with
| Empty -> true
| Node (x, l, r) ->
( (isBST l) && (isBST r) &&
(treeMax l) < x && x < (treeMin r) ) ``` This uses two helper functions: ```ocaml let rec treeMax tree = match tree with | Empty -> min_int
| Node (x, _, Empty) -> x
| Node (x, _, r) -> treeMax r

let rec treeMin tree =
match tree with
| Empty -> max_int
| Node (x, Empty, _) -> x
| Node (x, l, _) -> treeMin l
„`

**Exercise (Required).** The code above works but is inefficient. Why? Can you correct the code? (Try to avoid computing the min and max twice.)

### Processing BSTs

Let’s write a lookup function for BSTs:

„`ocaml
let rec lookup x tree =
match tree with
| Empty -> false
| Node (y, l, r) ->
if x < y then lookup x l else if x > y then lookup x r
else true
„`

## 2. Tail Recursion

Here’s the standard implementation of the factorial function:

„`ocaml
let rec fact n =
if n <= 1 then 1 else n * fact (n - 1) ``` Here's another version: ```ocaml let fact n = let rec helper n k = if n <= 1 then k else helper (n - 1) (k * n) in helper n 1 ``` This is called a *tail recursive* (or iterative) implementation. The difference between `fact` and `helper` is that, in the recursive case, `helper` applies *itself* tail recursively as the *very last thing it does* whereas `fact` has to perform a multiplication (by `n`) *after* the recursive call. The iterative version uses an accumulating parameter `k` that keeps track of the multiplications performed so far. Here's how it works: ```ocaml fact 4 => helper 4 1
=> helper 3 (4 * 1)
=> helper 2 (3 * (4 * 1))
=> helper 1 (2 * (3 * (4 * 1)))
=> 2 * (3 * (4 * 1))
=> 24
„`

The key point is that no pending computations are left to perform when the base case is reached — the accumulated value is simply returned. In contrast, a non tail-recursive function would have have to perform a series of pending multiplications on the way back up, so to speak.

The advantage here is that the OCaml compiler can implement tail recursive calls very efficiently by simply reusing the same stack frame for each call.

### Converting Non Tail-Recursive Functions to Tail Recursive

Here’s a tail-recursive version of list length:

„`ocaml
let length l =
let rec helper l k =
match l with
| [] -> k
| _ :: t -> helper t (k + 1) in
helper l 0
„`

Let’s try converting the `sum` function:

„`ocaml
let rec sum l =
match l with
| [] -> 0
| h :: t -> h + sum t

let sum l =
let rec helper l k =
match l with
| [] -> k
| h :: t -> helper t (h + k) in
helper l 0
„`

Here’s the standard implementation of the `map` function:

„`ocaml
let rec map f l =
match l with
| [] -> []
| h :: t -> (f h) :: map f t
„`

Here is a tail-recursive version:

„`ocaml
let map f l =
let rec helper l k =
match l with
| [] -> List.rev k
| h :: t -> helper t ( (f h) :: k ) in
helper l []
„`

This version, uses the accumulating parameter `k` as an accumulator but it builds up the result in reverse order. The call to `List.rev` reverses the accumulated list in the base case.

**Exercise.** Write a tail-recursive version of `append` and `factorial`.

### When is Tail Recursion Useful?

It’s useful when (1) the function in question operates over large data structures (lists, trees, etc.) *and* (2) it is likely to be called repeatedly in a larger computation (so that the efficiency gains are meaningful).

## 3. Processing Pairs and Lists of Pairs

### Processing Pairs

Tuples allow for aggregating data more flexibly than lists. The elements of a tuple can be of any type and needn’t be homogeneous (unlike lists). For example:

„`ocaml
let t1 = (true, false)
let t2 = (true,Dziś Katarzyna i Siergiej świętują dziesięć lat małżeństwa, otoczeni rodziną i przyjaciółmi, a ich dom pełen jest śmiechu i miłości.

Uncategorized2 dni ago

Piotrek wsadził kota do worka – syn sąsiada przypadkiem zobaczyłChłopiec natychmiast pobiegł do domu, aby powiedzieć o tym swojej mamie.

Uncategorized3 dni ago

Piotrowicz wepchnął kota do worka – chłopiec sąsiada przypadkiem to zobaczyłWieść o tym wydarzeniu błyskawicznie obiegła całe osiedle, a Piotrowicz musiał się tłumaczyć przed zbulwersowanymi sąsiadami.

Uncategorized3 dni ago

– Gratuluję! Właśnie straciliście i narzeczoną, i mieszkanie, i resztki mojego szacunku! – rzuciłam obrączkę przez okno.

Uncategorized3 dni ago

– Gratuluję! Właśnie straciliście i narzeczoną, i mieszkanie, i resztki mojego szacunku! – rzuciłam pierścionek zaręczynowy przez okno.

Uncategorized3 dni ago

– Potrzebuję bardzo starego psa, – prosiła kobieta w schronisku.

Uncategorized3 dni ago

– Potrzebuję bardzo starego psa – błagała kobieta w schronisku.

Uncategorized3 dni ago

Porzucony pies wrócił po trzech miesiącach do swojego właściciela – ten nie spodziewał się go zobaczyć.

Uncategorized3 dni ago

Pies wrócił do porzucającego go właściciela po trzech miesiącach: nie spodziewał się go zobaczyćGdy otworzył drzwi, pies rzucił mu się do nóg, a w oczach mężczyzny pojawiły się łzy wzruszenia i żalu.

Uncategorized3 dni ago

Święto minęło, a o psie po prostu zapomniano: rano właściciele nie wierzyli własnym oczomPies leżał spokojnie na kanapie, otoczony resztkami jedzenia i balonami, jakby sam z siebie urządził sobie najlepsze przyjęcie w swoim życiu.

Uncategorized3 dni ago

Święto minęło, a o psie po prostu zapomniano: rano właściciele nie wierzyli własnym oczomPrzed nimi stał pies, który przez całą noc samodzielnie otworzył lodówkę i zjadł cały zapas świątecznych przysmaków, a teraz spokojnie spał wśród pustych opakowań.

Uncategorized2 tygodnie ago

„Mamo, podpisz i zwolnij działkę – to teraz moje”. Córka nie wiedziała, że od dwóch miesięcy nie jestem już jej matką na papierze.

Uncategorized2 tygodnie ago

Mąż nie pracuje od pół roku, śpi do obiadu i uważa, że powinnam go karmić. A ja zwolniłam się w odpowiedzi.

Uncategorized1 tydzień ago

Tylko obejrzymy działkę i wracamy! — obiecała teściowa w piątkowy wieczór. Wyjechali w niedzielę. Przyjechałam w poniedziałek — i założyłam kłódkę.

Uncategorized4 tygodnie ago

Wira smażyła kotlety, gdy do kuchni wszedł mąż. – Wiro, musimy porozmawiać – rzekł stanowczo Igor. – Mów – odrzekła żona. – Może usiądziesz i posłuchasz? – w głosie Igora zabrzmiała niecierpliwość. – Muszę cały czas patrzeć na kotlety – odpowiedziała żona. – Co chciałeś mi powiedzieć? – Igor się potknął, ledwo dobierając słowa. – Spotkałem inną kobietę… odchodzę od ciebie! – Gratuluję ci. I bardzo się cieszę za ciebie! – spokojnie powiedziała Wira. – Co masz na myśli, gratuluję? Czy cieszę się z ciebie? – mąż spojrzał zaskoczony. Ale Igor nawet nie mógł sobie wyobrazić, co Wira w tej chwili zamierzała.

Uncategorized2 tygodnie ago

Mąż powiedział, że bez niego przepadnę. Nie dyskutowałam – i zrobiłam wszystko po swojemuI udowodniłam mu w najpiękniejszy możliwy sposób, że potrafię radzić sobie doskonale sama.

Uncategorized2 tygodnie ago

Mąż postanowił odpocząć ode mnie i dzieci i uciekł do teściowej. Wrócił – i aż go zatkało.

Uncategorized4 dni ago

Teściowa była przekonana, że po rozwodzie nadal zamieszka w mieszkaniu byłej synowej i będzie dostawać od niej pomoc.

Uncategorized1 tydzień ago

— Skoro urodziłaś córkę, a nie syna, zwalniaj mieszkanie — oświadczyła teściowa. Mąż stanął po stronie żony.

Uncategorized6 dni ago

— Żyjesz za dobrze po rozwodzie, — powiedziała była teściowa i postanowiła „przywrócić sprawiedliwość”

Uncategorized4 tygodnie ago

– Przecież cię ostrzegałam – tam, gdzie zabrałeś pieniądze, tam idź na kolację! A śniadanie, swoją drogą, też – powiedziała żona i usiadła w fotelu z robótką ręczną.

Trending