<repo_name>GambuzX/MIEIC_aeda<file_sep>/Solved Tests/teste2_17_18/Hospital.cpp
/*
 * Hospital.cpp
 */

#include "Hospital.h"
//
#include <algorithm>


Hospital::Hospital(unsigned trayC):trayCapacity(trayC)
{ }

void Hospital::addDoctor(const Doctor &d1) {
	doctors.push_back(d1);
}

list<Doctor> Hospital::getDoctors() const {
	return doctors;
}

void Hospital::addTrays(stack<Patient> tray1) {
	letterTray.push_back(tray1);
}

list<stack<Patient> > Hospital::getTrays() const {
	return letterTray;
}



unsigned Hospital::numPatients(string medicalSpecialty) const
{
	unsigned total = 0;

	for (const auto & doctor: doctors){
		if (doctor.getMedicalSpecialty() == medicalSpecialty){
			total += doctor.getPatients().size();
		}
	}

	return total;

}

void Hospital::sortDoctors() {
	vector<Doctor> ord;
	for (const auto & doc : doctors) ord.push_back(doc);

	for (unsigned int p = 1; p < ord.size(); p++)
	{
		Doctor tmp = ord[p];
		int j;
		for (j = p; j > 0 && tmp < ord[j-1]; j--)
			ord[j] = ord[j-1];
		ord[j] = tmp;
	}

	doctors.clear();
	for (auto & ele : ord) doctors.push_back(ele);
}





bool Hospital::addDoctor(unsigned codM1, string medicalSpecialty1) {
	int nDocs = 0;
	for (const auto & doc : doctors)
		if (doc.getMedicalSpecialty() == medicalSpecialty1)
			nDocs++;
	if (nDocs >= 3) return false;
	doctors.push_back(Doctor(codM1, medicalSpecialty1));
	return true;
}



queue<Patient> Hospital::removeDoctor(unsigned codM1) {
	list<Doctor>::iterator it;
	queue<Patient> p1;
	for (it = doctors.begin(); it != doctors.end(); it++)
		if (it->getCode() == codM1) {
			p1 = it->getPatients();
			doctors.erase(it);
			return p1;
		}

	throw DoctorInexistent();

}


bool Hospital::putInLessBusyDoctor(unsigned cod1, string medicalSpecialty1) {

	int stackSize = -1;
	Doctor * lessOcupied = NULL;

	for (auto & doctor: doctors) {
		if (doctor.getMedicalSpecialty() == medicalSpecialty1) {
			if ((int) doctor.getPatients().size() < stackSize || stackSize == -1) {
				stackSize = doctor.getPatients().size();
				lessOcupied = &doctor;
			}
		}
	}

	if (stackSize == -1) return false;

	lessOcupied->addPatient(Patient(cod1, medicalSpecialty1));
	return true;

}



void Hospital::processPatient(unsigned codM1) {

	for (Doctor & doc: doctors) {
		if(doc.getCode() == codM1) {
			Patient pat(1, "");
			try {
				pat = doc.removeNextPatient();
			}
			catch(Doctor::PatientInexistent & excp) {
				break;
			}
			bool inserted = false;
			for (auto & band : letterTray) {
				if (band.size() < trayCapacity) {
					band.push(pat);
					inserted = true;
					break;
				}
			}
			if (!inserted) {
				stack<Patient> newS;
				newS.push(pat);
				letterTray.push_back(newS);
			}
			break;
		}
	}

}


unsigned Hospital::removePatients(unsigned codP1) {
	unsigned total = 0;
	list<stack<Patient>>::iterator it;
	for (it = letterTray.begin(); it != letterTray.end(); it++) {
		if (it->top().getCode() == codP1){
			it->pop();
			total++;
		}
		if (it->size() == 0) letterTray.erase(it--);
	}

	return total;
}



<file_sep>/Practical Classes/TP03/animal.cpp

#include "animal.h"
#include <sstream>

string Animal::getNome() const {
	return nome;
}

int Animal::getIdade() const {
	return idade;
}

Veterinario* Animal::getVet() const {
	return vet;
}

Animal::Animal(string nome, int idade) {
	this->nome = nome;
	this->idade = idade;
	vet = NULL;
	if (Animal::maisJovem == -1 || Animal::maisJovem > idade) Animal::maisJovem = idade;
}

int Animal::maisJovem = -1;

string Animal::getInformacao() const {
	ostringstream oss;
	oss << nome << ", " << idade;
	if (vet != NULL) {
		oss << ", " << vet->getNome() << ", " << vet->getCodOrdem();
	}
	return oss.str();
}

bool Animal::alocaVet(Veterinario *vete) {
	if (vete == NULL) return 1;
	vet = vete;
	return 0;
}

Cao::Cao(string nome, int idade, string raca): Animal(nome,idade) {
	this->raca = raca;
}

bool Cao::eJovem() const { return idade<5; }

string Cao::getInformacao() const {
	return (Animal::getInformacao() + ", " + raca);
}

Voador::Voador(int vmax, int amax) {
	velocidade_max = vmax;
	altura_max = amax;
}

string Voador::getInformacao() const {
	ostringstream oss;
	oss << velocidade_max << ", " << altura_max;
	return oss.str();
}

Morcego::Morcego(string nome, int idade, int vmax, int amax): Animal(nome, idade), Voador(vmax, amax) { }

bool Morcego::eJovem() const { return idade<4; }

string Morcego::getInformacao() const {
	return (Animal::getInformacao() + ", " + Voador::getInformacao());
}

<file_sep>/Practical Classes/TP08/Dicionario.h
#ifndef _DIC
#define _DIC
#include <string>
#include <fstream>
#include "BST.h"


class PalavraSignificado {
      string palavra;
      string significado;
public:
       PalavraSignificado(string p, string s): palavra(p), significado(s) {}
       string getPalavra() const { return palavra; }
       string getSignificado() const { return significado; }
       void setSignificado(string sig) { significado = sig; }
       bool operator < (const PalavraSignificado &ps1) const;
};

class Dicionario
{
      BST<PalavraSignificado> palavras;
public:
      Dicionario(): palavras(PalavraSignificado("","")){};
      BST<PalavraSignificado> getPalavras() const;
      void lerDicionario(ifstream &fich);
      string consulta(string palavra) const;
      bool corrige(string palavra, string significado);
      void imprime() const;
};


// a alterar
class PalavraNaoExiste
{
	string pantes, santes, pdepois, sdepois;
public:
	PalavraNaoExiste(string a, string b, string c,string d): pantes(a), santes(b), pdepois(c), sdepois(d) {}
	string getPalavraAntes() const { return pantes; }
	string getSignificadoAntes() const { return santes; }
	string getPalavraApos() const { return pdepois; }
	string getSignificadoApos() const { return sdepois; }
};



#endif
<file_sep>/Practical Classes/TP01/Parque.cpp
#include "Parque.h"
#include <vector>

using namespace std;

ParqueEstacionamento::ParqueEstacionamento(unsigned int lot, unsigned int nMaxCli): lotacao(lot), numMaximoClientes(nMaxCli) {
	vagas = lot;
}

unsigned int ParqueEstacionamento::getNumLugares() const {
	return lotacao;
}

unsigned int ParqueEstacionamento::getNumMaximoClientes() const {
	return numMaximoClientes;
}

