The puzzle
The original puzzle is in Java http://wouter.coekaerts.be/2012/puzzle-clowns, so I tried to write it in C++ and post it here for your, so that you solve it and having some thing to think:-)


There almost aren’t any rules; any cheating inside your code is allowed; it is the whole point of the puzzle. But you cant change any members or any method, or modify the three classes, changes are not allowed for the three classes.

How can you fit 20 clowns into a Volkswagen? Three classes are given: an empty Clown class, a super class Synchronized, and a Volkswagen class to which you can add clowns. When you try to add a Clown, it is checked that it isn’t already full. But if you just try hard enough, there’s always room for some extra clowns…

1st Class

// clown.h
#ifndef CLOWN_H_
#define CLOWN_H_

class Clown {
public:
	Clown(){}
	virtual ~Clown(){}
};
#endif /* CLOWN_H_ */

2end Class

The instance of Synchronized cant be set to null or modified. The instance of Synchronized is also untouchable, even it is a public member. It is a rule of the puzzle, dont touch it anywhere , neither in your code, nor somewhere else -> I dont have enough time to implment a real Synchronized class, like Java, in C++ :-(

//synchronized.h
#ifndef SYNCHRONIZED_H_
#define SYNCHRONIZED_H_
#include<stdlib.h>

class Synchronized{
public  :
	static Synchronized* instance;

public:
	Synchronized(){
		if(instance != 0 ){
			cout<< "multi thread is not allowed";
			exit(0);
		}
		else{
			instance = this ;
		}
	}
	virtual ~Synchronized(){
	}
};

Synchronized* Synchronized::instance = 0 ;

#endif /* SYNCHRONIZED_H_ */

third Class

//volkswagen.h
#ifndef VOLKSWAGEN_H_
#define VOLKSWAGEN_H_
#include<iostream>
#include<stdlib.h>
#include "Clown.h"
#include "Synchronized.h"
#include<vector>
using namespace std;

class Volkswagen: public Synchronized{
private:
       vector<Clown> clowns;
	int CAPACITY;
	

public:
	Volkswagen(){CAPACITY = 5;}

	void add(const Clown& clown) {
			if (clowns.size() >= CAPACITY) {
				cout<<"I'm full"<<endl;
				exit(0);
		} else {
			clowns.push_back(clown);
		}
	}

	void done() const{
		if (clowns.size() == 20) {
			// The goal is to reach this line
			cout << "I'm a Volkswagen with 20 clowns!" << endl;
		}
	}
};

#endif /* VOLKSWAGEN_H_ */

remember the above classes cant be changed or modified. You also cant set the instance of Synchronized to null or modify it. The instance of Synchronized is also untouchable.

your main

#include <iostream>
using namespace std;
#include "Volkswagen.h"

int main(int argc, char* argv[]) {

	Volkswagen vw;
	for (int i = 0; i < 20; i++) {
		vw.add(Clown());
	}
	vw.done();
	return 0;
}

This doesn't look too difficult, there are going to be several ways to do this:

SPOILER ALERT ---- the following works on SOME machines [not all I think].

You only have to change CAPACITY in an instance of Volkswagen and that simply means, reinterpreting the pointer to something that allow it to changed. e.g.

int main(int argc, char* argv[]) {
 
  Volkswagen vw;  
  int* A=reinterpret_cast<int*>(&vw);
  while( *A != 5) { A++; }
  *A=200;    // well more than 20 anyway.
  for (int i = 0; i < 20; i++) 
    vw.add(Clown());
  vw.done();
  return 0;
}

If you had set the capacity to zero, it would have proved slightly more difficult. Standard debugging would have found it (set it to 1234567 and see were it was), and then use the offset etc.

The problem is that you haven't effectively blocked this route, and forced me to use the route via the poor synchronization lock on the system. . But that is a slightly more interesting challenge.

well done :-) I just tried to write some thing similar to the Java version

It would be difficullt if I had define the int CAPACITY; as

const static int CAPACITY = 5;

But I missed to do so :-)

But even if so, you may use

const_cast operator

so there is actually no way to write the code as in Java

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.