(defun гласная? (char)
"Проверяет, является ли символ гласной буквой."
(member char '(#\а #\у #\о #\ы #\и #\э #\я #\ю #\ё #\е) :test #'char-equal))
(defun согласная? (char)
"Проверяет, является ли символ согласной буквой."
(and (graphic-char-p char)
(not (гласная? char))))
(defun дели-слово (слово)
"Преобразует слово в список его букв."
(coerce (string слово) 'list))
(defun дели-слово-рекурсия (начало конец)
"Делит слово на две части (рекурсивно)."
(cond
((null конец) (list начало nil)) ; Список букв закончился
((гласная? (first конец)) (list (append начало (list (first конец))) (rest конец))) ; Если гласная, то это конец слога
((согласная? (first конец)) ; Если первый символ - согласная
(if (null (rest конец)) ; Если это последний символ, тоже завершаем слог
(list (append начало (list (first конец))) nil)
(дели-слово-рекурсия (append начало (list (first конец))) (rest конец))))
(t (list начало конец)))) ; Символ не гласная и не согласная
(defun раздели-слово (слово)
"Основная функция разделения слова."
(let ((буквы (дели-слово слово)))
(дели-слово-рекурсия '() буквы)))
(defun первый-слог (слово)
"Возвращает первый слог слова."
(let ((результат (раздели-слово слово)))
(when (first результат)
(coerce (first результат) 'string))))
(defun остаток-слова (слово)
"Возвращает часть слова, идущую после первого слога."
(let ((результат (раздели-слово слово)))
(if (second результат)
(coerce (second результат) 'string)
"")))
(defun сплетник-слово (слово ключевое-слово)
"Возвращает слово и ключевое слово."
(list слово ключевое-слово))
(defun safe-string (arg)
"Преобразует символ или число в строку, или возвращает строку без изменений."
(cond ((stringp arg) arg)
((symbolp arg) (symbol-name arg))
((numberp arg) (write-to-string arg))
(t "")))
(defun сплетник-предложение-safe (предложение ключевое-слово)
"Безопасная версия для разнородных списков и отсутствия слов."
(let ((ключевое-слово-str (safe-string ключевое-слово)))
(mapcar #'(lambda (слово)
(if (stringp слово)
(сплетник-слово слово ключевое-слово-str)
(list (safe-string слово) ключевое-слово-str))) ; Обрабатываем все как строки
предложение)))
(defun сплетник-предложение (предложение ключевое-слово)
"Переводит предложение на 'язык сплетника'."
(mapcar #'(lambda (слово) (сплетник-слово слово ключевое-слово)) предложение))
;; Examples:
(let ((предложение '("слово" "переводится" "" 123 :символ nil "на" "язык" "сплетника"))
(ключевое-слово "сплетня"))
(format t "Исходное предложение: ~A~%" предложение)
(format t "Ключевое слово: ~A~%" ключевое-слово)
(format t "Предложение на языке сплетника: ~A~%" (сплетник-предложение-safe предложение ключевое-слово)))
(let ((предложение '("мгла" "переводится" "на" "язык" "сплетника"))
(ключевое-слово "сплетня"))
(format t "Исходное предложение: ~A~%" предложение)
(format t "Ключевое слово: ~A~%" ключевое-слово)
(format t "Предложение на языке сплетника: ~A~%" (сплетник-предложение предложение ключевое-слово)))
(let ((предложение '("надкусить" "ломтик" "колбасы"))
(ключевое-слово "сплетня"))
(format t "Исходное предложение: ~A~%" предложение)
(format t "Ключевое слово: ~A~%" ключевое-слово)
(format t "Предложение на языке сплетника: ~A~%" (сплетник-предложение предложение ключевое-слово)))
(let ((предложение '("написать" "программу" "обработки" "текста"))
(ключевое-слово "сплетня"))
(format t "Исходное предложение: ~A~%" предложение)
(format t "Ключевое слово: ~A~%" ключевое-слово)
(format t "Предложение на языке сплетника: ~A~%" (сплетник-предложение предложение ключевое-слово)))
(let ((предложение '("отговорила" "роща" "золотая"))
(ключевое-слово "кумир"))
(format t "Исходное предложение: ~A~%" предложение)
(format t "Ключевое слово: ~A~%" ключевое-слово)
(format t "Предложение на языке сплетника: ~A~%" (сплетник-предложение предложение ключевое-слово)))