int ParqueEstacionamento::posicaoCliente(const string &nome) const {
	int index = -1;
	for (unsigned i = 0; i < clientes.size(); i++)
		if (clientes[i].nome == nome)
			index = i;
	return index;
}

bool ParqueEstacionamento::adicionaCliente(const string & nome) {
	bool success = false;
	if (posicaoCliente(nome) == -1 && clientes.size() < numMaximoClientes) {
		InfoCartao newCard;
		newCard.nome = nome;
		newCard.presente = false;
		clientes.push_back(newCard);
		success=true;
	}
	return success;
}

bool ParqueEstacionamento::entrar(const string & nome) {
	vector<InfoCartao>::iterator it;
	for (it = clientes.begin(); it != clientes.end(); it++) {
		if (it->nome == nome) {
			if (!it->presente && vagas > 0) {
				it->presente = true;
				vagas--;
				return true;
			}
			else return false;
		}
	}
	return false;
}

bool ParqueEstacionamento::retiraCliente(const string & nome) {
	vector<InfoCartao>::iterator it;
	for (it = clientes.begin(); it != clientes.end(); it++) {
		if (it->nome == nome) {
			if (!it->presente){
				clientes.erase(it);
				return true;
			}
			else {
				return false;
			}
		}
	}
	return false;
}

bool ParqueEstacionamento::sair(const string & nome) {
	vector<InfoCartao>::iterator it;
	for (it = clientes.begin(); it != clientes.end(); it++) {
		if (it->nome == nome) {
			if (it->presente) {
				it->presente = false;
				vagas++;
				return true;
			}
			else return false;
		}
	}
	return false;
}

unsigned int ParqueEstacionamento::getNumLugaresOcupados() const {
	return lotacao-vagas;
}

unsigned int ParqueEstacionamento::getNumClientesAtuais() const {
	return clientes.size();
}
<file_sep>/Practical Classes/TP07/StackExt.h
# include <iostream>
# include <stack>

using namespace std;

template <class T>
class StackExt {
private:
	stack<T> allValues;
	stack<T> minValues;
public:
	StackExt() {};
	bool empty() const;
	T& top();
	void pop();
	void push(const T& val);
	T& findMin();
};

template <class T>
bool StackExt<T>::empty() const {
	return allValues.empty();
}

template <class T>
T& StackExt<T>::top() {
	return allValues.top();
}

template <class T>
void StackExt<T>::pop() {
	T val = allValues.top();
	if (!allValues.empty())
		allValues.pop();
	if (!minValues.empty() && minValues.top() == val)
		minValues.pop();
}

template <class T>
void StackExt<T>::push(const T& val) {
	allValues.push(val);
	if (minValues.empty() || val <= minValues.top())
		minValues.push(val);
}

template <class T>
T& StackExt<T>::findMin() {
	return minValues.top();
}
<file_sep>/Practical Classes/TP03/html/search/all_3.js
var searchData=
[
  ['veterinario',['Veterinario',['../class_veterinario.html',1,'']]],
  ['voador',['Voador',['../class_voador.html',1,'']]]
];
<file_sep>/Practical Classes/TP08/Jogo.cpp
#include "Jogo.h"
#include <sstream>

BinaryTree<Circulo> & Jogo::getJogo() {
	return jogo;
}


ostream &operator << (ostream &os, Circulo &c1)
{
	// a alterar
	return os;
}



Jogo::Jogo(int niv, vector<int> &pontos, vector<bool> &estados)
{

	jogo = criaJogo(0, niv, pontos, estados);
}

BinaryTree<Circulo> Jogo::criaJogo(int pos, int niv, vector<int> &pontos, vector<bool> &estados) {

	if (niv == 0) return Circulo(pontos[pos], estados[pos]);
	return BinaryTree<Circulo>(Circulo(pontos[pos], estados[pos]), criaJogo(2*pos+1, niv-1, pontos, estados), criaJogo(2*pos+2, niv-1, pontos, estados));
}


string Jogo::escreveJogo()
{
	BTItrLevel<Circulo> iter(jogo);
	string returnS = "";
	while (!iter.isAtEnd()) {
		ostringstream oss("");
		oss << iter.retrieve().getPontuacao() << '-';

		if (iter.retrieve().getEstado()) oss << "true-";
		else oss << "false-";

		oss << iter.retrieve().getNVisitas() << '\n';
		returnS += oss.str();
		iter.advance();
	}
	return returnS;
}


int Jogo::jogada()
{
	int pos=1, score;
	BTItrLevel<Circulo> iter(jogo);
	if(iter.isAtEnd()) return -1;
	while(true) {
		Circulo &c1 = iter.retrieve();
		bool state = c1.getEstado(); int n;
		if (!state) n = pos;
		else n = pos+1;
		c1.mudaEstado();
		c1.incrementVisits();
		score = c1.getPontuacao();
		int i = 0;
		while (i<n && !iter.isAtEnd()) {
			iter.advance();
			i++;
		}
		if (!iter.isAtEnd()) pos += n;
		else break;
	}
	return score;
}



int Jogo::maisVisitado()
{
	int max = 0;

	BTItrLevel<Circulo> iter(jogo);
	iter.advance();
	while(!iter.isAtEnd()) {
		if (iter.retrieve().getNVisitas() > max)
			max = iter.retrieve().getNVisitas();
		iter.advance();
	}

	return max;;
}




<file_sep>/Practical Classes/TP08/Dicionario.cpp
#include <iostream>
#include <string>
#include <fstream>
#include "Dicionario.h"
#include "BST.h"

using namespace std;


BST<PalavraSignificado> Dicionario::getPalavras() const
{ return palavras; }



bool PalavraSignificado::operator < (const PalavraSignificado &ps1) const
{
	return palavra < ps1.getPalavra();
}


void Dicionario::lerDicionario(ifstream &fich)
{
	string savingString;
	while (getline(fich, savingString)) {
		string nome = savingString;
		getline(fich, savingString);
		string definition = savingString;
		palavras.insert(PalavraSignificado(nome, definition));
	}
	return;
}


string Dicionario::consulta(string palavra) const
{
	BSTItrIn<PalavraSignificado> iter(palavras);
	while (!iter.isAtEnd()) {
		if (iter.retrieve().getPalavra() == palavra) {
			return iter.retrieve().getSignificado();
		}
		PalavraSignificado pantes = iter.retrieve();
		iter.advance();

		if (! iter.isAtEnd() && iter.retrieve().getPalavra() > palavra) {
			throw PalavraNaoExiste(pantes.getPalavra(), pantes.getSignificado(), iter.retrieve().getPalavra(), iter.retrieve().getSignificado());
		}
	}
	throw PalavraNaoExiste("", "", "", "");
	return "";
}


bool Dicionario::corrige(string palavra, string significado)
{
	try {
		consulta(palavra);

		BST<PalavraSignificado> newBST(PalavraSignificado("",""));
		BSTItrIn<PalavraSignificado> iter(palavras);
		while (!iter.isAtEnd()) {
			if (iter.retrieve().getPalavra() == palavra) {
				newBST.insert(PalavraSignificado(palavra, significado));
			}
			newBST.insert(iter.retrieve());
			iter.advance();
		}
		palavras = newBST;
	}
	catch (PalavraNaoExiste & exc) {
		palavras.insert(PalavraSignificado(palavra, significado));
		return false;
	}

	return true;
}


void Dicionario::imprime() const
{
	BSTItrIn<PalavraSignificado> iter(palavras);
	while (!iter.isAtEnd()) {
		cout << iter.retrieve().getPalavra() << endl << iter.retrieve().getSignificado() << endl;
		iter.advance();
	}

    return;
}
<file_sep>/Solved Tests/teste1_16_17/Postman.h
/*
 * Postman.h
 */

#ifndef SRC_POSTMAN_H_
#define SRC_POSTMAN_H_

#include "Mail.h"
#include <string>
#include <vector>

class Postman {
	static int currID;
	unsigned int id;
	string name;
	vector<Mail *> myMail;
public:
	Postman();
	Postman(string name);
	void setName(string nm);
	void addMail(Mail *m);
	void addMail(vector<Mail *> mails);
	string getName() const;
	vector<Mail *> getMail() const;
	unsigned int getID() const;
	bool operator<(const Postman &) const;
};

class NoPostmanException {
	string name;
public:
	NoPostmanException(string n) { name = n; }
	string getName() const { return name; }
};


#endif /* SRC_POSTMAN_H_ */
<file_sep>/Practical Classes/TP03/zoo.cpp
#include "zoo.h"
#include <sstream>


int Zoo::numAnimais() const {
	return animais.size();
}

int Zoo::numVeterinarios() const {
	return veterinarios.size();
}

void Zoo::adicionaAnimal(Animal *a1) {
	animais.push_back(a1);
}

string Zoo::getInformacao() const {
	string info = "";
	vector<Animal *>::const_iterator it;
	for (it = animais.begin(); it != animais.end(); it++) {
		info += (*it)->getInformacao() + "; ";
	}
	return info;
}

bool Zoo::animalJovem(string nomeA) {
	vector<Animal *>::const_iterator it;
	for (it = animais.begin(); it != animais.end(); it++) {
		if ((*it)->getNome() == nomeA)
			return (*it)->eJovem();
	}
	return false;
}

void Zoo::alocaVeterinarios(istream &isV) {
	string name, codeS;
	while(getline(isV, name)) {
		getline(isV, codeS);
		long code = stoi(codeS);
		Veterinario * vet = new Veterinario(name, code);
		veterinarios.push_back(vet);
	}

	size_t vetNum = veterinarios.size();
	for (size_t i = 0; i < animais.size(); i++) {
		animais[i]->alocaVet(veterinarios[i%vetNum]);
	}
}

bool Zoo::removeVeterinario(string nomeV) {

	size_t vetIndex = -1;
	for (size_t i = 0; i < veterinarios.size(); i++) {
		if (veterinarios[i]->getNome() == nomeV) {
			vetIndex = i;
			break;
		}
	}

	if ((int) vetIndex == -1) return false;

	vector<Animal *>::const_iterator it;
	for (it = animais.begin(); it != animais.end(); it++) {
		if (veterinarios.size() <= 1)
			(*it)->alocaVet(NULL);
		else if ((*it)->getVet()->getNome() == nomeV)
			(*it)->alocaVet(veterinarios[(vetIndex + 1) % veterinarios.size()]);
	}

	veterinarios.erase(veterinarios.begin() + vetIndex);
	return true;
}

bool Zoo::operator<(Zoo& zoo2) const {
	int sum1 = 0, sum2 = 0;
	vector<Animal *>::const_iterator it;

	for (it = animais.begin(); it != animais.end(); it++)
		sum1 += (*it)->getIdade();

	for (it = zoo2.animais.begin(); it != zoo2.animais.end(); it++)
		sum2 += (*it)->getIdade();

	return sum1 < sum2 ? sum1 : sum2;
}

<file_sep>/Solved Tests/teste1_17_18/Garage.h
/*
 * Garage.h
 *
 *  Created on: 24/10/2017
 *      Author: hlc
 */

#ifndef SRC_GARAGE_H_
#define SRC_GARAGE_H_

#include <vector>

template <class Vehicle>
class Garage {
	std::vector<Vehicle *> vehicles;
	const unsigned int capacity;
public:
	Garage(int size);
	~Garage();
	std::vector<Vehicle *> getVehicles() const;
	void setVehicles(std::vector<Vehicle *> vehicles);
	int getCapacity() const;
	bool addVehicle(Vehicle *vehicle);
	Vehicle* removeVehicle(std::string brand, std::string model);
	float avgPrice(std::string brand) const;
	void sortVehicles();
};

class NoSuchVehicleException {
public:
	NoSuchVehicleException() { }
};

class NoSuchBrandException {
	std::string brand;
public:
	NoSuchBrandException(std::string b) { brand = b; }
	std::string getBrand() { return brand; }
};

template <class Vehicle>
Garage<Vehicle>::Garage(int size) : capacity(size) {
}

template <class Vehicle>
Garage<Vehicle>::~Garage() {
	typename std::vector<Vehicle *>::const_iterator it;
	for (it=vehicles.begin(); it!=vehicles.end(); it++) {
		delete *it;
	}
}

template<class Vehicle>
std::vector<Vehicle *> Garage<Vehicle>::getVehicles() const {
	return vehicles;
}

template<class Vehicle>
void Garage<Vehicle>::setVehicles(std::vector<Vehicle*> vehicles) {
	this->vehicles = vehicles;
}

template<class Vehicle>
int Garage<Vehicle>::getCapacity() const {
	return capacity;
}

template<class Vehicle>
bool Garage<Vehicle>::addVehicle(Vehicle * vehicle) {
	if (vehicles.size() >= capacity) return false;
	for (size_t i = 0; i < vehicles.size(); i++)
		if (*vehicles[i] == *vehicle)
			return false;

	vehicles.push_back(vehicle);
	return true;
}

template<class Vehicle>
void Garage<Vehicle>::sortVehicles() {
	for (unsigned i = 1; i < vehicles.size(); i++) {
		Vehicle * tmp = vehicles.at(i);
		int j;
		for (j = i; j > 0 && *tmp < *(vehicles[j-1]); j--)
			vehicles[j] = vehicles[j-1];
		vehicles[j] = tmp;
	}
}

template<class Vehicle>
Vehicle* Garage<Vehicle>::removeVehicle(std::string brand, std::string model) {
	int index = -1;
	for (size_t i = 0; i < vehicles.size(); i++)
		if (vehicles.at(i)->getBrand() == brand && vehicles.at(i)->getModel() == model)
			index = i;
	if (index == -1) throw NoSuchVehicleException();

	Vehicle * vehicleToRemove = vehicles[index];
	vehicles.erase(vehicles.begin()+index);
	return vehicleToRemove;
}

template<class Vehicle>
float Garage<Vehicle>::avgPrice(std::string brand) const {
	float total = 0;
	int nV = 0;
	for (size_t i = 0; i < vehicles.size(); i++) {
		if (vehicles.at(i)->getBrand() == brand) {
			total += vehicles.at(i)->getPrice();
			nV++;
		}
	}

	if (total == 0) throw NoSuchBrandException(brand);
	return total/nV;
}

#endif /* SRC_GARAGE_H_ */
<file_sep>/Practical Classes/TP10/Aposta.cpp
#include "Aposta.h"
#include <iostream>
#include <sstream>

using namespace std;

bool Aposta::contem(unsigned num) const
{
	tabHInt::const_iterator it = numeros.find(num);
	if (it != numeros.end()) return true;
	return false;
}


void Aposta::geraAposta(const vector<unsigned> & valores, unsigned n)
{
	unsigned inserted = 0;
	for (unsigned i = 0; i < valores.size(); i++) {
		if (inserted >= n) break;
		pair<tabHInt::iterator, bool> ret = numeros.insert(valores[i]);
		if (ret.second) inserted ++;
	}
}


unsigned Aposta::calculaCertos(const tabHInt & sorteio) const
{
	unsigned certos = 0;
	tabHInt::const_iterator it;
	for (it = sorteio.begin(); it != sorteio.end(); it++) {
		if (contem(*it)) certos++;
	}
	return certos;
}




<file_sep>/Practical Classes/TP02/Frota.cpp
#include "Frota.h"
#include "Veiculo.h"
#include <string>

using namespace std;

void Frota::adicionaVeiculo(Veiculo * v1) {
	veiculos.push_back(v1);
}

int Frota::numVeiculos() const {
	return veiculos.size();
}

int Frota::menorAno() const {
	int menor = 0;
	for (unsigned i = 0; i < veiculos.size(); i++) {
		int ano = (veiculos.at(i))->getAno();
		if (ano < menor || menor == 0) {
			menor = ano;
		}
	}
	return menor;
}

vector<Veiculo *> Frota::operator() (int anoM) const {
	vector<Veiculo *> vehicles;
	for (const auto & veic : veiculos) {
		if (anoM == veic->getAno()) vehicles.push_back(veic);
	}
	return vehicles;
}

float Frota::totalImposto() const{
	float total;
	for (const auto & veic: veiculos) {
		total += veic->calcImposto();
	}
	return total;
}

<file_sep>/Practical Classes/TP03/html/search/all_1.js
var searchData=
[
  ['cao',['Cao',['../class_cao.html',1,'']]]
];
<file_sep>/Practical Classes/TP02/Veiculo.cpp
#include "Veiculo.h"
#include <iostream>


using namespace std;

Veiculo::Veiculo(string mc, int m, int a) {
	marca = mc;
	mes = m;
	ano = a;
}

int Veiculo::getAno() const {
	return ano;
}

int Veiculo::getMes() const {
	return mes;
}

string Veiculo::getMarca() const {
	return marca;
}

int Veiculo::info() const {
	cout << "Marca: " << marca << endl;
	cout << "Mes: " << mes << endl;
	cout << "Ano: " << ano << endl;
	return 3;
}

bool Veiculo::operator<(const Veiculo & v) const {
	if (ano == v.getAno())
		return mes > v.getMes() ? false : true;
	else
		return ano > v.getAno() ? false : true;
}

Motorizado::Motorizado(string mc, int m, int a, string c, int cil): Veiculo(mc, m, a) {
	combustivel = c;
	cilindrada = cil;
}

string Motorizado::getCombustivel() const {
	return combustivel;
}

int Motorizado::info() const {
	Veiculo::info();
	cout << "Combustivel: " << combustivel << endl;
	cout << "Cilindrada: " << cilindrada << endl;
	return 5;
}

float Motorizado::calcImposto() const {
	float imposto = 0;
	string co = combustivel;
	int ci = cilindrada;
	if ((co == "gasolina" && ci <= 1000) || (co != "gasolina" && ci <= 1500)) {
		if (getAno() > 1995) imposto = 14.56;
		else imposto = 8.10;
	}
	else if ((co == "gasolina" && ci > 1000 && ci <= 1300) || (co != "gasolina" && ci > 1500 && ci <= 2000)) {
		if (getAno() > 1995) imposto = 29.06;
		else imposto = 14.56;
	}
	else if ((co == "gasolina" && ci > 1300 && ci <= 1750) || (co != "gasolina" && ci > 2000 && ci <= 3000)) {
		if (getAno() > 1995) imposto = 45.15;
		else imposto = 22.65;
	}
	else if ((co == "gasolina" && ci > 1750 && ci <= 2600) || (co != "gasolina" && ci > 3000)) {
		if (getAno() > 1995) imposto = 113.98;
		else imposto = 54.89;
	}
	else if (co == "gasolina" && ci > 2600 && ci <= 3500) {
		if (getAno() > 1995) imposto = 181.17;
		else imposto = 87.13;
	}
	else if (co == "gasolina" && ci > 3500) {
		if (getAno() > 1995) imposto = 320.89;
		else imposto = 148.37;
	}
	return imposto;
}

Automovel::Automovel(string mc, int m, int a, string c, int cil): Motorizado(mc,m,a,c,cil) {}

int Automovel::info() const {
	return Motorizado::info();
}

Camiao::Camiao(string mc, int m, int a, string c, int cil, int cm): Motorizado(mc,m,a,c,cil) {
	carga_maxima = cm;
}

int Camiao::info() const {
	Motorizado::info();
	cout << "Carga maxima: " << carga_maxima << endl;
	return 6;
}

Bicicleta::Bicicleta(string mc, int m, int a, string t): Veiculo(mc, m ,a) {
	tipo = t;
}

int Bicicleta::info() const {
	Veiculo::info();
	cout << "Tipo: " << tipo << endl;
	return 4;
}

float Bicicleta::calcImposto() const { return 0; }



<file_sep>/Practical Classes/TP04/grafo.h
#include <iostream>
#include <vector>

using namespace std;

/**
 * Versao da classe generica Grafo usando a classe vector
 */

template <class N, class A> class Aresta;

template <class N, class A>
class No {
public:
	N info;
	vector< Aresta<N,A> > arestas;
	No(N inf) {
		info = inf;
	}
};

template <class N, class A>
class Aresta {
public:
	A valor;
	No<N,A> *destino;
	Aresta(No<N,A> *dest, A val) {
		valor = val;
		destino = dest;
	}
};

template <class N, class A> 
class Grafo { 
	vector< No<N,A> *> nos;
  public: 
    Grafo();
    ~Grafo(); 
    Grafo & inserirNo(const N &dados);
    Grafo & inserirAresta(const N &inicio, const N &fim, const A &val);
    Grafo & eliminarAresta(const N &inicio, const N &fim);
    A & valorAresta(const N &inicio, const N &fim);
    int numArestas(void) const;
    int numNos(void) const;
    void imprimir(std::ostream &os) const; 
};

template <class N, class A>
std::ostream & operator<<(std::ostream &out, const Grafo<N,A> &g);


// excecao  NoRepetido
template <class N>
class NoRepetido
{
public:
   N info;
   NoRepetido(N inf) { info=inf; }
};
template <class N>
std::ostream & operator<<(std::ostream &out, const NoRepetido<N> &no)
{ out << "No repetido: " << no.info; return out; }



// excecao NoInexistente
template <class N>
class NoInexistente {
public:
	N info;
	NoInexistente(N inf) {
		info = inf;
	}
};
template <class N>
std::ostream & operator<<(std::ostream &out, const NoInexistente<N> &ni)
{ out << "No inexistente: " << ni.info; return out; }



// excecao ArestaRepetida
template <class N>
class ArestaRepetida {
public:
	N start, end;
	ArestaRepetida(N s, N e) {
		start = s;
		end = e;
	}
};
template <class N>
std::ostream & operator<<(std::ostream &out, const ArestaRepetida<N> &ni)
{ out << "Aresta repetida: " << ni.start << " , " << ni.end;; return out; }

// excecao ArestaInexistente
template <class N>
class ArestaInexistente {
public:
	N start, end;
	ArestaInexistente(N s, N e) {
		start = s;
		end = e;
	}
};
template <class N>
std::ostream & operator<<(std::ostream &out, const ArestaInexistente<N> &ni)
{ out << "Aresta inexistente: " << ni.start << " , " << ni.end;; return out; }


template <class N, class A>
Grafo<N,A>::Grafo() {}

template <class N, class A>
Grafo<N,A>::~Grafo() {
	typename vector <No<N,A> *>::const_iterator it;
	for (it = nos.begin(); it!=nos.end(); it++)
		delete *it;
}

template <class N, class A>
int Grafo<N,A>::numNos() const {
	return nos.size();
}

template <class N, class A>
int Grafo<N,A>::numArestas() const {
	int total = 0;
	for (size_t i = 0; i < nos.size(); i++)
		total += (*nos[i]).arestas.size();
	return total;
}

template <class N, class A>
Grafo<N, A> & Grafo<N,A>::inserirNo(const N &dados) {
	for (size_t i = 0; i < nos.size(); i++) {
		if ((*nos[i]).info == dados)
			throw NoRepetido<N>(dados);
	}
	No<N,A> * newNode = new No<N,A>(dados);
	nos.push_back(newNode);
	return *this;
}


template <class N, class A>
Grafo<N, A> & Grafo<N, A>::inserirAresta(const N &inicio, const N &fim, const A &val) {
	No<N,A> * start = NULL;
	No<N,A> * end = NULL;

	for (size_t i = 0; i < nos.size(); i++)
		if ((*nos[i]).info == inicio) start = nos[i];
		else if ((*nos[i]).info == fim) end = nos[i];

	if (start == NULL) throw NoInexistente<N>(inicio);
	if (end == NULL) throw NoInexistente<N>(fim);

	for (auto it = start->arestas.begin(); it != start->arestas.end(); it++) {
		if (it->destino == end) throw ArestaRepetida<N>(inicio, fim);
	}

	Aresta<N, A> ar (end, val);
	start->arestas.push_back(ar);
	return *this;
}

template <class N, class A>
A & Grafo<N, A>::valorAresta(const N &inicio, const N &fim) {
	No<N,A> * start = NULL;
	No<N,A> * end = NULL;
	Aresta<N,A> * edge = NULL;

	for (size_t i = 0; i < nos.size(); i++) {
		if ((*nos[i]).info == inicio) start = nos[i];
		if ((*nos[i]).info == fim) end = nos[i];
	}

	if (start == NULL) throw NoInexistente<N>(inicio);
	if (end == NULL) throw NoInexistente<N>(fim);

	for (auto it = start->arestas.begin(); it != start->arestas.end(); it++)
		if (it->destino == end) edge = &(*it);

	if (edge == NULL) throw ArestaInexistente<N>(inicio, fim);

	return edge->valor;
}

template <class N, class A>
Grafo<N,A> & Grafo<N,A>::eliminarAresta(const N &inicio, const N &fim) {
	No<N,A> * start = NULL;
	No<N,A> * end = NULL;
	int index = -1;

	for (size_t i = 0; i < nos.size(); i++) {
		if ((*nos[i]).info == inicio) start = nos[i];
		if ((*nos[i]).info == fim) end = nos[i];
	}

	if (start == NULL) throw NoInexistente<N>(inicio);
	if (end == NULL) throw NoInexistente<N>(fim);


	for (size_t i = 0; i < start->arestas.size(); i++) {
		if (start->arestas[i].destino == end)
			index = i;
	}

	if (index == -1) throw ArestaInexistente<N>(inicio, fim);

	start->arestas.erase(start->arestas.begin()+index);
	return *this;
}

template <class N, class A>
void Grafo<N,A>::imprimir(std::ostream &os) const {
	for (const auto & node: nos) {
		os << "( " << node->info;
		for (const auto & edge: node->arestas) {
			os << "[ " << edge.destino->info << " " << edge.valor << "] ";
		}
		os << ") ";
	}
}


template <class N, class A>
std::ostream & operator<<(std::ostream &out, const Grafo<N,A> &g) {
	g.imprimir(out);
	return out;
}

<file_sep>/Practical Classes/TP06/Jogo.cpp
/*
 * Jogo.cpp
 *
 */

#include "Jogo.h"
using namespace std;


unsigned Jogo::numPalavras(string frase)
{
  if ( frase.length() == 0 ) return 0;
  int n=1;
  unsigned pos = frase.find(' ');
  while ( pos != string::npos ) {
    frase = frase.substr(pos+1);
    pos = frase.find(' ');
    n++;
  }
  return n;
}


Jogo::Jogo()
{
	criancas.clear();
}

Jogo::Jogo(list<Crianca>& lc2)
{
	for (const auto & c : lc2) criancas.push_back(c);
}

void Jogo::insereCrianca(const Crianca &c1)
{
	criancas.push_back(c1);
}

list<Crianca> Jogo::getCriancasJogo() const
{
	return criancas;
}


string Jogo::escreve() const
{
	string res = "";
	for (const auto & c : criancas) res += c.escreve() + '\n';
	return res;
}


Crianca& Jogo::perdeJogo(string frase)
{
	int nP = numPalavras(frase);
	while(criancas.size() > 1) {
		int index = (nP-1) % criancas.size();
		list<Crianca>::iterator it = criancas.begin();
		for (int i = 0; i < index; i++) it++;
		criancas.erase(it);
	}
	return *(criancas.begin());
}


list<Crianca>& Jogo::inverte()
{
	list<Crianca> lista;
	int n = criancas.size();
	for (int i = 0; i < n; i++) {
		lista.push_back(criancas.back());
		criancas.pop_back();
	}
	criancas.clear();
	for (const auto & c: lista) criancas.push_back(c);
	// a alterar
	return criancas;
}


list<Crianca> Jogo::divide(unsigned id)
{
	list<Crianca> lista;
	list<Crianca>::iterator it;
	for (it = criancas.begin(); it != criancas.end(); it++) {
		if (it->getIdade() > id) {
			lista.push_back(*it);
			it = criancas.erase(it);
			it--;
		}
	}

	return lista;
}


void Jogo::setCriancasJogo(const list<Crianca>& l1)
{
	for (const auto & c : l1) criancas.push_back(c);
}


bool Jogo::operator==(Jogo& j2)
{
	return criancas == j2.getCriancasJogo();
}


list<Crianca> Jogo::baralha() const
{
	list<Crianca> copy = criancas;
	list<Crianca> randomL;
	for (unsigned i = 0; i < criancas.size(); i++){
		int index = rand() % copy.size();
		list<Crianca>::iterator it = copy.begin();
		for (int j = 0; j < index; j++) it++;
		randomL.push_back(*it);
		copy.erase(it);
	}
	return randomL;
}
<file_sep>/Practical Classes/TP03/veterinario.cpp

#include "veterinario.h"

