Skip to content
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

Code review 20190423 1832 1 #14

Merged
merged 12 commits into from
Apr 23, 2019
31 changes: 31 additions & 0 deletions code_review/permutations_20190423_1832_1/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

# Overview

The task is to compute all the permutations for a given vector of integers (but of course the specific integer type is not relevant for the solution)

The strategy is based on recursion + iterations

At each recursion, the state consists of

- the root sequence `a` which is the set of elements already placed

- the remaining elements set `b` which is the set of elements still to be placed

Inside the recursion, a loop places the `N(i)` (with `i` recursion index and) remaining elements producing the same amount of new root sequences and a new recursion is started so that `N(i+1)=N(i)-1` hence meaning the overall complexity is `O(N!)` as expected

The recursion ends when there are no more elements to place hence `b.empty()` is true

Each recursion set ends with a valid sequence hence they are all merged together in a final list of sequences

- [Article on CodeReview StackExchange](https://codereview.stackexchange.com/questions/217939/compute-all-the-permutations-for-a-given-vector-of-integers)

# Solutions

- [Sol1](sol.cpp)







53 changes: 53 additions & 0 deletions code_review/permutations_20190423_1832_1/sol.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include <iostream>
#include <vector>
using namespace std;

vector<int> remove_item (const vector<int>& a, const unsigned int id)
{
vector<int> res;
for(unsigned int i=0; i<a.size(); ++i) if(i!=id) res.push_back(a[i]);
return res;
}


vector<int> add_item(const vector<int>& a, const int b)
{
vector<int> res=a;
res.push_back(b);
return res;
}

vector< vector<int> > merge(const vector< vector<int> >& a, const vector< vector<int> >& b)
{
vector< vector<int> > res=a;
for(const auto& e : b) res.push_back(e);
return res;
}



vector< vector<int> > permutations(const vector<int>& b, const vector<int>& a={})
{

if(b.empty()) return { a };

vector< vector<int> > res;
for(unsigned int i=0; i<b.size(); ++i) res=merge(res, permutations(remove_item(b,i), add_item(a, b[i])));
return res;
}

int main() {
// your code goes here

auto res = permutations({1,2,3,4,5});
cout << "Sol Num = " << res.size() << endl;
for(const auto& a : res)
{
for(const auto& b : a) cout << to_string(b) << " ";
cout << endl;
}
return 0;
}



31 changes: 31 additions & 0 deletions code_review/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

# Overview

This regards [Code Reviews](https://codereview.stackexchange.com/) related code submissions

# Permutations

- Compute all the possible permutations for a given vector
- [Article](permutations_20190423_1832_1/readme.md)
- [Post on CodeReview StackExchange](https://codereview.stackexchange.com/questions/217939/compute-all-the-permutations-for-a-given-vector-of-integers)



# Search in Array

- Search min element in an array which was previously sorted in ascending order and then rotated with respect to a random pivot
- [Article](smallest_elem_in_sorted_and_rotated_array_20190423_1835_1/readme.md)
- [Post on CodeReview StackExchange](https://codereview.stackexchange.com/questions/217897/find-the-smallest-element-in-a-sorted-and-rotated-array/217949#217949)







Work in progress





Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

#include <iostream>
#include <vector>
using namespace std;

vector<int> a = {5,6,7,8,9,10,11, 1,2,3,4};

unsigned int solve(const vector<int>& a, unsigned int l=0, unsigned int r=0)
{
if(a.empty()) throw runtime_error("Empty");
if(a.size()==1) return 0;
if(r==0) r=a.size()-1; ///< Overwrite the invalid initialization with the right value, unfortunately it is not possible to do this in function declaration
if(a[l] < a[r]) return l; ///< Sorted in Ascending Order
if(r-l==1) return r;
const auto m = (r+l)/2;
if(a[m] > a[l]) return solve(a, m, r);
return solve(a, l, m);
}

int main() {
// your code goes here
cout << "Min=" << a[solve(a)];
return 0;
}







Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

#include <iostream>
#include <vector>
#include <iterator>
using namespace std;

vector<int> a = {5,6,7,8,9,10,11, 1,2,3,4};

vector<int>::iterator solve(const vector<int>::iterator l, const vector<int>::iterator r)
{
if(l==r) return r; ///< Covers the single element array case
if(*l < *r) return l; ///< Sorted in Ascending Order
if(r-l==1) return r;
const auto m = l + distance(l,r)/2;
if(*m > *l) return solve(m, r);
return solve(l, m);
}

int main() {
// your code goes here
cout << "Min=" << *solve(a.begin(), a.end()-1);
return 0;
}








Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@

# Overview

Here is my minimal solution about the problem

- the strategy is divide-and-conquer for the reasons already explained by @papagaga

- it is based on the idea that before the rotation the array has this structure

```
[m .. p P .. M]
```

with

- `m` min

- `M` max

- `p` pivot

- `P` next to the pivot so that `P>p`


- while after the rotation it has the following structure

```
[P .. M m .. p]
```

so the idea is to update the `l` left cursor and `r` right cursor so that `v[l] > v[r]` with a divide and conquer strategy so to have `O(LogN)` complexity and ultimately the final condition is `l` and `r` are contiguous
and the first identifies `M` while the second identifies `m` hence return the last one

**EDIT** Following @papagaga suggestion I provide 2 implementations

- [Article on CodeReview StackExchange](https://codereview.stackexchange.com/questions/217897/find-the-smallest-element-in-a-sorted-and-rotated-array/217949#217949)


## 1. Index based solution

[Index based](index_based1.cpp)

Comments

- Added the empty array case management using Exception
- An alternative could have been using Maybe Monad (a Boost Optional) to represent non meaningful results


## 2. Iterators based solution

[Iterators based](iterator_based1.cpp)

Comments

- Working with iterators allows to represent invalid values so no need for Exception and explicit Maybe Monad as the iterator type is one
- The first check automatically manages the one element case
- The empty array case should be managed before calling this function as it expects both the iterators point to valid elements