Tower of Hanoi recursion solution explanation - recursion

I have struggled with Tower of Hanoi problem for 3 months. Here's the simplest code I can find:
void moveDisk(int n, char from, char to, char buffer)
{
if(n == 1)
{
cout << "Move disk 1 from " << from << " to " << to << endl;
return;
}
moveDisk(n-1, from, buffer, to);
cout << "Move disk " << n << " from " << from << " to " << to << endl;
moveDisk(n-1, buffer, to, from);
}
int main()
{
moveDisk(3, 'A', 'C', 'B');
}
And it works perfectly well:
Move disk 1 from A to C
Move disk 2 from A to B
Move disk 1 from C to B
Move disk 3 from A to C
Move disk 1 from B to A
Move disk 2 from B to C
Move disk 1 from A to C
My biggest question is: Why it works?
I have done some research and they all say that: "Move the first n-1 disks to the 'buffer', then move the n disk to the 'to' stack and finally move the first n-1 disks to the 'to' stack. I understand the idea of it, but my question is: why writing the code that way works? Also: why do we need to print:
cout << "Move disk 1 from " << from << " to " << to << endl;
in the base case in order for it to work? If according to the idea above, why don't we just return when we hit the base case instead?
I tried to track the recursion by hand and the variable "from", "to", and "buffer" keep changing constantly - but somehow it works!
Please explain to me why?
Thank you!

Related

Point Cloud Library and While Loop

i am new to C++ and PCL. i wish to save the values of pointer in while loop and wanted to display the saved one . Here is part of my code . Please guide how to save the value of "coefficients->values[0] ,coefficients->values[1], coefficients->values[2], coefficients->values[3]" in an array each time loop runs.
// While 20% of the original cloud is still there
while (cloud_filtered->points.size () > 0.20 * nr_points)
{
// Segment the largest planar component from the remaining cloud
seg.setInputCloud (cloud_filtered);
seg.segment (*inliers, *coefficients);
if (inliers->indices.size () == 0)
{
std::cerr << "Could not estimate a planar model for the given dataset." << std::endl;
break;
}
std::cerr << "Model coefficients: " << coefficients->values[0] << " "
<< coefficients->values[1] << " "
<< coefficients->values[2] << " "
<< coefficients->values[3] << std::endl;
}
I am assuming that you are following this example code since the snippet you added in your question is almost to same. If this is the case, then you can declare a std::vector<pcl::ModelCoefficients> just before the while loop and push the coefficients into that like
std::vector<pcl::ModelCoefficients> coeffs;
while(...){
...
coeffs.push_back(*coefficients);
}
Also check the documentation for pcl::ModelCoefficients here which is nothing but a header and a vector of floats. Note that defining the coeffs as a vector of shared pointers and pushing pointers to the coefficients will not work in this case since previously pushed coefficients will be overwritten by seg.segment(*inliers, *coefficients);.

Memory copy speed comparison CPU<->GPU

I am now learning boost::compute openCL wrapper library.
I am experiencing very slow copy procedure.
If we scale CPU to CPU copy speed as 1, how fast is GPU to CPU, GPU to GPU, CPU to GPU copy?
I don't require precise numbers. Just a general idea would be a great help. In example CPU-CPU is at least 10 times faster than GPU-GPU.
No one is answering my question.
So I made a program to check the copy speed.
#include<vector>
#include<chrono>
#include<algorithm>
#include<iostream>
#include<boost/compute.hpp>
namespace compute = boost::compute;
using namespace std::chrono;
using namespace std;
int main()
{
int sz = 10000000;
std::vector<float> v1(sz, 2.3f), v2(sz);
compute::vector<float> v3(sz), v4(sz);
auto s = system_clock::now();
std::copy(v1.begin(), v1.end(), v2.begin());
auto e = system_clock::now();
cout << "cpu2cpu cp " << (e - s).count() << endl;
s = system_clock::now();
compute::copy(v1.begin(), v1.end(), v3.begin());
e = system_clock::now();
cout << "cpu2gpu cp " << (e - s).count() << endl;
s = system_clock::now();
compute::copy(v3.begin(), v3.end(), v4.begin());
e = system_clock::now();
cout << "gpu2gpu cp " << (e - s).count() << endl;
s = system_clock::now();
compute::copy(v3.begin(), v3.end(), v1.begin());
e = system_clock::now();
cout << "gpu2cpu cp " << (e - s).count() << endl;
return 0;
}
I expected that gpu2gpu copy would be fast.
But on the contrary, cpu2cpu was fastest and gpu2gpu was so slow in my case.
(My system is Intel I3 and Intel(R) HD Graphics Skylake ULT GT2.)
Maybe parallel processing is one thing and copy speed is another.
cpu2cpu cp 7549776
cpu2gpu cp 18707268
gpu2gpu cp 65841100
gpu2cpu cp 65803119
I hope anyone can benefit with this test program.