Veterinario::Veterinario(string n, int c) {
	nome = n;
	codOrdem = c;
}

string Veterinario::getNome() const {
	return nome;
}

long Veterinario::getCodOrdem() const {
	return codOrdem;
}



<file_sep>/Practical Classes/TP10/Jogador.cpp
#include "Jogador.h"


void Jogador::adicionaAposta(const Aposta & ap)
{
	apostas.insert(ap);
}

unsigned Jogador::apostasNoNumero(unsigned num) const
{
	unsigned count = 0;

	tabHAposta::const_iterator it;
	for (it = apostas.begin(); it != apostas.end(); it++) {
		if (it->contem(num)) count++;
	}

	return count;
}


tabHAposta Jogador::apostasPremiadas(const tabHInt & sorteio) const
{
	tabHAposta money;

	tabHAposta::const_iterator it;
	for (it = apostas.begin(); it != apostas.end(); it++) {
		int correct = 0;
		for (tabHInt::const_iterator it2 = sorteio.begin(); it2 != sorteio.end(); it2++) {
			if (it->contem(*it2)) correct++;
		}
		if (correct > 3) {
			money.insert(*it);
		}
	}

	return money;
}
<file_sep>/Practical Classes/TP07/Balcao.cpp
#include <queue>
#include <cstdlib>
#include "Balcao.h"
#include <random>

using namespace std;


Cliente::Cliente() {
	numPresentes = rand() % 5 + 1;
}


int Cliente::getNumPresentes() const {
	return numPresentes;
}


Balcao::Balcao(int te): tempo_embrulho(te) {
	tempo_atual = 0;
	prox_chegada = rand() % 20 + 1;
	prox_saida = 0;
	clientes_atendidos = 0;
}      


void Balcao:: proximoEvento()
{
	if (clientes.empty() || prox_chegada < prox_saida) {
		tempo_atual = prox_chegada;
		chegada();
	}
	else {
		tempo_atual = prox_saida;
		saida();
	}
}


void Balcao::chegada()
{
	Cliente cl = Cliente();
	clientes.push(cl);
	prox_chegada = rand() % 20 + 1;

	if (clientes.size() == 1)
		prox_saida = tempo_atual + cl.getNumPresentes() * tempo_embrulho;

	cout << "tempo= " << tempo_atual << "'\nchegou novo cliente com " << cl.getNumPresentes() << " presentes" << endl;
}   


void Balcao::saida()
{
	Cliente cl = getProxCliente();
	clientes.pop();
	clientes_atendidos++;

	if (clientes.size() == 0) prox_saida = tempo_atual;
	else prox_saida = tempo_atual + clientes.front().getNumPresentes() * tempo_embrulho;

	cout << "tempo= " << tempo_atual << "'\nsaiu cliente com " << cl.getNumPresentes() << " presentes" << endl;
}


int Balcao::getTempoAtual() const { return tempo_atual; }


int Balcao::getProxChegada() const { return prox_chegada; }


ostream & operator << (ostream & out, const Balcao & b1)
{
	cout << "Numero de clientes atendidos: " << b1.clientes_atendidos << ", Numero de clientes em espera: " << b1.clientes.size() << endl;

    return out;
}


int Balcao::getTempoEmbrulho() const {
	return tempo_embrulho;
}


int Balcao::getProxSaida() const {
	return prox_saida;
}


int Balcao::getClientesAtendidos() const {
	return clientes_atendidos;
}


Cliente & Balcao::getProxCliente() {
	if (clientes.empty()) throw FilaVazia();
	return clientes.front();
}

<file_sep>/Solved Tests/teste1_16_17/Postman.cpp
/*
 * Postman.cpp
 */
#include "Postman.h"

template <class N>
extern unsigned int numberDifferent(const vector<N> &);

Postman::Postman(): id(0) {}

Postman::Postman(string n) {
	name = n;
	id = currID;
	currID++;
}

int Postman::currID = 1;

void Postman::setName(string nm){
	name = nm;
}

string Postman::getName() const{
	return name;
}

vector<Mail *> Postman::getMail() const {
	return myMail;
}

void Postman::addMail(Mail *m) {
	myMail.push_back(m);
}

void Postman::addMail(vector<Mail *> mails) {
	myMail.insert(myMail.end(),mails.begin(),mails.end());
}

unsigned int Postman::getID() const{
	return id;
}

bool Postman::operator<(const Postman &postman) const {
	int n1, n2;
	vector<string> zipCodes;
	for (const auto & mail : myMail)
		zipCodes.push_back(mail->getZipCode());
	n1 = numberDifferent(zipCodes);

	zipCodes.clear();

	for (const auto & mail : postman.getMail())
		zipCodes.push_back(mail->getZipCode());
	n2 = numberDifferent(zipCodes);

	return n1 < n2;
}


<file_sep>/Solved Tests/teste1_16_17/PostOffice.cpp
/*
 * PostOffice.cpp
 */

#include "PostOffice.h"
#include <string>

PostOffice::PostOffice(string firstZCode, string lastZCode):
								firstZipCode(firstZCode), lastZipCode(lastZCode)
{}
PostOffice::PostOffice() {}

void PostOffice::addMailToSend(Mail *m) {
	mailToSend.push_back(m);
}

void PostOffice::addMailToDeliver(Mail *m) {
	mailToDeliver.push_back(m);
}

void PostOffice::addPostman(const Postman &p){
	postmen.push_back(p);
}

vector<Mail *> PostOffice::getMailToSend() const {
	return mailToSend;
}

vector<Mail *> PostOffice::getMailToDeliver() const {
	return mailToDeliver;
}

vector<Postman> PostOffice::getPostman() const {
	return postmen;
}

vector<Mail *> PostOffice::removePostman(string name) {
	vector<Mail *> mail;
	for (size_t i = 0; i < postmen.size(); i++)
		if (postmen.at(i).getName() == name) {
			mail = postmen.at(i).getMail();
			postmen.erase(postmen.begin()+i);
			break;
		}
	return mail;
}


vector<Mail *> PostOffice::endOfDay(unsigned int &balance) {
	balance = 0;
	vector<Mail *> retVec;
	for (const auto & mail : mailToSend) {
		balance += mail->getPrice();
		if (mail->getZipCode() >= firstZipCode && mail->getZipCode() <= lastZipCode)
			addMailToDeliver(mail);
		else
			retVec.push_back(mail);
	}
	mailToSend.clear();
	return retVec;
}


Postman PostOffice::addMailToPostman(Mail *m, string name) {
	int index = -1;
	for (size_t i = 0 ; i < postmen.size(); i++)
		if (postmen.at(i).getName() == name)
			index = i;

	if (index == -1) throw NoPostmanException(name);
	postmen.at(index).addMail(m);
	return postmen.at(index);
}
<file_sep>/Solved Tests/teste2_16_17/Purchase.cpp
/*
 * Purchase.cpp
 *
 *  Created on: Nov 16, 2016
 *      Author: hlc
 */

#include "Purchase.h"

using namespace std;

Purchase::Purchase(long cli) : client (cli) {
}

long Purchase::getClient() const {
	return client;
}

list< stack<Article*> > Purchase::getBags() const {
	return bags;
}

/**
 * Create an Article associated with the client of this purchase.
 */
