Задача о числах мудрецов




Принцип обмена данными из 1С с сайтом (на MySQL) и выдачи (публикации) этих данных по запросу.
PHP-Скрипт автоматической загрузки данных из файла данных в формате CSV в базу данных сайта работающего на WordPress.

В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с "/////    echo" использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1. 
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

<?php // Полная загрузка сервисных книжек, создан 2024-01-05 12:44:55

global $wpdb2;
global $failure;
global $file_hist;

/////  echo '<H2><b>Старт загрузки</b></H2><br>';

$failure=FALSE;
//подключаемся к базе
$wpdb2 = include_once 'connection.php'; ; // подключаемся к MySQL
// если не удалось подключиться, и нужно оборвать PHP с сообщением об этой ошибке
if (!empty($wpdb2->error))
{
/////   echo '<H2><b>Ошибка подключения к БД, завершение.</b></H2><br>';
$failure=TRUE;
wp_die( $wpdb2->error );
}

$m_size_file=0;
$m_mtime_file=0;
$m_comment='';
/////проверка существования файлов выгрузки из 1С
////файл выгрузки сервисных книжек
$file_hist = ABSPATH.'/_1c_alfa_exchange/AA_hist.csv';
if (!file_exists($file_hist))
{
/////   echo '<H2><b>Файл обмена с сервисными книжками не существует.</b></H2><br>';
$m_comment='Файл обмена с сервисными книжками не существует';
$failure=TRUE;
}

/////инициируем таблицу лога
/////если не существует файла то возврат и ничего не делаем
if ($failure){
///включает защиту от SQL инъекций и данные можно передавать как есть, например: $_GET['foo']
/////   echo '<H2><b>Попытка вставить запись в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>$m_comment));
wp_die();
/////    echo '<H2><b>Возврат в начало.</b></H2><br>';
return $failure;
}
/////проверка лога загрузки, что бы не загружать тоже самое
$masiv_data_file=stat($file_hist);   ////передаем в массив свойство файла
$m_size_file=$masiv_data_file[7];    ////получаем размер файла
$m_mtime_file=$masiv_data_file[9];   ////получаем дату модификации файла
////создаем запрос на получение последней удачной загрузки
////выбираем по штампу времени создания (редактирования) файла загрузки AA_hist.csv, $m_mtime_file

/////   echo '<H2><b>Размер файла: '.$m_size_file.'</b></H2><br>';
/////   echo '<H2><b>Штамп времени файла: '.$m_mtime_file.'</b></H2><br>';
/////   echo '<H2><b>Формирование запроса на выборку из лога</b></H2><br>';
////препарируем запрос
$text_zaprosa=$wpdb2->prepare("SELECT * FROM `vin_logs` WHERE `last_mtime_upload` = %s", $m_mtime_file);
$results=$wpdb2->get_results($text_zaprosa);

if ($results)
{   foreach ( $results as $r)
{
////если штамп времени и размер файла совпадают, возврат
if (($r->last_mtime_upload==$m_mtime_file) && ($r->last_size_upload==$m_size_file))
{////echo '<H2><b>Возврат в начало, т.к. найдена запись в логе.</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>$m_mtime_file,'last_size_upload'=>$m_size_file,'comment'=>'Загрузка отменена, новых данных нет, т.к. найдена запись в логе.'));
wp_die();
return $failure;
}
}
}
////если данные новые, пишем в лог запись о начале загрузки
/////echo '<H2><b>Попытка вставить запись о начале загрузки в лог таблицу</b></H2><br>';
$insert_fail_zapros=$wpdb2->insert('vin_logs', array('time_stamp'=>time(),'last_mtime_upload'=>0, 'last_size_upload'=>$m_size_file, 'comment'=>'Начало загрузки'));

////очищаем таблицу
$clear_tbl_zap=$wpdb2->prepare("TRUNCATE TABLE %s", 'vin_history');
$clear_tbl_zap_repl=str_replace("'","`",$clear_tbl_zap);
$results=$wpdb2->query($clear_tbl_zap_repl);
/////   echo '<H2><b>Очистка таблицы сервисных книжек</b></H2><br>';
if (empty($results))
{
/////   echo '<H2><b>Ошибка очистки таблицы книжек, завершение.</b></H2><br>';
//// если очистка не удалась, возврат
$failure=TRUE;
wp_die();
return $failure;
}