Peek on QTextStream

I would like to peek the next characters of a QTextStream reading a QFile, in order to create an efficient tokenizer.
However, I don't find any satisfying solution to do so.
QFile f("test.txt");
f.open(QIODevice::WriteOnly);
f.write("Hello world\nHello universe\n");
f.close();
f.open(QIODevice::ReadOnly);
QTextStream s(&f);
int i = 0;
while (!s.atEnd()) {
++i;
qDebug() << "Peek" << i << s.device()->peek(3);
QString v;
s >> v;
qDebug() << "Word" << i << v;
}
Gives the following output:
Peek 1 "Hel" # it works only the first time
Word 1 "Hello"
Peek 2 ""
Word 2 "world"
Peek 3 ""
Word 3 "Hello"
Peek 4 ""
Word 4 "universe"
Peek 5 ""
Word 5 ""
I tried several implementations, also with QTextStream::pos() and QTextStream::seek(). It works better, but pos() is buggy (returns -1 when the file is too big).
Does anyone have a solution to this recurrent problem? Thank you in advance.
You peek from QIODevice, but then you read from QTextStream, that's why peek works only once. Try this:
while (!s.atEnd()) {
++i;
qDebug() << "Peek" << i << s.device()->peek(3);
QByteArray v = s.device()->readLine ();
qDebug() << "Word" << i << v;
}
Unfortunately, QIODevice does not support reading single words, so you would have to do it yourself with a combination of peak and read.
Try disable QTextStream::autoDetectUnicode. This may read device ahead to perform detection and cause your problem.
Set also a codec just in case.
Add to the logs s.device()->pos() and s.device()->bytesAvailable() to verify that.
I've check QTextStream code. It looks like it always caches as much data as possible and there is no way to disable this behavior. I was expecting that it will use peek on device, but it only reads in greedy way. Bottom line is that you can't use QTextStream and peak device at the same time.

Tcp payload extraction and correct ip address

