#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

typedef struct node {
	struct node* next;
	int data;
} node_t;

//could be only `last`; by definition, `head = last->next;`
typedef struct{
	node_t* head;
	node_t* last;
} CIRC;

//exo
CIRC mkcircular();
void insert(CIRC* cycle, int el);
node_t* extract(CIRC* cycle);
node_t* rotateToEven(CIRC* cycle);
node_t* rotateToOdd(CIRC* cycle);

void rotate(CIRC* cycle);

int main(void)
{
	CIRC circ = mkcircular();
	insert(&circ, 42);
	insert(&circ, 21);
	insert(&circ, 12);

	printf("rotateToEven -> %d\n", rotateToEven(&circ)->data);
	printf("rotateToOdd -> %d\n", rotateToOdd(&circ)->data);
	printf("rotateToOdd -> %d\n", rotateToOdd(&circ)->data);
	printf("rotateToEven -> %d\n", rotateToEven(&circ)->data);

	printf("--------------------------\n");
	printf("extract -> %d\n", extract(&circ)->data);
	printf("extract -> %d\n", extract(&circ)->data);
	printf("extract -> %d\n", extract(&circ)->data);
	assert(!extract(&circ));
}

CIRC mkcircular(){
	return (CIRC){};
}

void insert(CIRC* cycle, int el){
	node_t* new = malloc(sizeof(node_t));
	if(cycle->head == NULL)
		cycle->head = cycle->last = new;
	new->next = cycle->head;
	new->data = el;

	cycle->last->next = new;
	cycle->last = new;
}

//problem with return node_t, it is the user that has to free the memory
//that he did not explicitly allocated...
node_t* extract(CIRC* cycle){
	if(cycle->head == NULL || cycle->last == NULL)
		return NULL;
	node_t* ret = cycle->head;
	if(cycle->head == cycle->last){
		cycle->head = cycle->last = NULL;
		return ret;
	}
	cycle->head = cycle->head->next;
	cycle->last->next = cycle->head; 
	return ret;
}

void rotate(CIRC* cycle){
	cycle->last = cycle->head;
	cycle->head = cycle->head->next;
}

node_t* rotateToEven(CIRC* cycle){
	while(cycle->head->data % 2 != 0)
		rotate(cycle);
	return cycle->head;
}

node_t* rotateToOdd(CIRC* cycle ){
	while(cycle->head->data % 2 == 0)
		rotate(cycle);
	return cycle->head;

}
