Is there anyway of finding combinations bounded to particular binary numbers? - arrays

Lets say we have an array of 4 binary numbers i.e [1,0,0,0].
So, this means we do have 4 unique combinations using the formula, (m+n)! / (m! * n!),
Where m is the total number of 1's in that array and n is the total number of 0's in that array.
Now, How can we generate the four unique combinations ?
[ PS: considering dynamic input array containing only 1's and 0's ]

It should work.
Started from here:
https://www.geeksforgeeks.org/write-a-c-program-to-print-all-permutations-of-a-given-string/
I added a little piece of code to avoid duplicates.
func permute<T : Comparable>(a: inout [T], l: Int, r: Int, permutations: inout [[T]])
{
// Base case
if l == r
{
if !permutations.contains(a)
{
permutations.append(a)
}
}
else
{
// Permutations made
for i in l...r
{
// Swapping done
a.swapAt(l, i)
// Recursion called
permute(a: &a, l: l+1, r: r, permutations: &permutations)
//backtrack
a.swapAt(l, i)
}
}
}
var array = [1, 0, 0, 0, 1]
var permutations = [[Int]]()
permute(a: &array, l: 0, r: array.count - 1, permutations: &permutations)
permutations.forEach { (permutazio) in
print(permutazio)
}

Related

Variant on Sequence-Based enumeration of permutations

This is a follow up on this thread, which main issue was to iterate over all permutations of an array, that is given ["a","b","c"], obtain ["bca","acb".. etc], using an iterator.
Thanks to Martin R's insights, and also his inputs in another thread, I came up with another possible solution for the 'Sequence-Based enumeration of permutations' problem using iterators. The issue is that I'm not sure I have all permutations although there are good indications they're all there. The algorithm is guaranteed to provide n! permutations at the most, with no duplicates.
The idea behind this approach is the following, say there's an array a=["a","b","c"...], of size n. Listing all permutations can be viewed as picking elements from bags:
■
■
■
■ ■
■ ■ ■
■ ... ■ ■ ■
0 ... n-3 n-2 n-1
So the algorithm takes the initial array, and removes a row, pass it recursively until there is no row left. At this point, if an iterator can be found, all individual permutations can be addressed independently. The iterator is hidden in FactorialSequence below, where a method next() allows to move from adjacents points.
public struct FactorialSequence : Sequence, IteratorProtocol {
private var current: [Int]
public init(size:Int) {
self.current = Array(repeating: 0, count: size)
}
public mutating func next() -> [Int]? {
return self.__next();
}
private mutating func __next() -> [Int]? {
var next = current
defer {
current = next;
}
for i in self.current.indices.reversed() {
if next[i] < current.count - i - 1 {
next[i] += 1
return next;
}
next[i] = 0
}
return nil
}
}
func permute(seq:[String],at:[Int]) -> String? {
if seq.count > 0 {
var ss = seq;
let uu = seq[at.first!]
var cc = at;
_ = ss.remove(at: cc.first!)
_ = cc.remove(at: 0);
return uu + (permute(seq:ss,at:cc) ?? "")
}
return nil ;
}
the permute() function is called passing the iterator (an array) calculated from FactorialSequence:
var fs = FactorialSequence(size: 3)
print("\(fs.current):\(permute(seq:["a","b","c"], at: fs.current)!)")
while let uu = fs.next() {
print("\(uu):\(permute(seq:["a","b","c"], at: uu)!)")
}
and gives (in flatten string format):
[-0.000][-0.000][171] [0, 0, 0]:abc
[0.0009][0.0009][174] [0, 1, 0]:acb
[0.0016][0.0007][174] [1, 0, 0]:bac
[0.0024][0.0008][174] [1, 1, 0]:bca
[0.0032][0.0008][174] [2, 0, 0]:cab
[0.0040][0.0008][174] [2, 1, 0]:cba
Note on 'no duplicates': Since permutations are accessed using an array (the iterator), if two iterators differ by one elements, they point to two different permutations. Although a little thin, I take this as an argument for not having duplicates.
The only question remaining is 'are they all there?'. One could say that there are n! distinct arrays pointing at a given permutation, but I'm not too sure about the validity of that argument, since it comes from a 'drawing'... Pointers welcome.
I didn't thoroughly scrub SO to check if this had been already formulated this way or in a similar way (although links in the original thread use other approaches). Apologies if it did.
For a given size N the FactorialSequence produces a sequence of all arrays
[ i.0, i.1, ..., i.(N-1) ]
such that
0 <= i.0 < N, 0 <= i.1 < N-1, ..., 0 <= i.(N-1) < 1
that are exactly
N * (N-1) * ... * 1 = N!
elements. The permute() function then picks the element with index i.0
from the given array with N elements, then the element with i.1 from
the remaining N-1 elements, and so on.
So yes, this indeed produces all possible permutations of the array.
However, the code can be simplified a bit. First, FactorialSequence
does not return the initial array [ 0, ..., 0 ], corresponding to
the identity permutation. Also the separate __next() method seems
unnecessary.
If we change the code to
public struct FactorialSequence : Sequence, IteratorProtocol {
private var current: [Int]
private var firstIteration = true
public init(size:Int) {
self.current = Array(repeating: 0, count: size)
}
public mutating func next() -> [Int]? {
if firstIteration {
firstIteration = false
return current
}
for i in self.current.indices.reversed() {
if current[i] < current.count - i - 1 {
current[i] += 1
return current;
}
current[i] = 0
}
return nil
}
}
then all permutations are returned (including the initial identity), and
the defer statement is no longer necessary.
The permute() function can be simplified slightly, and made generic:
func permute<E>(array: [E], at: [Int]) -> [E] {
if at.isEmpty { return [] }
var at = at
var array = array
let firstIndex = at.remove(at: 0)
let firstElement = array.remove(at: firstIndex)
return [firstElement] + permute(array: array, at: at)
}
Now
let array = ["a", "b", "c"]
let fs = FactorialSequence(size: 3)
for p in fs {
print(permute(array: array, at: p).joined())
}
produces the expected output.
Note however that permute() produces a lot of intermediate arrays,
therefore I assume it to be less efficient than the other methods
that you referenced.
An alternative would be to swap the picked element to its new
place, this avoids recursion and temporary arrays:
func permute<E>(array: [E], at: [Int]) -> [E] {
var result = array
for (i, j) in at.enumerated() {
result.swapAt(i, i + j)
}
return result
}
(It produces the permutations in a different order, though.)