Article* Purchase::createArticle(long barCode, bool present, bool deliverHome) {

	Article * art = new Article(client, barCode);
	art->setPresent(present);
	art->setDeliverHome(deliverHome);

	return art;

}

/**
 * Add an Article to the bags of this purchase. A new bag is added when the last bag is full.
 */
void Purchase::putInBag(Article* article) {

	bool inserted = false;
	for (auto & bag : bags) {
		if (bag.size() < Purchase::BAG_SIZE) {
			inserted = true;
			bag.push(article);
		}
	}
	if (!inserted) {
		stack<Article*> newBag;
		newBag.push(article);
		bags.push_back(newBag);
	}

}

/**
 * Pop from the bags all articles that are presents.
 * All other articles are pushed back into the bags where they were, maintaining order.
 */
vector<Article*> Purchase::popPresents() {
	vector<Article*> presents;

	for (auto & bag : bags) {
		list<Article*> temp;
		while(bag.size() > 0) {
			if(bag.top()->getPresent()) {
				presents.push_back(bag.top());
			}
			else {
				temp.push_back(bag.top());
			}
			bag.pop();
		}
		list<Article*>::reverse_iterator it;
		for (it = temp.rbegin(); it != temp.rend(); it++) bag.push(*it);
	}

	return presents;

}

<file_sep>/Solved Tests/teste2_17_18/Doctor.cpp
/*
 * Doctor.cpp
 */

#include "Doctor.h"


Patient::Patient(unsigned codP, string mS): codeP(codP), medicalSpecialty(mS)
{}

string Patient::getMedicalSpecialty() const {
	return medicalSpecialty;
}

unsigned Patient::getCode() const {
	return codeP;
}

Doctor::Doctor(unsigned codM, string mS): codeM(codM), medicalSpecialty(mS)
{}


Doctor::Doctor(unsigned codM, string mS, queue<Patient> patients1): codeM(codM), medicalSpecialty(mS), patients(patients1)
{}

unsigned Doctor::getCode() const {
	return codeM;
}

string Doctor::getMedicalSpecialty() const {
	return medicalSpecialty;
}

queue<Patient> Doctor::getPatients() const {
	return patients;
}

void Doctor::addPatient(const Patient &p1) {
	patients.push(p1);
}

Patient Doctor::removeNextPatient() {
	if (!patients.empty()) {
		Patient p1 = patients.front();
		patients.pop();
		return p1;
	}
	else throw PatientInexistent();
}




void Doctor::moveToFront(unsigned codP1) {
	queue<Patient> temp = patients;
	queue<Patient> newQueue;
	while (temp.size() > 0) {
		Patient pat = temp.front();
		temp.pop();
		if (pat.getCode() == codP1) newQueue.push(pat);
	}
	while(patients.size() > 0) {
		Patient pat = patients.front();
		patients.pop();
		if (pat.getCode() != codP1) newQueue.push(pat);
	}
	patients = newQueue;


}

bool Doctor::operator<(Doctor & doc) {
	if (medicalSpecialty == doc.getMedicalSpecialty() && patients.size() == doc.getPatients().size())
		return codeM < doc.getCode();
	else if (patients.size() == doc.getPatients().size())
		return medicalSpecialty < doc.getMedicalSpecialty();
	return patients.size() < doc.getPatients().size();
}

<file_sep>/Practical Classes/TP05/parque.cpp
#include "parque.h"
#include "insertionSort.h"
#include "sequentialSearch.h"
#include <vector>

using namespace std;


ParqueEstacionamento::ParqueEstacionamento(unsigned int lot, unsigned int nMaxCli):
	lotacao(lot), numMaximoClientes(nMaxCli) {
    numClientes = 0;
    vagas=lot; 
}

ParqueEstacionamento::~ParqueEstacionamento() {}

vector<InfoCartao> ParqueEstacionamento::getClientes() const { return clientes; }


bool ParqueEstacionamento::adicionaCliente(const string & nome)
{
 	if ( numClientes == numMaximoClientes ) return false;
	if ( posicaoCliente(nome) != -1 ) return false;
	InfoCartao info;
	info.nome = nome;
    info.presente = false;
    info.frequencia = 0;  // a fazer
	clientes.push_back(info);
	numClientes++;
	return true;
}
 
bool ParqueEstacionamento::retiraCliente(const string & nome)
{
	for (vector<InfoCartao>::iterator it = clientes.begin(); it != clientes.end(); it++)
		if ( it->nome == nome ) {
			if ( it->presente == false ) {
				clientes.erase(it);
				numClientes--;
				return true;
			}
			else return false;
		}
	return false;
}
  
unsigned int ParqueEstacionamento::getNumLugares() const
{
	return lotacao;
}
                   
unsigned int ParqueEstacionamento::getNumLugaresOcupados() const
{
	return lotacao-vagas;
}

int ParqueEstacionamento::getFrequencia(const string &nome) const {
	int index = posicaoCliente(nome);
	if (index == -1) throw ClienteNaoExistente(nome);
	return clientes[index].frequencia;
}

bool ParqueEstacionamento::entrar(const string & nome)
{
	if ( vagas == 0 ) return false;
	int pos = posicaoCliente(nome);
	if ( pos == -1 ) return false;
	if ( clientes[pos].presente == true ) return false;
	clientes[pos].frequencia++;
	clientes[pos].presente = true;
	vagas--;
	return true;
}

bool ParqueEstacionamento::sair(const string & nome)
{
	int pos = posicaoCliente(nome);
	if ( pos == -1 ) return false;
	if ( clientes[pos].presente == false ) return false;
	clientes[pos].presente = false;
	vagas++;
	return true;
}

int ParqueEstacionamento::posicaoCliente(const string & nome) const {
	InfoCartao ic;
	ic.nome = nome;
	return sequentialSearch(clientes, ic);
}

void ParqueEstacionamento::ordenaClientesPorFrequencia() {
	insertionSort(clientes);
}

void ParqueEstacionamento::ordenaClientesPorNome() {
	for(unsigned int j=clientes.size()-1; j>0; j--){
		bool troca=false;
		for(unsigned int i = 0; i<j; i++)
			if(clientes[i+1].nome < clientes[i].nome) {
				swap(clientes[i],clientes[i+1]);
				troca = true;
			}
		if (!troca) return;
	}
}

vector<string> ParqueEstacionamento::clientesGamaUso(int n1, int n2) {
	vector<InfoCartao> v = clientes;
	vector<string> nomes;
	insertionSort(v);

	for (size_t i = 0; i < v.size(); i++)
		if (v.at(i).frequencia >= n1 && v.at(i).frequencia <= n2)
			nomes.push_back(v.at(i).nome);
	return nomes;
}

InfoCartao ParqueEstacionamento::getClienteAtPos(vector<InfoCartao>::size_type p) const {
	if (p > clientes.size()-1) throw PosicaoNaoExistente(p);
	return clientes.at(p);
}

bool InfoCartao::operator==(const InfoCartao &ic1) const { return ic1.nome == nome; }
bool InfoCartao::operator<(const InfoCartao &ic1) const {
	if (ic1.frequencia == frequencia) {
		return  nome < ic1.nome;
	}
	return ic1.frequencia < frequencia;
}

