Евгений Степанищев

Этот сайт — моя персональная записная книжка. Интересны мне, по большей части, программирование, история и события из моей жизни.

Ева говорит

Ева во время отдыха в ОАЭ, октябрь 2025

Обсуждаем нового тьютора в школе, которую взяли на место уволившейся прежней:
— Дочка, как тебе новый тьютор?
— Мне она не очень нравится…
— А что такое?..
— Ну понимаешь, она не очень-то вовлечённая. Если Э. И. (это учитель) или Г. И. (прежний тьютор) кидаешь мячик своих эмоций, они кидают его в ответ, а этот тьютор как будто шагает в сторону и мячик падает на пол…

февраль 2026

В школе заболела учительница, её заменяет другая, спрашиваю Еву нравится ли ей новая учительница:
— Нет, папочка, не очень!..
— Почему?
— Ну знаешь, она слишком строгая, всё контролирует, как будто каждый наш шаг — решающий шаг в будущее!

21.02.2026

Мы в тот день летали в Стамбул, прилетели очень поздно, пока ехали в отель, Ева уснула. Стараемся её растормошить, так как через несколько минут нам выходить:
— Ева, ну смотри какая красота! Какое красивое здание!
— Угу, — нехотя открывая один глаз и щурясь, — тут самое время появиться кроватке, но что-то я её не вижу!

21.02.2026

Выходит из детской с целой кучей лошадок, вырезанных из бумаги и раскрашенных:
— Уф, папочка, я так устала их вырезать!
Я, знаю, что она опять это скорее всего делала не за столом, а на полу, поэтому и чувствует себя уставшей:
— Может тебе это надо было не на полу делать, давай, может, я тебе стул отрегулирую, если неудобно?
— Нет, я сейчас ничего этого не хочу, хочу чтобы ты посмотрел и восхитился!

28.03.2026

Выходные, я у себя в кабинете, наблюдаю за экспериментом на дашборде, дочка выходит из комнаты, видит меня:
— Пап, а есть что-нибудь вкусненькое?
— Да, там яблоки есть и мандарины…
Поворачивается в сторону кухонного стола, видит её любимые булочки с маком:
— Не-е-т, пожалуй, я возьму булочки. Будут и́х уминать и причитать как я с них толстею…

12.04.2026

У Евы выскочил очередной прыщ на носу, жена:
— Опять в тебя кто-то влюбился!
Дочка смеётся:
— В меня уже столько мальчиков втюрилось, сколько у нас в классе нет!

29.04.2026

Ева сегодня плохо себя чувствует, легла в моём кабинете и пробует уснуть:
— Пап, включи какую-нибудь свою лекцию, может я усну?
Через несколько минут:
— Надо было записать голос моего учителя по философии, у него очень спокойный голос, даже чрезмерно, я всегда на его уроках отлично спала!

11.05.2026

Мурчащий котик: результат

Кто-то в комментариях просил показать, каким получился Мурчащий котик — дочкин школьный проект кота. Как по мне, вышло великолепно. Спасибо бабушке, моей маме: в 90-е она много шила и теперь вспомнила прежние навыки. Нашить на такую небольшую игрушку шерсть очень непросто.

Одно меня расстраивает — в проекте дочки мало участвовала сама дочка. Выбрала модель для печати, глаза и нос, по сути — всё. По-прежнему считаю, что это вина школы — преподаватель должен помогать ребёнку выбирать проект по силам.

Brainfuck: оптимизирующий интепретатор

Удивительно, как некоторые бесполезные идеи иногда накрепко захватывают наш ум. Я тут в качестве примера хотел привести игру «Жизнь» Конвея, но при всей своей кажущейся бесполезности она в своё время сильно продвинула математику.

Меня в своё время захватила идея языка программирования «Брейнфак». Оглядываясь назад, думаю, её тоже нельзя объявить полностью бесполезной: в своё время я немало поломал голову над созданием оптимизирующего интерпретатора для этого языка.