How to create n strings of random lengths the sum of which is equal to a given amount?

I'm trying to create an algorithm to create n strings of random length the sum of which is equal to a given amount.
An example to make it clearer:
total = 20;
n = 7;
strings = ['aaaa', 'a', 'aaaaaaa', 'aa', 'aaa', 'aa', 'a'];
So I have 7 strings of random lengths and the sum of their individual lengths is (unless I made an error counting) 20.
Till now I came up with this recursive function:
gaps = [];
function createGapsArray(total, n) {
if (n == 1) {
var gapLength = total;
} else {
var gapLength = getRandomInt(1, total / 2);
}
var gap = "";
for (var i = 0; i < gapLength; i++) {
gap += "a";
}
gaps.push(gap);
if (n > 1 && total > 0) {
createGapsArray(total - gapLength, --n);
}
}
Which doesn't really work. Usually it finishes before generating all the n segments I want. With the few tests that I've done, it seems that dividing the total by 4 instead of 2, gets the job done. Like:
var gapLength = getRandomInt(1, total / 4);
But the choice of this constraint is just arbitrary. I'm wondering if there is a better approach to this.
Also, I'm aware that with my approach the algorithm is likely to generate longer segments at first and smaller ones towards the end. I wouldn't mind an even distribution, but it's not a big deal because for what I need it I can simply shuffle the array once it's done.
This is a similar problem to "find a random collection of k numbers whose sum is N". The original version of this answer used a simple solution which is unbiased if the numbers are continuous (i.e. floating point): generate k-1 numbers in the range [0, N], sort them, put 0 at the beginning and N at the end, and then find the differences between successive elements. But since there are no fractional characters, we need the numbers to be integers and the above algorithm is biased against collections which include 0 (there is an infinitesimal probability of getting 0 in the continuous case, but it is significant in the discrete case).
An unbiased solution for generating non-empty integer solutions is to find a random (k-1)-combination of the integers in the inclusive range [1, N-1]. To find the random combination use the first k-1 elements of a random shuffle of the range (using the Fisher-Yates shuffle). The combination is then sorted (if necessary) and a 0 prepended; these values are the starting positions of each string (so that the next value is the ending position.)
That will not produce empty substrings, since each substring has a unique starting point. To include empty substrings, use the above with N+k instead of N, and then shrink every range by 1: if the indices are sorted, you can do that by subtracting i from the ith index.
In Python:
from random import sample
def random_split(str, k):
v = [0] + sorted(sample(range(1, len(str)), k-1)) + [len(str)]
return [str[v[i]:v[i+1]] for i in range(k)]
def random_split_allow_empty(str, k):
v = [0] + sorted(sample(range(1, len(str)+k), k-1)) + [len(str)+k]
return [str[v[i]-i:v[i+1]-i-1] for i in range(k)]
In Javascript:
function shuffle(vec, k) {
for (let i = 0; i < k; ++i) {
let r = i + Math.floor(Math.random() * (vec.length - i));
let t = vec[r];
vec[r] = vec[i];
vec[i] = t;
}
return vec;
}
function random_partition(N, k) {
let v = [];
for (let i = 1; i < N; ++i) v[i-1] = i;
shuffle(v, k - 1);
v[k-1] = 0;
return v.slice(0, k).sort((a,b)=>a-b);
}
function random_split(s, k) {
return random_partition(s.length, k).map(
(v, i, a) => s.slice(v, a[i+1]));
}
function random_split_allow_empty(s, k) {
return random_partition(s.length + k, k).map((v,i)=>v-i).map(
(v, i, a) => s.slice(v, a[i+1]));
}
Strictly speaking, you can't do this, because you're adding constraints to at least the last "string" that violate the desired randomness property. Of course, how strictly you need to interpret the requirement for randomness depends largely on what you're doing in the bigger problem domain.
What you could do instead, is start with an initial string of the desired length, and then iteratively generate a random split point until you have the desired number of fragments. To be truly random, you'd have to allow for some of those fragments to be empty (e.g. what happens if you randomly pick a single-character fragment to split?), but that could probably be worked around without doing too much violence to the randomness of the overall result...
The way to think of it is as having string of characters of length equal to total. I'll use 20 as an example:
string: aaaaaaaaaaaaaaaaaaaa
index: 01234567890123456789
You then generate N-1 random numbers between 0 and total that correspond to the positions that you should cut the string to generate N different strings.
Lets say the numbers are 5, 8, 13, 15, 1, 3. These will be the indices to cut the string:
string: a aa aa aaa aaaaa aa aaaaa
index: 0|12|34|567|89012|34|56789
This is the same as generating N-1 random numbers, sorting them, adding 0 at the beginning of the list and total at the end, and taking the difference:
var numbers = [0];
for (var i = 0; i < N-1; i++) numbers.push(getRandomInt(0, total));
numbers.push(total);
numbers.sort();
var strings = [];
for (var i = 0; i < N; i++)
strings.push(new Array(numbers[i + 1] - numbers[i]).join('a'));
This will give a uniform distribution.
Note that if you want only non-empty strings there should be no duplicate random values.

Swift - speed and efficiency of higher order functions (reduce)

Quick question please about the efficiency of higher order swift functions with large input data. During a recent test I had a question about finding 'equlibirum indexes' in arrays- i.e. the index of an array where the sum of all elements below the index equals the sum of all elements above the index
An equilibrium index of this array is any integer P such that 0 ≤ P <
N and the sum of elements of lower indices is equal to the sum of
elements of higher indices, i.e.
A[0] + A[1] + ... + A[P−1] = A[P+1] + ... + A[N−2] + A[N−1].
The challenge was to write a short function which computed the first (or any) index which was considered 'equilibirum'.
I put together a simple snippet which scored highly but failed some of the 'performance' tests which used large input data (array sizes around 100,000).
Here's the code
public func solution(inout A : [Int]) -> Int {
var index = 0;
for _ in A {
let sumBefore = A[0...index].reduce(0) { $0 + $1 }
let sumAfter = A[index...A.count-1].reduce(0) { $0 + $1 }
if (sumBefore == sumAfter) { return index; }
index += 1;
}
return -1;
}
Would anyone please be able to explain why the code performs so poorly with large sets of data, or any recommended alternatives?
Here, for example is a description of a failing perfomance test:
Large performance test, O(n^2) solutions should fail.
✘ TIMEOUT ERROR
running time: >6.00 sec., time limit: 0.22 sec.
It looks like the challenge is failing because your solution is O(n^2).
Your for loop, along with 2 sequential reduces inside, make your solution ~ O(2*n^2) since reduce goes through all the elements again.
A simpler solution is to first compute the whole sum, and then iterate through the elements once, subtracting each value from the whole sum, one by one, thus having access to the left and right sums, for comparison.
Using Swift 3.0, Xcode 8:
func findEquilibriumIndex(in array: [Int]) -> Int? {
var leftSum = 0
var rightSum = array.reduce(0, combine: +)
for (index, value) in array.enumerated() {
rightSum -= value
if leftSum == rightSum {
return index
}
leftSum += value
}
return nil
}
let sampleArray = [-7, 1, 5, 2, -4, 3, 0]
findEquilibriumIndex(in: sampleArray)
The problem is not that "the built-in functions perform so poorly."
Your solution is slow because in each iteration, N elements are
added (N being the length of the array). It would be more efficient
to compute the total sum once and update the "before sum"
and "after sum" while traversing through the array. This reduces
the complexity from O(N^2) to O(N):
public func solution(A : [Int]) -> Int {
var sumBefore = 0
var sumAfter = A.reduce(0, combine: +)
for (idx, elem) in A.enumerate() {
sumAfter -= elem
if sumBefore == sumAfter {
return idx
}
sumBefore += elem
}
return -1
}
(Swift 2.2, Xcode 7.3.1)
Remarks:
There is no reason to pass the array as inout parameter.
An operator (in this case +) can be passed as a argument to the reduce() function.
enumerate() returns a sequence of array indices together with
the corresponding element, this saves another array access.
Note also that a more "Swifty" design would be to make the return type
an optional Int? which is nil if no solution was found.
The incrementalSums extension
If you define this extension
extension Array where Element : SignedInteger {
var incrementalSums: [Element] {
return Array(reduce([0]) { $0.0 + [$0.0.last! + $0.1] }.dropLast())
}
}
given an array of Int(s) you can build an array where the Int at the n-th position represents the sum of the values from 0 to (n-1) in the original array.
Example
[1, 2, 3, 10, 2].incrementalSums // [0, 1, 3, 6, 16]
The equilibriumIndex function
Now you can build a function like this
func equilibriumIndex(nums: [Int]) -> Int? {
let leftSums = nums.incrementalSums
let rightSums = nums.reversed().incrementalSums.reversed()
return Array(zip(leftSums, rightSums)).index { $0 == $1 }
}
Here is a functional version of the solution in Swift 3
let total = sampleArray.reduce(0,+)
var sum = 0
let index = sampleArray.index{ v in defer {sum += v}; return sum * 2 == total - v }
If I understand correctly the element at the resulting index is excluded from the sum on each side (which I'm not certain the other solutions achieve)

Easy way to check an array for contiguous three or more numbers in Swift

Is there any easy way to check if an array contains contiguous value of three or more? e.g. [4, 2, 1, 1, 1, 7, 4, 4, 4, 4] contains two contiguous sequence of 1 and 4. To check I wish to give 1 and minimum allowed conjugation, in this case 2, it will just return true. Thanks.
We can start out by making use of a neat extension to SequenceType by user #oisdk in his answer in the following thread:
How to find same value(duplicate) in an int array in order?
The extension groups successive elements in tuples (value, numberOfSuccessions):
/* from SO user #oisdk:s answer in Q&A:
https://stackoverflow.com/a/35325141/4573247 */
extension SequenceType where Generator.Element: Equatable {
func group() -> [(Generator.Element, Int)] {
var res: [(Generator.Element, Int)] = []
for el in self {
if res.last?.0 == el {
res[res.endIndex-1].1 += 1
} else {
res.append((el,1))
}
}
return res
}
}
Using this, we can swiftly write another extension for checking if---for a given array---a contiguous sequence (for some minimum number of successions/repeats) exists for a given number:
extension SequenceType where Generator.Element == Int {
func containsContiguousValue(value: Int, forMinimumRepeats rep: Int) -> Bool {
return !self
.group()
.contains{ (val, count) in count >= rep && val == value }
}
}
Used as follows
/* Example usage */
let array = [4, 2, 1, 1, 1, 7, 4, 4, 4, 4]
array.containsContiguousValue(1, forMinimumRepeats: 3) // true
array.containsContiguousValue(1, forMinimumRepeats: 4) // false
array.containsContiguousValue(4, forMinimumRepeats: 4) // true
array.containsContiguousValue(2, forMinimumRepeats: 3) // false
I think the simplest possible way is with the help of the reduce function. If you want you can extend the data structures, but I am not quite a fan of that. So here is a simple solution to your example
// example array
let a = [4, 2, 1, 1, 1, 7, 4, 4, 4, 4]
let minRepeats = 3 // desired min repeats
let elementToCheck = 4 // element to check
let m = a.reduce(0) { (initial: Int, el: Int) -> Int in
if initial >= minRepeats {
return initial
} else {
return el == elementToCheck ? initial + 1 : 0
}
}
// if m == minRepeats the check is positive, if m < minRepeats the check is negative
// let check = a.reduce(0){...} == minRepeats gives you the right result
// Thanks to user3441734 for the correction
The answers above were helpful but not quite as generic as I needed. Also, they are a little outdated, so for those who come across this requirement, here's a generic reusable Swift 4.2 implementation:
An extension on any Collection that returns an array of ranges representing the indices of consecutive elements in a collection matching a given predicate.
https://gist.github.com/shaps80/8ec24f82ad1e54d42709277ec2af93a3

Issues summing up array using for loop in swift

I'm trying to iterate through an array and sum up all the values using generics like so:
func reduceDaArray <T, U>(a: [T], startingValue: U, summed: (U, T) -> U) -> U {
var sum = 0
for number in a {
sum = sum + number
}
return sum
}
reduceDaArray([2,3,4,5,6], 2, +) //(22)
It's giving me the following errors:
Binary operator '+' cannot be applied to operands of type 'Int' and 'A' with regards to the line sum = sum + number
and
Int is not convertible to 'U' with regards to the line return sum
I know this is accomplished better with the reduce method, but I wanted to complete the task using iteration for this instance to get some practice. Why are these errors occurring? I never explicitly stated that T is an Int.
In your reduceDaArray() function,
var sum = 0
declares an integer instead of using the given startingValue.
And
sum = sum + number
tries to add a generic array element to that integer, instead of using
the given summed closure.
So what you probably meant is
func reduceDaArray <T, U>(a: [T], startingValue: U, summed: (U, T) -> U) -> U {
var sum = startingValue
for number in a {
sum = summed(sum, number)
}
return sum
}
which compiles and works as expected:
let x = reduceDaArray([2, 3, 4, 5, 6], 2, +)
println(x) // 22
let y = reduceDaArray([1.1, 2.2], 3.3, *)
println(y) // 7.986
let z = reduceDaArray(["bar", "baz"], "foo") { $0 + "-" + $1 }
println(z) // foo-bar-baz

Resources