Fmodf returning same value - random

Here's my code:
x = fmodf((float)rand(), (float)(1/sqsize)) + x1;
The problem is, whenever sqsize is a multiple of square-multiple of 4(e.g 4,16,64), it always returns the same numbers. sqsize is the square root for the multiple (so for 4 it is 2, for 16 it is 4, for 64 it is 8, etc).
x1 is defined as:
x1 = fmodf(value,sqsize)/sqsize;
where value is equal to a number in 0-sqsize^2.
Any ideas why I keep getting the same value? Thanks.

Try (float)(1.0/sqsize) --- the (float) cast you are using does not do anything until 1/sqsize is computed at the moment. Meaning it will probably evaluate to 0 all the time.

Related

Rearrange list to satisfy a condition

I was asked this during a coding interview but wasn't able to solve this. Any pointers would be very helpful.
I was given an integer list (think of it as a number line) which needs to be rearranged so that the difference between elements is equal to M (an integer which is given). The list needs to be rearranged in such a way that the value of the max absolute difference between the elements' new positions and the original positions needs to be minimized. Eventually, this value multiplied by 2 is returned.
Test cases:
//1.
original_list = [1, 2, 3, 4]
M = 2
rearranged_list = [-0.5, 1.5, 3.5, 5.5]
// difference in values of original and rearranged lists
diff = [1.5, 0.5, 0.5, 1.5]
max_of_diff = 1.5 // list is rearranged in such a way so that this value is minimized
return_val = 1.5 * 2 = 3
//2.
original_list = [1, 2, 4, 3]
M = 2
rearranged_list = [-1, 1, 3, 5]
// difference in values of original and rearranged lists
diff = [2, 1, 1, 2]
max_of_diff = 2 // list is rearranged in such a way so that this value is minimized
return_val = 2 * 2 = 4
Constraints:
1 <= list_length <= 10^5
1 <= M <= 10^4
-10^9 <= list[i] <= 10^9
There's a question on leetcode which is very similar to this: https://leetcode.com/problems/minimize-deviation-in-array/ but there, the operations that are performed on the array are mentioned while that's not been mentioned here. I'm really stumped.
Here is how you can think of it:
The "rearanged" list is like a straight line that has a slope that corresponds to M.
Here is a visualisation for the first example:
The black dots are the input values [1, 2, 3, 4] where the index of the array is the X-coordinate, and the actual value at that index, the Y-coordinate.
The green line is determined by M. Initially this line runs through the origin at (0, 0). The red line segments represent the differences that must be taken into account.
Now the green line has to move vertically to its optimal position. We can see that we only need to look at the difference it makes with the first and with the last point. The other two inputs will never contribute to an extreme. This is generally true: there are only two input elements that need to be taken into account. They are the points that make the greatest (signed -- not absolute) difference and the least difference.
We can see that we need to move the green line in such a way that the signed differences with these two extremes are each others opposite: i.e. their absolute difference becomes the same, but the sign will be opposite.
Twice this absolute difference is what we need to return, and it is actually the difference between the greatest (signed) difference and the least (signed) difference.
So, in conclusion, we must generate the values on the green line, find the least and greatest (signed) difference with the data points (Y-coordinates) and return the difference between those two.
Here is an implementation in JavaScript running the two examples you provided:
function solve(y, slope) {
let low = Infinity;
let high = -Infinity;
for (let x = 0; x < y.length; x++) {
let dy = y[x] - x * slope;
low = Math.min(low, dy);
high = Math.max(high, dy);
}
return high - low;
}
console.log(solve([1, 2, 3, 4], 2)); // 3
console.log(solve([1, 2, 4, 3], 2)); // 4

How to find number of possible ways to pick numbers greater than or equal to a given number from multiple lists?

I am trying to pick one number from multiple arraylists and find all possible ways to pick the numbers such that the sum of those numbers is greater than a given number. I can only think of brute force implementation.
For example, I have five arraylists such as
A = [2, 6, 7]
B = [6, 9]
C = [4]
D = [4, 7]
E = [8, 10, 15]
and a given number is 40.
Then after picking one number from each list, all possible ways could be
[7, 9, 4, 7, 15]
[6, 9, 4, 7, 15]
So, these are the two possible ways to pick numbers greater than or equal to 40. In case the given number is small then there could be many solutions. So how can I count them without brute force? Even with brute force how do I devise the solution in Java.
Below is my implementation. It works fine for small numbers but if the numbers are large then it gives me runtime error since the program runs for too long.
public static void numberOfWays(List<Integer> A, List<Integer> B, List<Integer> C, List<Integer> D,
List<Integer> E, int k){
long ways = 0;
for(Integer a:A){
for(Integer b:B){
for(Integer c:C){
for(Integer d:D){
for(Integer e:E){
int sum = a+b+c+d+e;
//System.out.println(a+" "+b+" "+c+" "+d+" "+e+" "+sum);
if(sum > k)
ways++;
}
}
}
}
}
System.out.println(ways);
}
The list can contain up to 1000 elements and the elements can range from 1 to 1000. The threshold value k can range from 1 to 10^9.
I am not a java programmer.But I think its a logical problem.So,I have solved it for you in python.I am pretty sure you can convert it into java.
Here is the code:
x = input('Enter the number:')
a = [2, 6, 7]
b = [6, 9]
c = [4]
d = [4, 7]
e = [8, 10, 15]
i = 0
z = 0
final_list = []
while i <= int(x):
try:
i += a[z]
final_list.append(a[z])
except BaseException:
pass
try:
i += b[z]
final_list.append(b[z])
except BaseException:
pass
try:
i += c[z]
final_list.append(c[z])
except BaseException:
pass
try:
i += d[z]
final_list.append(d[z])
except BaseException:
pass
try:
i += e[z]
final_list.append(e[z])
except BaseException:
pass
z += 1
print(final_list)
One way is this. There has to be at least one solution where you pick one number from each array and add them up to be greater than or equal to another.
Considering the fact that arrays might have random numbers in any order, first use this sort function to have them in decreasing order (largest number first, smallest number last) :
Arrays.sort(<array name>, Collections.reverseOrder());
Then pick the 1st element in the array :
v = A[0]
w = B[0]
x = C[0]
y = D[0]
z = E[0]
Then you can print them like this : v,w,x,y,z
Now your output will be :
7,9,4,7,15
Since it took the largest number of each array, it has to be equal to or greater than the given number, unless the number is greater than all of these combined in which case it is impossible.
Edit : I think I got the question wrong. If you want to know how many of the possible solutions there are, that is much easier.
First create a variable to store the possibilities
var total = 0
Use the rand function to get a random number. In your array say something like :
v=A[Math.random(0,A[].length)]
Do the same thing for all arrays, then add them up
var sum = v+w+x+y+z
Now you have an if statement to see if the sum is greater than or equal to the number given (lets say the value is stored in the variable "given")
if(sum >= given){
total+=1
}else{
<repeat the random function to restart the process and generate a new sum>
}
Finally, you need to repeat this multiple times as incase there are multiple solutions, the code will only find one and give you a false total.
To solve this, create a for loop and put all of this code inside it :
//create a variable outside to store the total number of elements in all the arrays
var elements = A[].length + B[].length + C[].length + D[].length + E[].length
for(var i = 0; i <= elements; i++){
<The code is inside here, except for "total" as otherwise the value will keep resetting>
}
The end result should look something like this :
var total = 0
var elements = A[].length + B[].length + C[].length + D[].length + E[].length
for(var i = 0; i <= elements; i++){
v=A[Math.random(0,A[].length)]
w=B[Math.random(0,B[].length)]
x=C[Math.random(0,C[].length)]
y=D[Math.random(0,D[].length)]
z=E[Math.random(0,E[].length)]
var sum = v+w+x+y+z
if(sum >= given){
total+=1
}else{
v=A[Math.random(0,A[].length)]
w=B[Math.random(0,B[].length)]
x=C[Math.random(0,C[].length)]
y=D[Math.random(0,D[].length)]
z=E[Math.random(0,E[].length)]
}
}
At the end just print the total once the entire cycle is over or just do
console.log(total)
This is just for reference and the code might not work, it probably has a bunch of bugs in it, this was just my 1st draft attempt at it. I have to test it out on my own but i hope you see where I'm coming from. Just look at the process, make your own amendments and this should work fine.
I have not deleted the first part of my answer even though it isn't the answer to this question just so that if you're having trouble in that part as well, where you select the highest possible number, it might help you
Good luck!

Excess (-1) in base 4 representation

