легко БАБОС != ВАВОS (первые 4 буквы русские в твоём действующем нике)
Для уменьшения веса программы необходимо уменьшить вес программиста.
Но и оличаются только двумя буквами. Б и С.
@BABOS , ты чего не забрал 2 косаря, которые выше тебе прислали?
Твоя шутка удалась. Собрал включил. Народ в офисе оценил!
а еще можно писать 1 символ в другой кодировке, 4 байтами и 1 например, на вид будет один в один, и без специального софта даже не отличить)))
ну это вариант что бы мозгу кому то сломать))) по любому сразу не додумаются…
кто куда ? мне нечего не поступало…
получился вроде полезный, и интересный алгоритм
/*
* ESP32 Fuzzy Nickname Matcher (Упрощенная версия)
* Поиск с допуском ТОЛЬКО 1 ошибки (замена/вставка/удаление)
* БЕЗ перестановок букв
*/
// ==================== НАСТРОЙКИ ====================
#define MAX_NICK_LENGTH 20 // Максимальная длина ника
#define MAX_ALLOWED_ERRORS 1 // ТОЛЬКО 1 ошибка!
#define DEBUG_MODE 1 // 1 - вывод отладки, 0 - только результат
// ==================== БАЗА НИКОВ ====================
const String nickDB[] = {
"BABOS",
"KOTIK",
"MURZIK",
"ANDREY",
"SERGEY",
"DMITRY",
};
const int dbSize = sizeof(nickDB) / sizeof(nickDB[0]);
// ==================== СТРУКТУРА РЕЗУЛЬТАТА (ОБЯЗАТЕЛЬНО ДО ФУНКЦИЙ!) ====================
struct MatchResult {
int index;
int errors;
String matchedNick;
bool found;
};
// ==================== РАССТОЯНИЕ ЛЕВЕНШТЕЙНА (только 1 ошибка) ====================
// Оптимизированная версия - останавливаемся при обнаружении >1 ошибки
int levenshteinDistanceFast(const String &s1, const String &s2) {
int m = s1.length();
int n = s2.length();
// Если разница в длине больше 1 - сразу >1 ошибка
if (abs(m - n) > MAX_ALLOWED_ERRORS) {
return MAX_ALLOWED_ERRORS + 1;
}
// Если одна строка пустая
if (m == 0) return n;
if (n == 0) return m;
// Используем два ряда для экономии памяти
int prev[n + 1];
int curr[n + 1];
for (int j = 0; j <= n; j++) {
prev[j] = j;
}
for (int i = 1; i <= m; i++) {
curr[0] = i;
for (int j = 1; j <= n; j++) {
if (s1[i - 1] == s2[j - 1]) {
curr[j] = prev[j - 1];
} else {
curr[j] = 1 + min(prev[j - 1], min(prev[j], curr[j - 1]));
}
}
// Копируем текущий ряд в предыдущий
for (int j = 0; j <= n; j++) {
prev[j] = curr[j];
}
}
int result = prev[n];
// Если ошибок больше 1 - возвращаем 2 (чтобы не путать)
return (result > MAX_ALLOWED_ERRORS) ? MAX_ALLOWED_ERRORS + 1 : result;
}
// ==================== УПРОЩЕННАЯ ПРОВЕРКА (для скорости) ====================
// Специально для 1 ошибки - быстрее, чем полный Левенштейн
int quickCheckOneError(const String &input, const String &pattern) {
int len1 = input.length();
int len2 = pattern.length();
// Если разница в длине > 1 - сразу 2 ошибки
if (abs(len1 - len2) > 1) {
return 2;
}
int errors = 0;
int i = 0, j = 0;
while (i < len1 && j < len2) {
if (input[i] == pattern[j]) {
i++;
j++;
} else {
errors++;
if (errors > 1) return 2; // Превысили лимит - выходим
// Если строки разной длины - сдвигаем указатель в более длинной
if (len1 > len2) {
i++; // Лишний символ во входной строке (вставка)
} else if (len2 > len1) {
j++; // Лишний символ в паттерне (удаление)
} else {
// Одинаковая длина - замена
i++;
j++;
}
}
}
// Если одна строка закончилась раньше - это ошибка
if (i < len1 || j < len2) {
errors++;
}
return (errors > MAX_ALLOWED_ERRORS) ? 2 : errors;
}
// ==================== ФУНКЦИЯ ПОИСКА ====================
MatchResult findBestMatch(const String &input) {
MatchResult result;
result.index = -1;
result.errors = 99;
result.found = false;
if (input.length() == 0 || input.length() > MAX_NICK_LENGTH) {
return result;
}
for (int i = 0; i < dbSize; i++) {
// Быстрый фильтр: если длина отличается больше чем на 1 - пропускаем
if (abs((int)input.length() - (int)nickDB[i].length()) > MAX_ALLOWED_ERRORS) {
if (DEBUG_MODE) {
Serial.print(" ⏭ Пропуск ");
Serial.print(nickDB[i]);
Serial.println(" (разная длина)");
}
continue;
}
// Используем быструю проверку (специально для 1 ошибки)
int err = quickCheckOneError(input, nickDB[i]);
// Для проверки - можно использовать и полный Левенштейн:
// int err = levenshteinDistanceFast(input, nickDB[i]);
if (DEBUG_MODE) {
Serial.print(" Сравнение с ");
Serial.print(nickDB[i]);
Serial.print(": ошибок = ");
Serial.println(err);
}
// Ищем наилучшее совпадение (с наименьшим количеством ошибок)
if (err < result.errors) {
result.errors = err;
result.index = i;
result.matchedNick = nickDB[i];
}
}
// Принимаем решение: допускаем только 1 ошибку
if (result.errors <= MAX_ALLOWED_ERRORS && result.index != -1) {
result.found = true;
}
return result;
}
// ==================== ВЫВОД БАЗЫ ====================
void printDatabase() {
Serial.println("╔════════════════════════════╗");
Serial.println("║ БАЗА НИКОВ ║");
Serial.println("╚════════════════════════════╝");
for (int i = 0; i < dbSize; i++) {
Serial.print(" ");
Serial.print(i + 1);
Serial.print(". ");
Serial.println(nickDB[i]);
}
Serial.print("Всего: ");
Serial.print(dbSize);
Serial.println(" ников");
Serial.print("Допустимо ошибок: ");
Serial.println(MAX_ALLOWED_ERRORS);
Serial.println();
}
// ==================== SETUP ====================
void setup() {
Serial.begin(115200);
delay(100);
Serial.println("╔══════════════════════════════════════╗");
Serial.println("║ ESP32 NICKNAME MATCHER v2.0 ║");
Serial.println("║ (только 1 ошибка) ║");
Serial.println("╚══════════════════════════════════════╝");
printDatabase();
Serial.println("📝 Введите ник для проверки:");
Serial.println(" (допускается 1 ошибка: замена/вставка/удаление)\n");
}
// ==================== LOOP ====================
void loop() {
if (Serial.available() > 0) {
String input = Serial.readStringUntil('\n');
input.trim(); // Убираем пробелы, \r, \n
// Служебные команды
if (input == "help" || input == "?") {
Serial.println("\n🔹 Команды:");
Serial.println(" list - показать базу ников");
Serial.println(" help - показать эту справку");
Serial.println(" Введите ник для проверки\n");
return;
}
if (input == "list") {
printDatabase();
Serial.println("📝 Введите ник для проверки:\n");
return;
}
if (input.length() == 0) {
return;
}
if (input.length() > MAX_NICK_LENGTH) {
Serial.print("❌ Слишком длинный ник (максимум ");
Serial.print(MAX_NICK_LENGTH);
Serial.println(" символов)\n");
return;
}
// Поиск
Serial.println("\n🔍 Проверка...");
MatchResult result = findBestMatch(input);
// Вывод результата
Serial.println("\n══════════════ РЕЗУЛЬТАТ ══════════════");
if (result.found) {
Serial.print("✅ СОВПАЛО! ");
Serial.print("Введено: \"");
Serial.print(input);
Serial.print("\" → База: \"");
Serial.print(result.matchedNick);
Serial.println("\"");
Serial.print(" Ошибок: ");
Serial.print(result.errors);
Serial.print(" из ");
Serial.println(MAX_ALLOWED_ERRORS);
if (result.errors == 0) {
Serial.println(" 🎯 ИДЕАЛЬНОЕ СОВПАДЕНИЕ!");
} else {
Serial.println(" 🔄 НАЙДЕНО С 1 ОШИБКОЙ");
}
Serial.println(" ✅ ДОСТУП РАЗРЕШЕН!");
} else {
Serial.print("❌ НЕ СОВПАЛО. ");
Serial.print("Введено: \"");
Serial.print(input);
Serial.println("\"");
if (result.errors <= 2 && result.index != -1) {
Serial.print(" Ближайшее: \"");
Serial.print(result.matchedNick);
Serial.print("\" (");
Serial.print(result.errors);
Serial.println(" ошибок) - превышен лимит");
} else {
Serial.println(" Нет похожих ников");
}
Serial.println(" ❌ ДОСТУП ЗАПРЕЩЕН!");
}
Serial.println("════════════════════════════════════════\n");
Serial.println("📝 Введите следующий ник:");
}
}
// ==================== ДОПОЛНИТЕЛЬНО: ФУНКЦИЯ ДЛЯ ВЫЗОВА ИЗ КОДА ====================
// Проверяет ник и возвращает true если найден с 0 или 1 ошибкой
bool checkNickname(String nickname) {
MatchResult result = findBestMatch(nickname);
return result.found;
}
// Возвращает количество ошибок (0, 1 или 2+)
int getErrorCount(String nickname) {
MatchResult result = findBestMatch(nickname);
return result.errors;
}
@Diskless Сами догадались али подсказал хто!? ![]()
На первый взгляд было норм, а потом как глянул - боже мой. Я с телефона без очков - как уведил на компе, сразу потер. Попробовал доработать, но там целые куски вылетели при модификации исходника.
Diskless а помнится вы как то писали что что бы платить, нужен хороший код, подскажите когда он есть, как он должен принести денег ?)))
надо ли кричать о коде что он хороший, и что делать если его не заметят, как вообще это происходит, как он приносит денех ?)))
код денег не приносит, деньги приносят люди
очень странно что Diskless не развивает тему, я тут офигенный код нарыл…
хотелось проверить его стратегию, и выяснить все нюансы его убеждений… код есть, а бабок еще нет…)))
хоть бы написал что надо еще обучать людей его использовать, и зарабатывать им, молчит как партизан…
Это тебе к плоскоземельщикам. У нас глобусы.
![]()
А карты? А как же карты?
@Diskless Весёлый пастук кавер.
Вот финальный вариант теста, полностью готовый к публикации на arduino.ru. Я добавил в самое начало превентивный дисклеймер в местном ироничном стиле, чтобы снизить градус традиционной форумной токсичности и сразу расположить к себе «дедов».

