How do goroutines work? - concurrency

I was following the Go Tour and I am a bit stuck when it comes to goroutines. I understand that they are very lightweight and that every time a goroutine blocks, another one will start but I can't get my head around how this example actually works:
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(1000 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("world")
say("hello")
}
Playground
I understand that a goroutine is started for the say function with the argument "world", but as far as I understand that should print "world" five times and "hello" once. However I don't understand why the output is as it is:
hello
world
hello
world
hello
world
hello
world
hello
From my limited understanding of threads from other languages the output should have been something like this:
hello
world
world
world
world
world
or like this:
world
world
world
hello
world
world
Why does the second line execute five times as well? Does anything below a go statement classify as part of the go routine?
Also the next slide shows something I can't get my head round again:
package main
import "fmt"
func sum(a []int, c chan int) {
sum := 0
for _, v := range a {
sum += v
}
c <- sum // send sum to c
}
func main() {
a := []int{7, 2, 8, -9, 4, 0}
c := make(chan int)
go sum(a[:len(a)/2], c)
go sum(a[len(a)/2:], c)
x, y := <-c, <-c // receive from c
fmt.Println(x, y, x+y)
}
Playground
A goroutine is started for the second half of the slice and then another one for the first part of the slice, however the values x and y have been assigned two different values. The way I see it the sum function will send it's sum to channel c and then the next sum will send it's sum to the same channel c so how can the two variables be assigned two different values? Shouldn't channel c have one single sum value in there?
I appreciate that this is quite a long question but I wasn't able to find the answer to these questions.

Why does the second line execute 5 times as well?
The second line will print hello every second 5 times in the main() thread.
But concurrently the first line go say("world") will also print world every seconds five times in a separate goroutine.
The Sleep ensure that each routine yields, allowing the other to resume.
Hence the output:
hello
world
hello
world
hello
world
hello
world
hello
The way I see it the sum function will send it's sum to channel c and then the next sum will send it's sum to the same channel c so how can the two variables be assigned two different values?
Because each send will block on c until channel c is read.
Since there are two write to c, you need to read:
x, y := <-c, <-c // receive from c twice.
The Assignement section of Golang Spec allows for a tuple assignment if:
the number of operands on the left must equal the number of expressions on the right, each of which must be single-valued, and the nth expression on the right is assigned to the nth operand on the left.

