Scale a list of numbers from -1.0 to 1.0 - algorithm

This should be an easy one.
I have a list of numbers. How do I scale list's values, between -1.0 and 1.0 in order for min = -1 and max = 1.0?

Find the min and the max
then for each number scale x to 2 * (x - min)/( max - min) - 1
Just to check --
min scales to -1
and max scales to 1
If it is a long list precomputing c = 2/(max - min) and scaling with c * x - 1 is a good idea.

This is a signed normalization
1 - get the Minimum and Maximum value on the list (MinVal,MaxVal)
2 - convert each number using this expressions
signedNormal = (((originalNumber - Minimum) / (Maximum - Minimum)) * 2.0) - 1.0
I deliberately made this inefficient in order to be clear - more efficient would be
double min = myList.GetMinimum();
double max = myList.GetMaximum();
double signedRangeInverse = 1.0 / (max - min);
for(int i = 0;i < myList.NumberOfItems();i++)
myList[i] = (((myList[i] - min) * signedRangeInverse) * 2.0) - 1
No point in recalculating range each time
No point in dividing range, mult is faster

If you want 0 to still equal 0 in the final result:
Find the number with the largest magnitude. This will either map to 1 or -1.
Work out what you need to multiply it by to make it 1 or -1.
Multiply all the numbers in the collection by that factor.
E.g
[ -5, -3, -1, 0, 2, 4]
Number with largest magnitude is -5. We can get that to equal -1 by multiplying by 0.2 (-1 / -5). (Beware of divide by 0s if your numbers are all 0s.)
So multiply all the elements by 0.2. This would give:
[-1, -0.6, -0.2, 0, 0.4, 0.8]
Although note that
[ -5, -5, -5 ] -> [ -1, -1, -1 ]
and
[ 5, 5, 5 ] -> [ 1, 1, 1 ]
and
[ 0, 0, 0 ] -> [ 0, 0, 0 ]
That may or may not be what you want. Thanks to #Hammerite for prompting me on that one with his very helpful comment :)

Related

Can counting sort sort decimal values?

Can Counting Sort sort decimal values? I'm just started learning java recently and I'm unsure. Does anyone know if it can or not?
Counting Sort only works because you know exactly how many elements there are in the array, and because each index in an array represents an integer of the same value. The array [1, 2, 0, 2, 1] can be represented as [1, 2, 2] in the middle stage of the sort. There is one 0, two 1s, and two 2s.
This is not possible in the same way with decimals. If you could ensure a certain level of precision I suppose you could add a slot for each potential value. For example, if all the decimals were rounded to the nearest tenth you would need at 10 slots for each whole number plus 1 slot for 0: 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0
// the original array
[0.1, 1.1, 0.7, 1.4, 0.5, 0.7]
// after the counting step
// 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9
[ 0 1 0 0 0 1 0 2 0 0
// 1.1 1.2 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9
1 0 0 0 1 0 0 0 0 0 ]
// when expanded to the sorted array
[0.1, 0.5, 0.7, 0.7, 1.1, 1.4]
So for a sort with a max value of N, the size of the counting array (K) would be N * 10. So k = 10N. This is obviously not true counting sort, since the counting step would be more complex since each value cannot be so easily mapped to an index.
So while theoretically possible and would have the same time complexity, it would not be a "true" counting sort while also taking up FAR more memory space to be practical, especially when sorting large number ranges with high precision, and being less flexible than other sorting algorithms. You would be better off using most any other sorting algorithm.

Kth element in transformed array

