Replace ONLY next to each other duplicates - arrays

How to make replacement of next to each other ONLY false duplicates in array but don't touch the ones that seperate.
From this:
{false, false, false, false, true, true, false, true, false, false};
to this:
{false, true, true, false, true, false}

I think a smart method would be the following.
boolean[] myArray = {false, false, false, false, true, true, false, true, false, false};
// Introduce myArray[0] to your array result.
for (int i = 1; i < myArray.length; i++) {
if (myArray[i-1] || myArray[i]) // Introduce myArray[i] to your array result.
}
You introduce the value if current value is true, or if the last one (controlled by introduce variable) was not false. First element is always introduced, because wether is true or false, the logic problem says to introduce it.
Also, I think it would go faster if you don't short-circuit myArray[i-1] || myArray[i] and let myArray[i-1] | myArray[i]. It is faster to check the second value of the or operation than make the if instruction at the compiler level to see if the first value is already true.

You can check the next element and remove the current false only if next is false.At the same time you can make changes to the same array to remove duplicates.
int index=0;
for(int i=0;i<arr.size()-1;i++)
{
if(arr[i]==false && arr[i+1]==false)
continue;
else //this should exist in array
{
arr[index]=arr[i];
index++;
}
}
arr[index++]=arr[arr.size()-1];//for the last element
//Last element added irrespective of being true or false
//Now you can remove the elements from index to end
std::remove(arr.begin()+index,arr.end());

Using C++ and the standard library:
v.erase(std::unique(v.begin(), v.end(),
[](bool a, bool b){ return !(a||b); }),
v.end());
The standard library std::unique function compresses the collection by overwriting all but the first of a sequence of duplicates. In this case, we use a lambda function in order to avoid counting two consecutive true values as duplicates; only a pair of values such that !(a||b) is true counts, and that expression is only true if both a and b are false. (!a && !b would have worked just as well and very likely generates identical code.)
std::unique returns the end point of the compressed range; it is then necessary (or at least useful) to reduce the size of the container, which is what the erase member function does, assuming that it is implemented for the container v (here, I'm assuming that v is a std::vector but a std::deque or std::list would work as well).
Live on ideone

Related

Algorithm that finds the start and the finish of many sub-arrays?

so I have this question in C:
Given an array that only contains 0's and 1's (Example: [1,1,0,0,0,0,1,0,1,0,1,1]).
I need to find the start of a "ring interval" and the finish of the same "ring interval" (there could be many rings like that, we'll have to store the start and finish of each one in a matrix of 2 columns)
"Silence" is when at least two 0's are next to each other. (in the given array, the sub array [0,0,0,0] is silent.
"Ring interval" is when Silence doesn't occur. (example in the given array, the sub array [1,1] (first 2 values), and the sub array [1,0,1,0,1,1] (the end of the array)).
So we'll have to store [0,1] in the first row of the matrix.
then [6,11]. since the second sub array starts at the 6th index and ends at the 11th.
I can't seem to describe it any better, it's in a different language and quite a bit more complicated than this.. i hope you understand!
Examples:
Array = [0,0,0,0,1,0,1,1,1,0,0,0,1,0,0]
Matrix would be : [4,8] [12,12]
Array = [1,0,0,1,1]
Matrix would be : [0,0] [3,4]
Thank you!
I have a simple algorithm for this that you can quite easily translate to C with a bit of research. You could also translate it to basically any other language as well:
Step 1) create two boolean values. One will be true if there is currently a "silence", the other will be true if the last value seen was a zero. Both of these should be true. If we do not assume that there are infinite zeros before the first element of the array, then there will be problems if the first number in the array is zero.
Step 2) loop over the array and check against one of 2 conditions: a) If you see a 1, set silence to false, previousZero to false. If this 1 breaks a silence, store this value as it is the beginning of your next range. b) If the value is zero and there is not a silence, set previousZero to true. If previousZero was already true, you have reached a silence, so set silence to true and store your beginning position and end position in your output array. Your end position in this situation would be the current position -2 to account for the zeros you just examined
Step 3) once you've looped through the entire array, you need to make sure you didn't end on a valid range. if silence is false, you know you ended on a valid range. store this range in your output array by using the begin value you stored in your loop and the end of the array as the end value.
This algorithm runs in linear time. Here is some pseudo-code to get you started on your implementation in C or whatever you choose.
findRing(Array arr)
bool silence = true, previousZero = true;
int currentBegin = 0, currentEnd = 0;
for( int i = 0; i<arr.length; i++) {
if(arr[i] == 1)
if(silence == true)
currentBegin = i;
silence = false;
previousZero = false;
else if(arr[i] == 0 && silence == false)
if(previousZero)
silence = true;
currentEnd = 1-2;
addToOutput(currentBegin, currentEnd);
else
previousZero = true;
}
if(silence == false)
currentEnd = arr.length - 1;
addToOutput(currentBegin, currentEnd);
I implemented this pseudo-code in C++ and got the same outputs you provided in your examples. It should be easy to implement in C or Matlab as you mentioned and runs in O(n) time.

