#include <LiquidCrystal.h>
#include <Arduino.h>
const String nameUkraine = "ЯРОСЛАВ"; // Use a String to store Ukrainian characters
//const char nameUkraine[] = {'Я', 'Р', 'О', 'С', 'Л', 'А', 'В'};
//const char nameUkraine[] = {'\u042F', '\u0420', '\u041E', '\u0421', '\u041B', '\u0410', '\u0412'};
int dotDuration = 300; // Change the value based on your requirement
int ledPin = 1; // Change the pin based on your assignment
const char characters[] = {'\u0410', '\u0411', '\u0412', '\u0413', '\u0491', '\u0414', '\u0415', '\u0404', '\u0416', '\u0417', '\u0418', '\u0406', '\u0407', '\u0419', '\u041A', '\u041B', '\u041C', '\u041D', '\u041E', '\u041F', '\u0420', '\u0421', '\u0422', '\u0423', '\u0424', '\u0425', '\u0426', '\u0427', '\u0428', '\u0429', '\u042C', '\u042E', '\u042F'};
const char cyrillicToAsciiMap[] = {
'A', // For '\u0410' (А)
'B', // For '\u0411' (Б)
'V', // For '\u0412' (В)
'G', // For '\u0413' (Г)
'G', // For '\u0491' (ґ, similar to Г)
'D', // For '\u0414' (Д)
'E', // For '\u0415' (Е)
'E', // For '\u0404' (Є)
'Zh', // For '\u0416' (Ж)
'Z', // For '\u0417' (З)
'I', // For '\u0418' (И)
'I', // For '\u0406' (І)
'Yi', // For '\u0407' (Ї)
'Y', // For '\u0419' (Й)
'K', // For '\u041A' (К)
'L', // For '\u041B' (Л)
'M', // For '\u041C' (М)
'N', // For '\u041D' (Н)
'O', // For '\u041E' (О)
'P', // For '\u041F' (П)
'R', // For '\u0420' (Р)
'S', // For '\u0421' (С)
'T', // For '\u0422' (Т)
'U', // For '\u0423' (У)
'F', // For '\u0424' (Ф)
'Kh', // For '\u0425' (Х)
'Ts', // For '\u0426' (Ц)
'Ch', // For '\u0427' (Ч)
'Sh', // For '\u0428' (Ш)
'Shch', // For '\u0429' (Щ)
' ', // For '\u042C' (Ь, soft sign, no direct ASCII equivalent)
'Yu', // For '\u042E' (Ю)
'Ya' // For '\u042F' (Я)
};
// Define Morse code for Ukrainian alphabet
const String morseCodeUkraine[] = {
".-", // А
"-...", // Б
".--", // В
"....", // Г
"--.", // Ґ
"-..", // Д
".", // Е
"..-..",// Є
"...-", // Ж
"--..", // З
"-.--", // И
"..", // І
".---.",// Ї
".---", // Й
"-.-", // К
".-..", // Л
"--", // М
"-.", // Н
"---", // О
".--.", // П
".-.", // Р
"...", // С
"-", // Т
"..-", // У
"..-.", // Ф
"----", // Х
"-.-.", // Ц
"---.", // Ч
"--.-", // Ш
"--.--",// Щ
"-..-" // Ь
"..--", // Ю
".-.-", // Я
};
template <typename K, typename V>
struct KeyValuePair {
K key;
V value;
KeyValuePair* next;
};
template <typename K, typename V>
class HashMap {
public:
HashMap() : tableSize(10), numElements(0) {
table = new KeyValuePair<K, V>*[tableSize]();
for (int i = 0; i < tableSize; i++) {
table[i] = nullptr;
}
}
~HashMap() {
Clear();
delete[] table;
}
void insert(const K& key, const V& value) {
int index = hash(key);
Serial.print("Hash: ");
Serial.println(index);
KeyValuePair<K, V>* newPair = new KeyValuePair<K, V>{key, value, nullptr};
if (table[index] == nullptr) {
table[index] = newPair;
} else {
KeyValuePair<K, V>* current = table[index];
while (current->next != nullptr) {
current = current->next;
}
current->next = newPair;
}
numElements++;
// Check if the load factor exceeds the threshold (e.g., 75%)
if (static_cast<double>(numElements) / tableSize > LOAD_FACTOR_THRESHOLD) {
resizeTable();
}
}
V get(const K& key) const {
int index = hash(key);
KeyValuePair<K, V>* current = table[index];
while (current != nullptr) {
if (current->key == key) {
return current->value;
}
current = current->next;
}
return V();
}
int getTableSize() {
return tableSize;
}
int getNumElements() {
return numElements;
}
void displayHashMap() {
for (int i = 0; i < numElements; i++) {
KeyValuePair<K, V>* current = table[i];
Serial.print(i);
Serial.print(" ");
if (current == nullptr) {
Serial.println(" element in map is null");
}
while (current != nullptr) {
Serial.print("Key: ");
Serial.print(current->key);
Serial.print(", Value: ");
Serial.println(current->value);
current = current->next;
}
}
}
private:
static const double LOAD_FACTOR_THRESHOLD;
int hash(const K& key) const {
const int charactersValues[] = {
0x0410, 0x0411, 0x0412, 0x0413, 0x0491, 0x0414, 0x0415, 0x0404,
0x0416, 0x0417, 0x0418, 0x0406, 0x0407, 0x0419, 0x041A, 0x041B,
0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x0423,
0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042C, 0x042E, 0x042F
};
int keyIntValue = static_cast<int>(key);
Serial.print("Key Integer Value: ");
Serial.println(keyIntValue, HEX); // Debugging
keyIntValue = static_cast<int>(key);
for (unsigned int i = 0; i < sizeof(charactersValues) / sizeof(charactersValues[0]); ++i) {
if (charactersValues[i] == keyIntValue) {
return i; // Return the index of the character as its hash value
}
}
return -1; // Return -1 if character not found
}
void resizeTable() {
int oldSize = tableSize;
tableSize *= 2; // Double the size
KeyValuePair<K, V>** newTable = new KeyValuePair<K, V>*[tableSize]();
// Rehash all existing elements into the new table
for (int i = 0; i < oldSize; i++) {
KeyValuePair<K, V>* current = table[i];
while (current != nullptr) {
int newIndex = hash(current->key);
KeyValuePair<K, V>* next = current->next;
current->next = newTable[newIndex];
newTable[newIndex] = current;
current = next;
}
}
delete[] table;
table = newTable;
}
void Clear() {
for (int i = 0; i < tableSize; i++) {
KeyValuePair<K, V>* current = table[i];
while (current != nullptr) {
KeyValuePair<K, V>* next = current->next;
delete current;
current = next;
}
table[i] = nullptr;
}
numElements = 0;
}
int tableSize;
int numElements;
KeyValuePair<K, V>** table;
};
template <typename K, typename V>
const double HashMap<K, V>::LOAD_FACTOR_THRESHOLD = 0.75;
HashMap<char, String> morseCodeMap;
void initUkraineMorseCodeMap() {
for (int i = 0; i < 32; i++) {
morseCodeMap.insert(cyrillicToAsciiMap[i], morseCodeUkraine[i]);
}
}
void setup()
{
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
initUkraineMorseCodeMap();
}
void loop()
{
morseCodeMap.displayHashMap();
Serial.println(morseCodeMap.getNumElements());
Serial.println(morseCodeMap.getTableSize());
// Serial.println(nameUkraine);
// Serial.println("Number of Elements: " + String(nameUkraine.length()));
// for (int i = 0; i < nameUkraine.length(); i++) {
// if (i % 2 != 0) {
// Serial.println(i);
// convertAndShowMorseCode(nameUkraine[i]); // Use charAt to get characters from the String
// }
// }
delay(10000);
}
void convertAndShowMorseCode(char letter) {
Serial.println(letter);
String moreCodeRepresentation = morseCodeMap.get(letter);
if (moreCodeRepresentation != "") {
Serial.println("Correct letter.");
Serial.println(moreCodeRepresentation);
showMorseCode(moreCodeRepresentation.c_str());
} else {
Serial.println("Invalid letter.");
}
}
void showMorseCode(const char* morseCode) {
for (int i = 0; i < sizeof(morseCode)/2; i++) {
if (morseCode[i] == '.') {
digitalWrite(ledPin, HIGH); // LED ON for dot duration
delay(dotDuration);
digitalWrite(ledPin, LOW); // LED OFF
} else if (morseCode[i] == '-') {
digitalWrite(ledPin, HIGH); // LED ON for 3 times dot duration (dash)
delay(dotDuration * 3);
digitalWrite(ledPin, LOW); // LED OFF
}
}
// Gap between letters
delay(dotDuration * 2);
}