Skip to content

Instantly share code, notes, and snippets.

@odarbelaeze
Created April 16, 2013 17:16
Show Gist options
  • Save odarbelaeze/5397706 to your computer and use it in GitHub Desktop.
Save odarbelaeze/5397706 to your computer and use it in GitHub Desktop.
#include <cstdio>
#include <exception>
#include <iostream>
#include <sstream>
#include <string>
// 1234--------
template<typename T>
class Stack
{
public:
Stack()
{
allocated_ = 1;
N_ = 0;
data_ = new T[allocated_];
}
~Stack() {
delete[] data_;
}
void push(T item)
{
if (N_ == allocated_)
{
T* copy = data_;
allocated_ *= 2;
data_ = new T[allocated_];
for (int i = 0; i < N_; ++i)
data_[i] = copy[i];
}
data_[N_++] = item;
}
T pop()
{
if (N_ == 0) throw std::exception();
if (N_ == allocated_ / 4)
{
T* copy = data_;
allocated_ /= 2;
data_ = new T[allocated_];
for (int i = 0; i < N_; ++i)
data_[i] = copy[i];
}
return data_[--N_];
}
T top()
{
return data_[N_ - 1];
}
bool contains(const T& item)
{
bool flag = false;
for (int i = 0; i < N_; ++i)
{
if (data_[i] == item)
{
flag = true;
}
}
return flag;
}
bool isEmpty() {
return N_ == 0;
}
size_t size()
{
return N_;
}
T operator[] (int i)
{
return data_[i];
}
private:
T* data_;
size_t allocated_;
size_t N_;
};
class BlocksWorld
{
public:
BlocksWorld(int N) {
N_ = N;
data_ = new Stack<int>[N_];
for (int i = 0; i < N_; ++i)
{
data_[i].push(i);
}
}
~BlocksWorld() {
delete[] data_;
}
void print() {
for (int i = 0; i < N_; ++i)
{
std::cout << i << ": ";
for (int j = 0; j < data_[i].size(); ++j)
{
std::cout << data_[i][j] << " ";
}
std::cout << std::endl;
}
}
void moveOnto(int a, int b) {
int id_a = find_(a);
int id_b = find_(b);
Stack<int> aux_a;
Stack<int> aux_b;
while (data_[id_a].top() != a) aux_a.push(data_[id_a].pop());
while (data_[id_b].top() != b) aux_b.push(data_[id_b].pop());
data_[id_a].pop();
data_[id_b].pop();
while (!aux_a.isEmpty()) data_[aux_a.top()].push(aux_a.pop());
while (!aux_b.isEmpty()) data_[aux_b.top()].push(aux_b.pop());
data_[id_b].push(b);
data_[id_b].push(a);
}
void moveOver(int a, int b) {
int id_a = find_(a);
int id_b = find_(b);
Stack<int> aux_a;
while (data_[id_a].top() != a) aux_a.push(data_[id_a].pop());
data_[id_a].pop();
while (!aux_a.isEmpty()) data_[aux_a.top()].push(aux_a.pop());
data_[id_b].push(a);
}
void pileOnto(int a, int b) {
int id_a = find_(a);
int id_b = find_(b);
Stack<int> aux_a;
Stack<int> aux_b;
while (data_[id_a].top() != a) aux_a.push(data_[id_a].pop());
while (data_[id_b].top() != b) aux_b.push(data_[id_b].pop());
aux_a.push(data_[id_a].pop());
while (!aux_a.isEmpty()) data_[id_b].push(aux_a.pop());
while (!aux_b.isEmpty()) data_[aux_b.top()].push(aux_b.pop());
}
void pileOver(int a, int b) {
int id_a = find_(a);
int id_b = find_(b);
Stack<int> aux_a;
while (data_[id_a].top() != a) aux_a.push(data_[id_a].pop());
aux_a.push(data_[id_a].pop());
while (!aux_a.isEmpty()) data_[id_b].push(aux_a.pop());
}
private:
size_t N_;
Stack<int>* data_;
int find_(int item)
{
int pos = 0;
while(!data_[pos].contains(item)) pos++;
return pos;
}
};
int main(int argc, char const *argv[])
{
char buffer[50];
char verb[10];
char adverb[10];
int n, a, b;
std::gets(buffer);
std::sscanf(buffer, "%d\n", &n);
BlocksWorld bw(n);
// Command parser
while (std::gets(buffer))
{
if (std::string(buffer) == "quit") break;
std::sscanf(buffer, "%s %d %s %d\n", verb, &a, adverb, &b);
if (std::string(verb) == "move")
{
if (std::string(adverb) == "onto")
{
bw.moveOnto(a, b);
}
else if (std::string(adverb) == "over")
{
bw.moveOver(a, b);
}
}
else if (std::string(verb) == "pile")
{
if (std::string(adverb) == "onto")
{
bw.pileOnto(a, b);
}
else if (std::string(adverb) == "over")
{
bw.pileOver(a, b);
}
}
}
bw.print();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment