-
Notifications
You must be signed in to change notification settings - Fork 0
Jpere838 hw1 #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: EdwardBranch
Are you sure you want to change the base?
Jpere838 hw1 #1
Changes from all commits
3a1b108
5d5f054
ce7a7f7
f7a1203
ba9bd42
6a5e018
54aef80
705c42d
0b1edfb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| (* | ||
| Jose Gabriel Perez | ||
| ex 1: could save gcd on reduce to avoid double calc on big nums | ||
| Also, finding common denom instead to reduce computing could be better for large numbers | ||
| *) | ||
|
|
||
| //ex1 | ||
| let rec gcd = function | ||
| | (a,0) -> a | ||
| | (a,b) -> gcd (b, a % b) | ||
|
|
||
| let reduce = function | ||
| | (a, b) -> (a/gcd(a,b), b/gcd(a,b)) | ||
|
|
||
| let (.+) (a,b) (c,d) = reduce (a*d + b*c, b*d) | ||
| let (.*) (a,b) (c,d) = reduce (a*c, b*d) | ||
|
|
||
| //ex2 | ||
| let revlists l = List.map List.rev l | ||
|
|
||
| //ex3 Really banking on l1 and l2 having equal length, otherwise it will just do it up to the smaller size | ||
| let rec interleave = function | ||
| | ([], l) -> [] | ||
| | (l, []) -> [] | ||
| | (x::xs, y::ys) -> x:: y :: interleave(xs, ys) | ||
|
|
||
| //ex4 | ||
| let gencut(n, l1) = | ||
| let rec helpcut (n, a, b) = | ||
| if List.isEmpty b then (n, a, b) | ||
| elif List.length a < n then helpcut (n, a @ (List.head b :: []), List.tail b) | ||
| else (n, a, b) | ||
| let (_, f1, f2) = helpcut (n, [], l1) | ||
| (f1, f2) | ||
|
|
||
| let cut l1 = gencut((List.length l1)/2, l1) | ||
|
|
||
| //ex5 | ||
| let shuffle l = interleave (cut l) | ||
|
|
||
| //ex6 | ||
| let countshuffles n = | ||
| let rec countaux(deck, target) = | ||
| if deck = target then 0 | ||
| else 1 + countaux(shuffle deck, target) | ||
| countaux(shuffle [1..n],[1..n]) + 1 | ||
|
|
||
| //samples | ||
| interleave ([1;2;3],[4;5;6]);; | ||
| cut [1;2;3;4;5;6];; | ||
| shuffle [1;2;3;4];; | ||
| countshuffles 8;; | ||
| countshuffles 52;; | ||
|
|
||
| shuffle [1; 2; 3; 4; 5; 6; 7; 8];; | ||
| shuffle [1; 5; 2; 6; 3; 7; 4; 8];; | ||
| shuffle [1; 3; 5; 7; 2; 4; 6; 8];; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| (* Homework 2 | ||
|
|
||
| *) | ||
|
|
||
| /// 1. Returns a list of pairs that represents the cartesian product | ||
| let rec cartesian(xs, ys) = | ||
| match xs, ys with | ||
| | (xs, []) -> [] | ||
| | ([], ys) -> [] | ||
| | (x::xs, ys) -> (List.map(fun y -> x,y) ys) @ (cartesian (xs,ys));; | ||
|
|
||
| /// 2. Powerset set returns the set of all subsets of set | ||
| let rec powerset = function | ||
| | [] -> [[]] | ||
| | x::xs -> List.collect (fun subset -> [subset; x::subset]) (powerset xs) | ||
|
|
||
| /// 3. Transpose an m-by-n matrix | ||
| let rec transpose = function | ||
| | (_::_)::_ as M -> List.map List.head M :: transpose (List.map List.tail M) | ||
| | _ -> [] | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here let rec transpose = function
| (_::_)::_ as M -> List.map List.head M :: transpose (List.map List.tail M)
| _ -> [] |
||
|
|
||
| //// 4. Correctness of sort recursive function with respect to the Checklist for Programming with Recursion | ||
| (* | ||
| Step One: It is okay, because empty and single item lists are automatically sorted | ||
| Step Two: wrong, because even assuming that sort (x2::xs) returns the correct answer, there is no guarantee | ||
| that x1 is the minimun since it was only compared to x2 and is not checked again. | ||
| For a counter example sort [3;2;1];; will return [2;1;3;]. | ||
| All that this sort function really guarantees is that the largest element goes to the end of the list. | ||
| (Note: works like the insertion step of insertion sort, if it gets called n-1 times the list would be sorted) | ||
| Step Three: Each recursive call gets an input that is smaller than the original input | ||
| *) | ||
| let rec sort = function | ||
| | [] -> [] | ||
| | [x] -> [x] | ||
| | x1::x2::xs -> if x1 <= x2 then x1 :: sort (x2::xs) | ||
| else x2 :: sort (x1::xs) | ||
|
|
||
| /// 5. Analyze mergesort with respect to the Checking for Programming with Recursion (merge and split work correctly) | ||
| (* | ||
| Step One: It is okay, because empty lists are automatically sorted | ||
| Step Two: If mergesort of M and N return the correct answer, then since split and merge are correct the non-base case | ||
| is correct too. There is a missing base case that leads to a bug, but step 2 is still satisfied. | ||
| Step Three: Each recursive call gets an input that is smaller than the original input | ||
|
|
||
| Clue something is wrong: The mergesort function is missing a case, which causes mergesort to be seen by | ||
| the compiler as 'a list -> 'b list instead of 'a list -> 'a list | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... list instead of 'a list -> 'a list which tells us our merge sort is returning a list of items of a different type than given, which shouldn't be the case as we're simply sorting the elements. |
||
| *) | ||
| let rec merge = function | ||
| | ([], ys) -> ys | ||
| | (xs, []) -> xs | ||
| | (x::xs, y::ys) -> if x < y then x :: merge (xs, y::ys) | ||
| else y :: merge (x::xs, ys) | ||
|
|
||
| let rec split = function | ||
| | [] -> ([], []) | ||
| | [a] -> ([a], []) | ||
| | a::b::cs -> let (M,N) = split cs | ||
| (a::M, b::N) | ||
|
|
||
| let rec mergesort = function | ||
| | [] -> [] | ||
| | [x] -> [x] //Bug corrected | ||
| | L -> let (M, N) = split L | ||
| merge (mergesort M, mergesort N) | ||
|
|
||
| /// 6. Define F# function curry f that converts an uncurried function to a curried function, and | ||
| (* an F# uncurry f that does the opposite conversion *) | ||
| let curry f a b = f (a, b) | ||
| let uncurry f (a,b) = f a b | ||
|
|
||
| (* | ||
| val curry : ('a * 'b -> 'c) -> 'a -> 'b -> 'c | ||
| val uncurry : ('a -> 'b -> 'c) -> 'a * 'b -> 'c | ||
| *) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| // 1 | ||
| let rec inner xs ys = | ||
| match (xs, ys) with | ||
| | ([x],[y]) -> x*y | ||
| | (x::xs, y::ys) -> x*y + inner xs ys | ||
| | (_, _)-> failwith "inner defined for equal sized lists only" | ||
|
|
||
|
|
||
|
|
||
| // 2 using transpose from last HW | ||
| let rec transpose = function | ||
| | (_::_)::_ as M -> List.map List.head M :: transpose (List.map List.tail M) | ||
| | _ -> [] | ||
|
|
||
| // Posible to improve this by transposing beforehand | ||
| let rec multiply = function | ||
| |([], _) -> [] | ||
| |(x::xs, ys) -> List.map (inner x) (transpose ys) :: multiply (xs, ys) | ||
|
|
||
| // 3 | ||
| let flatten1 xs = List.fold (@) [] xs | ||
| let flatten2 xs = List.foldBack (@) xs [] | ||
| let makelistlist n = List.map (fun x -> [x]) [1..n] | ||
| #time | ||
| (*In practice flatten1 behaves as O(n^2) and flatten2 is (O(n))*) | ||
|
|
||
| // 4 | ||
| (* | ||
| twice successor 0 would be 2 = 2^1 | ||
| twice twice successor 0 would be 4 = 2^2 | ||
| twice twice twice successor 0 would be 16 = 2^4 | ||
| And so on.. | ||
|
|
||
| The current value becomes equals to 2 to the power of the previous value | ||
|
|
||
| The function will be defined recursively, as follows: | ||
| f(n) = | ||
| if n = 0 then 1 | ||
| else 2 ^ (f(n-1)) | ||
|
|
||
| We can write this function as: | ||
| let rec f = function | ||
| | 0 -> 1.0 | ||
| | n -> 2.0 ** (f (n-1));; | ||
| *) | ||
|
|
||
| // 5 | ||
| type 'a stream = Cons of 'a * (unit -> 'a stream);; | ||
|
|
||
| let rec map f (Cons(x, xsf)) = Cons (f x, fun() -> map f (xsf()));; | ||
|
|
||
| // 6 | ||
| type Exp = Num of int | ||
| | Neg of Exp | ||
| | Sum of Exp * Exp | ||
| | Diff of Exp * Exp | ||
| | Prod of Exp * Exp | ||
| | Quot of Exp * Exp | ||
|
|
||
| let rec evaluate = function | ||
| | Num n -> Some n | ||
| | Neg e -> match evaluate e with | ||
| | None -> None | ||
| | Some n -> Some (-1 * n) | ||
| |Sum (e1, e2) -> match (evaluate e1, evaluate e2) with | ||
| |(None, _) -> None | ||
| |(_, None) -> None | ||
| |(Some n1, Some n2) -> Some (n1 + n2) | ||
| |Diff (e1, e2) -> match (evaluate e1, evaluate e2) with | ||
| |(None, _) -> None | ||
| |(_, None) -> None | ||
| |(Some n1, Some n2) -> Some (n1 - n2) | ||
| |Prod (e1, e2) -> match (evaluate e1, evaluate e2) with | ||
| |(None, _) -> None | ||
| |(_, None) -> None | ||
| |(Some n1, Some n2) -> Some (n1 * n2) | ||
| |Quot (e1, e2) -> match (evaluate e1, evaluate e2) with | ||
| |(None, _) -> None | ||
| |(_, None) -> None | ||
| |(_, Some 0) -> None | ||
| |(Some n1, Some n2) -> Some (n1 - n2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kill the indents