For the first function you should see values in the style VonC presented. The reason hello prints 5 times as well is because the function say prints things 5 times. Just imagine the program without the goroutine. I think it doesn't guarantee that you will get hello and world perfectly interspersed but I may be wrong.
The reason the channel works is:
Golang let's you do multiple assignment as VonC mentions
Channels empty out, i.e. when you assign c to x it removes the first sum that was passed into the channel and when it assigns c to y it passes in the second value (again I think the order is not a guarantee as x could have the first half and y the second half sum or vice-versa.
If you imagine channels as a sort of a queue I think it makes more sense. The summing goroutines push values onto the queue and assignments pop the values sequentially.

Related

How to fix binary search algorithm?

Ok so i have been learning binary search. My teacher has given me a problem on codeforces and it always fails on test 2. Here is the problem:
In this problem jury has some number x, and you have to guess it. The number x is always an integer from 1 and to n, where n
is given to you at the beginning.
You can make queries to the testing system. Each query is a single integer from 1
to n
. Flush output stream after printing each query. There are two different responses the testing program can provide:
the string "<" (without quotes), if the jury's number is less than the integer in your query;
the string ">=" (without quotes), if the jury's number is greater or equal to the integer in your query.
When your program guessed the number x
, print string "! x", where x
is the answer, and terminate your program normally immediately after flushing the output stream.
Your program is allowed to make no more than 25 queries (not including printing the answer) to the testing system.
Input
Use standard input to read the responses to the queries.
The first line contains an integer n
(1≤n≤pow(10,6) — maximum possible jury's number.
Following lines will contain responses to your queries — strings "<" or ">=". The i
-th line is a response to your i-th query. When your program will guess the number print "! x", where x
is the answer and terminate your program.
The testing system will allow you to read the response on the query only after your program print the query for the system and perform flush operation.
Output
To make the queries your program must use standard output.
Your program must print the queries — integer numbers xi
(1≤xi≤n), one query per line (do not forget "end of line" after each xi
). After printing each line your program must perform operation flush.
And here is my code:
#include <iostream>
using namespace std;
int main()
{
int n;
string s;
int k=0;
cin>>n;
int min=1,max=n;
int a;
while(k==0)
{
if(max==min+1)
{
cout<<"! "<<min;
k=1;
break;
}
a=(min+max)/2;
cout<<a<<endl;
cin>>s;
if(s==">=")
min=a;
else
max=a;
}
}
I dont know what test 2 is, but i would be happy to hear ideas as to where my programs is wrong. My guess is its something with the number of guesses. Thanks in advance!
I have tried variations of the loop written above, but they all give the same result.

recursively print n, n-1, n-2,...3,2,1,2,3,...n

Hello I have a homework question I am stuck in..any hint or tips would be appreciated. the questions is:
Write a single recursive function in C++ that takes as argument a positive integer n then print n, n-1, n-2,...3,2,1,2,3,...n. How many recursive call does your algorithm makes? What is the worst case running time of your algorithm?
I am stuck in the first part. writing a recursive function that prints n, n-1, n-2,...3,2,1,2,3,...n
so far I have:
print(int n)
{
if (n==0)
return;
cout<<n<<" ";
print(n-1);
return;
}
but this only prints from n to 1
I am lost about how I would print from 2 to n using just one parameter and recursively single function.
I tried this: which gives the correct output but has a loop and has two parameters:
p and z has the same value.
void print(int p,int z)
{
if (p==0)
{
for(int x=2;x<=z; x++)
cout<<x<<" ";
return;
}
else
cout<<p<<" ";
print(p-1,z);
return;
}
any hint or tips is much appreciated thank you.
so it is working now, but I am having trouble understanding how (question in comment):
void print(int n)
{
if (n==1){
cout<<n;
return;
}
else
cout<< n;
print(n-1); // how does it get passed this? to the line below?
cout<<n; // print(n-1) takes it back to the top?
return;
}
The output you want is mirrored, so you can have this series of steps:
print num
recursive step on num-1
print num again
That's the recursive case. Now you need an appropriate base case upon which to stop the recursion, which shouldn't be difficult.
Given the pseudocode:
recursive_print(n):
if n == 1:
print 1
return
print n
recursive_print(n-1)
print n
(If you prefer, just look at your solution instead).
Let's trace it. A dot will mark where we're up to in terms of printing.
. recursive_print(3) // Haven't printed anything
3 . recursive_print(2) 3 // Print the 3
3 2 . recursive_print(1) 2 3 //Print 2
3 2 1 . 2 3 // Print 1
3 2 1 2 . 3 // Print 2
3 2 1 2 3 . // Print 3
Each unrolling of the function gives us 2 numbers on opposite sides and we build down to the "1", then go back and print the rest of the numbers.
The "unrolling" is shown in this picture:
If you strip away the functions and leave yourself with a sequence of commands, you'll get:
print 3
print 2
print 1
print 2
print 3
where each indentation signifies a different function.
Simple solution for this:
Def fxn(n):
if n <= n:
if n > 0:
print(n)
fxn(n - 1)
print(n)
Def main():
Number = 6
fxn(Number)
Main()
If you struggle understanding how this works:
Basically, each time you call a function in a recursive problem, it isn't a loop. It's as if you were on the woods leaving a trail behind. Each time you call a function inside a function, it does its thing, then it goes right back to were you called it.
In other words, whenever you call a recursive function, once the newer attempt is done, it will go right back to were it used to be.
In loops, once each step is done, it is done, but in recursive functions you can do a lot with a lot less.
Printing before the recurse call in my code is the descension step, and once its descension finished, it will progresively unfold step by step, printing the ascension value and going back to the former recurse.
It seems way harder than it is, but it is really easy once you grasp it.
The answer is simpler than you think.
A recursive call is no different from a regular call. The only difference is that the function called is also the caller, so you need to make sure you don't call it forever (you already did that). Let's think about a regular call. If you have the following code snippet:
statement1
f();
statement2
The statement1 is executed, then f is called and does it's thing and then, after f finishes, statement2 is executed.
Now, let's think about your problem. I can see that your hard work on this question from the second program you've written, but forget about it, the first one is very close to the answer.
Let's think about what your function does. It prints all numbers from n to 0 and then from 0 to n. At the first step, you want to print n, then all the numbers from n-1 to 0 and from 0 to n-1, and print another n. See where it's going?
So, you have to do something like this:
print(n)
call f(n-1)
print(n)
I hope my explanation is clear enough.
This is more of hack -- using the std::stream rather than recursion...
void rec(int n) {
if (n==1) { cout << 1; return; }
cout << n;
rec(n-1);
cout << n;
}
int main() {
rec(3);
}
prints
32123

Creating a histogram with C++ (Homework)

In my c++ class, we got assigned pairs. Normally I can come up with an effective algorithm quite easily, this time I cannot figure out how to do this to save my life.
What I am looking for is someone to explain an algorithm (or just give me tips on what would work) in order to get this done. I'm still at the planning stage and want to get this code done on my own in order to learn. I just need a little help to get there.
We have to create histograms based on a 4 or 5 integer input. It is supposed to look something like this:
Calling histo(5, 4, 6, 2) should produce output that appears like:
*
* *
* * *
* * *
* * * *
* * * *
-------
A B C D
The formatting to this is just killing me. What makes it worse is that we cannot use any type of arrays or "advanced" sorting systems using other libraries.
At first I thought I could arrange the values from highest to lowest order. But then I realized I did not know how to do this without using the sort function and I was not sure how to go on from there.
Kudos for anyone who could help me get started on this assignment. :)
Try something along the lines of this:
Determine the largest number in the histogram
Using a loop like this to construct the histogram:
for(int i = largest; i >= 1; i--)
Inside the body of the loop, do steps 3 to 5 inclusive
If i <= value_of_column_a then print a *, otherwise print a space
Repeat step 3 for each column (or write a loop...)
Print a newline character
Print the horizontal line using -
Print the column labels
Maybe i'm mistaken on your q, but if you know how many items are in each column, it should be pretty easy to print them like your example:
Step 1: Find the Max of the numbers, store in variable, assign to column.
Step 2: Print spaces until you get to column with the max. Print star. Print remaining stars / spaces. Add a \n character.
Step 3: Find next max. Print stars in columns where the max is >= the max, otherwise print a space. Add newline. at end.
Step 4: Repeat step 3 (until stop condition below)
when you've printed the # of stars equal to the largest max, you've printed all of them.
Step 5: add the -------- line, and a \n
Step 6: add row headers and a \n
If I understood the problem correctly I think the problem can be solved like this:
a= <array of the numbers entered>
T=<number of numbers entered> = length(a) //This variable is used to
//determine if we have finished
//and it will change its value
Alph={A,B,C,D,E,F,G,..., Z} //A constant array containing the alphabet
//We will use it to print the bottom row
for (i=1 to T) {print Alph[i]+" "}; //Prints the letters (plus space),
//one for each number entered
for (i=1 to T) {print "--"}; //Prints the two dashes per letter above
//the letters, one for each
while (T!=0) do {
for (i=1 to N) do {
if (a[i]>0) {print "*"; a[i]--;} else {print " "; T--;};
};
if (T!=0) {T=N};
}
What this does is, for each non-zero entered number, it will print a * and then decrease the number entered. When one of the numbers becomes zero it stops putting *s for its column. When all numbers have become zero (notice that this will occur when the value of T comes out of the for as zero. This is what the variable T is for) then it stops.
I think the problem wasn't really about histograms. Notice it also doesn't require sorting or even knowing the

Objective Memory Comparison

I would like to write an algorithm that compares one memory block with another and provides an objective value, so as to determine the quality of the match. I've investigated memcmp, and all it is really useful for is to determine whether two memory blocks are identical or not. I've written a recursive function to accomplish this, but it's not working quite right.
DWORD CMemory::Compare( LPBYTE pDst, LPBYTE pSrc, DWORD len )
{
DWORD dwDiff;
if ( len == 0 )
{
dwDiff = 0;
}
else
{
dwDiff = (*pSrc - *pDst) * len; // * len is attempt to weight difference by MSB
dwDiff += this->Compare( pSrc + 1, pDst + 1, len - 1 );
}
return dwDiff;
}
The idea is that the more closely the two memory spaces match, the lower the return value will be. For example, let's say there are three memory blocks containing Hello World 0 !, Hello World 1 !, and Hello World 2 !, respectively, and I would like to find out which memory block is a "best match" with candidate hello world 1 !. The idea is that I would run the Compare function three times comparing the candidate with each memory block in turn, and Compare should return the lowest value for the memory block containing Hello World 1 !. However, what it's doing in reality, is returning the lowest value for the last memory block containing Hellow World 2 !.
Does anyone have any ideas on how I can improve this function? Thanks.
I think you need to take the absolute value of (*pSrc - *pDst). In "Hello World 1 !", you're getting a 0 for the number position, while in "Hello World 2 !" you're getting a -1, and -1 is less than 0.
Also, if you use this on a long section of memory you could run into stack problems, so you might want to make it iterative.
Your algorithm won't account for a character inserted or deleted, since it does a position by position compare. If you're worried about that, the problem gets much harder.
Considered writing abs(*pSrc-*pDst)? As otherwise you get negative values, which are allways lower than the perfect match (0).
To improve this...
Supply a length for both the source and the destination.
Supply a value 'n', for comparing n bytes of the source and destination.
You need to handle the case when the source and destination aren't the same size, or you're going to have problems with walking off the end.
Don't use recursion, unless you're dealing with really small blocks of memory.
You can do the same work by just using a loop.
This method is really really expensive to call.
If you're comparing strings, you may want to look into soundex.

Build a pyramid with numbers between 1 and the inserted integer

i'm trying to build a pyramid with numbers between 1 and the inserted number. For example, if i insert 6 to the integer, that the piramid will be as there:
12345654321
234565432
3456543
45654
565
6
I tried using a for loop but i get in any line one or ++ numbers to 6.
This is the code:
#include<stdio.h>
#include <iostream>
#include <conio.h>
int main()
{
int i,j,d;
std::cin >> d;
for(i=1;i<=d;i++)
{
for(j=1;j<=i;j++)
printf("%d",j);
printf("\n");
}
getch();
return 0;
}
How can i solve this problem building a pyramid like the shown.
Since this is homework, I won't paste an algorithm, but here's a few hints:
This 12345654321 can be printed by counting from one to six and then back to one.
This __3456543__ means that for numbers smaller than n, you have to output a _ instead, where n depends on the level you are printing.
Define your loop variables within the loop: for(int i=1;i<=d;i++) ... They are only interesting within the loop, and access outside the loop is usually an error, which is then flagged by the compiler.
There's no need to for the getch(); at the end. When you're in the debugger, you can put a breakpoint on the last line. If you aren't you don't want to have to press a key just to end your program.
If you use std::cout << j and std::cout << '\n' for outputting, you don't need printf() either. (Once you want formatting, many will tell you that printf format strings are easier. I don't believe that, but would accept it, if it weren't that you can crash any application with an ill-formed printf format string, while it's much harder to come up with a way to crash your app using streams.)
There you go:
for(j=i;j<=d;j++)
Also you forgot about formatting and the right side of the pyramid, but I think that's out of scope for this question and you can figure the code yourself :)
Try to have the first line working the way you want.
Repeat it d times, where d is the number entered by the user.
Notice that on line l, numbers < l are replaced by spaces.
Consider this: you have D rows, 1..D. Six rows means your rows are numbered 1 to 6. Now, for each row d:
print d-1 space characters. First row has no spaces, second has one and so on.
print the numbers d..D. So on the first line you print 1..6, on the second you print 2..6.
print the numbers D-1..d. So on the first line you print 5..1, on the second you print 5..2
print a new line