Algorithm that mix array respecting certain constraints - arrays

I've this problem:
i must develop an algorithm that get an int array and reshuffles the elements respecting these constraints:
For each element, must be lower than its neighbors or greater than its neighbors:
for each x in array a,
( a[x-1]<=a[x] AND a[x+1]<=a[x] )
OR
( a[x-1]>=a[x] AND a[x+1]>=a[x] )
This all in theta(n log n) in the worst case
I've no idea how to do this, my only intuition is that i must do something similar to merge-sort...
Sorry for mi poor English

Sort the array
Cut it in halfs
Put elements from first half in between elements of the second half
If number of elemnts is not even move last element to the front
Example:
2 3 1 5 7 8 6 4 9
1 2 3 4 5 6 7 8 9
1 5 2 6 3 7 4 8 9
9 1 5 2 6 3 7 4 8

As a naive approach, you could perform some sorting first and group the array to groups of equal size. Afterwards, adjacent groups would have to be pairwise switched; if the number of groups is odd, the first group needs to be switched to the back.
An example:
Input: 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 (already sorted)
Groups: (9 9) (8 8) (7 7) (6 6) (5 5) (4 4) (3 3) (2 2) (1 1)
Groups pairwise switched: (8 8) (9 9) (6 6) (7 7) (4 4) (5 5) (2 2) (3 3) (1 1)
First group moved to the back: (9 9) (6 6) (7 7) (4 4) (5 5) (2 2) (3 3) (1 1) (8 8)
Perhaps the idea can be refined to obtain a better algorithm.

Related

Using Key operator to make a game but need more tree depth to create a more complex tree

I am working on a game using the Key operator to create simple parent tree nodes connected with children. Like (1 3 2 7 11 12) with 1 as a parent node and 3 2 7 11 12 children. The array has all the information via Key to create the nested array. Of course its extremely fast. But I actually need 2 or 3 more depth. I can create a different tree construction shown on the 'same' array - second image. This different encoding (1 2 1 1 2 3 1 3 3.....) allows arbitrarily nesting vector depth and works perfectly. - with just a simple array.
There could be enough information with the Key transformation on the array then more code to connect the children nodes - for needed depth. Are there any same or similar APL/Co-dfns for (1.) transforming the array into the tree (2.) - and back? I am new to APL and focusing on the rectangular. Tree wrangling is down the road. I need almost the same for Key speed due to very long arrays and their nested arrays.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
1 2 1 1 2 3 1 3 3 3 1 1 2 7 8 9 16 4
Using Key:
{⊂⍵}⌸1 2 1 1 2 3 1 3 3 3 1 1 2 7 8 9 16 4
(1 3 4 7 11 12) (2 5 13) (6 8 9 10) (14) (15) (16) (17) (18)
Using maybe Key and something else....
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
1. 1 2 1 1 2 3 1 3 3 3 1 1 2 7 8 9 16 4
2. (1 3 4 (7 14) 11 12) (2 5 13) (6 (8 15) (9 (16 17)) 10) (,18)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
1 2 2 2 2 2 1 7 8 3 10 11 10 10 10 15 9
(different array for same tree encoding)
(1(7(8 (9 17)))) (2 3 4 5 6) (10(11 12) 13 14 (15 16))
({⊂⍵}⌸⍠ 2) 1 2 1 1 2 3 1 3 3 3 1 1 2 7 8 9 16 4
Perhaps using Variant on Key down the road?
There are some ways to do this, but the best method will depend on what you want to do with the results. If you really do have very large arrays, then producing the "nested children" representation of arrays is going to be expensive no matter how you compute them, because the underlying representation is expensive (though, no more expensive than the same sort of representation in another language).
Section 3.2 of (Hsu 2019) discusses this in detail:
"A data parallel compiler hosted on the GPU". Hsu, Aaron W.
https://scholarworks.iu.edu/dspace/handle/2022/24749
Generally speaking, if you intend to work with the data in some way, it is almost always faster and easier to work directly with the parent vector or depth vector representation instead of first converting to a record-type style representation.
One technique is to query the data in parent vector form first, to identify the relevant nodes over which you intend to work, and only then to extract the children nodes for that limited set using primitives like membership (∊) or where (⍸).
If you can describe the sort of operations you intend to perform over these nested representations, there might be a better algorithm that does not require the conversion.
If you do wish to simply create the full record-type representation, there is some conversion code in (Hsu 2019). You can also look at the P2D and D2P functions in the Co-dfns compiler:
https://github.com/Co-dfns/Co-dfns/blob/master/src/codfns/P2D.aplf
https://github.com/Co-dfns/Co-dfns/blob/master/src/codfns/D2P.aplf
These may give you some additional help in converting between the formats.
If you need to convert directly between the parent and record-type representation, you can use something akin to this:
kids←{0=≢k←⍸p=⍵:⍵ ⋄ ⍵,∇¨k~⍵}¨
And apply it to the root nodes of your tree like this:
kids ⍸p=⍳≢p
where p is your parent vector.
I hope this helps!

