#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;


int **init_a(int **a, int n){
	a=new int *[n];
	for(int i=0;i<n;i++)
		a[i]=new int[n];

	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++) {
			a[i][j]=rand()%2;
		}

	}
	return a;
}

void print_2D(int **a, int n) {
	for(int i=0;i<n;i++) {
		for(int j=0;j<n;j++){
			cout<< a[i][j] <<"  ";
		}
		cout<<endl;
	}
}

void print_matrix(int **a, int rows, int cols){

	for(int i=0;i<rows;i++){
		for(int j=0;j<cols;j++){
			cout<< a[i][j]<<"  ";
		}
		cout<<endl;
	}
}

void print_adresses(int **a, int rows, int cols){

	for(int i=0;i<rows;i++){
		for(int j=0;j<cols;j++){
		cout<<&a[i][j]<<"  ";
		}
		cout<<endl;
	}

}

int **resize_2D(int **&a, int oldN, int newN){
	int **newA = new int *[newN];
	for(int i=0;i<newN;i++)
		newA[i]=new int[newN];
	
	for(int i=0;i<oldN;i++)
			for(int j=0;j<oldN;j++)
				newA[i][j]=a[i][j];
	for(int i=0; i<newN;i++){
		for(int j=0;j<newN;j++){
			if(i>=oldN || j>=oldN)
				newA[i][j]=rand()%2;
		}
	}

	for(int i=0;i<oldN;i++)
		delete[] a[i];
	delete[] a;

	a=newA;

	return a;
}

int **add_columns(int **&a, int oldRows, int oldCols, int addedCols){

	int newCols=oldCols+addedCols;

	int **newA = new int*[oldRows];
	for(int i = 0; i<oldRows; i++)
		newA[i]=new int[newCols];

	for(int i=0;i<oldRows;i++)
		for(int j=0;j<oldCols;j++)
			newA[i][j]=a[i][j];

	for(int i=0;i<oldRows;i++)
		for(int j=oldCols;j<newCols;j++)
			newA[i][j]=rand()%2;

	for(int i=0;i<oldRows;i++)
		delete[] a[i];

	delete[] a;
	a=newA;

	return a;
}

int **add_rows(int **&a, int oldRows, int oldCols, int addedRows){

	int newRows=oldRows+addedRows;

	int **newA = new int*[newRows];
	for(int i=0;i<newRows;i++)
		newA[i]=new int[oldCols];

	for(int i=0;i<oldRows;i++)
		for(int j=0;j<oldCols;j++)
			newA[i][j]=a[i][j];

	for(int i=oldRows;i<newRows;i++)
		for(int j=0;j<oldCols;j++)
			newA[i][j]=rand()%2;
	for(int i=0;i<oldRows;i++)
		delete[] a[i];

	delete[] a;
	a=newA;

	return a;
}

int main() {

	int **a=nullptr;

	cout<< "Randomly generated 3x3 matrix: "<<endl<<"(equipped with integers in [0,1])"<<endl;
	a=init_a(a, 3);
	print_2D(a, 3);

	cout<< "Each value corresponds to an adress from below: "<<endl;
	print_adresses(a, 3, 3);

	cout<< "Same matrix resized to 4x4: "<<endl;
	resize_2D(a, 3, 4);
	print_2D(a, 4);

	cout<< "Once we add two columns we get the 4x6 below: "<<endl;
	add_columns(a, 4, 4, 2);
	print_matrix(a, 4, 6);

	//PRINT MATRIX

	cout<< "And adding two rows to this one will give us the 6x6 matrix below: "<< endl;
	add_rows(a, 4, 6, 2);
	print_2D(a, 6);
	//enallaktika      print_matrix(a, 6, 6);

	cout<<endl<<"goodbye ~"<<endl;

return 0;
}