I'm trying to extract tcp payload from a packet , and here's a minimal case of capture callback:
void capture_callback (u_char *hdr , const struct pcap_pkthdr* pkthdr , const u_char* buff)
{
struct ether_header *eptr = (struct ether_header *) buff;
buff += sizeof (ether_header); /* jump over ethernet header: 14 bytes */
if ( ntohs (eptr->ether_type) == ETHERTYPE_IP )
{
struct ip *iph;
struct tcphdr *tcp_header;
iph = (struct ip *) buff;
buff += sizeof (ip); /* jump over ip header */
if ( iph->ip_p == IPPROTO_TCP )
{
tcp_header = (struct tcphdr *) buff;
buff += sizeof (tcphdr); /* jump over tcp header */
cout << inet_ntoa (iph->ip_src) << ":" << ntohs (tcp_header->th_sport) <<
" --> " << inet_ntoa(iph->ip_dst) << ":" << ntohs (tcp_header->th_dport) << endl;
}
}
}
But something went wrong here , source and destination IP address are the same.
And besides , how can i print out payload ? Since i can't just convert a unsigned char array to a char array explicitly, which ends on "\0" , it might get wrong.
192.168.56.1:48065 --> 192.168.56.1:80
192.168.56.80:80 --> 192.168.56.80:48065
EDIT
---------------------
THanks to Celeda , i solved the ip address issue by separating the call of inet_ntoa:
cout << "IP: " << inet_ntoa (iph->ip_src) << ":" << ntohs (tcp_header->th_sport) <<
" --> ";
cout << inet_ntoa(iph->ip_dst) << ":" << ntohs (tcp_header->th_dport) << endl;
And now the second part , i'm using:
cout << hex << buff << endl;
For HTTP protocol , and i'm not seeing anything like "GET /" , but multiple blank line
EDIT 2
--------------------------
I'm not so sure about TCP options for now , i'll check more documents about details ,
but for now this functions well.
if ( iph->ip_p == IPPROTO_TCP )
{
tcp_header = (struct tcphdr *) buff;
buff += tcp_header->th_off * 4;
cout << "IP: " << inet_ntoa (iph->ip_src) << ":" << ntohs (tcp_header->th_sport) <<
" --> ";
cout << inet_ntoa(iph->ip_dst) << ":" << ntohs (tcp_header->th_dport) << endl;
for ( int i = 0 ; i < iph->ip_len - iph->ip_off * 4; i ++ )
{
if ( isascii (buff[i]) )
{
cout << buff[i];
}
}
cout << endl << "-----------" << endl;
}
inet_ntoa() uses a static buffer. You are overwriting the buffer by calling it twice. Use inet_ntop() instead.
The payload might be binary data. How do you want to print it out? As a hex dump or something like that? Just look over the payload and print the bytes as hex one at a time for a simplistic hex dump. Or if you are sure that it's printable data you can dump it directly to the output with any function such as fwrite() that lets you specify the length of the string to write.
EDIT FOR ADDITIONAL INFORMATION IN THE QUESTION
The "extra characters" you see before the HTTP data sound like TCP options you are trying to interpret as payload data. Be sure to calculate the size of the TCP header correctly when you jump the buff pointer over it. It's 4 bytes * th_off. While you're at it, you should do the same for the IP header using ip_hl because the IP header is not always 20 bytes either.
Afterwards, the ending condition in your for loop is wrong. First, ip_off (the fragment offset) doesn't enter into it, and, second, both ip_hl and tcp_off are measured in units of 4 bytes, not in bytes.
Compare what you're getting with your code with how Wireshark decodes the same packet and you will be able to easily diagnose any further discrepancy.

QList memory deallocation

I'm trying to free memory after using QList, but it doesn't seem to work properly.
Here's my code:
QList<double> * myList;
myList = new QList<double>;
double myNumber;
cout << "CP1" << endl;
getchar(); // checkpoint 1
for (int i=0; i<1000000; i++)
{
myNumber = i;
myList->append(myNumber);
cout << myList->size() << endl;
}
cout << "CP2!" << endl;
getchar(); // checkpoint 2
for (int i=999999; i>0; i--)
{
myList->removeLast();
cout << myList->size() << endl;
}
cout << "CP3!" << endl;
getchar(); // checkpoint 3
delete myList;
cout << "CP4!" << endl;
getchar(); // checkpoint 4
Memory usage:
CP1: 460k
CP2:19996k
CP3:19996k
CP4:16088k
So it looks like despite removing of elements and deleting myList still large part of memory is being used. I believe there is a way to handle it but I can't find it.
Thanks in advance for any help.
Pawel
Memory manager is not required to release the memory your program has allocated. There are no problems in your deallocation.
QList is an array based list. The array expands automatically, but does not shrink automatically. Removing elements from the list does not affect the size of the array.
To trim the array down to the actual size, create a new QList and add the contents to it. Then delete the original list.
Unfortunately looks like there is no convenience method to do this, like the List.TrimExcess() in .NET.

Resources