I've been trying to wrap my head around this one problem for the last couple of days, and I can't figure out a way to solve it. So, here it goes:
Given the base 4(that is 0, 1, 2, 3 as digits for a number), find the excess (-1) in base 4 representation of any negative or positive integer number.
examples:
-6 = (-1)22
conversely, (-1)22 in excess (-1) of base 4 = 2 * 4^0 + 2 * 4^1 + (-1) * 4^2 = 2 + 8 - 16 = 10 - 16 = -6 in base 10
27 = 2(-1)(-1)
conversely, 2(-1)(-1) = (-1) * 4^0 + (-1) * 4^1 + 2 * 4^2 = -1 - 4 + 32 = 27
I did come up with a few algorithms for positive numbers, but none of them hold true for all negative numbers, so into the trash they went.
Can anyone give me some kind of clue here? Thanks!
----------------
Edit: I'm going to try to rephrase this question in such a way that it does not raise any confusions.
Consider the radix obtained by subtracting 1 from every digit, called the excess-(-1) of base 4. In this radix, any number can be represented using the digits -1, 0, 1, 2. So, the problem asks for an algorithm that gets as an input any integer number, and gives as output the representation of that given number.
Examples:
decimal -6 = -1 2 2 for the excess-(-1) of base 4.
To verify this, we take the representation -1 -1 2 and transform it to a decimal number, start from the right-most digit and use the generic base n to base 10 algorithm, like so:
number = 2 * 4^0 + 2 * 4^1 + (-1) * 4^2 = 2 + 4 - 16 = -6
I don't know if "quaterit" is the correct word for the radix in this representation, but I'm going to use it anyway.
Since you say you already have an algorithm for positive numbers, I'll try to take a negative number as an input and write something that uses what you already have. The code below doesn't quite work, but I'll explain why at the end.
int[] BaseFourExcessForNegativeNumbers(int x) {
int powerOfFour = 1;
while (-powerOfFour > x) {
powerOfFour *= 4;
}
int firstQuaterit = -1;
int remainder = x + powerOfFour;
int[] otherQuaterits;
if (remainder >= 0) {
otherQuaterits = BaseFourExcessForPositiveNumbers(remainder);
} else {
otherQuaterits = BaseFourExcessForNegativeNumbers(remainder);
}
int[] result = new int[otherQuaterits.Length + 1];
result[0] = firstQuaterit;
for (int index = 0; index < otherQuaterits.Length; ++index) {
result[index + 1] = otherQuaterits[index];
}
return result;
}
The idea here is that every negative number x will start with a (-1) in this representation. If that (-1) is in the 4^n position, we want to find out how to represent x - (-1)*4^n to see how to represent the rest of the number.
The reason the code I wrote won't work is that it doesn't take into consideration the possibility that the second quaterit is a 0. If that happens, the array my code will produce will be missing that 0. In fact, if BaseFourExcessForPositiveNumbers is written in the same way, the resulting array will be missing every 0, but will otherwise be correct. A workaround is to keep track of which place the first quaterit takes, and then make the array that size, and fill it from the back to the front.

Mapping function for two integers