Для начала — про сам язык. Я узнал о нём примерно в 2000 году, когда была мода на так называемые «эзотерические языки» — языки, разработанные в качестве шутки или для исследования какой-нибудь абсурдной идеи. «Брейнфак» как раз из таких: в нём всего восемь инструкций, но при этом это полноценный язык. Нейросеть мне на нём даже написала «Тетрис».

«Брейнфак» оперирует ячейкой в массиве, индекс которой можно сдвигать при помощи конструкций < и >. Кроме того, ячейку можно декрементировать (-), инкрементировать (+), вывести на экран символ, код которой записан в ячейке (.), либо записать код введённого с клавиатуры символа (,).

Кроме того, в «Брейнфаке» можно организовывать циклы при помощи парных инструкций [ и ] неограниченной вложенности. [ проверяет значение текущей ячейки, если там не ноль, выполняет тело цикла. Например, [-] записывает в текущую ячейку ноль, декрементируя значение в цикле.

Так как это единственная управляющая конструкция, циклов в обычной программе на «Брейнфаке» — огромное количество. Например, вот так выглядит минимальный «квайн», программа, которая при запуске выведет саму себя:

->++>+++>+>+>++>>+>+>+++>>+>+>++>+++>+++>+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+>+>+
+>>>+++>>>>>+++>+>>>>>>>>>>>>>>>>>>>>>>+++>>>>>>>++>+++>+++>+>>+++>>>+++>+>+++>+
>++>+++>>>+>+>+>+>++>+++>+>+>>+++>>>>>>>+>+>>>+>+>++>+++>+++>+>>+++>+++>+>+++>+>
++>+++>++>>+>+>++>+++>+>+>>+++>>>+++>+>>>++>+++>+++>+>>+++>>>+++>+>+++>+>>+++>>+
++>>+[[>>+[>]+>+[<]<-]>>[>]<+<+++[<]<<+]>>+[>]+++[++++++++++>++[-<++++++++++++++
++>]<.<-<]

Я задумался об оптимизации программ на «Брейнфаке» ещё в начале 2000-х, запрограммировав свои идеи на ДжаваСкрипте.

Первые мысли были вполне очевидными — объединять одинаковые конструкции. Вместо того чтобы последовательно инкрементировать ячейку десять раз, на этапе предпроцессинга можно сразу подсчитать количество «плюсов» и прибавить сколько требуется.

Потом я начал транслировать идиомы Brainfuck напрямую в ДжаваСкрипт, что тоже заметно повысило производительность. Например, конструкцию [-] можно заменить простой записью нуля в текущую ячейку — без выполнения цикла.

Настоящий прорыв случился, когда я понял: так можно оптимизировать не только отдельные идиомы, а вообще все циклы без ввода-вывода, если после выполнения цикла указатель возвращается в ту же ячейку, с которой начал. Например, [->+++++<] превращается во что-то вроде d[i+1] = d[i] * 5; d[i] = 0.

В дальнейшем я сильно развил эту идею. И если простейшие оптимизации встречаются и в реализациях других авторов, то настолько глубоко, насколько мне известно, не копал никто.

В середине 2000-х я переписал свой интерпретатор на ПХП, сохранив основной принцип, и время от времени ненадолго загорался желанием что-нибудь в нём улучшить. Недавно я полностью переписал его с помощью нейросетей, перевёл на свежую версию ПХП, покрыл тестами и так далее. Но сами принципы оптимизации остались теми же — придуманные мной ещё в 2000-е.

Проект лежит у меня на «ГитХабе».

Забавные часы

Купил себе на «Авито» бывший платёжный терминал — на борту «Андроид», так что мысль была запрограммировать себе (при помощи нейросетей, разумеется) какую-нибудь несложную развлекуху, типа «Мира в бутылке», чтобы на моём столе что-нибудь постоянно двигалось.

Пока у меня что-то руки до этого не дошли, а если уж быть совсем точным, то когда терминал приехал, проект, ради которого я его купил, что-то перестал меня вдохновлять, так что терминал просто одиноко светился по ночам, бесполезно расходуя электричество.

В итоге, когда я в очередной раз засиделся за каким-то проектом, мне пришло в голову, что было бы неплохо, если бы он напоминал бы мне сколько сейчас времени. Признаться, я не особо за ним слежу, часы в углу экрана как-то не бросаются в глаза, а из терминала получится отличное напоминание тому, что пора бы и честь знать.

Скачал с «Гуглфонтса» 1500 случайных шрифтов, выдрал из них цифры и сварганил приложение на «Флаттере», которое выводит цифры случайным шрифтом и в случайном контрастном цвете. В приложении два фона — светлый и тёмный, выбираются автоматически в зависимости от освещённости, которая измеряется камерой.

Проект выложен у меня на «Гитхабе».

Мокко

Я тут на днях читал архивы журнала «Огонёк», пытался понять, когда названия месяцев стали писать с маленькой буквы. Я был убеждён, что до революции названия месяцев всегда писались с большой, на манер английского языка. Оказалось, это не так: во всём архиве месяцы написаны с маленькой, начиная с XIX века.

Но речь не об этом. В выпуске № 6 за 1941 год в одной из заметок попалось слово «мокко», которое выглядит чистым анахронизмом.

Мокко сейчас — синоним моккачино, то есть смеси эспрессо, горячего молока и шоколада, сложно представить, что о его существовании знали в СССР в 40-е. Оказалось, что тогда это был просто сорт арабики из Йемена, названный в честь порта Моха.

Эффект Шерлока Холмса

Есть такой поразительный эффект; думаю, у него наверняка есть какое-то название, но не вижу смысла им интересоваться. Если ты умеешь находить неточности в деталях какого-то явления, у тебя возникает ложное ощущение, будто ты глубоко понимаешь всю тему в целом.

Все мы, наверное, читали тот рассказ Конана Дойла про Шерлока Холмса, где великий сыщик попытался совершить преступление, но оказалось, что он в этом плох. Думаю, тот рассказ, как и меня, ничему не научил никого из читающих эти строки.

Например, я довольно давно понял, что у меня неплохо получается вставать на место неподготовленного пользователя и находить огрехи в интерфейсах. Это умение помогало мне на прошлой работе в «Яндексе», помогает и сейчас: я вхожу в группу развития нашего продукта и чувствую себя там полезным.

Я несколько раз в жизни настолько преисполнялся уверенности, что, раз я вижу, чем дизайн плох, значит, смогу создать хороший. Все мои три — или около того — попытки довольно жёстко ставили меня на место: критикую я хорошо, а самостоятельно делаю дизайн плохо.

«Космонавт — мотоциклетный мастер»

Я много раз писал о том, что есть ряд фильмов и книг, застрявших в моей памяти, которые я едва помню, и почему-то мне плохо от того, что я не могу вспомнить, что это за фильмы или книги. Слава нейросетям — многое из этого списка удалось разыскать, но самые крепкие орешки до сих пор зудят в моей голове: нейросети тут помочь не смогли.

Сегодня благодаря одному из читателей почти закрылся ещё один мой гештальт. «Почти» — потому что книгу я ещё не заказал, но зато теперь знаю её название и даже смог прочесть из неё несколько рассказов в интернете.

Это детская книжка Витаутаса Казевича Петкявичюса «Космонавт — мотоциклетный мастер», которая была издана в 1983 году в переводе с литовского.

Несмотря на то, что я помнил из неё несколько дословных фраз, никак не мог её найти, видимо нигде в интернете нет её текста. Я давно планировал обратиться к читателям в отдельном посте, вдруг кто-то сможет вспомнить, а тут так повезло.

Левши и ручки

Мои прописи из первого класса. Я учился в 1 «Д» средней школы №7 города Лениногорска

В первом классе я был левшой, как и папа. Не помню в точности, когда меня начали переучивать, помню только, что переучивали в школе, в начальных классах. Кажется именно тогда у меня испортился почерк. Я начал снова красиво писать к концу школы, потом позже в техникуме перешёл на чертёжный шрифт — очень любил черчение, но позже снова вернулся к своему более врачебному варианту.

Никогда не понимал почему меня переучили, думаю и родителям особо не объясняли — надо и всё, время было такое. Сегодня утром наткнулся на одно место в книге, которую сейчас читаю:

Когда пишешь ручкой задом наперед, это погибель для перьев — у левшей та же проблема, все время перья ломаются.

— из книги «Среди других» Джо Уолтон.

Возможно когда-то это было один из двух аргументов, почему нужно переучивать левшей. Второй я тоже знаю, он ещё древнее — ученики в школах всегда сидят справа от окон, левая рука заслоняет свет от окна. Почему этот аргумент так долго был в ходу, бог его знает. Электрическое освещение с нами уже около века.

Я начинал учиться в 1984 году, перьевые ручки пропали в школах примерно к середине 70-х, но возможно методику обновить забыли и она диктовала переучивать левшей по старой памяти — из-за освещения и перьевых ручек, которые ломались.

«Тетрис» на Brainfuck

Ну разумеется я вчера не смог уснуть без того, чтобы не посмотреть что ещё мог бы написать ИИ на «Брейнфаке»! Попробовал написать «Тетрис», тем более что у меня были готовые идеи как это сделать. Правда для этого пришлось модифицировать интерпретатор. Свой собственным, разумеется, который я начал писать ещё в 2001-м году, надо бы про него рассказать тоже однажды.

Дело в том, что у «Брейнфака» нет рандомизации и ввод устроен очень просто — есть инструкцию чтения символа и всё. Правда сам язык не определяет подробности чтения символа, поэтому реализации отличаются. В основном авторы интерпретаторов делают буферизированный ввод, дожидаясь нажатия кнопки «Ввод». Правда тут тоже есть нюансы — где-то можно ввести строку, а где-то «Ввод» надо нажимать после введения каждого символа.

Чтобы приступить к «Тетрису» пришлось сделать две модификации.

Во-первых, ввести команду @, которая записывает случайное число в текущую ячейку («Брейнфак» всё сохраняет в ячейках, двигаясь по ней при помощи специальных команд). В таком расширении языка нет ничего необычного — когда он был на волне популярности, ему постоянно придумывали всякие расширения.

Во-вторых, я добавил специальный режим опроса клавиатуры — неблокирующее чтение. Мы передаём программе весь ввод пользователя сразу, а если он ничего не вводил, записываем в текущую ячейку ноль.

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

Чтобы каждый раз не вспоминать какие ключи нужны программе, я придумал способ как их указывать — если в начале программы на «Брейнфаке» стоит обычный шебанг, я беру параметры интерпретатора оттуда.

Как легко догадаться по скриншотам, нейросеть (я использовал «ГПТ-5.5») отлично справилась с задачей. Но что интересно, чтобы это сделать она реализовала ровно ту идею, про которую я писал в прошлый раз — написала генератор на ПХП, при помощи которого сгенерировала программу на «Брейнфаке». Немудрено — программа получилась монументальной — под сотню мегабайт в первой попытке.

Я даже сделал в своём интерпретаторе поддержку сжатия исходников. Наверное никому раньше не приходило в голову этим заниматься — как правило программы на «Брейнфаке» пишут люди и до таких размеров они их не доводят.

Трансляция такого огромного файла и применение оптимизаций занималось около 15—20 секунд на моём ноутбуке, так что пришлось применить ряд оптимизаций — немного переписать парсер интерпрератора, сделать кеширование и поработать над уменьшением размера кода «Тетриса».

«Тетрис» работает в консоли и, надеюсь, никому не надо объяснять, что для раскрашивания блоков и позиционирования тут широко применяются анси-коды, я их использую чуть ли не в каждой консольной программе, вряд ли кого-то это удивит.

Единственное о чём надо рассказать — как регулируется скорость игры. В «Брейнфаке» нет ничего, чтобы создавать паузы заданной длительности, но некоторые программы работают ощутимо долго. Хотя у меня и оптимизирующий интерпретатор, всё оптимизировать он не может. Поэтому мы с нейросетью просто «на глазок» подобрали код, который достаточно плохо оптимизируется и тормозит на моём ноутбуке ровно насколько, чтобы играть было комфортно.

ИИ: Brainfuck

Три года назад я в шутку предлагал программистам переходить на «Брейнфак» — эзотерический язык программирования из восьми конструкций, который плохо давался нейросеткам. Что-то похожее на программу на этом языке они писали, но получался мусор.

Я пропустил момент, когда модели научились на нём писать. Буквально вчера догадался снова попробовать, оказалось — могут! Программу на скриншоте мне «Курсор» написал в режиме «Авто», где выбираются, в основном, слабые модели. Топовые справляются даже с такими заданиями как написать несложный эмулятор командной строки с несколькими основными командами и небольшой файловой системой!

Для человека это уже какой-то запредельный уровень. Если бы я решал эту задачу, я бы написал себе сначала какой-нибудь макроязык с трансляцией в «Брейнфак» и уже на нём написал то, что требуется.

Две вещи, с которыми модели ещё не справляются — это написание «квайна» (программы, которая выводит сама себя) и оптимизация программ на «Брейнфаке» по размеру. Даже топовые модели наотрез у меня отказываются такое писать. Даже после прямого приказа.

Интересно будет помучить этой задачкой новую модель «Антропика», которая должна появиться летом — я считаю их модели лучшими, хотя их последний «Опус» несколько разочаровал.

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

Семидесятипятилетнее вино

Папе в марте исполнилось 75 лет — юбилей и довольно значительная дата. Поэтому хотелось поздравить его как-то небанально. Они с мамой всегда в начале мая приезжают к нам в гости из Лениногорска, и мы с братишкой хотели по приезде чем-нибудь его удивить, но всю голову сломали.

С идеей выручила жена — папа хорошо относится к качественному вину, вот она и предложила найти ему бутылочку вина семидесятипятилетней выдержки. Мне сразу показалось, что это шикарный подарок, но найти его в Казани оказалось нереально.

Хорошо, что у нас есть интернет! Искомое нашлось на одном из сайтов, правда там ничего не было сказано про доставку, но после звонка и почти двухчасового обсуждения всех деталей по «Телеграму» вино было упаковано и в тот же день поехало в Казань.

Я сильно переживал как оно доедет — консультант в магазине сказал, что не все бутылки могут пережить транспортировку, поскольку в некоторых бывают трещины. Он выбрал без видимых трещин и тщательно упаковал, но я всё равно волновался.

Доехало всё шикарно, в целостности и сохранности. Сегодня подарок вручили, надеюсь и до Лениногорска он доберётся без эксцессов.

Коммунистический массив

Я тут в мемах, которые кинули бывшие коллеги, увидел «коммунистическую сортировку» — она каждому присваивает среднее значение, и не смог пройти мимо. Написал «коммунистический массив»:

class CommunistArray extends \ArrayObject
{
    public function __construct(array $array = [])
    {
        parent::__construct(self::createCommunistArray($array));
    }

    public function offsetSet(mixed $key, mixed $value): void
    {
        parent::offsetSet($key, $value);
        $this->redistribute();
    }

    public function offsetUnset(mixed $key): void
    {
        $first = $this->getIterator()->key();

        if ($first !== null) {
            $this[$first] += $this[$key];
            parent::offsetUnset($key);
            $this->redistribute();
        }
    }

    private static function createCommunistArray(array $array): array
    {
        if ($array) {
            $avg = array_sum($array) / sizeof($array);
            return array_fill_keys(array_keys($array), $avg);
        }

        return [];
    }

    private function redistribute(): void
    {
        (void) $this->exchangeArray(self::createCommunistArray((array) $this));
    }
}

Он делает всех равными и перераспределяет блага автоматически:

$comrades = new CommunistArray([0b1, 0o0, 3e1, 0x45]);

print_r($comrades); # 25, 25, 25, 25

$comrades[2] = 4;
print_r($comrades); # 19.75, 19.75, 19.75, 19.75

unset($comrades[0]);
print_r($comrades); # 24.6875, 24.6875, 24.6875

Книга с Некрасова

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

Зашли в дом на Некрасова, куда меня приглашали когда-то осмотреть чердак перед расселением. Сейчас он совершенно брошен и медленно разрушается. Внутри следы бытования бомжей, которые, похоже, перестали уже там бывать из-за опасности обрушения — в месте их ночёвки провалилось перекрытие и рухнула одна стена.

Мы туда соваться, понятное дело, не стали, зашли в крепкую половину дома. На наше счастье бомжи не мёрзли — в одном из углов обнаружилась солидная стопка советских книг по химии, в которой нашлись две книги 1920-х годов. Мы их поделили поровну.

Мне достался первый томик «Химии жизни» 1923 года в отличном состоянии. Книжка редкая — тираж всего 3000 экземпляров, но вряд ли востребованная — думаю за сто с лишним лет её научная ценность упала ниже нуля.

Интересно, что её автор биохимик Владимир Сергеевич Садиков был в 1942-м году эвакуирован из Ленинграда к нам в Казань, где вскоре и скончался. Как знать, может эту книжку он привёз с собой.

На двух её страницах виден круглый штамп, но он сильно выцвел, мало что можно разобрать, кроме того, что это штамп какого-то института. Садиков успел поработать в нескольких ленинградских институтах, возможно это штамп одного из них. Но не исключено, что это может быть отметка нашего химического института, куда сам автор мог выслать в своё время книгу для ознакомления.

Книги: «Возвращение Синей Бороды»

Трудно сказать, почему я до сих пор сохранял веру в то, что Пелевин ещё напишет что-то такое, что однажды меня зацепит, — какую-то книгу, настолько важную, что надо немедленно хватать всё, что выходит из-под его пера, чтобы приобщиться к ней как можно скорее.

Многие говорят, что он давно исписался, я, наверное, с этим тоже согласен, но почему-то всё равно не бросал его читать.

Не скажу, что мне каждый раз приходилось делать над собой усилие: некоторые его вещи давались мне легче, другие труднее, но ни через одну я не продирался так, как через текст его свежей книги «Возвращение Синей Бороды». Тут я окончательно завяз. Примерно на половине я сообразил, что мне совершенно не хочется её дочитывать.

Я очень не люблю бросать книги, возможно это какая-то моя обсессия, но эту постараюсь бросить. Вместе с писателем и его неудачным спектаклем.

Есенин

Никогда не любил и не понимал стихи Есенина, мне всегда больше нравился Маяковский. Впрочем, кроме Маяковского меня вообще мало какие стихи привлекают — в этом смысле я однолюб. Впрочем, я давно догадывался, что дело в подаче. Наверное с тех пор, как услышал стихи Олеси Балтусовой в её собственном исполнении. Мы дружим больше 20 лет, но я до сих пор не воспринимаю её стихов в виде текста.

Как-то в машине услышал песню «Заметался пожар голубой» в исполнении Легенары, сначала не понравилось, я даже не дослушал. Потом она попалась ещё и ещё, я особо-то и внимания не обратил — был в своих мыслях. Возможно поэтому песня пробила какие-то мои внутренние фильтры и я вдруг её даже полюбил.

Только потом я узнал, что это стихи Есенина и попробовать послушать тоже самое в исполнении Безрукова. Мне совершенно не понравилось. В исполнении Легенары эти стихи звучат очень лирично, с каким-то надрывом, мне подходит, а Безруков читает, напротив, восторженно, как весенний щенок.

В общем, в восприятии стихов я очень нуждаюсь в помощи исполнителя.

Наверняка это очень примитивно — не уметь видеть стихотворную красоту самостоятельно, но что делать, пока не научился. Собственно, целенаправленного я для этого делал очень мало, нет сильной потребности, что ли…

Портрет Сергея Есенина нарисованный «Джи-Пи-Ти Имейдж 2»
Ранее Ctrl + ↓