diff --git a/DBHandler/DBHandler.cpp b/DBHandler/DBHandler.cpp new file mode 100644 index 0000000..58d50ab --- /dev/null +++ b/DBHandler/DBHandler.cpp @@ -0,0 +1,25 @@ +#include "DBHandler.hpp" + +#include +//host = localhost port = 5432 dbname = postgres user = postgres password = **** + + +DBHandler::DBHandler(std::string connStr) : connectionObject(connStr.c_str()) { + try { + if (connectionObject.is_open()) { + std::cout << "Databased connected" << std::endl; + } + else + std::cout << "Failed to connect to Databased" << std::endl; + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } +}; + + + + + + + diff --git a/DBHandler/DBHandler.hpp b/DBHandler/DBHandler.hpp new file mode 100644 index 0000000..71f9db7 --- /dev/null +++ b/DBHandler/DBHandler.hpp @@ -0,0 +1,14 @@ +#ifndef DBHANDLER_HPP_ +#define DBHANDLER_HPP_ +#include +#include + +class DBHandler { +protected: + pqxx::connection connectionObject; + +public: + DBHandler(std::string connStr); +}; + +#endif \ No newline at end of file diff --git a/DBHandler/DBLogin.cpp b/DBHandler/DBLogin.cpp new file mode 100644 index 0000000..344e8b0 --- /dev/null +++ b/DBHandler/DBLogin.cpp @@ -0,0 +1,41 @@ +#include "DBLogin.hpp" +#include + +DBLogin::DBLogin(std::string connStr) : DBHandler(connStr) {}; + + + +/* + +return 1 if admin | 0 if not admin | -1 if failed + +*/ + +int DBLogin::checkValidLogin(std::string id, std::string pw) { + + try { + pqxx::work worker(connectionObject); + + std::string query = + "SELECT admin FROM studenten_veranstalter WHERE id = $1 AND passwort = $2"; + + pqxx::result response = worker.exec_params(query, id, pw); + + if (response.affected_rows() > 0) { + + + if (response[0][0].is_null()) + return 0; + return response[0][0].as(); + + } + + return -1; + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } + +} + + diff --git a/DBHandler/DBLogin.hpp b/DBHandler/DBLogin.hpp new file mode 100644 index 0000000..e348fed --- /dev/null +++ b/DBHandler/DBLogin.hpp @@ -0,0 +1,18 @@ +#ifndef _DBLOGIN_HPP_ +#define _DBLOGIN_HPP_ +#include "DBHandler.hpp" + +class DBLogin : public DBHandler { +public: + DBLogin(std::string connStr); + /* + +return 1 if admin | 0 if not admin | -1 if failed + +*/ + int checkValidLogin(std::string id, std::string pw); +}; + + + +#endif diff --git a/DBHandler/DBPlan.cpp b/DBHandler/DBPlan.cpp new file mode 100644 index 0000000..9a3f0bb --- /dev/null +++ b/DBHandler/DBPlan.cpp @@ -0,0 +1,477 @@ +#include "DBPlan.hpp" + +DBPlan::DBPlan(std::string connStr) : DBHandler(connStr) { +}; + + +void DBPlan::vertretung(std::string tag, std::string stunde, std::string dauer) { + try { + std::string prevStunde = std::to_string(std::stoi(stunde) - 1); + std::string cap = std::to_string(18 - std::stoi(dauer)); + std::string nextStunde; + std::string nextTag = tag; + std::string prevTag = tag; + if (dauer == "4") { + + nextStunde = std::to_string(std::stoi(stunde) + 2); + std::cout << nextStunde << std::endl; + } + else { + nextStunde = std::to_string(std::stoi(stunde) + 1); + std::cout << nextStunde << std::endl; + } + + if (prevStunde == "0") { + prevStunde = "5"; + prevTag = std::to_string(std::stoi(tag) - 1); + if (prevTag == "0") { + prevTag = "5"; + } + } + + if (nextStunde == "6") { + nextStunde = "1"; + nextTag = std::to_string(std::stoi(tag)+1); + if (nextTag == "6") { + nextTag = "1"; + } + } + + pqxx::work worker(connectionObject); + + + std::string query = + "UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstalter_ID = " + "(SELECT ID FROM Veranstalter WHERE ID != (SELECT Veranstalter_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2) " + "AND ID != (SELECT Veranstalter_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $3 AND tag = $4) LIMIT 1) WHERE uhrzeit_id = $5 AND tag = $6; "; + + + pqxx::result response = worker.exec_params(query, prevStunde, prevTag, nextStunde, nextTag, stunde, tag); + + worker.commit(); + + + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + + } +} + +void DBPlan::sucheVertretung(std::string tag, std::string stunde) { + std::string dauer = getDauer(tag, stunde); + vertretung(tag, stunde, dauer); + incarbeitszeit(tag, stunde, dauer); + + if (dauer == "4") { + upperHour(tag, stunde); + } + + + +} + +void DBPlan::meldeKrank(std::string id, std::string tag, std::string stunde) { + + try { + + pqxx::work worker(connectionObject); + std::string query = + "UPDATE Veranstalter SET krank = TRUE WHERE ID = $1"; + + pqxx::result response = worker.exec_params(query, id); + worker.commit(); + + sucheVertretung(tag, stunde); + meldeGesund(id); + + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + + } +} + + +void DBPlan::meldeGesund(std::string id) { + try { + pqxx::work worker(connectionObject); + std::string query = + "UPDATE Veranstalter SET krank = FALSE WHERE ID = $1"; + + pqxx::result response = worker.exec_params(query, id); + worker.commit(); + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } +} + + + + +void DBPlan::deleteVeranstalterForeign(std::string id) { + try { + pqxx::work worker(connectionObject); + std::string query = + "UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstalter_ID = NULL WHERE Veranstalter_ID = $1;"; + + pqxx::result response = worker.exec_params(query, id); + worker.commit(); + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } +} + +void DBPlan::deleteVeranstalter(std::string id) { + + deleteVeranstalterForeign(id); + + try { + pqxx::work worker(connectionObject); + std::string query = + "DELETE FROM Veranstalter WHERE ID = $1"; + + pqxx::result response = worker.exec_params(query, id); + worker.commit(); + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } +} + + +void DBPlan::deleteVeranstaltungForeign(std::string id) { + try { + pqxx::work worker(connectionObject); + std::string query = + "UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstaltung_ID = NULL WHERE Veranstalter_ID = $1;"; + + pqxx::result response = worker.exec_params(query, id); + worker.commit(); + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } +} + +void DBPlan::deleteVeranstaltung(std::string id) { + deleteVeranstaltungForeign(id); + + try { + pqxx::work worker(connectionObject); + std::string query = + "DELETE FROM Veranstaltung WHERE ID = $1"; + + pqxx::result response = worker.exec_params(query, id); + worker.commit(); + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } + +} + + +void DBPlan::hinzufuegenVeranstaltung(std::string name, std::string dauer, std::string ort, std::string raum) { + try { + pqxx::work worker(connectionObject); + std::string query = + "INSERT INTO Veranstaltung (name, dauer, ort, raum) VALUES ($1, $2, $3, $4);"; + pqxx::result response = worker.exec_params(query, name, dauer, ort, raum); + worker.commit(); + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } + +} + + +void DBPlan::hinzufuegenVeranstalter(std::string email, std::string name, std::string pw, std::string admin) { + try { + pqxx::work worker(connectionObject); + std::string query = + "INSERT INTO Veranstaltung (email, name, pw, admin) VALUES ($1, $2, $3, $4);"; + pqxx::result response = worker.exec_params(query, email, name, pw, admin); + worker.commit(); + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } + +} + + +void DBPlan::deleteStudent(std::string id) { + try { + pqxx::work worker(connectionObject); + std::string query = + "DELETE FROM studenten WHERE ID = $1;"; + pqxx::result response = worker.exec_params(query, id); + worker.commit(); + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } + +} + + +void DBPlan::hinzufuegenStudent(std::string email, std::string name, std::string pw) { + + try { + pqxx::work worker(connectionObject); + std::string query = + "INSERT INTO studenten (email, name, pw) VALUES ($1, $2, $3);"; + pqxx::result response = worker.exec_params(query, email, name, pw); + worker.commit(); + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } + + +} + + + +std::string DBPlan::getDauer(std::string tag, std::string stunde) { + try { + pqxx::work worker(connectionObject); + std::string query = + "SELECT dauer FROM Veranstaltung WHERE ID = (SELECT Veranstaltung_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2);"; + + pqxx::result response = worker.exec_params(query, stunde, tag); + + worker.commit(); + + + return response[0][0].c_str(); + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } +} + + + + + + + + + + +void DBPlan::addFirstOfDayTwo(std::string tag) { + try { + pqxx::work worker(connectionObject); + std::string query = + "UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstalter_ID = (SELECT ID FROM Veranstalter WHERE arbeitszeit <= 16 AND krank = FALSE LIMIT 1) " + "WHERE uhrzeit_id = 1 AND tag = $1;"; + pqxx::result response = worker.exec_params(query, tag); + worker.commit(); + + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } +} + +void DBPlan::addTwoHour(std::string tag, std::string stunde) { + try { + + std::string prevStunde = std::to_string(std::stoi(stunde) - 1); + + std::cout << " prevStunde: " << prevStunde << " Tag: " << tag << " stunde " << stunde << std::endl; + pqxx::work worker(connectionObject); + std::string query = + "UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstalter_id = (SELECT ID FROM Veranstalter " + "WHERE arbeitszeit <= 16 AND krank = FALSE " + "AND(standort = (SELECT ort FROM Veranstaltung WHERE ID = (SELECT veranstaltung_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2)) " + "AND ID != (SELECT veranstalter_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2)) " + "ORDER BY random() LIMIT 1) " + "WHERE uhrzeit_id = $3 AND tag = $4;"; + pqxx::result response = worker.exec_params(query, prevStunde, tag, stunde, tag); + worker.commit(); + + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } +} + +void DBPlan::addFirstOfDayFour(std::string tag) { + try { + pqxx::work worker(connectionObject); + std::string query = + "UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstalter_ID = (SELECT ID FROM Veranstalter WHERE arbeitszeit <= 14 AND krank = FALSE LIMIT 1) " + "WHERE uhrzeit_id = 1 AND tag = $1;"; + pqxx::result response = worker.exec_params(query, tag); + worker.commit(); + + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } +} + +void DBPlan::addFourHour(std::string tag, std::string stunde) { + try { + + std::string prevStunde = std::to_string(std::stoi(stunde) - 1); + pqxx::work worker(connectionObject); + std::string query = + "UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstalter_id = (SELECT ID FROM Veranstalter " + "WHERE arbeitszeit <= 14 AND krank = FALSE " + "AND(standort = (SELECT ort FROM Veranstaltung WHERE ID = (SELECT veranstaltung_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2)) " + "AND ID != (SELECT veranstalter_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2)) " + "ORDER BY random() LIMIT 1) " + "WHERE uhrzeit_id = $3 AND tag = $4;"; + pqxx::result response = worker.exec_params(query, prevStunde, tag, stunde, tag); + worker.commit(); + + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } +} + +void DBPlan::upperHour(std::string tag, std::string stunde) { + try { + + std::string nextStunde = std::to_string(std::stoi(stunde) + 1); + + pqxx::work worker(connectionObject); + std::string query = + "UPDATE Veranstalter_Veranstaltung_Uhrzeit SET Veranstalter_ID = (SELECT Veranstalter_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2)" + "WHERE uhrzeit_id = $3 AND tag = $2;"; + pqxx::result response = worker.exec_params(query, stunde, tag, nextStunde); + worker.commit(); + + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } +} + + +void DBPlan::updateStandort(std::string tag, std::string stunde) { + try { + + + pqxx::work worker(connectionObject); + std::string query = + "UPDATE Veranstalter SET standort = (SELECT ort FROM Veranstaltung WHERE ID = (SELECT Veranstaltung_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2)) WHERE ID = (SELECT Veranstalter_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $1 AND tag = $2);"; + pqxx::result response = worker.exec_params(query, stunde, tag); + worker.commit(); + + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } +} + +void DBPlan::incarbeitszeit(std::string tag, std::string stunde, std::string amount) { + try { + + + pqxx::work worker(connectionObject); + + std::string query = + "UPDATE Veranstalter SET arbeitszeit = arbeitszeit + $1 WHERE ID = (SELECT Veranstalter_ID FROM Veranstalter_Veranstaltung_Uhrzeit WHERE uhrzeit_id = $2 AND tag = $3);"; + + pqxx::result response = worker.exec_params(query,amount, stunde, tag); + worker.commit(); + + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } +} + +void DBPlan::createPlan() { + + + + try { + for (int tag = 1; tag < 6; tag++) { + std::string tagStr = std::to_string(tag); + for (int stunde = 1; stunde < 6; stunde++) { + std::string stundeStr = std::to_string(stunde); + //get dauer of next class + + if (std::stoi(getDauer(tagStr, stundeStr)) == 2) { + if (stunde == 1) { + addFirstOfDayTwo(tagStr); + } + else { + addTwoHour(tagStr, stundeStr); + } + updateStandort(tagStr, stundeStr); + incarbeitszeit(tagStr, stundeStr, "2"); + } + else { + if (stunde == 1) { + addFirstOfDayFour(tagStr); + + } + else { + addFourHour(tagStr, stundeStr); + } + upperHour(tagStr, stundeStr); + incarbeitszeit(tagStr, stundeStr, "4"); + updateStandort(tagStr, stundeStr); + stunde++; + } + + } + + } + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } + +} + + + +std::vector DBPlan::getPlan() { + try { + + std::vector plan; + + pqxx::work worker(connectionObject); + + std::string query = + "SELECT tag, u.anfangszeit, u.endzeit, o.ort, o.name, v.name, v.ID FROM Veranstalter_Veranstaltung_Uhrzeit LEFT JOIN Veranstalter v ON Veranstalter_Veranstaltung_Uhrzeit.veranstalter_ID = v.ID " + "LEFT JOIN Uhrzeit u ON Veranstalter_Veranstaltung_Uhrzeit.uhrzeit_ID = u.ID " + "LEFT JOIN Veranstaltung o ON Veranstalter_Veranstaltung_Uhrzeit.veranstaltung_ID = o.ID " + "ORDER BY tag, uhrzeit_ID;"; + + pqxx::result response = worker.exec(query); + worker.commit(); + + for (const auto& row : response) { + std::string rowstring; + for (const auto& col : row) { + rowstring.append(col.c_str()); + rowstring.append(" , "); + } + plan.push_back(rowstring); + + } + + return plan; + + + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } +} + + + diff --git a/DBHandler/DBPlan.hpp b/DBHandler/DBPlan.hpp new file mode 100644 index 0000000..263b1a4 --- /dev/null +++ b/DBHandler/DBPlan.hpp @@ -0,0 +1,50 @@ +#ifndef _DBPLAN_HPP_ +#define _DBPLAN_HPP_ + + +#include "DBHandler.hpp" +#include +#include + +class DBPlan : public DBHandler { +private: + //Functions needed for creation and updating of the plan + std::string getDauer(std::string tag, std::string stunde); + void addFirstOfDayTwo(std::string tag); + void addTwoHour(std::string tag, std::string stunde); + void addFirstOfDayFour(std::string tag); + void upperHour(std::string tag, std::string stunde); + void addFourHour(std::string tag, std::string stunde); + void sucheVertretung(std::string tag, std::string stunde); + void vertretung(std::string tag, std::string stunde, std::string dauer); + void deleteVeranstalterForeign(std::string id); + void deleteVeranstaltungForeign(std::string id); + void updateStandort(std::string tag, std::string stunde); + void incarbeitszeit(std::string tag, std::string stunde, std::string amount); +public: + DBPlan(std::string connStr); + + void meldeKrank(std::string id, std::string tag, std::string stunde); + void meldeGesund(std::string id); + void deleteVeranstaltung(std::string id); + void hinzufuegenVeranstaltung(std::string name, std::string dauer, std::string ort, std::string raum); + + + void deleteVeranstalter(std::string id); + void hinzufuegenVeranstalter(std::string email, std::string name, std::string pw, std::string admin); + + + void deleteStudent(std::string id); + void hinzufuegenStudent(std::string email, std::string name, std::string pw); + + + void createPlan(); + + //Each string in form of (tag , anfangszeit , endzeit , Ort , Veranstaltung , Mitarbeiter , mitarbeiterID , ) + std::vector getPlan(); + + + +}; + +#endif diff --git a/README b/README new file mode 100644 index 0000000..316fe18 --- /dev/null +++ b/README @@ -0,0 +1,2 @@ +Code written with libpqxx-version 7.4.1 +install-guide: http://en.wiki.imlint.org/Pqxx_tutorial diff --git a/script.sql b/script.sql new file mode 100644 index 0000000..dc2a8b4 --- /dev/null +++ b/script.sql @@ -0,0 +1,151 @@ + +DROP VIEW studenten_veranstalter; +DROP TABLE Veranstalter_Veranstaltung_Uhrzeit; +DROP TABLE Studenten; +DROP TABLE Veranstalter; +DROP TABLE Uhrzeit; +DROP TABLE veranstaltung; +DROP SEQUENCE global_id_seq; + + + + + +CREATE SEQUENCE global_id_seq; + +CREATE TABLE Studenten ( + matrikelnummer INTEGER PRIMARY KEY DEFAULT nextval('global_id_seq'), + name VARCHAR(30) NOT NULL, + email VARCHAR(30) NOT NULL, + passwort VARCHAR(30) NOT NULL +); + + +CREATE OR REPLACE FUNCTION random_between_two() +RETURNS VARCHAR AS $$ +BEGIN + IF random() < 0.5 THEN + RETURN 'A'; + ELSE + RETURN 'B'; + END IF; +END; +$$ LANGUAGE plpgsql; + + +CREATE TABLE Veranstalter ( + ID INTEGER PRIMARY KEY DEFAULT nextval('global_id_seq'), + name VARCHAR(30), + email VARCHAR(30), + passwort VARCHAR(30), + arbeitszeit INTEGER DEFAULT 0, + standort VARCHAR(30) DEFAULT random_between_two(), + krank BOOLEAN DEFAULT FALSE, + admin BOOLEAN NOT NULL DEFAULT FALSE +); + + + + + + CREATE VIEW studenten_veranstalter AS + SELECT matrikelnummer AS id, passwort, NULL AS admin FROM Studenten + UNION ALL + SELECT ID, passwort, admin FROM Veranstalter; + + + + CREATE TABLE Veranstaltung ( + ID SERIAL PRIMARY KEY, + ort VARCHAR(30) NOT NULL, + raum INTEGER NOT NULL, + name VARCHAR(90) NOT NULL, + dauer INTEGER NOT NULL + ); + + + + + CREATE TABLE Uhrzeit ( + ID SERIAL PRIMARY KEY, + anfangszeit TIME NOT NULL, + endzeit TIME NOT NULL ); + + + + INSERT INTO Uhrzeit (anfangszeit, endzeit) VALUES + ('08:00:00', '10:00:00'), + ('10:00:00', '12:00:00'), + ('12:00:00', '14:00:00'), + ('14:00:00', '16:00:00'), + ('16:00:00', '18:00:00'); + + + CREATE TABLE Veranstalter_Veranstaltung_Uhrzeit ( + uhrzeit_ID INTEGER REFERENCES Uhrzeit(ID), + tag INTEGER NOT NULL, + veranstalter_ID INTEGER REFERENCES Veranstalter(ID), + veranstaltung_ID INTEGER REFERENCES Veranstaltung(ID), + PRIMARY KEY(uhrzeit_ID, tag) + ); + + + INSERT INTO Veranstalter (name, email, passwort, admin) VALUES + ('tech_guru', 'admin@example.com', 'password123', TRUE), +('code_master', 'user1@example.com', 'password1', FALSE), +('binary_hero', 'user2@example.com', 'password2', FALSE), +('debug_ninja', 'user3@example.com', 'password3', FALSE), +('data_wizard', 'user4@example.com', 'password4', FALSE), +('script_samurai', 'user5@example.com', 'password5', FALSE), +('dev_genius', 'user6@example.com', 'password6', FALSE), +('cyber_maven', 'user7@example.com', 'password7', FALSE), +('net_knight', 'user8@example.com', 'password8', FALSE), +('bit_boss', 'user9@example.com', 'password9', FALSE), +('sys_sensei', 'user10@example.com', 'password10', FALSE), +('crypto_champ', 'user11@example.com', 'password11', FALSE); + + + INSERT INTO Veranstaltung (ort, raum, name, dauer) VALUES + ('A', '101', 'Grundlagen der Programmierung', 2), +('B', '202', 'Algorithmen und Datenstrukturen', 4), +('A', '103', 'Netzwerkgrundlagen', 2), +('B', '204', 'Betriebssystemkonzepte', 4), +('A', '105', 'Softwareentwicklung', 2), +('B', '206', 'Intelligente Systeme', 4), +('A', '107', 'Datenbanksysteme', 2), +('B', '208', 'Webtechnologien', 2), +('A', '109', 'Computergrafikgrundlagen', 2), +('B', '210', 'Maschinelles Lernen', 2); + + +INSERT INTO Veranstalter_Veranstaltung_Uhrzeit (uhrzeit_ID, tag, veranstaltung_ID) VALUES +(1, 1, 1), +(2, 1, 7), +(3, 1, 8), +(4, 1, 3), +(5, 1, 10), + +(1, 2, 4), +(2, 2, 4), +(3, 2, 5), +(4, 2, 6), +(5, 2, 6), + +(1, 3, 7), +(2, 3, 8), +(3, 3, 9), +(4, 3, 10), +(5, 3, 1), + +(1, 4, 2), +(2, 4, 2), +(3, 4, 3), +(4, 4, 4), +(5, 4, 4), + +(1, 5, 5), +(2, 5, 6), +(3, 5, 6), +(4, 5, 7), +(5, 5, 8); +