///////////////////////////////////////////////////////////////////   
// Name: Elias Martinez   
// Date: 10/20/2025   
// Class: CSCI 2380-01   
// Semester: Fall 2025   
/////////////////////////////////////////////////////////////////// 
#include <iostream>
using namespace std;
 
class Node {
public:
    string name;   // The data stored in the node
    Node* next;    // Pointer to the next node
 
    // Constructor to create a new node
    Node(string val) {
        name = val;
        next = nullptr;
    }
};
 
// Add a new node at the end of the list
void insertLast(Node*& head, string value) {
    Node* newNode = new Node(value);
 
    if (head == nullptr) {
        // If the list is empty, new node becomes the head
        head = newNode;
    } else {
        // Otherwise, go to the end and add the new node
        Node* temp = head;
        while (temp->next != nullptr) {
            temp = temp->next;
        }
        temp->next = newNode;
    }
}
 
// Insert a node as the third node in the list
void insertThird(Node*& head, string value) {
    Node* newNode = new Node(value);
 
    if (head == nullptr) {
        // If list is empty, just add the node at the beginning
        head = newNode;
        return;
    }
 
    Node* temp = head;
    int count = 1;
 
    // Move to the second node (if it exists)
    while (temp->next != nullptr && count < 2) {
        temp = temp->next;
        count++;
    }
 
    // If fewer than 2 nodes, insert at the end
    if (count < 2) {
        temp->next = newNode;
    } else {
        // Insert after the second node
        newNode->next = temp->next;
        temp->next = newNode;
    }
}
 
// Delete the first node and return its value
string deleteFront(Node*& head) {
    if (head == nullptr) {
        return "List is empty";
    }
 
    Node* temp = head;
    string deletedValue = temp->name;
    head = head->next; // Move head to next node
    delete temp;       // Free memory
    return deletedValue;
}
 
// Delete the second node and return its value
string deleteSecond(Node*& head) {
    if (head == nullptr || head->next == nullptr) {
        return "List is too short";
    }
 
    Node* temp = head->next;
    string deletedValue = temp->name;
    head->next = temp->next; // Skip over the second node
    delete temp;
    return deletedValue;
}
 
// Update the value of the last node
void updateLast(Node* head, string value) {
    if (head == nullptr) return;
 
    Node* temp = head;
    while (temp->next != nullptr) {
        temp = temp->next;
    }
    temp->name = value; // Change the last node's name
}
 
// Print all the values in the list
void printList(Node* head) {
    Node* temp = head;
    while (temp != nullptr) {
        cout << temp->name;
        if (temp->next != nullptr) cout << " ";
        temp = temp->next;
    }
    cout << endl;
}
 
// Main function to test everything
int main() {
    Node* h1 = nullptr;
    Node* h2 = nullptr;
 
    insertLast(h1, "Daniela");
    insertLast(h1, "Daria");
    insertLast(h1, "Berta");
    insertLast(h1, "Hugo");
    insertThird(h1, "Hector");
 
    printList(h1); // Output: Daniela Daria Hector Berta Hugo
 
    updateLast(h1, "Bernardo");
 
    printList(h1); // Output: Daniela Daria Hector Berta Bernardo
 
    cout << deleteFront(h1) << endl; // Output: Daniela
 
    insertThird(h2, "Daniela");
 
    printList(h2); // Output: Daniela
 
    cout << deleteSecond(h2) << endl; // Output: List is too short
}