I came across this question in recent interview :
Given an array A of length N, we are supposed to answer Q queries. Query form is as follows :
Given x and k, we need to make another array B of same length such that B[i] = A[i] ^ x where ^ is XOR operator. Sort an array B in descending order and return B[k].
Input format :
First line contains interger N
Second line contains N integers denoting array A
Third line contains Q i.e. number of queries
Next Q lines contains space-separated integers x and k
Output format :
Print respective B[k] value each on new line for Q queries.
e.g.
for input :
5
1 2 3 4 5
2
2 3
0 1
output will be :
3
5
For first query,
A = [1, 2, 3, 4, 5]
For query x = 2 and k = 3, B = [1^2, 2^2, 3^2, 4^2, 5^2] = [3, 0, 1, 6, 7]. Sorting in descending order B = [7, 6, 3, 1, 0]. So, B[3] = 3.
For second query,
A and B will be same as x = 0. So, B[1] = 5
I have no idea how to solve such problems. Thanks in advance.
This is solvable in O(N + Q). For simplicity I assume you are dealing with positive or unsigned values only, but you can probably adjust this algorithm also for negative numbers.
First you build a binary tree. The left edge stands for a bit that is 0, the right edge for a bit that is 1. In each node you store how many numbers are in this bucket. This can be done in O(N), because the number of bits is constant.
Because this is a little bit hard to explain, I'm going to show how the tree looks like for 3-bit numbers [0, 1, 4, 5, 7] i.e. [000, 001, 100, 101, 111]
*
/ \
2 3 2 numbers have first bit 0 and 3 numbers first bit 1
/ \ / \
2 0 2 1 of the 2 numbers with first bit 0, have 2 numbers 2nd bit 0, ...
/ \ / \ / \
1 1 1 1 0 1 of the 2 numbers with 1st and 2nd bit 0, has 1 number 3rd bit 0, ...
To answer a single query you go down the tree by using the bits of x. At each node you have 4 possibilities, looking at bit b of x and building answer a, which is initially 0:
b = 0 and k < the value stored in the left child of the current node (the 0-bit branch): current node becomes left child, a = 2 * a (shifting left by 1)
b = 0 and k >= the value stored in the left child: current node becomes right child, k = k - value of left child, a = 2 * a + 1
b = 1 and k < the value stored in the right child (the 1-bit branch, because of the xor operation everything is flipped): current node becomes right child, a = 2 * a
b = 1 and k >= the value stored in the right child: current node becomes left child, k = k - value of right child, a = 2 * a + 1
This is O(1), again because the number of bits is constant. Therefore the overall complexity is O(N + Q).
Example: [0, 1, 4, 5, 7] i.e. [000, 001, 100, 101, 111], k = 3, x = 3 i.e. 011
First bit is 0 and k >= 2, therefore we go right, k = k - 2 = 3 - 2 = 1 and a = 2 * a + 1 = 2 * 0 + 1 = 1.
Second bit is 1 and k >= 1, therefore we go left (inverted because the bit is 1), k = k - 1 = 0, a = 2 * a + 1 = 3
Third bit is 1 and k < 1, so the solution is a = 2 * a + 0 = 6
Control: [000, 001, 100, 101, 111] xor 011 = [011, 010, 111, 110, 100] i.e. [3, 2, 7, 6, 4] and in order [2, 3, 4, 6, 7], so indeed the number at index 3 is 6 and the solution (always talking about 0-based indexing here).

Ruby Split number in ones or halves

I like to split up a score in an array of n positions.
Lets say my score is 11 and the array is of size 12.
Then I like to have some array that is filled with for example 11 ones or 10 ones and 2 halves (0.5). In the end it should sum to 11.
Then the possible scores are:
size = 12
possible_scores = (0..size).step(0.5).to_a
I can create an array of 12 positions:
scores = Array.new(size) {0}
I could pick a random value from the following possible values:
[0, 0.5, 1].sample
I'm looking for an efficient way to retrieve a random array without having lots of state variables if possible. I already tried to do this in a while loop:
while score < 0
and reduce the value of score with the random value and keep track of the array positions that are set. But it became quite a messy piece of code.
Any ideas how to solve this? Thanks!
Edit:
For this example I want an array that sums up to 11. So any one of
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0.5, 0.5]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1]
Or whatever combination that sums up to 11.
Parameters and variables
Given:
tot, the desired total, an integer or an odd multiple of 0.5; and
size, the total number of 0's, 0.5's and 1's that total tot, with the requirement that size >= tot.
we define three variables:
n0 equals the number of zeroes;
n0pt5_pairs equals the number of pairs of 0.5's; and
n1 equals the number of ones.
Case 1: tot is an integer
We require:
0 <= n0pt5_pairs <= [tot, size-tot].min
Note that because n1 = tot - n0pt5_pairs, 2 * n0pt5_pairs + n1 = n0pt5_pairs + tot > size if n0pt5_pairs > size-tot. That is, the total number of 0.5's and ones exceeds size if the number of 0.5 pairs exceeds size-tot.
Given a value for n0pt5_pairs that satisfies the above requirement, n0 and n1 are determined:
n1 = tot - n0pt5_pairs
n0 = size - 2*n0pt5_pairs - n1
= size - tot - n0pt5_pairs
We can therefore randomly select a random triple [n0, 2*n0pt5_pairs, n1] as follows:
def random_combo(size, tot)
n0pt5_pairs = rand(1+[tot, size-tot].min)
[size-tot-n0pt5_pairs, 2*n0pt5_pairs, tot-n0pt5_pairs]
end
For example:
arr = random_combo(17, 11)
#=> [3, 6, 8]
This is used to generate the array
arr1 = [*[0]*arr[0], *[0.5]*arr[1], *[1]*arr[2]]
#=> [0, 0, 0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 1, 1, 1, 1, 1, 1, 1, 1]
which we shuffle:
arr1.shuffle
#=> [1, 0, 0.5, 1, 0.5, 0, 1, 1, 0, 1, 1, 1, 0.5, 0.5, 1, 0.5, 0.5]
Note arr1.size #=> 17 and arr.sum #=> 11.
Case 2: tot is a multiple of 0.5
If
tot = n + 0.5
where n is an integer, every combination of 0's, 0.5's and 1's will have at least one 0.5. We therefore can compute the number of 0's and 1's, together with the number of 0.5's in excess of one. To do that we simply reduce tot by 0.5 (making it equal to an integer) and size by one, use generate_for_integer to solve that problem, then for each three-element array returned by that method increase the number of 0.5's by one.
def generate(size, tot)
return nil if size.zero?
is_int = (tot == tot.floor)
tot = tot.floor
size -= 1 unless is_int
n0pt5_pairs = rand(1+[tot, size-tot].min)
[*[0]*(size-tot-n0pt5_pairs), *[0.5]*(2*n0pt5_pairs + (is_int ? 0 : 1)),
*[1]*(tot-n0pt5_pairs)].
shuffle
end
ge = generate(17, 10)
#=> [0, 1, 0, 1, 0.5, 0.5, 0, 0.5, 0.5, 1, 1, 1, 1, 0.5, 0.5, 0.5, 0.5]
ge.size #=> 17
ge.sum #=> 10.0
go = generate(17, 10.5)
#=> [0.5, 0.5, 0.5, 1, 0, 0.5, 0.5, 1, 1, 0.5, 1, 1, 0.5, 1, 0.5, 0.5, 0]
go.size #=> 17
go.sum #=> 10.5
Ruby provides all you require here, no need to write any algorithmic code. Array#repeated_combination is your friend here:
[0, 0.5, 1].
repeated_combination(12). # 91 unique variant
to_a. # unfortunately it cannot be lazy
shuffle. # to randomize array outcome
detect { |a| a.sum == 11 }.
shuffle # to randomize numbers inside array
#⇒ [0.5, 0.5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
Sidenote: one might avoid the necessity to shuffle twice (both array of generated arrays and the resulting array) by using Array#repeated_permutation, but this would drastically increase memory load and execution time.
I like Cary Swoveland's answer, but in fact this can be done without generating an array of solutions.
Let's consider a few examples.
Given size = 6 and score = 3, without shuffling, these are the possible outputs (numbered on the left for reasons that will become apparent):
i ones halves zeroes
0│ 1 1 1 0 0 0 3 0 3
1│ 1 1 ½ ½ 0 0 2 2 2
2│ 1 ½ ½ ½ ½ 0 1 4 1
3│ ½ ½ ½ ½ ½ ½ 0 6 0
Given size = 6 and score = 3.5:
i ones halves zeroes
0│ 1 1 1 ½ 0 0 3 1 2
1│ 1 1 ½ ½ ½ 0 2 3 1
2│ 1 ½ ½ ½ ½ ½ 1 5 0
Given size = 11 and score = 4.5:
i ones halves zeroes
0│ 1 1 1 1 ½ 0 0 0 0 0 0 4 1 6
1│ 1 1 1 ½ ½ ½ 0 0 0 0 0 3 3 5
2│ 1 1 ½ ½ ½ ½ ½ 0 0 0 0 2 5 4
3│ 1 ½ ½ ½ ½ ½ ½ ½ 0 0 0 1 7 3
4│ ½ ½ ½ ½ ½ ½ ½ ½ ½ 0 0 0 9 2
Given size = 12 and score = 11:
i ones halves zeroes
0│ 1 1 1 1 1 1 1 1 1 1 1 0 11 0 1
1│ 1 1 1 1 1 1 1 1 1 1 ½ ½ 10 2 0
Can you see the patterns? After a bit of chin-scratching we discover the following facts:
The number of possible outputs 𝑛 for a given size and score is given by:
𝑛 = min(⌊score⌋, size − ⌈score⌉) + 1
As 𝑖 increases, the number of ones decreases. The number of ones is given by:
count(1) = ⌊score⌋ − 𝑖
As 𝑖 increases, the number of halves (½) increases. The number of halves is given by:
count(½) = 2(𝑖 + mod(score, 1))
In other words, it's 2𝑖 + 1 if score has a fractional part, or 2𝑖 otherwise.
As 𝑖 increases, the number of zeroes decreases, given by:
count(0) = size − ⌈score⌉ − 𝑖
With these four facts in mind we can generate any of the 𝑛 possible outputs at random by picking a random 𝑖 where 0 ≤ 𝑖 < 𝑛:
𝑖 = random( [0..𝑛) )
These facts are easy to translate into Ruby code:
n = [score.floor, size - score.ceil].min + 1
i = rand(n)
num_ones = score.floor - i
num_halves = 2 * (i + score % 1)
num_zeroes = (size - score.floor) - i
Now we just need to clean it up a bit and put it in a function that takes size and score as arguments, turns num_ones, num_halves, and num_zeroes into an array of 0s, 0.5s, and 1s, and shuffles the result:
def generate(size, score)
init_ones = score.floor
init_zeroes = size - score.ceil
i = rand([init_ones, init_zeroes].min + 1)
num_ones = init_ones - i
num_halves = 2 * (i + score % 1)
num_zeroes = init_zeroes - i
[ *[1]*num_ones, *[0.5]*num_halves, *[0]*num_zeroes ].shuffle
end
generate(6, 3.5)
# => [0.5, 1, 0, 0.5, 0.5, 1]
You can see the result in action on repl.it: https://repl.it/#jrunning/UnpleasantDimpledLegacysystem (Note that when you run it on repl.it the output appears very slowly. This is only because repl.it executes Ruby code on the server and streams the result back to the browser.)
If I get the point, one possible option could be (brute force)
size = 12
sum = 11
tmp = Array.new(12){1}
loop do
raise 'not possible' if tmp.sum < sum
tmp[tmp.index(1)] = 0.5 if tmp.index(1)
unless tmp.index(1)
tmp[tmp.index(0.5)] = 0
end
break if tmp.sum == sum
end
tmp #=> [0.5, 0.5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
tmp.sum #=> 11.0