SO,
The problem
I have two integers, which are in first case, positive, and in second case - just any integers. I need to create a map function F from them to some another integer value, which will be:
Result should be integer value. For first case (x>0, y>0), positive integer value
Symmetric. That means F(x, y) = F(y, x)
Unique. That means F(x0, y0) = F(x1, y1) <=> (x0 = x1 ^ y0 = y1) V (y0 = x1 ^ x0 = y1)
My approach
At first glance, for positive integers we could use expression like F(x, y) = x2 + y2, but that will fail - for example, 892 + 232 = 132 + 912 As for second (common) case - that's even more complicated.
Use-case
That may be useful when dealing with some things, which supposed to be order-independent and need to be unique. For example, if we want to find cartesian product of many arrays and we want result to be unique independent of order, i.e. <x,z,y> is equal to <x,y,z>. It may be done with:
function decartProductPair($one, $two, $unique=false)
{
$result = [];
for($i=0; $i<count($one); $i++)
{
for($j=0; $j<count($two); $j++)
{
if($unique)
{
if($i!=$j)
{
$result[$i*$i+$j*$j]=array_merge((array)$one[$i],(array)$two[$j]);
// ^
// |
// +----//this is the place where F(i,j) is needed
}
}
else
{
$result[]=array_merge((array)$one[$i], (array)$two[$j]);
}
}
}
return array_values($result);
}
Another use-case is to properly group sender and receiver in some SQL table, so that different senders/receivers will be differed while they should stay symmetric. Something like:
SELECT
COUNT(1) AS message_count,
sender,
receiver
FROM
test
GROUP BY
-- this is the place where F(sender, receiver) is needed:
sender*sender + receiver*receiver
(By posting samples I wanted to show that issue is certainly related to programming)
The question
As mentioned, the question is - what can be used as F? I want as simple F as it's possible. Keep in mind two cases:
Integer x>0, y>0. F(x,y) > 0
Any integer x, y and so any integer F(x,y) as a result
May be F isn't just an expression - but some algorithm to find desired result for any x,y (so tagging with algorithm too). However, expression is better because it's more like that it will be able to use that expression in SQL or PHP or whatever. Feel free to edit tagging because I'm not sure if two tags here is enough
Most simple solution: f(x,y) = x^5 + y^5
No positive integer is known which can be written as the sum of two fifth powers in more than one way.
As for now, this is unsolved math problem.
You need a MAX_INTEGER constant, and the result will need to hold MAX_INTEGER**2 (say: be a long, if both are int's). In that case, one such function is:
f(x,y) = min(x,y)*MAX_INTEGER + max(x,y)
But I propose a different solution: use a hash function (say md5) of the string resulting from the concatenation of str(min(x,y)), a separator (say ".") and str(max(x,y)). That is:
f(x,y) = md5(str(min(x,y)) + "." + str(max(x,y)))
It is not unique, but collisions are very rare, and probably OK for most use cases. If still worried about collisions, save the actualy {x,y} along with f(x,y), and check if collisions happened.
Sort input numbers and interleave their bits:
x = 5
y = 3
Step 1. Sorting: 3, 5
Step 2. Mixing bits: 11, 101 -> 1_1_, 1_0_1 -> 11011 = 27
So, F(3, 5) = 27
A compact representation is x*(x+3)/2 + y*(x+1) + (y*(y-1))/2, which comes from an arrangement like this:
x->
y 0 1 3 6 10 15
| 2 4 7 11 16
v 5 8 12 17
9 13 18
14 19
20
According to [Stackoverflow:mapping-two-integers-to-one-in-a-unique-and-deterministic-way][1], if we symmetrize the formula we would have the following:
(x + y) * (x + y + 1) / 2 + min(x, y)
This might just work. For
(x + y) * (x + y + 1) / 2 + x
is unique, then the first formula is also unique.
[1]: Mapping two integers to one, in a unique and deterministic way

How to best create a random float in a range between two floats

I know that I can generate random floats with rand(max). I tried to generate a float in a range, this shouldn't be hard. But e.g rand(1.4512) returns 0, thus rand isn't calculating with floats. Now I tried a little trick, converting the thing to an integer and after randomizing a fitting number in my desired range, calculating it back to a float.. which is not working.
My question is how to do this in a better way. If there is no better way, why is this one not working? (Maybe it's too late for me, I should've started sleeping 2 hours ago..). The whole thing aims to be a method for calculating a "position" field for database records so users can order them manually. I've never done something like this before, maybe someone can hint me with a better solution.
Here's the code so far:
def calculate_position(#elements, index)
min = #elements[index].position
if #elements[index + 1].nil?
pos = min + 1
else
pos = min + (rand(#elements[index + 1].position * 10000000000) / 10000000000)
end
return pos
end
Pass a range of floats to rand
If you want to "create a random float in a range between two floats", just pass a range of floats to rand.
rand(11.2...76.9)
(Tested with Ruby 2.1)
Edit
According to the documentation: https://ruby-doc.org/core-2.4.0/Random.html
There are two different ways to write the random function: inclusive and exclusive for the last value
rand(5..9) # => one of [5, 6, 7, 8, 9]
rand(5...9) # => one of [5, 6, 7, 8]
rand(5.0..9.0) # => between 5.0 and 9.0, including 9.0
rand(5.0...9.0) # => between 5.0 and 9.0, excluding 9.0
Let's recap:
rand() will generate a (psuedo-)random
float between 0 and 1.
rand(int) will generate a
(psuedo-)random integer between 0 and
int.
So something like:
def range (min, max)
rand * (max-min) + min
end
Should do nicely.
Update:
Just tested with a little unit test:
def testRange
min = 1
max = 100
1_000_000.times {
result = range min, max
print "ERROR" if result < min || result > max
}
end
Looks fine.
In 1.9 and 2.0 you can give a range argument to rand:
irb(main):001:0> 10.times { puts rand Math::E..Math::PI }
3.0656267148715446
2.7813979580609587
2.7661725184200563
2.9745784681934655
2.852157154320737
2.741063222095785
2.992638029938756
3.0713152547478866
2.879739743508003
2.7836491029737407
=> 10
I think your best bet is to use rand() to generate a random float between 0 and 1, and then multiply to set the range and add to set the offset:
def float_rand(start_num, end_num=0)
width = end_num-start_num
return (rand*width)+start_num
end
Note: since the order of the terms doesn't matter, making end_num default to 0 allows you to get a random float between 0 and x with float_rand(x).

Resources