I'm on a journey learning rust at my own pace. I'm primarily a C++, Python programmer.
Instead of just following the manual, I try to do weird things in the language and understand the behaviour.
I'm experimenting with the concept of shadowing variables in rust. Can I get an understanding of why this program prints 1 continuously?
fn main() {
let counter = 0;
let counter = loop{
let counter = counter + 1;
println!("{}", counter);
if counter == 10{
break counter * 2;
}
};
println!("The result is {}", counter);
}
Here is what I thought would occur. I haven't yet tried it in debugger though.
counter is initialized and assigned 0.
the loop is run,
2.1 counter will be incremented by 1.
2.2 it will print 1.
2.3 check if counter is 10, if it is so, break with counter * 2, this will be returned out of the loop.
2.4 else, just continue...
counter is now 20.
print "The result is 20"
I'd expect to see:
1
2
3
4
5
6
7
8
9
10
The result is 20
What I get:
1
1
1
1
1
1
1
1
1
.. and so on
Is it that shadowing reinitializes the named variable to 0? That is what occurs here..
In
let counter = 0;
let counter = loop{
let counter = counter + 1;
...
}
At any iteration, you're starting from a new scope, the previous version doesn't exist. The right part of the let counter = counter + 1; assignment always refer to the outside counter, which is always 0.
Related
I have this code and I want every combination to be multiplied:
fn main() {
let min = 1;
let max = 9;
for i in (min..=max).rev() {
for j in (min..=max).rev() {
println!("{}", i * j);
}
}
}
Result is something like:
81
72
[...]
9
72
65
[...]
8
6
4
2
9
8
7
6
5
4
3
2
1
Is there a clever way to produce the results in descending order (without collecting and sorting) and without duplicates?
Note that this answer provides a solution for this specific problem (multiplication table) but the title asks a more general question (any two iterators).
The naive solution of storing all elements in a vector and then sorting it uses O(n^2 log n) time and O(n^2) space (where n is the size of the multiplication table).
You can use a priority queue to reduce the memory to O(n):
use std::collections::BinaryHeap;
fn main() {
let n = 9;
let mut heap = BinaryHeap::new();
for j in 1..=n {
heap.push((9 * j, j));
}
let mut last = n * n + 1;
while let Some((val, j)) = heap.pop() {
if val < last {
println!("{val}");
last = val;
}
if val > j {
heap.push((val - j, j));
}
}
}
playground.
The conceptual idea behind the algorithm is to consider 9 separate sequences
9*9, 9*8, 9*7, .., 9*1
8*9, 8*8, 8*7, .., 8*1
...
1*9, 1*8, 1*7, .., 1*1
Since they are all decreasing, at a given moment, we only need to consider one element of each sequence (the largest one we haven't reached yet).
These are inserted into the priority queue which allows us to efficiently find the maximum one.
Once we have printed a given element we move onto the next one in the sequence and insert that into the priority queue.
By keeping track of the last element printed we can avoid duplicates.
I tried to run the following Node.js code:
for (let a = 5; a === 11 ; a++) {
console.log(a);
}
I want to know how this loop returns the result . (Logically, step by step.) Why does it log nothing to the console?
Example:
It starts with 5.
It then gets added by 1 each time.
It's stopping condition is...
Thanks in advance and do ask in comments if the question wasn't clear.
This particular loop should not print anything.
for (let a = 5; a === 11 ; a++) {
console.log(a);
}
The loop states: "Execute the code inside me, as long as a is equal to 11.
However, in our case, a is initialized to 5. Because of this, when we first start the loop, its run condition is already false, so it never executes.
An example of a loop that would print the numbers from 5 to 10:
for (let a = 5; a < 11 ; a++) {
console.log(a);
}
It is important to note that the condition in a for loop is the run condition, not the end condition.
Ok, so your problem here is that it only runs if the variable A is equal to 11.
If you want everything from 5 below 11 you use a < symbol.
I'll explain the steps in this example.
for (a = 5; a < 11; a++) {
console.log(a)
}
It starts with 5.
It then gets added by 1 each time.
Its stopping condition is if A is greater than or equal to 11.
I am trying to use a nested for loop to create x and y coordinates for a method call. However, console.log shows that the loop variables are starting at the wrong value. Why is this? Here is my code:
for(let x = 0; x < 64; x++) {
console.log(x);
for(let y = 0; y < 32; y++) {
console.log(y);
}
}
This prints:
22
23
24
25
26
27
28
29
30
31
34
0
1
2
3
4
5
6
7
8
[values 9 - 30 omitted]
31
34
1
...and so on
Are you sure? I have tested this with node v8.9.1 and the code works for me as expected:
The outer loop starts at index 0 which gets printed on the console,
then the inner loop prints numbers 0 to 31.
In turn the outer loop continues at index 1 which gets printed on console and
then the inner loop prints 0 to 31,
and so on
May be you got confused with the output at some point. Thus, my suggestion is to prefix the console outputs with x and y as shown below.
for(let x = 0; x < 64; x++) {
console.log('x=' + x);
for(let y = 0; y < 32; y++) {
console.log('y=' + y);
}
}
You can also trial this on repl.it
I can tell you with relative confidence that the behaviour your print is describing is not the behaviour a for-loop of the kind you've written will yield.
In fact, copy-pasting your exact code to the Chrome console (which runs V8, the same as node) will yield the correct result:
Your issue lies either elsewhere in your code or in the tool you're looking at the logging in.
Was trying to check a 2d vector and noticed some weird behavior that I haven't been able to find a explanation for.
fn main() {
let mut main_loop = vec![];
let mut x = 0;
let board_x = 10;
let mut y = 0;
let board_y = 10;
while y < board_y {
let mut row = vec![];
while x < board_x {
let v = random::<bool>();
println!("x:{}", x);
row.push(v);
x = x + 1;
}
println!("y:{}", y);
main_loop.push(row);
y = y + 1;
}
}
This only prints
x:0
x:1
x:2
x:3
x:4
x:5
x:6
x:7
x:8
x:9
y:0
y:1
y:2
y:3
y:4
y:5
y:6
y:7
y:8
y:9
Shouldn't this be printing out x:1 - x:10 10 times? Also what was even stranger was that when I looped back over the vectors using a nested for loops for each row, it counted out 60 indexes before exiting out. What am I missing?
Shouldn't this be printing out x:1 - x:10 10 times?
Why would it? You never set x back to zero after the inner loop is done.
Besides which, this sort of iteration should be done with a for loop:
for x in 0..10 { ... }
[...] when I looped back over the vectors using a nested for loops for each row, it counted out 60 indexes before exiting out.
I don't know; you didn't post that code, and I can't see any reason it would do that.
int x = 0 // global shared variable
T1: for (i=0; i++; i<100) x++;
T2: x++ // no loop, just one increment
T1 and T2 are separate threads. I am told the final value of x can be ANYTHING from the values of 1 and 101. How is this possible? I am wondering how this could possibly just be 1.
Obviously, something fails in the execution sequence, but I'm wondering what.
x++ is not atomic operation (at least in most languages), this operation actually works like this:
tmp = x;
tmp = tmp + 1;
x = tmp;
now assume next execution order:
T2: tmp = x; // tmp is 0
T1: run all loop iterations, finally x is 100
T2: tmp = tmp+1; x = tmp; // x is 1
to get any other number, imagine next order:
T1: started loop, at some point x is 45
T2: tmp = x; // tmp is 45
T1: finished loop, x is 100
T2: tmp = tmp+1; x = tmp; // x is 46
The reason for this behavior is memory caching. Since threads can be executed on independent cpu's following situation is possible:
T1: loads x value
T2: loads x value
T1: runs loop 10 times (T1_x=10)
T2: increments (T2_x=1)
T1: saves value 10 to memory
T2: saves value 1 to memory
This is why you need thread synchronization. You can read more here: Mutex example / tutorial?
Thank you #Lashane for correction.