#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;

struct Node{
	int value;
	char label;
	Node* next = nullptr;
};

int nodeSum(Node* current){
	int total = 0;
	while (current->next != nullptr){
		cout << current->label << ": " << current->value << endl;
		total += current->value;
		current = current->next;
	}
	cout << current->label << ": " << current->value << endl;
	total += current->value;
	cout << "total: ";
	return total;
}

float nodeAvg(Node* current){
	int total = 0;
	int nodeCount = 0;
	float average;
	while (current->next != nullptr){
		cout << current->label << ": " << current->value << endl;
		total += current->value;
		nodeCount++;
		current = current->next;
	}
	cout << current->label << ": " << current->value << endl;
	total += current->value;
	nodeCount++; //don't forget to count the last node!
	cout << "total: " << total << endl;
	cout << "number of nodes: " << nodeCount << endl;
	if(nodeCount > 0){
		average = float(total)/float(nodeCount); //if you get strange rounding with floats, this is the cure.
		cout << "average: "; 
		return average;
	}else{
		cout << "ERROR: No nodes: divide by zero.";
	}
	return 0;
}

int main(){
	Node *n = new Node;
	Node *first = nullptr;
	Node *second = nullptr;
	Node *curr = nullptr;
	Node *last = nullptr;

	srand(time(0));

	first = n;
	curr = first; // keep the address of the head of the second list
	curr->value = rand() % 100 + 1;
	curr->label = 'a';
	curr->next = new Node; // create the next node
	curr = curr->next; // make current this new node

	curr->value = rand() % 100 + 1;
	curr->label = 'b';
	curr->next = new Node;
	curr = curr->next;

	curr->value = rand() % 100 + 1;
	curr->label = 'c';

	// set current back to the head of the list
	curr = first;

	while(curr->next != nullptr){
		cout << "Node " << curr->label << ":\naddress: " << curr << ", value: " << curr->value << ", next address: " << curr->next << endl;
		curr = curr->next;
	} // then print the last node:
	cout << "Node " << curr->label << ":\naddress: " << curr << ", value: " << curr->value << ", next address: " << curr->next << endl;
	last = curr;

	cout << "\nAverage of the first list (a,b,c):\n" << setprecision(2) << fixed << nodeAvg(first) << endl;

	n = new Node;
	second = n; // keep the address of the head of the second list
	curr = second;

	curr->value = rand() % 100 + 1;
	curr->label = 'd';
	curr->next = new Node;
	curr = curr->next;

	curr->value = rand() % 100 + 1;
	curr->label = 'e';
	curr->next = new Node;
	curr = curr->next;

	curr->value = rand() % 100 + 1;
	curr->label = 'f';

	// set current back to the head of the list
	curr = second;

	while(curr->next != nullptr){
		cout << "Node " << curr->label << ":\naddress: " << curr << ", value: " << curr->value << ", next address: " << curr->next << endl;
		curr = curr->next;
	} //then print the last node:
	cout << "Node " << curr->label << ":\naddress: " << curr << ", value: " << curr->value << ", next address: " << curr->next << endl;

	cout << "\nAverage of the second list (d,e,f):\n" << setprecision(2) << fixed << nodeAvg(second) << endl;

	// How about linking the two separate lists?

	last->next = second;
	curr = last;
	cout << "Setting c's next pointer to &d.\n";
	cout << "Node " << curr->label << ":\naddress: " << curr << ", value: " << curr->value << ", next address: " << curr->next << endl;
	curr = curr->next;
	cout << "Node " << curr->label << ":\naddress: " << curr << ", value: " << curr->value << ", next address: " << curr->next << endl;

	curr = first;
	cout << "\nAverage of the second list (a,b,c,f,e,d):\n" << setprecision(2) << fixed << nodeAvg(first) << endl;
	
	return 0;
}