Give an O(N) algorithm to rearrange a list of true/false so that all false elements precede the true

I have an array of N elements containing only two distinct keys, true and false. I am trying to write an O(N) algorithm to rearrange the list so that all false elements precede the true elements. A specific requirement for this algorithm is that I can only traverse the array once (meaning I can NOT make two traversals over the array; once to count the number of true/false's and another time to assign values into the array). I am also not allowed to create an external temporary array.
Originally I wanted to use counting sort, but realized I could not do this since the requirement for this assignment is that I cannot create an external/temporary array.
Then, since there are only two possible values, I wanted to iterate through once and count them. Then Iterate through a second time and set the ordering (do the sort). However, I cannot do this either because I am only allowed to do one iteration.
So I am on my own trying to implement an algorithm that will iterate only once through the array and sort at the same time. So far what I have come up with is below (this is just an idea written more or less as pseudocode)
array = T T T T F F F F
int len = length of array.
counter = 0
For item in array
counter += 1
If counter <= len/2
if T change to F
else
if F change to T
Right as I completed this, I realized that this only works when all the T values are on one side of the array, and all the F values are on the other.
My question is, can somebody tell me which O(n) sorting algorithm I can use to sort through each item in the array and arrange it so that all of the false elements precede the true?
You can try the idea of the quick sort: walk through the array from the start and the end at the same time, and swap elements that have incorrect order. I.e. if you found true in the left half of the array, swap it with false in the right half.
Cause you have only 2 different values it's enough the single pass.
Example:
bool[] array = ...;
int low = 0;
int high = array.Length - 1;
do
{
while (array[low] == false)
low++;
while (array[high] == true)
high--;
if (low <= high)
{
bool temp = array[low];
array[low] = array[high];
array[high] = temp;
}
}
while (low < high);
This gives you exactly single pass, i.e. O(N).
Keep an index (lastFalseIdx) where to insert a False element. So, initially it is 0. Traverse the array from left to right, and if False found, swap it with element at lastFalseIdx, and increment the index.
Python (almost pseudo-code):
arr = [True, True, False, False, False, True]
print arr
lastFalseIdx = 0
for idx, val in enumerate(arr):
if val == False:
arr[lastFalseIdx], arr[idx] = arr[idx], arr[lastFalseIdx] # swap elements
lastFalseIdx = lastFalseIdx + 1
print arr
Demo
Here is a partial solution that constructs the correct output in a separate array. You can infer an inline implementations by observing what happens when you initialize output = input instead.
#!/usr/bin/python
input = [False, True, False, False, True, True, False, True, False]
def sort2(input):
i_false = 0
i_true = len(input) - 1
output = [None] * len(input)
for (i, val) in enumerate(input):
if val:
output[i_true] = True
i_true -= 1
else:
output[i_false] = False
i_false += 1
return output
print sort2(input)
After a single forward pass through the array, you have the desired output.
Concisely:
swap = 0
for index in range(len(list)):
if list[index] != true:
list[index], list[swap] = list[swap], list[index]
swap += 1
hope the below answer helps.
internal void ArrangeBooleanArray()
{
bool[] inputArray = {false, true, true, false};
int arrayLength = inputArray.Length;
bool[] outputArray = new bool[arrayLength];
int trueCount = 0;
int falseCount = 0;
foreach (var item in inputArray)
{
if (item == true)
{
trueCount++;
outputArray[arrayLength - trueCount] = item;
}
else
{
outputArray[falseCount] = item;
falseCount++;
}
}
}

Picking a random element from an array with exceptions

I'm trying to pick a random element from an array with exceptions.
For example let's say I have a boolean array with length 10, 2 of these are set to true at a random index. How can I select a random false boolean and set it to true?
I hope this isn't too vague, English isn't my first language.
There are a ton of ways to do this. Two main approaches that occur to me:
You could use a while loop that picked a random index until it found one that was false:
boolean[] array = {false, true, false};
int index = int(random(array.length));
while(array[index]){
index = int(random(array.length));
}
Or you could create a new array (or ArrayList) from just the indexes that are false, then randomly pick from that array:
boolean[] array = {false, true, false};
ArrayList<Integer> indexes = new ArrayList<Integer>();
for(int i = 0; i < array.length; i++){
if(!array[i]){
indexes.add(i);
}
}
int index = indexes.get(int(random(indexes.size())));
Note that you've tagged your question with the processing tag, so I'm using Processing syntax here. But these approaches are valid in a general sense as well.

How do I initialize an array without using a for loop in Go?

I have an array A of boolean values, indexed by integers 0 to n, all initially set to true.
My current implementation is :
for i := 0; i < n; i++ {
A[i] = true
}
Using a for loop is the simplest solution. Creating an array or slice will always return you a zeroed value. Which in case of bool means all values will be false (the zero value of type bool).
Note that using a Composite literal you can create and initialize a slice or array, but that won't be any shorter:
b1 := []bool{true, true, true}
b2 := [3]bool{true, true, true}
If you don't want to use a for loop, you can make it a little shorter by introducing a constant for the value true:
const T = true
b3 := []bool{T, T, T}
If n is big, for is the simplest solution.
Or you could switch the logic of your application, and use the array or slice to store the negated values in the slice, and that way the "all-false" zero value would be a good initial value. What I mean is that if your slice is to store if files are present, you could change the logic so the slice stores whether files are missing:
presents := []bool{true, true, true, true, true, true}
// Is equivalent to:
missings := make([]bool, 6) // All false
// missing=false means not missing, means present)
Also note that filling an array or slice with a specific value is known as a "memset" operation. Go does not have a builtin function for that, but for an efficient solution see this question:
Is there analog of memset in go?
Make initilization using range function without knowing the number of elements in the array.
for i,_:=range(A){A[i] = true}

Search if a specific attribute in all the elements of an array match a condition

I'm working with Swift, SpriteKit and Xcode 6,
I have an array of a SKSpriteNode class :
class EnemyVehicle: SKSpriteNode {
}
var vehicles = [EnemyVehicle]()
So I can add elements to this array like this:
vehicles.append(EnemyVehicle(imageNamed:"mySprite"))
And the superclass SKSpriteNode contains an attribute which is position.y, and I can access it in every element of my array with vehicle[x].position.y.
My question is: is it possible to test every specific attribute in an array (here position.y) and watch if it match the conditions? For example, if I want a condition which is true only when all of the position.y values of all my elements in my array are superior than 0? I know I could do it with a loop, but is there another easier way to do it?
Sounds like you want reduce.
Reduce takes a starting value, and then a closure that takes the running value and the next element of the array, and combines these two elements together, carrying that result forward to combine with the next element.
For example:
let a = [1,2,3]
// starting with zero, add each element to a total
let sum = a.reduce(0) { total, i in total + i }
// sum = 6
To check if all elements in an array match a given criteria, you want a combining function that checks the property and returns true or false, anding that with the previous criteria:
// assuming you’re ok for true for an empty array:
let allAboveGround = vehicles.reduce(true) {
previous, vehicle in
previous && vehicle.position.y > 0
}
There’s one downside to this – as soon as you hit a value that is false, you could stop right there because the overall value cannot be true. Reduce doesn’t cater for this so you may want to write a loop, or maybe an all function that wraps a loop, that quits early under these conditions:
func all<S: SequenceType>(source: S, pred: S.Generator.Element->Bool) -> Bool {
for x in source {
if !pred(x) { return false }
}
return true
}
let allAboveGround = all(vehicles) { $0.position.y > 0 }

Resources