How to use a nested for loop to create a 1D array of integer pairs on a range?

In bash, I am trying to create 1-D array that contains all possible integer pairs on a range from a low value to a high value (i.e. 1 to 2)
I've tried using a nested for loop, however the out put I get is the array of the correct size, but all values are the high value (in this case 2)
I've tried nested for loops, however the array I am creating is not the correct size nor does it contain the correct combinations.
for (( i=$low; i<=$high; i++ ))
do
range_array[i]=$i
done
range=${#range_array[#]}
range_squared=$(( $range*$range))
new_range=$(( 2*$range_squared))
for (( i = $low; i <= $high; i++ ));do
for (( j = 1; j <= $new_range; j++ )) do
combo_array[j]=$i
done
done
echo "the following is the combo array"
echo ${combo_array[#]}
I expect the combo_array to be:
1 1 1 2 2 1 2 2
instead it is
2 2 2 2 2 2 2 2
That's too much work for such a trivial task. Here is a simple and working one:
combo_array=()
for ((i=low; i<=high; ++i)); do
for ((j=low; j<=high; ++j)); do
combo_array+=("$i" "$j")
done
done
echo "${combo_array[#]}"
Given low=6 and high=9, it outputs
6 6 6 7 6 8 6 9 7 6 7 7 7 8 7 9 8 6 8 7 8 8 8 9 9 6 9 7 9 8 9 9

Returning five minimum integers from a vector consists of twenty integers in MATLAB [duplicate]

This question already has answers here:
How to find the index of the n smallest elements in a vector
(2 answers)
Closed 7 years ago.
I would like to return five minimum integers from a vector consists of twenty integers in MATLAB. Any help? Thanks.
Example:
X = [6 7 8 3 5 6 7 2 5 1 0 6 6 2 9 6 3 3 4 77];
How to get the five minimum values from this vector?
You can use Sort function and then take the 5 in the end of the array
sorted_x = sort(X)
5Minimum = sorted_x(15:20)

Build a large array from a small array in MATLAB? [duplicate]

This question already has answers here:
Octave / Matlab: Extend a vector making it repeat itself?
(3 answers)
Closed 8 years ago.
If I have a small array like a=[1 2 3 4 5], and want to build a large array from it with repeating it, like b=[1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 ....1 2 3 4 5], how can I do that in simplest way and lowest calculations?
repmat is what you are looking for
n = 5
b = repmat(a,1,n)

explanation of bit array implementation in C-FAQ

I was reading the C-FAQ question no: 20.8 which basically deals with bit arrays:
http://c-faq.com/misc/bitsets.html
One of the macros defined looks something like:
#define BITNSLOTS(nb) ((nb + CHAR_BIT - 1) / CHAR_BIT)
Is this macro meant to calculate the num of elements(or slots) in the char array (each slot = 8 bits) ? I am not sure what this macro is doing, in particular what the purpose of "+CHAR_BIT -1/CHAR_BIT" is. Any clues will be appreciated!
Yes, it calculates how many chars are needed to hold the bits. The addition stuff is to make it round up.
It is a way to round up.
If nb is smaller than CHAR_BIT, you'll still need at least one character.
Remember the division is integer division: there's no "... and three eighths". Suppose you want to group into slots of size 6 (yeah ... I know CHAR_BIT is 8 or more)
1 element: 1 slot: (1 + 6 - 1) / 6 == (6 / 6) == 1
...
5 elements: 1 slot: (5 + 6 - 1) / 6 == (10/6) == 1
6 elements: 1 slot: (6 + 6 - 1) / 6 == (11 / 6) == 1
7 elements: 2 slots: (7 + 6 - 1) / 6 == (12 / 6) == 2
...

Resources