How to generate all subsequence of even length from an array? - arrays

I am dealing with a problem and that problem requires the answer to this as a subroutine. I know how to generate all subsequences from an array using bit manipulation but struggling to generate subsequences of even length.
For the sake of example, assume that there is an array A = [2, 5, 4, 2, 3, 1]
I want all the subsequences of even length i.e., of length 2, 4, and 6.
Edit 1: 1<=N<=1000 where N is the size of the array.

Since you already know how to generate all subsequences, then just remove the last element and generate all subsequences of the remaining array, but append the last back to each subsequence with an odd length.
Easy to prove that this generates all the even-length subsequences:
Every even-length subsequence of A that does not end in the last element of A, is an even-length subsequence of the earlier elements.
Every even-length subsequence of A that does end in the last element of A, has that element preceded by an odd-length subsequence of the earlier elements.

Subarrays
Using generator functions, you can take advantage of deferred execution to iterate all of the even-lengthed subarrays without retaining the entire collection of subarrays in memory:
function * subarrays (array) {
for (let length = 1; length <= array.length; length++) {
for (let index = 0; index + length <= array.length; index++) {
yield array.slice(index, index + length);
}
}
}
const filter = predicate => function * (iterator) {
for (const value of iterator) {
if (predicate(value)) yield value;
}
};
const even = filter(subarray => subarray.length % 2 === 0);
for (const subarray of even(subarrays ([2, 5, 4, 2, 3, 1]))) {
console.log(subarray.join());
}
However, if you do want the entire collection of even-lengthed subarrays, you can use Array.from() to consume the iterator and populate an array of subarrays:
function * subarrays (array) {
for (let length = 1; length <= array.length; length++) {
for (let index = 0; index + length <= array.length; index++) {
yield array.slice(index, index + length);
}
}
}
const filter = predicate => function * (iterator) {
for (const value of iterator) {
if (predicate(value)) yield value;
}
};
const even = filter(subarray => subarray.length % 2 === 0);
const result = Array.from(even(subarrays([2, 5, 4, 2, 3, 1])));
console.log(JSON.stringify(result));
Subsequences
To iterate all even-lengthed subsequences, one of the easiest methods is to keep a lookup table of which values to filter() from the array. We can achieve this with fairly minimal memory overhead by leveraging a Uint32Array:
function _increment (uint32Array) {
for (let index = 0; index < uint32Array.length; index++) {
// use unsigned integer overflow to
// perform carry in base 2**32 addition
if (++uint32Array[index]) return;
}
}
function * subsequences (array) {
const lut = new Uint32Array(Math.ceil(array.length / 32));
let subsequence;
while (true) {
yield subsequence = array.filter(
(_, index) => (lut[index >>> 5] >>> (index % 32)) & 1
);
if (subsequence.length === array.length) return;
_increment(lut);
}
}
const filter = predicate => function * (iterator) {
for (const value of iterator) {
if (predicate(value)) yield value;
}
};
const even = filter(({ length }) => (length > 0) && (length % 2 === 0));
for (const subsequence of even(subsequences([2, 5, 4, 2, 3, 1]))) {
console.log(subsequence.join());
}

#include <stdio.h>
#define N 4
const int A[] = { 2, 5, 4, 2, 3, 1, -1 };
int out[1000];
void gen(const int *p, int *pout) {
if(pout - out < N) {
while((*pout = *p++) > 0)
gen(p, pout + 1);
} else { // print output
for(const int *o = out; o < pout; o++)
printf("%d ", *o);
putchar('\n');
}
}
int main(int argc, char **argv) {
gen(A, out);
return 0;
}

Here's Python, which is as good as pseudocode:
def even_subsequences(L):
# yield the empty subsequence
yield []
# iterate over subsequence starting points
for i in range(len(L)):
# subsequence end point is the starting point plus an even number
for j in range(i+2, len(L)+1, 2):
# slice the list
yield L[i:j]
>>> list(even_subsequences([1,2,3,4,5,6]))
[[],
[1, 2],
[1, 2, 3, 4],
[1, 2, 3, 4, 5, 6],
[2, 3],
[2, 3, 4, 5],
[3, 4],
[3, 4, 5, 6],
[4, 5],
[5, 6]]

