Ranges (double-dot ".." operator) with multiplication operator - rust

I recently came across this expression in some code written by GUILLAUME ENDIGNOUX, which produces a vector of 10 numbers:
(10 * i..10 * (i + 1)).collect()
Gives: 420, 421, 422, 423, 424, 425, 426, 427, 428, 429
Here is a working example, where I have replaced the number "10" with "3" to simplify:
fn main() {
let v = get_data(42);
assert_eq!(v, [126, 127, 128]);
}
fn get_data(i: usize) -> Vec<usize>{
(3 * i..3 * (i + 1)).collect() // How does this work?
}
What is going on here?
Changing the first number to for instance 1,like so:
( 1 * i..3 * (i + 1)).collect()
I expected the vecor to contain 1 element, but I got all numbers from 42 to 128 (inclusive). I.e. 86 numbers in total.

The .. operator has fairly low precedence meaning that your multiplication applies before it.
So
(1 * i..3 * (i + 1)).collect()
is equivalent to
((1 * i)..(3 * (i + 1)).collect()
with a value 42 for i that gives the range 42..129, matching what you observe.

Related

How spark reduce works here

How does spark reduce work for this example?
val num = sc.parallelize(List(1,2,3))
val result = num.reduce((x, y) => x + y)
res: Int = 6
val result = num.reduce((x, y) => x + (y * 10))
res: Int = 321
I understand the 1st result (1 + 2 + 3 = 6). For the 2nd result, I thought the result would be 60 but it's not. Can someone explain?
Step1 : 0 + (1 * 10) = 10
Step2 : 10 + (2 * 10) = 30
Step3 : 30 + (3 * 10) = 60
Update:
As per Spark documentation:
The function should be commutative and associative so that it can be
computed correctly in parallel.
https://spark.apache.org/docs/latest/rdd-programming-guide.html
(2,3) -> 2 + 3 * 10 = 32
(1,(2,3)) -> (1,32) -> 1 + 32 * 10 = 321
A reducer (in general, not just Spark), takes a pair, applies the reduce function and takes the result and applies it again to another element. Until all elements have been applied. The order is implementation specific (or even random if in parallel), but as a rule, it should not affect the end result (commutative and associative).
Check also this https://stackoverflow.com/a/31660532/290036

Python Bit Summation Algorithm

I am trying to implement a function that will be used to judge whether a generator's output is continuous. The method I am gravitating towards is to iterate through the generator. For each value, I right justify the bits of the value (disregarding the 0b), count the number of ones, and shift the number of ones.
#!/usr/bin/python3
from typing import Tuple
def find_bit_sum(top: int, pad_length: int) -> int :
"""."""
return pad_length * (top + 1)
def find_pad_length(top: int) -> int :
"""."""
return len(bin(top)) - 2 # -"0b"
def guess_certain(top: int, pad_length: int) -> Tuple[int, int, int] :
"""."""
_both: int = find_bit_sum(top, pad_length)
_ones: int = sum(sum(int(_i_in) for _i_in in bin(_i_out)[2 :]) for _i_out in range(1, top + 1))
return _both - _ones, _ones, _both # zeros, ones, sum
def guess(top: int, pad_length: int) -> Tuple[int, int, int] : # zeros then ones then sum
"""."""
_bit_sum: int = find_bit_sum(top, pad_length) # number of bits in total
_zeros: int = _bit_sum # ones are deducted
_ones: int = 0 # _bit_sum - _zeros
# detect ones
for _indexed in range(pad_length) :
_ones_found: int = int(top // (2 ** (_indexed + 1))) # HELP!!!
_zeros -= _ones_found
_ones += _ones_found
#
return _zeros, _ones, _bit_sum
def test_the_guess(max_value: int) -> bool : # the range is int [0, max_value + 1)
pad: int = find_pad_length(max_value)
_zeros0, _ones0, _total0 = guess_certain(max_value, pad)
_zeros1, _ones1, _total1 = guess(max_value, pad)
return all((
_zeros0 == _zeros1,
_ones0 == _ones1,
_total0 == _total1
))
if __name__ == '__main__' : # should produce a lot of True
for x in range(3000) :
print(test_the_guess(x))
For the life of me, I cannot make guess() agree with guess_certain(). The time complexity of guess_certain() is my problem: it works for small ranges [0, top], but one can forget 256-bit numbers (tops). The find_bit_sum() function works perfectly. The find_pad_length() function also works.
top // (2 ** (_indexed + 1))
I've tried 40 or 50 variations of the guess() function. It has thoroughly frustrated me. The guess() function is probabilistic. In its finished state: if it returns False, then the Generator definitely isn't producing every value in range(top + 1); however, if it returns True, then the Generator could be. We already know that the generator range(top + 1) is continuous because it does produce each number between 0 and top inclusively; so, test_the_guess() should be returning True.
I sincerely do apologise for the chaotic explanation. If you have anny questions, please don't hesitate to ask.
I adjusted your ones_found assignment statement to account for the number of powers of two per int(top // (2 ** (_indexed + 1))), as well as a additional "rollover" ones that occur before the next power of two. Here is the resulting statement:
_ones_found: int = int(top // (2 ** (_indexed + 1))) * (2 ** (_indexed)) + max(0, (top % (2 ** (_indexed + 1))) - (2 ** _indexed) + 1)
I also took the liberty of converting the statement to bitwise operators for both clarity and speed, as shown below:
_ones_found: int = ((top >> _indexed + 1) << _indexed) + max(0, (top & (1 << _indexed + 1) - 1) - (1 << _indexed) + 1)

Is there a limit to the size of a BigInt or BigUint in Rust?

Is there no limit to the size of a BigInt or BigUint from the num crate in Rust? I see that in Java its length is bounded by the upper limit of an integer Integer.MAX_VALUE as it is stored as an array of int.
I did go through the documentation for it but could not really deduce my answer from
A BigUint-typed value BigUint { data: vec!(a, b, c) } represents a
number (a + b * big_digit::BASE + c * big_digit::BASE^2).
big_digit::BASE being defined as
pub const BASE: DoubleBigDigit = 1 << BITS
BITS in turn is 32
So is the BigInt being represented as (a + b * 64 + c * 64^2) internally?
TL;DR: the maximum number that can be represented is roughly:
3.079 x 10^22212093154093428519
I suppose that nothing useful needs such a big number to be represented. You can be certain that the num_bigint will do the job, whatever the usage you have with it.
In theory, there is no limit to the num big integers size since the documentation says nothing about it (version 0.1.44). However, there is a concrete limit that we can calculate:
BigUint is a Vec<BigDigit>, and BigDigit is an u32. As far as I know, Rust does not define a max size for a Vec, but since the maximum possible allocated size is isize::MAX, the maximum number of BigDigit aka u32 is:
MAX_LEN = isize::MAX / sizeof(u32)
With this information, we can deduce that the maximum of a num::BigUint (and a num::BigInt as well) in the current implementation is:
(u32::MAX + 1) ^ MAX_LEN - 1 = 2^32^MAX_LEN - 1
To have this formula, we mimic the way we calculate u8::MAX, for example:
bit::MAX is 1,
the length is 8,
so the maximum is (bit::MAX + 1) ^ 8 - 1 = 255
Here is the full demonstration from the formula given by the num documentation:
a + b * big_digit::BASE + c * big_digit::BASE^2 + ...
If we are taking the max value, a == b == c == u32::MAX. Let's name it a. Let's name big_digit::BASE b for convenience. So the max number is:
sum(a * b^n) where n is from 0 to (MAX_LEN - 1)
if we factorize, we get:
a * sum(b^n) where n is from 0 to (MAX_LEN - 1)
The general formula of the sum of x^n is (x^(n + 1) - 1) / (x - 1). So, because n is MAX_LEN - 1, the result is:
a * (b^(MAX_LEN - 1 + 1) - 1) / (b - 1)
We replace a and b with the right value, and the biggest representable number is:
u32::MAX * (2^32^MAX_LEN - 1) / (2^32 - 1)
u32::MAX is 2^32 - 1, so this can be simplified into:
2^32^MAX_LEN - 1

New cords for larger line

I have a class representing lines on two-dimensional space:
class Line {
Point start;
Point end;
Float length; // calculated property, something like sqrt(pow(end.x - start.x, 2) + pow(end.y - start.y, 2))
}
I want a method to make a line bigger from the center.
For example, if I create some parallel to X:
Point start = Point(1, 3)
Point end = Point(1, 10)
Line newLine = Line(start, end) // newLine.length here is 7
and then call method makeBigger:
newLine.makeBigger(4); // pass number of points here
I want to receive new line (or modify old's start / end properties) with start = (1,1) / end = (1, 12), so its length becomes 11.
Please note, that I want to consider angles as well.
As far as I understand, makeBigger(4) denotes than you want to increase length by 4. So use simple proportionality
newlength = length + increasevalue
dx = (end.x - start.x) / 2
mx = (end.x + start.x) / 2
newstart.x = mx - dx * newlength / length
newend.x = mx + dx * newlength / length
and similar for y

Partition line into equal parts

This is a geometry question.
I have a line between two points A and B and want separate it into k equal parts. I need the coordinates of the points that partition the line between A and B.
Any help is highly appreciated.
Thanks a lot!
You just need a weighted average of A and B.
C(t) = A * (1-t) + B * t
or, in 2-D
Cx = Ax * (1-t) + Bx * t
Cy = Ay * (1-t) + By * t
When t=0, you get A.
When t=1, you get B.
When t=.25, you a point 25% of the way from A to B
etc
So, to divide the line into k equal parts, make a loop and find C, for t=0/k, t=1/k, t=2/k, ... , t=k/k
for(int i=0;i<38;i++)
{
Points[i].x = m_Pos.x * (1 - (i/38.0)) + m_To.x * (i / 38.0);
Points[i].y = m_Pos.y * (1 - (i/38.0)) + m_To.y * (i / 38.0);
if(i == 0 || i == 37 || i == 19) dbg_msg("CLight","(%d)\nPos(%f,%f)\nTo(%f,%f)\nPoint(%f,%f)",i,m_Pos.x,m_Pos.y,m_To.x,m_To.y,Points[i].x,Points[i].y);
}
prints:
[4c7cba40][CLight]: (0)
Pos(3376.000000,1808.000000)
To(3400.851563,1726.714111)
Point(3376.000000,1808.000000)
[4c7cba40][CLight]: (19)
Pos(3376.000000,1808.000000)
To(3400.851563,1726.714111)
Point(3388.425781,1767.357056)
[4c7cba40][CLight]: (37)
Pos(3376.000000,1808.000000)
To(3400.851563,1726.714111)
Point(3400.851563,1726.714111)
which looks fine but then my program doesn't work :D.
but your method works so thanks

Resources