Matching between two series after manipulation

Suppose, we're given two series of integer numbers as X[..] And Y[..], which
has the same length. We can choose any position i of the series X[] and
doing the operation like , X[i]=X[i] + 3, X[i + 2] = X[i + 2] + 2 , X[i + 4] = X[i + 4] + 1.
After manipulating the series with any number of time, is it possible to
find the same series like Y[..]?
I am thinking to implement it by brute force and normal combinational matching after manipulation. Is there any other process which can make it faster?
Given two series,
X [ 1, 2, 3 ,4, 5 ,6,8 ]
Y [ 1, 5, 6 ,6, 7 ,7,9 ]
if i=2 then
X [ 1, 5, 3 ,6, 5 ,7,8 ]
Y [ 1, 5, 6 ,6, 7 ,7,9 ]
and if i=3 then
X [ 1, 5, 6 ,6, 7 ,7,9 ]
Y [ 1, 5, 6 ,6, 7 ,7,9 ]
Matches the series.
You can see that for every index p resulting cell could be represented as
Y[p] = X[p] + F(p-4) + 2 * F(p-2) + 3 * F[p]
where F[p] is number of operation at p-th index.
So you have system of p linear equations for p unknowns Fi.
This is tridiagonal (sparse) system, it could be solved with some fast methods or with usual Gaussian elimination.
System might be inconsistent - in this case there are no solutions
Since an operation at index i modifies only elements present at index i, i + 2 and i + 4, that is, all indices >= i, we can build a greedy algorithm which iterates over the array X from left-to-right and at every index i compares the value with array Y.
Case X[i] > Y[i]: Then it's not possible to update X[i] to Y[i], hence return not possible.
Case X[i] == Y[i]: Then continue iterating over the next element at i + 1
Case X[i] < Y[i]: If (Y[i] - X[i]) mod 3 != 0, then return not possible, else compute m = (Y[i] - X[i])/3 and increment X[i] by 3 * m, X[i + 2] by 2 * m and X[i + 4] by m and continue iterating.
If we reach the end of array X, then it means it's possible to construct array Y from X using these operations.
Overall time complexity of the solution is O(n).

Finding the maximum possible sum/product combination of integers

Given an input of a list of N integers always starting with 1, for example: 1, 4, 2, 3, 5. And some target integer T.
Processing the list in order, the algorithm decides whether to add or multiply the number by the current score to achieve the maximum possible output < T.
For example: [input] 1, 4, 2, 3, 5 T=40
1 + 4 = 5
5 * 2 = 10
10 * 3 = 30
30 + 5 = 35 which is < 40, so valid.
But
1 * 4 = 4
4 * 2 = 8
8 * 3 = 24
24 * 5 = 120 which is > 40, so invalid.
I'm having trouble conceptualizing this in an algorithm -- I'm just looking for advice on how to think about it or at most pseudo-code. How would I go about coding this?
My first instinct was to think about the +/* as 1/0, and then test permutations like 0000 (where length == N-1, I think), then 0001, then 0011, then 0111, then 1111, then 1000, etc. etc.
But I don't know how to put that into pseudo-code given a general N integers. Any help would be appreciated.
You can use recursive to implement the permutations. Python code below:
MINIMUM = -2147483648
def solve(input, T, index, temp):
# if negative value exists in input, remove below two lines
if temp >= T:
return MINIMUM
if index == len(input):
return temp
ans0 = solve(input, T, index + 1, temp + input[index])
ans1 = solve(input, T, index + 1, temp * input[index])
return max(ans0, ans1)
print(solve([1, 4, 2, 3, 5], 40, 1, 1))
But this method requires O(2^n) time complexity.

Resources