Related

Returning a new array created from adding odd numbers from an array

I am trying to create an array from this following array arr=[1,2,3,4,5,6,7,8,9] and it will return as sum of numbers in this way 1+3 =4 ,3+5=8,5+7=12,7+9=16. so that final answer would be newArray =[4,8,12,16].
How can I achieve it. I have done below code but it doesn't work .
fun main(){
val sum = arrayOf(1,2,3,4,5,6,7,8,9)
var first =0;
var second=0
for (i in sum.indices){
if(sum[i]%2!=0){
first += sum[i]
if (second!=0){
println(" $first + $second")
first=second
}
}
}
}
// val arr = arrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9)
val arr = arrayOf(1, 3, 5, 6, 7, 8, 2, 4, 9) // shuffled for test purposes
val result = arr
// I first posted this line, which was wrong:
// .filterIndexed { index, _ -> index % 2 == 0 }
.filterIndexed { _, value -> value % 2 == 1 }
.windowed(2, 1)
.map { it.sum() }
println(result)
Details of the three steps:
After filterIndexed: [1, 3, 5, 7, 9]
After windowed: [[1, 3], [3, 5], [5, 7], [7, 9]]
And in the map each sublist is summed up.
Edit: The first version of this answer with filtering for index % 2 == 0 does by coincidence lead to the same result, because the input array in the OP was not shuffled.
lukas.j's answer is superior, but I wanted to also show a solution with only slight changes to your own code:
val sum = arrayOf(1,2,3,4,5,6,7,8,9)
var first =0;
var second=0
var result = emptyArray<Int>()
for (i in sum.indices){
if(sum[i]%2!=0){
if (first == 0) first = sum[i]
else second = sum[i]
if (second!=0){
println(" $first + $second")
result += first + second
first=second
}
}
}
println(result.contentToString())

Count of strictly increasing sequence of integers

You are given two list of integers a and b of same length n, Find the count of strictly increasing sequences of integers
I[0] < I[1] < .. < I[n-1] such that min(a[i], b[i]) <= I[i] <= max(a[i], b[i]) for each i.
Eg.
a = [6,3,4,4]
b = [1,5,1,6]
Four possible solutions are possible
[1 3 4 5],
[1 3 4 6],
[2 3 4 5],
[2 3 4 6].
The length of both arrays will not exceed 100.
Each element is between 1 and 10000.```
Can someone provide a hint for this question? I am not able to figure out
You can use a dynamic programming approach here. The states of your DP will be the current index and last value ,like count_sequence(int index, int last_value) , loop through min(a[index], b[index]) to max(a[index], b[index]) ,if there is a value greater then last_value go to next index with current value like count_sequence(index+1, current_value), if you reach base case which is index>=n that means you find a sequence then return 1. Using this you can find every possible sequence.
With memorization, the complexity will be O(n*m),
n = array size, m = maximum element
JavaScript/node.js solution:
const a = [6, 3, 4, 4]
const b = [1, 5, 1, 6]
const n = a.length
let min = []
let max = []
for (let i = n - 1; i >= 0; i--) {
let itemMin = (min[i] = Math.min(a[i], b[i]))
let itemMax = (max[i] = Math.max(a[i], b[i]))
if (i > 0) {
const maxBefore = Math.max(a[i - 1], b[i - 1])
// max of before index, >= current min
if (maxBefore >= min[i]) {
itemMin = Math.min(maxBefore + 1, max[i])
}
}
if (i < n - 1) {
const minAfter = min[i + 1]
// min of after index, <= current or calculated min
if (itemMin >= minAfter) {
itemMin = Math.min(minAfter - 1, min[i])
}
// max correction
itemMax = Math.min(max[i], minAfter - 1)
}
// Test is solution possible, if not do something
if (itemMin < min[i] || itemMin > max[i]) {
throw new Error('Impossible to solve...')
}
if (itemMax < min[i] || itemMax > max[i]) {
throw new Error('Impossible to solve...')
}
// Set min and max values
min[i] = itemMin
max[i] = itemMax
}
// ***** Printing results
function printResult(min, max, str = '', item = 0) {
const n = min.length
for (let j = min[item]; j <= max[item]; j++) {
if (item < n - 1) {
printResult(min, max, `${item !== 0 ? str : ''}${j},`, item + 1)
} else {
console.log(`[${str}${j}]`)
}
}
}
printResult(min, max)
Given two arrays, one holding the min value and the other the max value for each index, you could define a simple recursive function to derive each possible increasing sequence, with the starting value at each position being the maximum of the current min value and the previously selected value plus 1.
Here's some Java code to illustrate:
static void incSeq(int[] min, int[] max, int[] res, int pos, int prev)
{
if(pos == min.length)
{
System.out.println("seq: " + Arrays.toString(res));
return;
}
for(int j = Math.max(prev+1, min[pos]); j <= max[pos]; j++)
{
res[pos] = j;
incSeq(min, max, res, pos+1, j);
}
}
However, if we consider input such as:
min = {1, 1, 1, 1}
max = {100, 100, 100, 5}
we can see that our function is going to do a lot of useless work iterating through values in the first three positions that will not be part of an increasing sequence.
We can fix this by recognizing that the maximum value we need to consider for position i is one less that the max value at position i+1. If we start at the last position and work backwards using this rule we can update the max array above to:
max = {2, 3, 4, 5}
Which will mean a lot less work for our recursive function.
Here's the complete code:
public static void main(String[] args)
{
int n = 4;
int[] a = {6,3,4,4};
int[] b = {1,5,1,6};
int[] min = new int[n];
int[] max = new int[n];
System.out.println("a: " + Arrays.toString(a));
System.out.println("b: " + Arrays.toString(b));
for(int i=0; i<n; i++)
{
min[i] = Math.min(a[i], b[i]);
max[i] = Math.max(a[i], b[i]);
}
System.out.println("min: " + Arrays.toString(min));
System.out.println("max: " + Arrays.toString(max));
// cap max values
for(int i=n-1; i>0; i--)
{
max[i-1] = Math.min(max[i-1], max[i]-1);
}
System.out.println("max: " + Arrays.toString(max) + "\n");
incSeq(min, max, new int[n], 0, 0);
}
static void incSeq(int[] min, int[] max, int[] res, int pos, int prev)
{
if(pos == min.length)
{
System.out.println("seq: " + Arrays.toString(res));
return;
}
for(int j = Math.max(prev+1, min[pos]); j <= max[pos]; j++)
{
res[pos] = j;
incSeq(min, max, res, pos+1, j);
}
}
Output:
a: [6, 3, 4, 4]
b: [1, 5, 1, 6]
min: [1, 3, 1, 4]
max: [6, 5, 4, 6]
max: [2, 3, 4, 6]
seq: [1, 3, 4, 5]
seq: [1, 3, 4, 6]
seq: [2, 3, 4, 5]
seq: [2, 3, 4, 6]

Google Kick Start Time Limited on Dart

I found out that my code Time Limited, but algorithm is just fine i believe. Is it my code problem or language?
Here is the task: Task src
An arithmetic array is an array that contains at least two integers and the differences between consecutive integers are equal. For example, [9, 10], [3, 3, 3], and [9, 7, 5, 3] are arithmetic arrays, while [1, 3, 3, 7], [2, 1, 2], and [1, 2, 4] are not arithmetic arrays.
Sarasvati has an array of N non-negative integers. The i-th integer of the array is Ai. She wants to choose a contiguous arithmetic subarray from her array that has the maximum length. Please help her to determine the length of the longest contiguous arithmetic subarray.
import 'dart:io';
import 'dart:math';
foo (array){
var diff = [];
var size = 2;
var answ = 2;
for (int i = 0; i < array.length - 1; i++){
diff.add(array[i + 1] - array[i]);
}
for (int i = 1; i < diff.length; i++){
if (diff[i] == diff[i - 1]){
size++;
}
else{
size = 2;
}
answ = max(answ, size);
}
return answ;
}
void main() {
var N = int.parse(stdin.readLineSync());
for (int i = 0; i < N; i++){
var M = int.parse(stdin.readLineSync());
String s = stdin.readLineSync();
var intArray = [];
s.trim().split(" ").forEach((x) => intArray.add(int.parse(x)));
print("Case #${i + 1}: ${foo(intArray)}");
}
}

Find next smallest value in array?

This question has been eating at me for a while. Basically, if you have an input array [4, 5, 2, 6, 7, 1], the next smallest number for 4 and 5 is 2, and for 6 and 7 is 1. I need to identify these smaller numbers. I have an obvious n^2 solution in time, but I feel there is an O(n) solution in time. I need to act on the presence of the next smallest number to the right, and also act in the case there is no smaller number to the right.
I've tried thinking of dynamic programming solutions and data structures (specifically a stack), but I can't seem to keep correctness and O(n) time complexity both in check, one or the other seems to fail for me.
Any help?
You can think of using a stack data structure for this. I have implemented it in Java. The idea is push the index to pop and while the top index value in stack is greater than current index value of the array pop the stack and assign the value at current index to the poped index location.
// Java Implementation of the idea
import java.util.Arrays;
import java.util.Stack;
public class NextSmallest{
public static void main(String[] args) {
int [] A = {4, 5, 2, 6, 7, 1};
int [] ret = nextSmallest(A);
System.out.println(Arrays.toString(ret)); // prints [2, 2, 1, 1, 1, 0]
}
static int [] nextSmallest(int [] A) {
Stack<Integer> stack = new Stack<>();
int n = A.length;
int [] nextSmallestIndex = new int[n];
for(int i = 0; i < n; i++) {
while(!stack.isEmpty() && A[stack.peek()] > A[i]) {
nextSmallestIndex[stack.pop()] = A[i];
}
stack.push(i);
}
return nextSmallestIndex;
}
}
You can use this simple loop over all array elements and get index of numbers you want
var arr = [4, 5, 2, 6, 7, 1];
var object = {};
for (var i = 0; i < arr.length; i++) {
if (i > 0 && i < arr.length - 1 && arr[i] < arr[i - 1] && arr[i] < arr[i + 1]) {
object[i] = arr[i];
} else if (i >= arr.length - 1 && arr[i] < arr[i - 1]) {
object[i] = arr[i];
}
}
console.log(object);
The object for output represents the index of next smallest number and its value. So if you want the smallest value for 4 or 5, because their indexes are before 2, their next smallest number will be object[2] and also for 6 and 7.
Full code
var arr = [4, 5, 2, 7, 6, 1];
var object = {};
for (var i = 0; i < arr.length; i++) {
if (i > 0 && i < arr.length - 1 && arr[i] < arr[i - 1] && arr[i] < arr[i + 1]) {
object[i] = arr[i];
} else if (i >= arr.length - 1 && arr[i] < arr[i - 1]) {
object[i] = arr[i];
}
}
function getResult(inpArr, number, obj) {
var keys = Object.keys(obj);
var index = inpArr.findIndex(function(itm) {
return itm == number;
});
// the number is not in the array
if (index == -1) {
return null;
}
for (var i = 0; i < keys.length; i++) {
if (index == keys[i]) {
return null;
}
if (index < keys[i]) {
return obj[keys[i]];
}
}
}
console.log("Result for 4: ", getResult(arr, 4, object));
console.log("Result for 5: ", getResult(arr, 5, object));
console.log("Result for 6: ", getResult(arr, 6, object));
console.log("Result for 7: ", getResult(arr, 7, object));
console.log("Result for 1: ", getResult(arr, 1, object));
console.log("Result for 2: ", getResult(arr, 2, object));
How do you define your start point? If you know you want to start at element 3 and look from there on, or do you want to find a value, and start at whatever element that value is at and go from there? What happens if a lower value isn't found for the rest of the array?
In PHP just because I'm in the middle of a PHP project, assuming you know what element you want to start with in the array.
<?php
// our array of numbers
$array=array(4, 5, 2, 7, 6, 1);
// what index are we starting at?
$start=2;
// what index are we comparing to?
$counter=0;
// some output
print("First value is ".$array[$start]." at array element ".$start);
// while the initial value is less or equal to the compare value, AND
// the compare position is within the bounds of the array
// increment the counter - our comparison isn't lower
while((($start+$counter)<count($array))&&($array[($start)]<=$array[($start+$counter)])){
$counter++;
}
// did we make it through without exceeding bounds of array or not?
if(($start+$counter)<count($array)){
print("\nNext lower value is ".$array[($start+$counter)]." at array element ".($start+$counter));
}else{
print("\nEnd of array reached without finding lower value...");
}
print("\n");
?>
Find the below solution in O(n) way with optimized code in JavaScript
var arr = [4, 5, 2, 7, 6, 1, 3, 4];
function getNextSmallestValue(index){
var elemvalue = arr[index];
var minValue = elemvalue;
for(var i=index;i<arr.length;i++){
if(minValue> arr[i]){
minValue = arr[i];
}
if((minValue!==elemvalue && elemvalue<arr[i]) || i === arr.length-1){
return minValue;
}
}
}
console.log(getNextSmallestValue(0)); // 2
console.log(getNextSmallestValue(3)); // 1

Algorithm - Find existence of a 2d array in another 2d array

I came across this question while in an interview and i am unable to find the best way to do it.
The question says, there are two 2d arrays, one is bigger than the other.
Lets say,
Array_1 = [[1,2],
[5,6]]
and
Array_2 = [[1,2,3,4],
[5,6,7,8],
[9,10,11,12]]
Since, here the Array 2 contains Array 1, the algo should return true. Otherwise, false.
The size of the array can be anything.
Try this.
function Test() {
var x = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]];
var y = [[6, 7], [10, 12]];
for (i = 0; i < x.length; i++) {
for (j = 0; j < x[i].length; j++) {
if (x[i][j] == y[0][0])
if (findMatch(x, y, i, j)) {
console.log("Match Found");
return true;
}
}
}
console.log("Not found");
return false;
}
function findMatch(x, y, i, j) {
var b = true;
for (k = i; k < y.length; k++) {
for (n = j; n < y[k].length; n++) {
if (y[k - i][n - j] != x[k][n]) {
b = false;
break;
}
}
}
return b;
}
Note that this doesn't match if the smaller array is rotated inside the big array.(Written in javaScript)
I would fill in the smaller array to the bigger dimensions with null values (or with NaN), convert to 1D and truncate/strip the unnecessary nulls :
array_1 = [1, 2, null, null, 5, 6]
array_2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
then compare the 1D arrays, while skipping the null values - this would be O(n*m) in the worst case (such as [1,1,1,2] vs [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]), and it would be O(n) in the best case (if every number in the bigger array was different)
Edit: more logic is needed to ensure comparison only within the complete rows of the bigger array, not across rows...
I guess you could convert the arrays to dictionaries of positions and figure out a bit more complicated and faster algorithm if you need to do multiple comparisons...
You could also rotate the smaller array if needed, e.g.:
array_1_270 = [6, 2, null, null, 1, 5]
You can try aho-corasick algorithm for 2 dimension. Aho-corasick algorithm is the fastest multiple pattern matching. Here is a similar question:is there any paper or an explanation on how to implement a two dimensional KMP?
Maybe a little simpler in Python 2.6
def check():
small=[[1,2],[5,6]] #matches upper left corner
smallrows = len(small) #rows = 2
smallcols = len(small[0]) #cols = 2
big=[[1,2,3,4],[5,6,7,8],[9,10,11,12]]
bigrows = len(big) #rows = 3
bigcols = len(big[0]) #cols = 4
for i in range(bigrows-smallrows+1): #i is number row steps
for j in range(bigcols-smallcols+1): #j is number col steps
flag = 0
for k in range(smallrows):
for l in range(smallcols):
if big[i+k][j+l] != small[k][l]:
flag = 1
continue
if flag == 0:
return(True)
return(False)
print check()

Resources