ostream & operator<<(ostream & os, const ParqueEstacionamento & pe) {
	for (const auto &cl : pe.clientes) {
		os << cl.nome << " " << cl.frequencia;
		if (cl.presente) os << " - Present" << endl;
		else os << " - Not Present" << endl;
	}
	return os;
}

<file_sep>/Practical Classes/TP03/animal.h
#ifndef SRC_ANIMAL_H_
#define SRC_ANIMAL_H_

#include "veterinario.h"
#include <string>
using namespace std;

class Animal {
protected:
	string nome;
	int idade;
	Veterinario *vet;
	static int maisJovem;
public:
	/**
	 * Constructor for the Animal class
	 * @param nome Animal name
	 * @param idade Animal age
	 */
	Animal(string nome, int idade);

	/**
	 * Animal class Destructor
	 */
	virtual ~Animal(){};

	/**
	 * Name getter method
	 * @return Animal name
	 */
	string getNome() const;

	/**
	 * Age getter method
	 * @return Animal age
	 */
	int getIdade() const;

	/**
	 * Assigned veterinary getter method
	 * @return Animal assigned veterinary
	 */
	Veterinario* getVet() const;

	/**
	 * Youngest animal getter method
	 * @return Younger of the existent animal's age
	 */
	static int getMaisJovem() { return maisJovem; }

	/**
	 * Verify if the animal is considered young
	 * @return bool representing if the animal is young
	 */
	virtual bool eJovem() const = 0;

	/**
	 * Get the attributes' information of the animal
	 * @return string with the animal's information
	 */
	virtual string getInformacao() const;

	/**
	 * Assign a veterinary to the animal
	 * @param Veterinary to assign
	 * @return bool representing operation success
	 */
	bool alocaVet(Veterinario *vet);
};

class Cao: public Animal {
	string raca;
public:
	/**
	 * Constructor for the Cao class
	 * @param nome Cao name
	 * @param idade Cao age
	 * @param raca Cao breed
	 */
	Cao(string nome, int idade, string raca);

	/**
	 * Verify if the cao is considered young
	 * @return bool representing if the cao is young
	 */
	bool eJovem() const;

	/**
	 * Get the attributes' information of the Cao
	 * @return string with the Cao's information
	 */
	string getInformacao() const;
};



class Voador {
	int velocidade_max;
	int altura_max;
public:
	/**
	 *
	 */
	Voador(int vmax, int amax);
	virtual ~Voador(){};
	virtual string getInformacao() const;
};



class Morcego: public Animal, public Voador {
public:
	Morcego(string nome, int idade, int vmax, int amax);
	bool eJovem() const;
	string getInformacao() const;
};


#endif /* SRC_ANIMAL_H_ */
<file_sep>/README.md
# Algorithms and Data Structures 2018-2019 :file_folder:

Exercises solved during practical classes for the AEDA curricular unit, as well as tests from previous years.

#### Project
[https://github.com/GambuzX/Games_Library](https://github.com/GambuzX/Games_Library "GamesLibrary")

<br>

**Final Grade: 19**

### Technologies and Software Used
* C++
* Doxygen
* Visual Paradigm (UML diagram)
* Eclipse

### Curricular Unit Info
* **Date:** 2nd Year, 1st Semester, 2018/2019
* **Course:** [Algoritmos e Estruturas de Dados | Algorithms and Data Structures](https://sigarra.up.pt/feup/en/UCURR_GERAL.FICHA_UC_VIEW?pv_ocorrencia_id=419991 "AEDA") (AEDA)

### Disclaimer (Valid for any `MIEIC_course` repository)
This repository was used for educational purposes and I do not take any responsibility for anything related to its content. You are free to use any code or algorithm you find, but do so at your own risk.

<file_sep>/Practical Classes/TP11/MaquinaEmpacotar.cpp
/*
 * Empacotador.cpp
 */

#include "MaquinaEmpacotar.h"
#include <sstream>


MaquinaEmpacotar::MaquinaEmpacotar(int capCaixas): capacidadeCaixas(capCaixas)
{}

unsigned MaquinaEmpacotar::numCaixasUsadas() {
	return caixas.size();
}

unsigned MaquinaEmpacotar::addCaixa(Caixa& cx) {
	caixas.push(cx);
	return caixas.size();
}

HEAP_OBJS MaquinaEmpacotar::getObjetos() const {
	return this->objetos;
}

HEAP_CAIXAS MaquinaEmpacotar::getCaixas() const {
	return this->caixas;
}


/* a implementar pelos estudantes */

unsigned MaquinaEmpacotar::carregaPaletaObjetos(vector<Objeto> &objs) {

	unsigned loaded = 0;
	vector<Objeto>::iterator it;
	for (it = objs.begin(); it != objs.end(); it++) {
		if (it->getPeso() > capacidadeCaixas) continue;
		loaded++;
		objetos.push(*it);
		it = objs.erase(it);
		it--;
	}
	return loaded;
}


Caixa MaquinaEmpacotar::procuraCaixa(Objeto& obj) {
	Caixa cx = Caixa(capacidadeCaixas);
	unsigned size = caixas.size();
	vector<Caixa> vecCaixas;
	for (size_t i = 0; i < size; i++) {
		vecCaixas.push_back(caixas.top());
		caixas.pop();
	}

	vector<Caixa>::iterator it;
	for (it = vecCaixas.begin(); it != vecCaixas.end(); it++) {
		if (it->getCargaLivre() >= obj.getPeso()) {
			cx = *it;
			vecCaixas.erase(it);
			break;
		}
	}

	for (size_t i = 0; i < vecCaixas.size(); i++)
		caixas.push(vecCaixas[i]);

	return cx;
}


unsigned MaquinaEmpacotar::empacotaObjetos() {
	unsigned usedBoxes = 0;

	vector<unsigned> ids;

	unsigned n_objs = objetos.size();
	for (unsigned i = 0; i < n_objs; i++) {
		Objeto obj = objetos.top();
		objetos.pop();

		Caixa box = procuraCaixa(obj);
		box.addObjeto(obj);
		caixas.push(box);
		bool repeatedBox = false;
		for (unsigned j = 0; j < ids.size(); j++)
			if (ids[j] == box.getID())
				repeatedBox = true;

		if (!repeatedBox) {
			ids.push_back(box.getID());
			usedBoxes++;
		}
	}

	return usedBoxes;
}

string MaquinaEmpacotar::imprimeObjetosPorEmpacotar() const {
	string retString = "";

	if (objetos.size() == 0) return "Nao ha objetos!\n";

	HEAP_OBJS copy = objetos;

	unsigned n_objs = copy.size();
	for (unsigned i = 0; i < n_objs; i++) {
		Objeto obj = copy.top();
		copy.pop();

		ostringstream oss;
		oss << obj;
		retString += oss.str() + '\n';
	}

	return retString;
}



Caixa MaquinaEmpacotar::caixaMaisObjetos() const {
	if (caixas.size() == 0) throw MaquinaSemCaixas();

	HEAP_CAIXAS copy = caixas;
	unsigned n_boxes = copy.size();

	unsigned maxObjs = 0;
	Caixa cx;
	for (unsigned i = 0; i < n_boxes; i++) {
		Caixa temp = copy.top();
		copy.pop();
		if (temp.getSize() > maxObjs) {
			maxObjs = temp.getSize();
			cx = temp;
		}
	}
	return cx;
}



