Related
Having an excellent solution to: Cartesian product in Gray code order with itertools?, is there a way to add something simple to this solution to also report the set (its index) that underwent the change in going from one element to the next of the Cartesian product in Gray code order? That is, a gray_code_product_with_change(['a','b','c'], [0,1], ['x','y']) which would produce something like:
(('a',0,'x'), -1)
(('a',0,'y'), 2)
(('a',1,'y'), 1)
(('a',1,'x'), 2)
(('b',1,'x'), 0)
(('b',1,'y'), 2)
(('b',0,'y'), 1)
(('b',0,'x'), 2)
(('c',0,'x'), 0)
(('c',0,'y'), 2)
(('c',1,'y'), 1)
(('c',1,'x'), 2)
I want to avoid taking the "difference" between consecutive tuples, but to have constant-time updates --- hence the Gray code order thing to begin with. One solution could be to write an index_changed iterator, i.e., index_changed(3,2,2) would return the sequence -1,2,1,2,0,2,1,2,0,2,1,2 that I want, but can something even simpler be added to the solution above to achieve the same result?
There are several things wrong with this question, but I'll keep it like this, rather than only making it worse by turning it into a "chameleon question"
Indeed, why even ask for the elements of the Cartesian product in Gray code order, when you have this "index changed" sequence? So I suppose what I was really looking for was efficient computation of this sequence. So I ended up implementing the above-mentioned gray_code_product_with_change, which takes a base set of sets, e.g., ['a','b','c'], [0,1], ['x','y'], computing this "index changed" sequence, and updating this base set of sets as it moves through the sequence. Since the implementation ended up being more interesting than I thought, I figured I would share, should someone find it useful:
(Disclaimer: probably not the most pythonic code, rather almost C-like)
def gray_code_product_with_change(*args, repeat=1) :
sets = args * repeat
s = [len(x) - 1 for x in sets]
n = len(s)
# setup parity array and first combination
p = n * [True] # True: move foward (False: move backward)
c = n * [0] # inital combo: all 0's (first element of each set)
# emit the first combination
yield tuple(sets[i][x] for i, x in enumerate(c))
# incrementally update combination in Gray code order
has_next = True
while has_next :
# look for the smallest index to increment/decrement
has_next = False
for j in range(n-1,-1,-1) :
if p[j] : # currently moving forward..
if c[j] < s[j] :
c[j] += 1
has_next = True
# emit affected set (forward direction)
yield j
else : # ..moving backward
if c[j] > 0 :
c[j] -= 1
has_next = True
# emit affected set (reverse direction)
yield -j
# we did manage to increment/decrement at position j..
if has_next :
# emit the combination
yield tuple(sets[i][x] for i, x in enumerate(c))
for q in range(n-1,j,-1) : # cascade
p[q] = not p[q]
break
Trying to tease out as much performance as I could in just computing this sequence --- since the number of elements in the Cartesian product of a set of sets grows exponentially with the number of sets (of size 2 or more) --- I implemented this in C. What it essentially does, is implement the above-mentioned index_changed (using a slightly different notation):
(Disclaimer: there is much room for optimization here)
void gray_code_sequence(int s[], int n) {
// set up parity array
int p[n];
for(int i = 0; i < n; ++i) {
p[i] = 1; // 1: move forward, (1: move backward)
}
// initialize / emit first combination
int c[n];
printf("(");
for(int i = 0; i < n-1; ++i) {
c[i] = 0; // initial combo: all 0s (first element of each set)
printf("%d, ", c[i]); // emit the first combination
}
c[n-1] = 0;
printf("%d)\n", c[n-1]);
int has_next = 1;
while(has_next) {
// look for the smallest index to increment/decrement
has_next = 0;
for(int j = n-1; j >= 0; --j) {
if(p[j] > 0) { // currently moving forward..
if(c[j] < s[j]) {
c[j] += 1;
has_next = 1;
printf("%d\n", j);
}
}
else { // ..moving backward
if(c[j] > 0) {
c[j] -= 1;
has_next = 1;
printf("%d\n", -j);
}
}
if(has_next) {
for(int q = n-1; q > j; --q) {
p[q] = -1 * p[q]; // cascade
}
break;
}
}
}
}
When compared to the above python (where the yielding of the elements of the Cartesian product is suppressed, and only the elements of the sequence are yielded, so that the output is essentially the same, for a fair comparison), this C implementation seems to be about 15 times as fast, asymptotically.
Again this C code could be highly optimized (the irony that python code is so C-like being well-noted), for example, this parity array could stored in a single int type, performing bit shift >> operations, etc., so I bet that even a 30 or 40x speedup could be achieved.
Please need your help, I got one failed test case due to time out if anyone can help me to improve the time taken by code to be executed. This problem is from HackerRank website if anyone needs more explanation I will refer the link of the problem in the comments below
from itertools import combinations
def powerSum(X, N,n=1,poss=[]):
if(n**N <= X):
poss.append(n)
n+=1
rslt = powerSum(X,N,n,poss)
else:
tmp=[]
for _ in range(len(poss)):
oc=combinations(poss,_+1)
for x in oc:
ok = sum([num**N for num in x])
if(ok == X):
tmp.append(ok)
return len(tmp)
return rslt
I am not good in python, but I hope below java code can be easily understood, This is a indirectly a variation of subset sum problem which is a dynamic programming problem where you have to find no. of ways to get a given particular sum given an array of values,so basically before applying subset problem, I have made a list of number which can be used in making the required sum by stopping at that number whose kth power exceed the x because starting from that natural number, further natural number are going to have much larger kth power value so no need of keeping them in our list so break there then it is just a dynamic programming problem as mentioned above where our list has value of kth power of valid natural number and we have to find the different way to get the sum x using those kth power values.
below is the code for more clear understanding
import java.util.*;
public class Main {
public static int find_it(int x , int n , List<Integer> a , int [][] dp){
for(int i = 0; i < n; ++i){
dp[i][0] = 1;
}
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= x; ++j){
dp[i][j] += dp[i - 1][j];
if(j - a.get(i - 1) >= 0){
dp[i][j] += dp[i - 1][j - a.get(i - 1)];
}
}
}
return dp[n][x];
}
public static void main(String [] args){
Scanner input = new Scanner(System.in);
int x = input.nextInt() , k = input.nextInt();
List<Integer> a = new ArrayList<>();
for(int i = 1; ; ++i){
double value = Math.pow(i , k);
if(value > x){
break;
}
a.add((int)value);
}
int n = a.size();
int [][]dp = new int[n + 1][x + 1];
int answer = find_it(x , n , a , dp);
System.out.println(answer);
input.close();
}
}
For example, if L = [1,4,2,6,4,3,2,6,3], then we want 1 as the unique element. Here's pseudocode of what I had in mind:
initialize a dictionary to store number of occurrences of each element: ~O(n),
look through the dictionary to find the element whose value is 1: ~O(n)
This ensures that the total time complexity then stay to be O(n). Does this seem like the right idea?
Also, if the array was sorted, say for example, how would the time complexity change? I'm thinking it would be some variation of binary search which would reduce it to O(log n).
You can use collections.Counter
from collections import Counter
uniques = [k for k, cnt in Counter(L).items() if cnt == 1]
Complexity will always be O(n). You only ever need to traverse the list once (which is what Counter is doing). Sorting doesn't matter, since dictionary assignment is always O(1).
There is a very simple-looking solution that is O(n): XOR elements of your sequence together using the ^ operator. The end value of the variable will be the value of the unique number.
The proof is simple: XOR-ing a number with itself yields zero, so since each number except one contains its own duplicate, the net result of XOR-ing them all would be zero. XOR-ing the unique number with zero yields the number itself.
Your outlined algorithm is basically correct, and it's what the Counter-based solution by #BrendanAbel does. I encourage you to implement the algorithm yourself without Counter as a good exercise.
You can't beat O(n) even if the array is sorted (unless the array is sorted by the number of occurrences!). The unique element could be anywhere in the array, and until you find it, you can't narrow down the search space (unlike binary search, where you can eliminate half of the remaining possibilities with each test).
In the general case, where duplicates can be present any number of times, I don't think you can reduce the complexity below O(N), but for the special case outlined in dasblinkenlight's answer, one can do better.
If the array is already sorted and if duplicates are present an even number of times as is the case in the simple example shown, you can find the unique element in O(log N) time with a binary search. You will search for the position where a[2*n] != a[2*n+1]:
size_t find_unique_index(type *array, size_t size) {
size_t a = 0, b = size / 2;
while (a < b) {
size_t m = (a + b) / 2;
if (array[2 * m] == array[2 * m + 1]) {
/* the unique element is the the right half */
a = m + 1;
} else {
b = m;
}
}
return array[2 * m];
}
You can use variation of binary search if you have array is already sorted. It will reduce your cost to O(lg N). You just have to search left and right appropriate position. Here is the C/C++ implementation of your problem.(I am assuming array is already sorted)
#include<stdio.h>
#include<stdlib.h>
// Input: Indices Range [l ... r)
// Invariant: A[l] <= key and A[r] > key
int GetRightPosition(int A[], int l, int r, int key)
{
int m;
while( r - l > 1 )
{
m = l + (r - l)/2;
if( A[m] <= key )
l = m;
else
r = m;
}
return l;
}
// Input: Indices Range (l ... r]
// Invariant: A[r] >= key and A[l] > key
int GetLeftPosition(int A[], int l, int r, int key)
{
int m;
while( r - l > 1 )
{
m = l + (r - l)/2;
if( A[m] >= key )
r = m;
else
l = m;
}
return r;
}
int CountOccurances(int A[], int size, int key)
{
// Observe boundary conditions
int left = GetLeftPosition(A, 0, size, key);
int right = GetRightPosition(A, 0, size, key);
return (A[left] == key && key == A[right])?
(right - left + 1) : 0;
}
int main() {
int arr[] = {1,1,1,2,2,2,3};
printf("%d",CountOccurances(arr,7,2));
return 0;
}
I would like to have a function get_permutation that, given a list l and an index i, returns a permutation of l such that the permutations are unique for all i bigger than 0 and lower than n! (where n = len(l)).
I.e. get_permutation(l,i) != get_permutation(l,j) if i!=j for all i, j s.t. 0 <= i and j < len(l)!).
Moreover, this function has to run in O(n).
For example, this function would comply the with the requirements, if it weren't for the exponential order:
def get_permutation(l, i):
return list(itertools.permutations(l))[i]
Does anyone has a solution for the above described problem?
EDIT: I want the permutation from the index NOT the index from the permutation
If you don't care about which permutations get which indices, an O(n) solution becomes possible if we consider that arithmetic operations with arbitrary integers are O(1).
For example, see the paper "Ranking and unranking permutations in linear time" by Wendy Myrvold and Frank Ruskey.
In short, there are two ideas.
(1) Consider Fisher-Yates shuffle method to generate a random permutation (pseudocode below):
p = [0, 1, ..., n-1]
for i := 0 upto n-1:
j := random_integer (0, i)
exchange p[i] and p[j]
This transform is injective: if we give it a different sequence of random integers, it is guaranteed to produce a different permutation. So, we substitute random integers by non-random ones: the first one is 0, the second one 0 or 1, ..., the last one can be any integer from 0 to n-1.
(2) There are n! permutations of order n. What we want to do now is to write an integer from 0 to n!-1 in factorial number system: the last digit is always 0, the previous one is 0 or 1, ..., and there are n possibilities from 0 to n-1 for the first digit. Thus we will get a unique sequence to feed the above pseudocode with.
Now, if we consider division of our number by an integer from 1 to n to be O(1) operation, transforming the number to factorial system is O(n) such divisions. This is, strictly speaking, not true: for large n, the number n! contains on the order of O(n log n) binary digits, and that division's cost is proportional to the number of digits.
In practice, for small n, O(n^2) or O(n log n) methods to rank or unrank a permutation, and also methods requiring O(2^n) or O(n!) memory to store some precomputed values, may be faster than an O(n) method involving integer division, which is a relatively slow operation on modern processors.
For n large enough so that the n! does not fit into a machine word, the "O(n) if order-n! integer operations are O(1)" argument stops working. So, you may be better off for both small and large n if you don't insist on it being theoretically O(n).
Based on http://www.2ality.com/2013/03/permutations.html here's a possible solution. As #Gassa pointed out, elements.pop is not constant in order, and hence the solution is not linear in the length of the list. Therefore, I won't mark this as an accepted answer. But, it does the job.
def integerToCode(idx, permSize):
if (permSize <= 1):
return [0]
multiplier = math.factorial(permSize-1)
digit =idx / multiplier
return [digit] + integerToCode(idx % multiplier, permSize-1)
def codeToPermutation(elements, code):
return map(lambda i: elements.pop(i), code)
def get_permutation(l, i):
c = integerToCode(i, len(l))
return codeToPermutation(list(l), c)
Update: possible dupe of Finding n-th permutation without computing others, see there for algorithm.
If len(l) will be small, you could precompute perm_index = permutations(range(len(l))) and use it as a list of lists of indexes into your actual data.
Moreover, if you have a list of permutations from range(len(l)) and you need one for for range(len(l) - 1) you can do something like:
[x - 1 for x in perm_index[i][1:]]
Which takes advantage of the fact that the permutations are in sorted order when generated.
This solution works in O(1) (runtime complexity; amortised cost for dictionary lookups):
Code
#!/usr/bin/env python
import itertools
def get_permutation():
memoize = {}
def _memoizer(l, i):
if str(l) in memoize and i not in memoize[str(l)]:
memoize[str(l)][i] = memoize[str(l)]['permutations'].next()
else:
p = itertools.permutations(l)
memoize[str(l)] = {'permutations': p}
memoize[str(l)][i] = memoize[str(l)]['permutations'].next()
return memoize[str(l)][i]
return _memoizer
if __name__ == '__main__':
get_permutation = get_permutation()
l1 = list(range(10))
l2 = list(range(5))
print(get_permutation(l1, 1))
print(get_permutation(l1, 20))
print(get_permutation(l2, 3))
Output
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
(0, 1, 2, 3, 4, 5, 6, 7, 9, 8)
(0, 1, 2, 3, 4)
How it works
The code stores all past calls in a dictionary. It also stores the permutation object(s). So in case a new permutation gets requested, the next permutation is used.
The code uses itertools.permutations
A bit too late... C# code that should give you the result you expect:
using System;
using System.Collections.Generic;
namespace WpfPermutations
{
public class PermutationOuelletLexico3<T>
{
// ************************************************************************
private T[] _sortedValues;
private bool[] _valueUsed;
public readonly long MaxIndex; // long to support 20! or less
// ************************************************************************
public PermutationOuelletLexico3(T[] sortedValues)
{
if (sortedValues.Length <= 0)
{
throw new ArgumentException("sortedValues.Lenght should be greater than 0");
}
_sortedValues = sortedValues;
Result = new T[_sortedValues.Length];
_valueUsed = new bool[_sortedValues.Length];
MaxIndex = Factorial.GetFactorial(_sortedValues.Length);
}
// ************************************************************************
public T[] Result { get; private set; }
// ************************************************************************
/// <summary>
/// Return the permutation relative to the index received, according to
/// _sortedValues.
/// Sort Index is 0 based and should be less than MaxIndex. Otherwise you get an exception.
/// </summary>
/// <param name="sortIndex"></param>
/// <param name="result">Value is not used as inpu, only as output. Re-use buffer in order to save memory</param>
/// <returns></returns>
public void GetValuesForIndex(long sortIndex)
{
int size = _sortedValues.Length;
if (sortIndex < 0)
{
throw new ArgumentException("sortIndex should be greater or equal to 0.");
}
if (sortIndex >= MaxIndex)
{
throw new ArgumentException("sortIndex should be less than factorial(the lenght of items)");
}
for (int n = 0; n < _valueUsed.Length; n++)
{
_valueUsed[n] = false;
}
long factorielLower = MaxIndex;
for (int index = 0; index < size; index++)
{
long factorielBigger = factorielLower;
factorielLower = Factorial.GetFactorial(size - index - 1); // factorielBigger / inverseIndex;
int resultItemIndex = (int)(sortIndex % factorielBigger / factorielLower);
int correctedResultItemIndex = 0;
for(;;)
{
if (! _valueUsed[correctedResultItemIndex])
{
resultItemIndex--;
if (resultItemIndex < 0)
{
break;
}
}
correctedResultItemIndex++;
}
Result[index] = _sortedValues[correctedResultItemIndex];
_valueUsed[correctedResultItemIndex] = true;
}
}
// ************************************************************************
/// <summary>
/// Calc the index, relative to _sortedValues, of the permutation received
/// as argument. Returned index is 0 based.
/// </summary>
/// <param name="values"></param>
/// <returns></returns>
public long GetIndexOfValues(T[] values)
{
int size = _sortedValues.Length;
long valuesIndex = 0;
List<T> valuesLeft = new List<T>(_sortedValues);
for (int index = 0; index < size; index++)
{
long indexFactorial = Factorial.GetFactorial(size - 1 - index);
T value = values[index];
int indexCorrected = valuesLeft.IndexOf(value);
valuesIndex = valuesIndex + (indexCorrected * indexFactorial);
valuesLeft.Remove(value);
}
return valuesIndex;
}
// ************************************************************************
}
}
I have a working algorithm in Python which I want to convert to C++:
def gcd(a, b):
if (a % b == 0):
return b
else:
return gcd(b, a % b)
def solution(N, M):
lcm = N * M / gcd(N, M)
return lcm / M
I'm having a problem with large input values as the multiple of N and M causes integer overflow and using long to store its value doesn't seem to help, unless I'm doing something wrong.
Here's my current code:
int gcd(int a, int b)
{
if (a % b == 0)
return b;
else
return gcd(b, a % b);
}
int solution(int N, int M) {
// Calculate greatest common divisor
int g = gcd(N, M);
// Calculate the least common multiple
long m = N * M;
int lcm = m / g;
return lcm / M;
}
You are computing g=gcd(N,M), then m=N*M, then lcm=m/g, and finally returning lcm/M. That's the same as returning N/gcd(N,M). You don't need those intermediate calculations. Get rid of them. Now there's no problem with overflow (unless M=0, that is, which you aren't protecting against).
int solution(int N, int M) {
if (M == 0) {
handle_error();
}
else {
return N / gcd(N,M);
}
}
To begin with, change:
long m = N * M;
int lcm = m / g;
To:
long long m = (long long)N * M;
int lcm = (int)(m / g);
In general, you might as well change every int in your code to unsigned long long...
But if you have some BigInt class at hand, then you might want to use it instead.
Here is one for free: http://planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=9735&lngWId=3
It stores a natural number of any conceivable size, and supports all arithmetic operators provided in C++.
The problem is in long m = N*M.
The multiplication takes place as 32 bit integers only. Since both are of int type, overflow occurs.
Correction is long long m = (long long)N*M