Skip to content

Commit

Permalink
Merge pull request #14 from NicolaBernini/code_review_20190423_1832_1
Browse files Browse the repository at this point in the history
Code review 20190423 1832 1
  • Loading branch information
NicolaBernini authored Apr 23, 2019
2 parents 73738d5 + bf4f4a7 commit 3a5655c
Show file tree
Hide file tree
Showing 6 changed files with 241 additions and 0 deletions.
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







0 comments on commit 3a5655c

Please sign in to comment.