vak: (Default)
Serge Vakulenko ([personal profile] vak) wrote2020-08-13 11:51 pm
Entry tags:

Решение для запуска REPL приложения

Я придумал решение для запуска REPL приложения, упомянутое в предыдущем посте. Напомню формулировку: есть интерактивная процедура на Си++ со следующим интерфейсом.
void application(std::istream &input, std::ostream &output);
Процедура работает в стиле REPL: берет ввод из входного потока, обрабатывает, выдаёт результат в выходной поток и ждёт следующего ввода. Мы хотим запустить эту процедуру из нашей программы на Си++, посылать ей команды и получать результат. Это, в частности, полезно для автоматического тестирования. Примерно так:
send("foo\n");
std::string reply = receive();
REQUIRE(reply == "bar\n");
Решение выглядит в виде класса Interact и работает следующим образом:
#include "interact.h"

Interact session(application);
REQUIRE(session.receive() == "Hello!\n");

session.send("foo\n");
REQUIRE(session.receive() == "bar\n");
Исходники можно взять на Гитхабе: https://github.com/sergev/interactРеализация должна быть понятна из комментариев.
spamsink: (Default)

[personal profile] spamsink 2020-08-14 08:13 pm (UTC)(link)
Слишком простой алгоритм; за миллион с лишним прогонов нашлось меньше сотни разных путей выполнения, фаззингу не за что зацепиться. Хотя кратчайший ввод для достижения результата всего 20 байт: "\ntv0\n200\nt:0\n149\n20\n".
spamsink: (Default)

[personal profile] spamsink 2020-08-15 01:44 am (UTC)(link)
Это было без фаззинга, моей программой. Всегда можно вручную заменить последовательность одинаковых команд на увеличенный интервал, лишь бы ASCII-диапазона хватило. В данном случае повезло, что нужно было ровно 70 секунд и на свободное падение, и на торможение.

Это решение годится для большинства уровней (кроме 1 и 2, если не ошибаюсь).