////загружаем данные
$table='vin_history';         // Имя таблицы для импорта
//$file_hist Имя CSV файла, откуда берется информация     // (путь от корня web-сервера)
$delim=';';          // Разделитель полей в CSV файле
$enclosed='"';      // Кавычки для содержимого полей
$escaped='\

17 Comments

  1. itvdonsk

    И всего-то в задаче не указано что числа простые. Кажется автор телепат 80 уровня.

    Reply
  2. DoctorRoza

    Решать головоломки с помощью 1С — мое нутро отвергает это напрочь! Только хардкор, только С++/Java! 🙂

    Reply
  3. monkbest

    Не очень понятно, почему это обязательно простые числа?

    Reply
  4. Alien_job

    конечно не простые, автор об этом пишет в первом же абзаце

    Reply
  5. scientes

    (1) itvdonsk, Я прочитал замечание о простых числах и внес изменение в текст статьи, чтобы этот момент сразу стал понятен.

    Reply
  6. Alien_job

    4+61 < 100

    Reply
  7. scientes

    (6) Alien_job, если будет желание поэкспериментируйте со значением ограничения на сумму. Первое решение появится только тогда, когда верхняя граница равна 37, хотя сумма чисел решения будет меньше этого значения. 4 и 61 тоже самое, я сначала думал, что это ошибка в моей программе. Но нет, так и должно быть.

    Reply
  8. davealone

    Допустим мы отсеяли все простые, но дальше если сумма и произведение известны, почему не решить головоломку как систему уравнений? Есть:

    X + Y = SUM -> Y = SUM — X

    X * Y = PROD — > SUM*X — X#k8SjZc9Dxk2 = PROD -> X#k8SjZc9Dxk2 — SUM*X + PROD = 0

    Получим обычное квадратное уравнение, у которого меньший корень єто X, а больший Y

    Reply
  9. Alien_job

    (8) davealone, мы не знаем суммы и произведения

    Reply
  10. Alien_job

    (8) davealone, мы не знаем суммы и произведения(7)

    Reply
  11. Alien_job

    (7) да, экспериментирую. Но не представляю причину отсутствия решения при ограничении на сумму ммм меньше 37

    Reply
  12. Alien_job

    (7) «Среди строк таблицы есть такие, которые содержат уникальные значения в колонке сумма или произведение, например, произведение простых чисел будет уникальным. Такие данные нам надо удалить.» Почему вы удаляете уникальные произведения?

    Reply
  13. scientes

    (12) Alien_job, ни Пол, ни Салли не знают решение. Значит известные им значения суммы и произведения не позволяют назвать числа. Поэтому варианты с уникальными значениями мы и удаляем. Скажем, если бы Полу назвали произведение 143, он разложил его на множители 11 и 13. Это разложение единственное, он сразу называет ответ.

    Reply
  14. Идальго

    Если числа непростые, то рассмотрим давайте пару (4, 15). Так, Салли сказали сумму = 19, ну и Полу = 60. Понятно, что Пол не знает из каких двух множетелей получается сложное число 60, веть это может быть пара (2, 30) или (3, 20) или (4, 15) или (5, 12) или (6, 10). От того, знает/не знает Салли, что Пол не знает пару этих чисел — ничего не меняется. Да и сам Салли на самом деле не знает из каких слагаемых образовалась сумма = 19. Поэтому, я думаю чего-то не хватает в условии. Хотя может и ошибаюсь?

    Reply
  15. ildarovich

    Не знаю, где я ошибся, но вот решение, которое никак не хочет второй вариант на 439 показывать. Это всего один запрос и более короткий, чем у автора. Работает в консоли.

    ВЫБРАТЬ
    0 КАК Х
    ПОМЕСТИТЬ Бит
    
    ОБЪЕДИНИТЬ
    
    ВЫБРАТЬ
    1
    ;
    
    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    Бит0.Х + 2 * (Бит1.Х + 2 * (Бит2.Х + 2 * (Бит3.Х + 2 * (Бит4.Х + 2 * (Бит5.Х + 2 * (Бит6.Х + 2 * (Бит7.Х + 2 * (Бит8.Х + 2 * Бит9.Х)))))))) КАК Х
    ПОМЕСТИТЬ Ряд
    ИЗ
    Бит КАК Бит9,
    Бит КАК Бит8,
    Бит КАК Бит7,
    Бит КАК Бит6,
    Бит КАК Бит5,
    Бит КАК Бит4,
    Бит КАК Бит3,
    Бит КАК Бит2,
    Бит КАК Бит1,
    Бит КАК Бит0
    ;
    
    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    Ряд1.Х КАК Х,
    Ряд2.Х КАК У,
    Ряд1.Х + Ряд2.Х КАК Сумма,
    Ряд1.Х * Ряд2.Х КАК ХУ
    ПОМЕСТИТЬ Пробы
    ИЗ
    Ряд КАК Ряд1,
    Ряд КАК Ряд2
    ГДЕ
    Ряд1.Х < &Предел / 2
    И Ряд2.Х < &Предел — 1
    И 1 < Ряд1.Х
    И Ряд1.Х < Ряд2.Х
    И Ряд1.Х + Ряд2.Х <= &Предел
    ;
    
    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ РАЗЛИЧНЫЕ
    Пробы.Сумма
    ПОМЕСТИТЬ ТабуСумм
    ИЗ
    Пробы КАК Пробы
    ГДЕ
    Пробы.ХУ В
    (ВЫБРАТЬ
    Пробы.ХУ
    ИЗ
    Пробы КАК Пробы
    СГРУППИРОВАТЬ ПО
    Пробы.ХУ
    ИМЕЮЩИЕ
    КОЛИЧЕСТВО(*) = 1)
    ;
    
    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ЧислаСалли.ХУ
    ПОМЕСТИТЬ ЧислаПоля
    ИЗ
    Пробы КАК ЧислаСалли
    ГДЕ
    НЕ ЧислаСалли.Сумма В
    (ВЫБРАТЬ
    ТабуСумм.Сумма
    ИЗ
    ТабуСумм)
    
    СГРУППИРОВАТЬ ПО
    ЧислаСалли.ХУ
    
    ИМЕЮЩИЕ
    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ЧислаСалли.Сумма) = 1
    ;
    
    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ЧислаСалли.Сумма,
    МАКСИМУМ(ЧислаПоля.ХУ) КАК Произведение,
    МАКСИМУМ(ЧислаСалли.Х) КАК Х,
    МАКСИМУМ(ЧислаСалли.У) КАК У
    ИЗ
    Пробы КАК ЧислаСалли
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ ЧислаПоля КАК ЧислаПоля
    ПО ЧислаСалли.ХУ = ЧислаПоля.ХУ
    ГДЕ
    НЕ ЧислаСалли.Сумма В
    (ВЫБРАТЬ
    ТабуСумм.Сумма
    ИЗ
    ТабуСумм)
    
    СГРУППИРОВАТЬ ПО
    ЧислаСалли.Сумма
    
    ИМЕЮЩИЕ
    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ЧислаПоля.ХУ) = 1

    Показать

    А возможно, ошибки и нет, а ошибка в исходной статье? Дело в том, что предположение про простые числа — не совсем верное. Вот, например 8 разлагается на сомножители однозначно, но не является произведением двух простых чисел.

    Reply
  16. Sykoku

    Я думал, что решали ЛОГИЧЕСКУЮ задачу про мудрецов в колпаках (http://eruditor.ru/z/?2). А тут…

    Бухгалтерам надо предложить так баланс составлять: берем и заносим все составляющие в массивы и потом выбираем пересекающиеся по условиям цифры.

    Решать арифметические задачи методом подбора — это еще додуматься надо…

    Reply
  17. scientes

    (16) Sykoku, Я полагаю, что это не арифметическая задача. Ответ получается в результате выполнения запроса. В Послесловии разобрано как этот запрос работает. Все методы решения, которые я видел, в той или иной форме реализуют этот алгоритм.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *