Exercise 8 (Chapter 4)

1,042 views
Skip to first unread message

pantera

unread,
Dec 19, 2009, 9:52:35 PM12/19/09
to PPP-public
I was doing the Exercise 8 but got stuck on the tests (1000, 1000,000,
etc. grains of rice). Where I got stuck is, how can I test for these
within a SINGLE loop? I just can't figure out and so what I'm thinking
of is writing 3 separate loops for these 3 tests. Does anyone have any
idea? I'm using the book for self-study and I have no previous
programming experience whatsoever, so things get so hard to me many
times.

// Exercise 8: a Game of Chess reward
#include "std_lib_facilities.h"

int main()
{
const int N = 64;
int grain, sum;

sum = grain = 1;
int i = 2;
int n;
while (i <= N) {
grain *= 2;
sum += grain;
if (sum >= 1000) {
n = i;
cout << n <<" squares are needed for 1000 grains\n";
cout <<"Sum of grains: " << sum << endl;
break;
}
++i;
}
}

5at5ish

unread,
Dec 19, 2009, 11:10:53 PM12/19/09
to PPP-public
This is my solution:

#include<iostream>
using namespace std;

int main()
{
int grains_all = 0;
int grain_first = 1;
int grains_current = 1;
int sq_number = 1;
int sqs_amount = 64;


cout<< "Please enter the amount of rice grains" << '\n';
while (cin>> grains_all) {

int prev_grain = 1;
int next_grain = 0;
int i = 1;
int sum = 1;

for (i = 1; i < sqs_amount; ++i) {
next_grain = prev_grain * 2;
cout<< "There are " << prev_grain << " in square # " << i << "." <<
endl;
prev_grain = next_grain;
sum += next_grain;


if (sum >= grains_all) {
sq_number = i + 1;
cout<< "The number of squares required for at least " <<
grains_all
<< " grains of rice is " << sq_number << " squares."
<< "\nYour are in square number " << i + 1 << "."
<< "\nThe sum of all grains is " << sum <<"."
<< "\nThe amount of grains in current square is " << sum -
grains_all << "." << '\n';
break;
}

}
cout<< "|||There are " << prev_grain << " in square # " << i + 1
<< ".|||" << endl;

pantera

unread,
Dec 20, 2009, 12:21:38 AM12/20/09
to PPP-public
Hi 5at5ish, thanks for your help. The code you wrote is very useful to
me (the logic, design...). I've just figured out another answer to my
own question: Writing a function!!! Here it is:

// Exercise 8: a Game of Chess reward - version 2
#include "std_lib_facilities.h"

int find_squares(int);

int main()
{
int num_of_grains = 0;
cout <<"Pls enter the number of grains: ";
cin >> num_of_grains;
if (num_of_grains <= 0)
cout <<":=), you don't need any grains - you even want to donate
grains! :-)";
else
find_squares(num_of_grains);
}

int find_squares(int num_of_grains) // a function to find the number
of squares
// needed to get a specified number of grains
// of rice
{
int grain, sum_of_grains, square;
const int N = 64; // total number of squares on a chessboard
sum_of_grains = grain = 1;
square = 2;
while (square <= N) {
grain *= 2;
sum_of_grains += grain;
if (sum_of_grains >= num_of_grains) {
cout << square << " are needed for " << num_of_grains <<" of grains
of rice\n";
break;
}
++square;

Message has been deleted

Edico

unread,
Dec 20, 2009, 5:51:35 AM12/20/09
to PPP-public
This is my solution:

/* Chapter 4 Exercise 8
* There is an old story that the emperor wanted to thank the inventor
of the
* game of chess and asked the inventor to name his reward. The
inventor asked
* for one grain of rice for the first square, 2 for the second, 4 for
the
* third, and so on, doubling for each of the 64 squares. That may
sound
* modest, but there wasn't that much rice in the empire! Write a
program to
* calculate how many squares are required to give the inventor at
least 1000
* grains of rice, at least 1,000,000 grains, and at least
1,000,000,000
* grains. Yuu'll need a loop, of course, and probably an int to keep
track of
* which square you are at, an int to keep the number of grains on the
current
* square, and an int to keep track of grains on all previous squares.
We
* suggest that you write out the value of all your variables for
each
* iteration of the loop so that you can see what's going on. */

#include "std_lib_facilities.h"

int main()
{
unsigned int i;
int current_grains = 1;
int all_grains = 0;
int grains_t = 0;
int grains_m = 0;
int grains_b = 0;
int square_t = 0;
int square_m = 0;
int square_b = 0;
const int thousand = 1000;
const int million = 1000000;
const int billion = 1000000000;

for (i = 1; all_grains <= billion; ++i)
{
all_grains += current_grains;
current_grains *= 2;
if (i <= 4)
cout << i << " squares " << all_grains << " grains" <<
endl;
if (all_grains < thousand * 2) {
grains_t = all_grains;
square_t = i;
}
else if (all_grains < million * 2) {
grains_m = all_grains;
square_m = i;
}
else if (all_grains < billion * 2) {
grains_b = all_grains;
square_b = i;
}
}

cout << square_t << " squares for " << grains_t << " grains\n";
cout << square_m << " squares for " << grains_m << " grains\n";
cout << square_b << " squares for " << grains_b << " grains\n";

return 0;

pantera

unread,
Dec 20, 2009, 7:46:36 AM12/20/09
to PPP-public
Hi,

Back to my question about dealing with the error message/bad input the
user might put in, I just have come up with a possible solution.
Here's the revised program:

// Exercise 6
#include "std_lib_facilities.h"

void convert_to_digits();
void convert_to_spelledouts();

int main()
{
cout << "Enter s for spelled-outs or d for digits: ";
char choice;
cin >> choice;
if (choice == 'd') {
convert_to_digits();
}
else if (choice == 's') {
convert_to_spelledouts();
}

else
cout <<"Invalid choice!\n";
}

void convert_to_digits()
{
const int N = 10; // size of the vector
vector <string> myvector(N);
myvector[0] = "zero";
myvector[1] = "one";
myvector[2] = "two";
myvector[3] = "three";
myvector[4] = "four";
myvector[5] = "five";
myvector[6] = "six";
myvector[7] = "seven";
myvector[8] = "eight";
myvector[9] = "nine";

cout <<"Enter a number from 0 - 9 in digit form: ";
int num = 0;
while (cin >> num) {
if (num > 9) {
cout <<"Out of range!\n";
break;
}

cout << myvector[num] << endl;
}
}

void convert_to_spelledouts()
{
const int N = 10; // size of the vector
vector <string> myvector(N);
myvector[0] = "zero";
myvector[1] = "one";
myvector[2] = "two";
myvector[3] = "three";
myvector[4] = "four";
myvector[5] = "five";
myvector[6] = "six";
myvector[7] = "seven";
myvector[8] = "eight";
myvector[9] = "nine";

cout << "Enter a number from 0 - 9 in spelled-out form: ";
string s = " ";
while (cin >> s) {
bool found = 0; // This is how I dealt with my previous question of
handling error messages/bad inputs
for (int k = 0; k < N; ++k) {
if (s == myvector[k]) {
found = 1;
break;
}
}
if (found) { / This is how I dealt with my previous question of
handling error messages/bad inputs
for (int k = 0; k < N; ++k) {
if (s == myvector[k]) {
cout << k << endl;
}
}
}

else {
cout <<"Bad input!\n"; / This is how I dealt with my previous
question of handling error messages/bad inputs
}
}
}

If you have a better solution, please share it with us. I'm learning C+
+ as a first language from this book. By the way, so far I've been
finding this book excellent because it focuses on programming concepts
rather than syntax and language... Like this book a lot.

Message has been deleted
Message has been deleted
Message has been deleted
Message has been deleted

Jordan Harris

unread,
Mar 14, 2015, 12:11:24 AM3/14/15
to ppp-p...@googlegroups.com, gelh...@gmail.com
It's a bit of a weird solution, but this is what I got. It seems to work and it doesn't require much code or complicated logic. By the way, I used doubles here because integers wouldn't count high enough. So this kind of accounts for Exercise 9 too.

#include "../../../../std_lib_facilities.h"


using namespace std;

int main()
{

   
double square_num{ 1 };
   
double current_grain{ 1 };
   
double max_grain{ 1000 };
   
   
while (current_grain <= max_grain)
   
{    
        current_grain
*= 2;
       
++square_num;
       
       
if (current_grain > 1000 && current_grain <= 1050)
           
{
                cout
<< square_num << " squares needed for at least " << max_grain << " grains.\n";
                max_grain
= 1000000;
           
}
       
if (current_grain > 1000000 && current_grain <= 1050000)
           
{
                cout
<< square_num << " squares needed for at least " << max_grain << " grains.\n";
                max_grain
= 1000000000;
           
}
   
}
    cout
<< square_num << " squares needed for at least " << max_grain << " grains.\n";

    cout
<< '\n';
    keep_window_open
();        //    keeps window open until character is entered
}


Raivo Lapiņš

unread,
Jul 5, 2018, 12:39:11 PM7/5/18
to PPP-public
Hello! I have recently started to go through the Bjorns book to learn C++ and I stumbled upon your example to compare it to mine solution. After noticing that your example takes 1 square less for every milestone (1000; 1'000'000; 1'000'000'000) I decided to mention a logic flaw you have in your code. You should include another integer to hold value of total amount of grains you have, otherwise you just check for the amount of grains on current square but never sum them with amount of previous grains. That leads to a logic flaw.

Raivo Lapiņš

unread,
Jul 5, 2018, 12:45:24 PM7/5/18
to PPP-public
My solution for the exercise:

// EmperorStory.cpp : Defines the entry point for the console application.
// I don't include Bjorns std_lib_facilities header since this example can be done with only standard iostream header.

#include "stdafx.h"
#include <iostream>


int main()
{
//declare amount of current grains as 1 on the first square
int currentGrains{ 1 };

//declare amount of total grains as 1 in the beginning
int totalGrains{ 1 };

//declare iterator for current square starting from 1
int currentSquare{ 1 };

//print out amount of current grains on the square
std::cout << currentSquare << " " << currentGrains << " " << totalGrains << std::endl;

//loop through a loop while amount of grains is less than needed
while (totalGrains < 1'000'000'000) {
currentSquare++;
//Amount of grains on current square is equal to double the amount of the previous square
currentGrains *= 2;
//number of totalgrains is equal to total grains plus grains on current square
totalGrains += currentGrains;

//print out the number of current square followed by amount of grains on that square and then by total amount of grains
std::cout <<currentSquare <<" "<< currentGrains << " " << totalGrains << std::endl;

// 3 if statments that will check for milestones and print squares needed to reach them. Logic in if parentheses could probably be better.
if (totalGrains >= 1000 && totalGrains <=1100) {
std::cout << "The number of squares for 1000 grains are " << currentSquare << std::endl;
}

if (totalGrains >= 1'000'000 && totalGrains <= 1'100'000) {
std::cout << "The number of squares for 1'000'000 grains are " << currentSquare << std::endl;
}

if (totalGrains >= 1'000'000'000) {
std::cout << "The number of squares for 1'000'000'000 grains are " << currentSquare << std::endl;
}
}

    return 0;
}

Reply all
Reply to author
Forward
0 new messages