/* 
   Laboratorium Praktyki Programowania  
*/


/* Należ pozostawić definicję tylko jednej ze stałych : */

/* dla nowszych kompilatorów */
#define ANSI

/* dla starszych kompilatorów */
//#define ARM


#ifdef ANSI
#include <iostream>
#include <cstring>
#include <cassert>
using namespace std;
#endif

#ifdef ARM
#include <iostream.h>
#include <string.h>
#include <assert.h>
#endif


typedef int Elem;

const int MAXLIST=12;
const int MAXSTOS=1000000;

typedef struct lista{
  Elem e;
  struct lista *nast; 
} Lista;

/*Statyczny stos do przechowywania elementów list łączonych*/
typedef struct stos{
  int sp, //wskaźnik wierzchołka stosu
    capacity; //pojemność stosu
  Lista* ss;  //stos
} Stos;

/* wypisz element e*/
void wypisz_elem(Elem e);
/* wypisz elementy od początku listy*/
void wypisz_p(Lista *l);
/* wypisz elementy od końca listy*/
void wypisz_k(Lista *l);
/* zwraca wskaźnik do listy z elementem e wstawionym  na początek listy l */
void wstaw_p(Lista *&l, Stos &s, Elem e);
/*Inicjacja stosu o rozmiarze capacity*/
void stosTworz(Stos &s, int capacity);
/*Zarezerwuj na stosie miejsce dla kolejnego elementu*/
Lista* getElem(Stos &s);
/*Zwolnienie pamięcie dla stosu s*/
void stosNiszcz(Stos &s);


int main()
{
  int i,a,b;;
  Lista* l[MAXLIST];
  Stos s;
  
  //zerowanie tablicy 
  for (i=0; i<MAXLIST; i++) l[i]=NULL;
  //tworzenie stosu
  stosTworz(s,MAXSTOS);

  //wstawienie przypadkowych danych
  for (i=0; i<17; i++){
    a=i*4%MAXLIST;
    b=(i*13+6)%MAXLIST;
    if (a!=b){
      wstaw_p(l[a],s,b);
      wstaw_p(l[b],s,a);
    }
  }
 
  for (i=0; i<MAXLIST; i++){
    cout << "Rozmowy " << i << endl;
    wypisz_p(l[i]);
    cout << endl;
  }

  return 0;
}

/* wypisuje element e*/
void wypisz_elem(Elem e){
  cout << e << " ";
}

/* wypisuje elementy od początku listy*/
void wypisz_p(Lista *l){
  if (l){
    wypisz_elem(l->e);
    wypisz_p(l->nast);
  }
}

/* wypisuje elementy od końca listy*/
void wypisz_k(Lista *l){
  if (l){
    wypisz_k(l->nast);
    wypisz_elem(l->e);
  }
}

/* zwraca wkaźnik do listy z e wstawionym  na początek listy l*/
void wstaw_p(Lista *&l, Stos &stos, Elem e){
  Lista *pom;
  pom = getElem(stos);
  pom->e=e;
  pom->nast=l;
  l=pom;
}

/*Inicjacja stosu o rozmiarze capacity*/
void stosTworz(Stos &s, int capacity){
  s.sp=0;
  s.capacity=capacity;
  s.ss=new Lista[capacity];
  //upewnij się że przydzielono pamięć
  assert(s.ss);
}

/*Zarezerwuj na stosie miejsce dla kolejnego elementu*/
Lista* getElem(Stos &s){
  //upewnij się że jest jeszcze miejsce
  assert (s.sp+1<s.capacity);
  return &s.ss[s.sp++];
}

/*Zwolnienie pamięcie dla stosu s*/
void stosNiszcz(Stos &s){
  s.sp=0;
  s.capacity=0;
  delete[] s.ss;
}

