«Яндекс»

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

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

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

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

Оставить комментарий

Анатомия Котопса

Начали смотреть с дочкой детский боди-хоррор «Котопёс». Дочка тут же стала фанатом этого сериала и уже приступила к построению первой своей фанатской теории, самой очевидной, над которой сломано довольно много копий в интернете.

А именно — как эта животинка того-самого… в смысле, в туалет ходит.

Кот в красной рубашке с хитрой улыбкой стоит рядом с лежащим на подушке спящим котёнком в красной пижаме с соской, на фоне деревянного забора.
Кадр, раскрывающий тайну Котопса, первый сезон, шестая серия

Дочкина теория довольно неаппетитная, поэтому проводить не буду, хотя в интернете у неё тоже есть сторонники.

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

По его расположению сразу видно как у этой химеры функционирует пищеварение. Странно, что этот кадр в найденных мною обсуждениях анатомии Котопса не всплыл ни разу.

4 комментария

Интересный балкон

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

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

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

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

Согласно «Википедии», в Дружковке до революции действовали два завода, которые могли бы выпустить удерживающую балкон двутавровую балку, но самый подходящий из них — чугуноплавильный и сталелитейный, основной продукцией которого были рельсы. Строить его начинали в 1893 году, а в 1896 году о нём написал в своей классической повести «Молох» Александр Куприн:

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

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

Завод был разрушен в Гражданскую войну и вновь был возрождён в 1920-м, когда его объединили с Торецким сталелитейным и механическим заводов и переименовали в Дружковский машиностроительный завод.

Оставить комментарий

Полезный сценарий

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

Думаю, я не один такой, поэтому время от времени делюсь сценариями, которые оказались полезными для меня.

Сценарий: датчик в прихожей (08:00–20:00) фиксирует открытие двери. Станция в зале приветствует «Добро пожаловать!», остальные устройства сообщают «Кто-то пришёл».

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

6 комментариев

Лук эт зис

Ездили на прошлые выходные на дачу к А. Х., нашему другу, — поболтать, провести время. Заодно, помятуя, что он всерьёз увлёкся луком, решили тоже попробовать пострелять. Мне было интересно, но не более того, не сказать, что зацепило. Я люблю пострелять из огнестрела или пневматики, но лук стойкого интереса не вызывал.

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

Пока я стрелял, жена меня фотографировала, и уже позже, когда я отсматривал снятое, оказалось, что некоторые фотографии вызывают у меня ощущение, что их сгенерировала нейросеть. Я даже могу сказать какая — Stable Diffusion.

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

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

Во-вторых, видимо из-за каких-то артефактов сжатия, некоторые детали выглядят слишком гладкими (моя кожа, куртка), другие же — изобилующими странными деталями (край красной рукоятки лука). Такие особенности тоже часто встречаются в сгенерированных изображениях.

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

2 комментария

Пацаны и суверенитет

На фоне интереса к текстовому квесту нулевых «Гопник-2» кто-то из читателей посоветовал ознакомиться с книгой «Слово Пацана» Роберта Гараева, — проникнуться материалом. Я пытался придумать в игре что-то новое, но самостоятельно не выходило, так как я не слишком знаком с темой.

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

Пожалел, что начал читать, но это не вина книги, конечно, просто криминальная тема мне никогда не нравилась.

Только один отрывок зацепил, хочу поделиться:

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

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

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

6 комментариев

Whatcha gonna do when they come for you?

То, на что мне открыла глаза книга «Слово Пацана» Роберта Гараева, о которой я упоминал вчера, — что группировки с улиц Казани никуда не исчезли. По мнению одного из героев книги, в группировках состоят примерно 30% молодых пацанов нашего города. Это очень и очень много.

Причём пацана «с улицы» до сих пор можно отличить по неким внешним признакам:

Дела обсуждаются в WhatsApp и вконтакте, где мы создавали беседы — типа чатики. Основное правило: ни в коем случае не болтать лишнего. Появилась такая мода, что пацаны с улицы не ставят настоящие имена и фамилии во вконтакте. И фотографии нет. […]

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

Сейчас у пацанов одна отличительная черта — носят барсетки через плечо. И, конечно, все коротко стриженные — ни в коем случае не зачесанные набок волосы. За проборы даже спрашивают: при мне лично наваляли одному мальчишке. И джинсы должны быть широкими, не зауженными.

Я-то думал, что сейчас всем вообще всё равно кто во что одевается, по крайней мере в крупных городах.

У меня, кстати, во время чтения книги разблокировалось воспоминание: я, ещё школьник, стою на балконе, а через наш очень широкий двор «Грязь» в Лениногорске бежит толпа пацанов. Откуда-то я знаю, что идут они драться с каким-то другим двором. Это 1980-е годы.

Оставить комментарий

«Жизнь в коробке из-под Сяоми»

На заре интернета (для меня заря — это вторая половина 1990-х), был актуален формат «хомяков» (от слов home page — «домашняя страница»).

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

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

Два модульных куба-комнаты: слева — спальня с кроватью и окном, справа — рабочий кабинет с человеком за столом и ноутбуком, оба освещены тёплым светом.
«Жизнь в коробке из-под Сяоми» по версии нейросети «Кандинский 2.1»

Это я к чему вспомнил, — недавно какой-то читатель в заметке про то, что мой сайт уже не блог, а скорее дневник, написал классную фразу:

Так и жизнь проходит в собственной картонной коробке от Сяоми.

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

А может и нет.

4 комментария

Краткие инструкции к лекарствам

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

Почему прямо на блистере нельзя написать: «невротоникс, 1 таблетка 3 раза в сутки, рассосать, улучшает сон, снимает тревожность»? «Аспиринус, 2-6 раз в сутки, разжевать, запить, снимает боль».

Что-то вроде такого.

18 комментариев

Модуль scalar_objects

Очень мне нравится идея навести порядок в функциях ПХП при помощи присобачивания к примитивным типам что-то вроде методов.

К именованию встроенных функций есть много претензий:

  • различный стиль наименований: html_​entity_​decode, но htmlentities;
  • неинтуитивность некоторых названий: strcspn, strpbrk;
  • разный порядок параметров: strpos($haystack, $needle), array_search($needle, $haystack);

Считается, что это один из серьёзных недостатков ПХП. Напрашивается очевидное решение — сделать всем проблемным функциям алиасы, но так язык замусорится ещё сильнее.

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

declare(strict_types=1);

class IntHandler {
    public static function abs(int $self): int {
        return abs($self);
    }

    public static function div(int $self, int $other): int {
        return intdiv($self, $other);
    }

    public static function sqrt(int $self): float {
	return sqrt($self);
    }
}

register_primitive_type_handler('int', 'IntHandler');

$i = -5;
var_dump($i->abs()->div(2)->sqrt()); // 1.4142135623730951

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

Кроме того, повышается читаемость. Сравните два подхода

$result = substr(strtr(rtrim($className, '_'), '\\', '_'), 15);
$result = $className->trimRight('_')->replace('\\', '_')->slice(15);

Как по мне, очень хорошее решение, совершенно непонятно почему оно ещё не в языке.

Оставить комментарий

Северокорейские причёски

Зашёл с одним дружищем разговор про Северную Корею, и в рамках этого разговора он мне кинул ссылку на статью о разрешённых в этой стране женских и мужских причёсках.

Меня, как человека, который бреется налысо, заинтересовало — лысых корейцев не существует или все парики носят?

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

6 комментариев

Прогресс у дочки в чтении

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

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

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

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

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

Такая методика оказалась хороша тем, что позволяет поддержать интерес — дочке самой хочется продолжать, старается, читает.

Побочным эффектом подхода стало то, что почти исчезла боязнь больших текстов. Я даже не знал или забыл, что у детей существует такое явление.

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

2 комментария

Apple Vision Pro

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

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

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

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

Ещё интересное место:

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

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

6 комментариев

ИИ и «Эльбрус»

Прочитал свежую новость о том как ребята из «Гугла» при помощи алгоритмов искуственного интеллекта ускорили сортировку. На коротких последовательностях ускорение там достигает 70%:

AlphaDev’s newly discovered algorithm achieves a 70% increase in efficiency for sorting short sequences of elements and approximately 1.7% for sequences surpassing 250 000 elements, as compared to the algorithms in the C++ library.

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

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

В этой связи мне вспомнился многострадальный процессор «Эльбрус» со своей неоднозначной архитектурой VLIW, которую ещё недавно с удовольствием многие пинали.

Чёрный корпус компьютера с прозрачной боковой панелью, на которой крупными буквами написано «Эльбрус», стоит на гранитном подоконнике у окна с видом на деревья.
Компьютер на базе «Эльбруса», стоит у нас на подоконнике

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

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

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

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

Совсем не факт, конечно, что такая стратегия выгоднее традиционной, всё-таки характер нагрузки на код может поменяться в любую секунду. При этом традиционная архитектура подстроится, а VILW нет, но это вопрос баланса. Что лучше — дорогой (и потенциально более энергоёмкий) процессор, способный оптимизировать код сам или более дешёвый (и, возможно, более экономичный), у которого лапки. Возможно и VILW хорошо ляжет на какие-то задачи.

2 комментария

Ссылки через веб-архив

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

4 комментария

Сон про фраки

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

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

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

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

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

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

2 комментария

99 бутылок: SectorC

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

Пора возобновить.

76. SectorC — очень маленький компилятор подмножества языка Си. Помещается в один сектор — 512 байт, отсюда и название. Язык очень сильно урезанный, но всё равно меня поражает как автор запихнул имеющееся в такой малый объём.

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

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

Самые распространённые в выходном тексте буквы я кодирую полубайтом от 0x1 до 0xE, а более редкие — байтом от 0xF1 до 0xFC. Завтра попробую описать это чуть подробнее.

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

// Written by Evgeny Stepanischev https://bolknote.ru
// SectorC

int c; // input
int shift; int x;

void x() { if( c == ( x >> 8 ) ){ print_ch = x & 255; } }
void p() { print_ch = c; print_char(); }

void c2c() {
    c = c + shift;
    x =  288; x(); x =  613; x(); x =  879; x(); x = 1140; x(); x = 1388; x();
    x = 1634; x(); x = 1902; x(); x = 2145; x(); x = 2419; x(); x = 2674; x();
    x = 2918; x(); x = 3191; x(); x = 3338; x(); x = 3684; x(); x = 4200; x();
    x = 4396; x(); x = 4654; x(); x = 4981; x(); x = 5204; x(); x = 5481; x();
    x = 5739; x(); x = 6000; x(); x = 6253; x(); x = 6471; x(); x = 6734; x();
    x = 7033; x();

    if( c != 15 ){ print_char(); }
    shift = 0; if( c == 15 ){ shift = 15; }
}

int s; // input
void ps() {
    while( s ){
        c = s & 15;
        c2c();
        s = s >> 4;
        if( s == ( 0 - 1 ) ){ s = 0; } // signed workaround
    }
}

void bottle()  { s = 17249; ps(); s = 596; ps(); }
void of_beer() { s = 6961; ps(); s = 41510; ps(); }
void on_wall() { of_beer(); s = 5937; ps(); s = 8692; ps(); s = 22721; ps(); print_char(); }
void o_more()  { s = 40723; ps(); s = 675; ps(); }

int b; // input
void bottle_b() {
    if( b == 0 ){ s = 55; ps(); }
    if( b > 0 ){ print_num = b; print_u16(); }
    bottle();
    if( b != 1 ){ c = 115; p(); } // s
}

void main() {
    shift = 0; b = 99;

    while( b > 0 ){
        bottle_b(); on_wall();

        s = 303; ps(); /* ', ' */ bottle_b(); of_beer();
        c = 46; p(); // '.'
        print_newline();
        b = b - 1;

        s = 2143; ps(); s = 4735; ps(); s = 4723; ps(); s = 31806; ps();
        s = 59265; ps(); s = 35057; ps(); s = 409; ps(); s = 5231; ps();
        s = 936; ps(); s = 59215; ps(); s = 303; ps();

        bottle_b(); on_wall(); c = 46; p(); // '.'
        print_newline(); print_newline();
    }

    c = 78;  p(); /* 'N' */ o_more(); bottle(); c = 115; p(); // 's'
    on_wall();
    s = 28975; ps(); /* ', n' */ o_more(); bottle(); c = 115; p(); // 's'
    on_wall();
    c = 46;  p(); // '.'
    print_newline(); 

    s = 5039; ps(); s = 16692; ps(); s = 4639; ps(); s = 41801; ps();
    s = 30738; ps(); s = 1566; ps(); s = 53071; ps(); s = 913; ps();
    s = 4767; ps(); s = 41887; ps(); s = 4850; ps();
    b = 99; bottle_b(); on_wall(); c = 46; p(); // '.'
}

1 комментарий

Свёртка строк на SectorC (лонгрид)

Вчера я обещал рассказать что я придумал, чтобы компактнее выводить строки в языке SectorC. Напомню, это компактный компилятор подмножества Си, который занимает один сектор (512 байт).

Для начала посмотрим что доступно в компиляторе для вывода текста. В самом языке для этого ничего нет, но если заглянуть в стандартную библиотеку языка, которая подключается автоматически, то можно увидеть там функции print_char(), print_u16() и print_i16(), предназначенные, соответственно, для вывода символа, заданного его кодом, целого числа без знака и целого числа со знаком.

Соответственно вывод «Hello» выглядит так:

print_ch =  72; print_char(); // H
print_ch = 101; print_char(); // e
print_ch = 108; print_char(); // l
print_ch = 108; print_char(); // l
print_ch = 111; print_char(); // o

Очень многословно. Когда я вчера написал «песню о пиве» в таком формате, программа получилась чересчур длинной. Мне захотелось как-то её упросить. Вот как я рассуждал.

Код задаётся целым типом int, который имеет в этом языке 65536 значений. Поскольку мне нужны не все буквы, выглядит так как будто в одно число можно запихнуть несколько знаков. Но сколько?

Для начала посмотрим сколько символов вообще используется. Цифры меня не интересуют (числа выводятся отдельной функцией), поэтому выкинем их:

import sys
from collections import Counter
data = Counter(x for x in ''.join(sys.stdin.readlines()) if x > '9' or x < '0')

print(data)

Вот что получилось:

Counter({' ': 2306, 'e': 1305, 'o': 1108, 't': 903, 'l': 702, 'b': 601, 'n': 600, 'a': 598, 's': 497, 'r': 403, 'f': 300, 'w': 300, '\n': 298, 'd': 298, 'h': 202, ',': 200, '.': 200, 'u': 100, 'T': 99, 'i': 99, 'k': 99, 'p': 99, 'm': 4, 'G': 1, 'N': 1, 'y': 1})

Двадцать шесть символов. Жаль не шестнадцать, было бы удобно хранить — как я говорил выше, значений в целом типе помещается 65536 штук. Какая связь? Чтобы это понять, разберёмся откуда взялось число 65536.

Оно вытекает из особенностей машинного хранения. Минимальная единица хранения — бит, хранит всего два состояния, — биты, в свою очередь, собраны по восемь штук в байты. Тип int в данном случае — это два байта.

Отсюда получается, байт — восемь бит по два значения или 2⁸ = 256 значений, два байта — 256² = 65536. В десятичной системе выглядит довольно бессмысленно, но если перейти на шестнадцатеричную, где цифры записываются от 0…9, A…F, с префиксом 0x (он ставится чтобы различить две формы записи числа), то становится понятнее.

Тогда число 65536 будет выглядеть как 0xFFFF — визуально распадается на два байта по 256 (0xFF) значений или на четыре полубайта по 16 (0xF).

Я решил хранить символы в полубайтах. Поскольку символов у меня 26, а в полубайте помещается 16 значений, то одно значение пришлось занять префиксом — если он встречается, то мы используем вторую таблицу символов. Под префикс я выделил 0xF. Таким образом, в одном int можно закодировать от двух до четырёх символов.

Например, число 0x2F40 или 0x2 0xF 0x4 0x0 означает, что мы смотрим второй символ в первой таблице, потом переключаемся на вторую (так как встретили 0xF) и смотрим там четвёртый символ, а символ 0x0 имеет специальное значение, — он не выводится и нужен для того, чтобы у нас была возможность закодировать строку, которая короче, чем могла бы поместиться.

В первую таблицу я поместил самые часто встречающиеся символы, во вторую — те, что встречаются реже. Получилось намного компактнее. Например, строка «hello» в моём алфавите выводится вот так:

s = 21023; ps(); s = 53; ps(); // 0x521F, 0x35

Поскольку по техническим причинам число проще обрабатывать с конца, то я разворачиваю ту часть строки, которая кодируется. Это легко заметить по тому, что префиксное значение 0xF у меня находится в конце числа 0x521F.

Код для преобразования строк в такую форму выглядит следующим образом:

input = 'hello'

from itertools import *
# основная таблица
t0 = [' ', 'e', 'o', 't', 'l', 'b', 'n', 'a', 's', 'r', 'f', 'w', '\n', 'd']
# и дополнительная
t1 = ['h', ',', '.', 'u', 'T', 'i', 'k', 'p', 'm', 'G', 'N', 'y']

# поиск символов в таблицах
def conv(ch):
    try:
        yield t0.index(ch) + 1
    except ValueError:
        yield 0xF
        yield t1.index(ch) + 1

# подготовка к разбиению по группам, которые будут кодироваться вместе
def make_shifter():
    pos = 0
    gr  = 0

    def shifter(v):
        nonlocal pos
        nonlocal gr

        if pos == 4:
            pos = 0
            gr += 1

        # префикс переключения таблиц не может остаться в одиночестве,
        # поэтому мы не можем оставить его в хвосте
        if pos == 3 and v == 0xF:
            pos = 1
            gr += 1
        else:
            pos += 1

        return (v, gr, )
    return shifter

shifter = make_shifter()

# нумеруем группы символов
gen = (shifter(x) for x in chain(*(conv(ch) for ch in input)))
# собираем группы символов вместе
gen = groupby(gen, key = lambda x: x[1])

# двигаемся по собранным группам, собираем их в число
for x in gen:
    sum = 0
    for y in list(x[1])[::-1]:
        sum *= 16
        sum += y[0]

    print("s = {}; ps(); ".format(sum))

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

Первая выглядит совсем просто:

int s; // input
void ps() {
    while( s ){
        c = s & 15;
        c2c();
        s = s >> 4;
        if( s == ( 0 - 1 ) ){ s = 0; } // signed workaround
    }
}

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

Строка с комментарием нужна, так как число у нас знаковое (то есть возможные 65536 значений делятся пополам, часть значений считается отрицательным, другая часть — положительными). У отрицательных чисел есть особенность — битовый сдвиг (>>) хоть и считается эквивалентом деления на два, но из минус единицы ноль не делает.

c2c тут — как раз функция, которая должна преобразовывать код в символ (code-to-character). Она выглядит сложнее. Поскольку массивов в языке тоже нет, приходится выкручиваться как-то иначе. Самый простой способ — инструкциями if проверять каждое значение и найдя нужно, записать в специальную переменную искомый код.

Сначала я так и сделал, но выглядело, опять же, громоздко. В итоге, переделал чуть попроще: код сравнения выделил в короткую функцию x(), а пару что во что превращается закодировал в один int:

int c; // input
int x;
void x() { if( c == ( x >> 8 ) ){ print_ch = x & 255; } }

После такого кодирования функция code-to-character стала выглядеть вот так:

void c2c() {
    c = c + shift;
    x =  288; x(); x =  613; x(); x =  879; x(); x = 1140; x(); x = 1388; x();
    x = 1634; x(); x = 1902; x(); x = 2145; x(); x = 2419; x(); x = 2674; x();
    x = 2918; x(); x = 3191; x(); x = 3338; x(); x = 3684; x(); x = 4200; x();
    x = 4396; x(); x = 4654; x(); x = 4981; x(); x = 5204; x(); x = 5481; x();
    x = 5739; x(); x = 6000; x(); x = 6253; x(); x = 6471; x(); x = 6734; x();
    x = 7033; x();

    if( c != 15 ){ print_char(); }
    shift = 0; if( c == 15 ){ shift = 15; }
}

Как видите, код 0xF (15) устанавливает флаг сдвига значений shift, который в следующий раз складывается с кодом (c + shift) и сдвигает значение на следующем декодировании. Заметно, что нигде нет else, потому что этого оператора в языке тоже нет!

Как будто бы рассказал всё.

Вместо вывода — интересный своей компактностью компилятор, автору моё уважение, — я даже и не подозревал, что в таком малом объёме можно уложить полноценный язык! Очень и очень круто!

9 комментариев

Моя тема для «Эгеи»

Вчера выложил свою тему оформления для движка «Эгеи». Меня давно просили, а вчера был очередной комментарий на эту тему, ну я и сделал это наконец. Тему надо положить в папку user/themes/bolk, выбрать её в настройках блога и сбросить кеши.

5 комментариев

SectorCFuck

Очень интересно устроен разбор файла программы в компиляторе SectorC, который я ковыряю вечерами из любви к ненормальному программированию. Для тех, кто успел позабыть, напомню — этот компилятор занимает один сектор (512 байт) и способен выполнять программу на подмножестве Си.

Когда смотришь на код такого маленького объёма, сразу возникает вопрос — каким чудом удалось туда запихнуть грамматику языка Си, даже если какое-то подмножество? Ответ — хеширование.

Автор использует реализацию функции atoi, которая превращает любые строки в шестнадцатибитное числа:

unsigned short sectorc_atoi(const char *s)
{
    unsigned short n = 0;
    for (;;) {
        char c = *s++;
        if (!c) break;

        n = 10 * n + (c - '0');
    }

    return n;
}

Все токены, которые встречаются в программе, обязательно разделяются пробелами (за исключением ;, для него есть специальная обработка). Это позволяет довольно просто парсить программу — любой токен скармливаем atoi, получаем число и по таблице смотрим с чем имеем дело.

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

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

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

Ниже программа, выводящая «Hello» (её надо запускать без линтера):

<**^ ')'|] /=]
    -_.@" -[ )~( /@< $^+>\() /<'
    -_.@" -[ /<'' /@< $^+>\() /<'
    -_.@" -[ ,[~ /@< $^+>\() /<'
    -_.@" -[ +^^` /@< $^+>\() /<'
    -_.@" -[ /<(' /@< $^+>\() /<'
,[_

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

Терминал показывает выполнение скрипта ./run_raw.sh с предупреждением о неопределённом формате образа и выводом «Hello».
Пример запуска обфусцированной программы без линтера

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

Кстати, такое развлечение, когда мы не используем в программе алфавитно-цифровые символы, называется ЧтоНибудьFuck, уж так повелось, — FuckJS, FuckPHP и так далее. Отсюда и название заметки.

Оставить комментарий

Женя Владимирович

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

Так вот, меня не покидает ощущение, что у части имён как будто бы нет «официального» варианта. Например, у «Ляли» и «Олеси». Для меня всю жизнь немного необычно звучат «Ляля Узбековна» или «Олеся Александровна», словно тут должна стоять какая-то другая форма — что-то вроде «Лялия» и «Олесандра».

13 комментариев

Деление в SectorC

Очень неудобно, что в языке SectorC нет деления. Я сначала думал, что это из-за ограничений — ведь задумка в том, чтобы компилятор помещался в сектор (512 байт). В таком случае можно было бы выкинуть операции левого и правого сдвига (<< и >>), чтобы освободить место. Эти операции как раз можно было бы заменить умножением и делением.

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

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

При этом надо знать две вещи: присваивание значения переменной происходит через регистр AX, так что присвоив переменную саму себе, можно записать в AX её значение, и второе — если посчитать atoi (см. мою вчерашнюю заметку) для имени переменной и умножить получившееся число на два, можно получить ячейку, где хранится значение этой переменной.

Так вычисленный результат можно будет положить куда вздумается.

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

int div_a; int div_b; // input
int div_result;

void div()
{
    div_b = div_b;             // mov ax, [&div_b]
    asm 145;                   // xchg cx, ax
    asm 49; asm 210;           // xor dx, dx
    div_a = div_a;             // mov ax, [&div_a]
    asm 247; asm 241;          // div cx

    asm 163; asm 48; asm 193;  // mov [&div_result], ax
}

void main()
{
    div_a = 35500; div_b = 113; div();
    print_num = div_result; print_u16(); // «314»
}

Оставить комментарий

Писательская мозоль

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

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

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

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

В этой связи вопрос — у современных детей эта мозоль образовывается? Я что-то не обращал внимания. Может они письмо изучают как историческую данность и уже печатают все или, может, теперь в школах учат брать ручку «щепоткой»?

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

9 комментариев

Make QR-code great again!

Продолжаем рубрику «все побежали и я побежал».

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

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

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

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

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

Два QR-кода: слева — цифровой, стилизованный под облака и пейзаж; справа — мозаичный, выполненный из цветных плиток в круглой рамке.
Это работающие куар-коды, ведущие на мой сайт

Оставить комментарий

return в SectorC

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

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

Второе реализовать совсем просто, тут мне помогает некогда богатый опыт программирования на Ассемблерах. SectorC транслируется напрямую в машинный код, а значит адреса возвратов из функций хранятся на стеке. Так что надо всего лишь удалить верхний адрес возврата и мы вернёмся не в функцию, которая нас вызвала, а на уровень выше. Я делаю это командой pop ax.

Теперь посмотрим на первую задачу.

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

Напрашивается следующая реализация, — перед вызовом присваиваем возвращаемую переменную самой себе, в функции return() записываем содержимое AX в какую-нибудь переменную (я выбрал return) и возвращаемся.

Моя реализация вместе с примером использования ниже:

void return()
{
    // mov [&return], ax
    asm 163; asm 236; asm 229;
    // pop ax (clear stack from prev return address)
    asm 88;
}

void random()
{
    // xor ax, ax    int 0x1A         xchg ax, dx
    asm 49; asm 192; asm 205; asm 26; asm 146;
    // xor dx, dx    mov cx, 10
    asm 49; asm 210; asm 185; asm 10; asm 0;
    // div cx         inc dx  xchg ax, dx
    asm 247; asm 241; asm 66; asm 146;
    return();
}

void function()
{
    i = 0; while( i < 20 ){
        random();
        if( i >  return ){
            i = i; return();
        }
        i = i + 1;
    }

    i = 0; return();
}

void main()
{
    function();
    print_num = return; print_u16();
}

Кстати, возникает любопытный сторонний эффект — так как через AX делается не только присваивание, а вообще все операции, то функция return() захватывает любое последнее вычисленное выражение, что тоже может быть удобно.

Оставить комментарий

Дефицит внимания к сериалу

Какая-то ерунда у меня творится во время просмотра сериалов на ноуте — всё время хочется выйти из полноэкранного режима и посмотреть параллельно что-нибудь ещё — вдруг в «телегу» кто-нибудь написал или статья на «Хабре» новая вышла. Это что за расстройство внимания такое?

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

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

Не понимаю.

12 комментариев

Деревянный сердечник

Стопки красных папок с надписью «ВЫПУСКНАЯ КВАЛИФИКАЦИОННАЯ РАБОТА» на светлом столе, рядом ручка и лист с таблицей; на заднем плане — два чёрных стула.

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

Который год являюсь членом государственной экзаменационной комиссии на двух кафедрах ИВМиИТ КФУ (бывший факультет ВМК) и всё это время меня не могу отделаться от ощущения, что многие студенты руководствуются правилом «всё равно это никто не будет читать».

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

Ещё проблем доставляет мода на тёмные темы оформления — скриншоты с кодом теперь на бумаге выглядят как тёмно-серые буквы на чёрном фоне. Учитывая, что комиссия из-за проектора сидит в полумраке, глаза сломаешь такое читать.

Это 100% никто читать не будет, — просто потому, что прочесть это невозможно.

6 комментариев

Шур-шур-шур

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

Есть тут собачники? У кого-нибудь ещё так же? Как боретесь? Я уже смотрю в сторону каких-нибудь резиновых накладок на когти, если такие существуют.

6 комментариев

Законник

— Да. Я, конечно, не юрист, но…
— Этот вопрос решают не законники, а психологи. Теперь вся тяжесть проблемы легла на плечи Маллина, и он хорошо это понимал.

— «Маленький пушистик», Бим Пайпер, «Полярис», 1997

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

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

5 комментариев

Дорогою бобра

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

Ева выступила дважды — сначала сольно спела песню «Лесной олень» (ей она очень нравится), а после в общем хоре — «Дорогою добра».

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

Оставить комментарий

Фамильные вещи

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

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

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

У жены ситуацию чуть получше — сохранился патефон деда, а у бабушки хранится икона, которая когда-то досталась ей от её бабушки.

Тесть ещё как-то рассказывал, что в сундуке его бабушки лежали какие-то фотографии на стеклянных пластинах, «тонких, как лист бумаги», но куда всё делось он не знает.

Сложно сказать откуда во мне любовь к старинным предметам, но наверное, раз существуют музеи, я не один такой. Кажется, если бы я работал сотрудником с допуском к запасниками Национального музея, не вылезал бы оттуда месяцами, — говорят запасники там огромные!

2 комментария

Простейший HTTP-прокси

У Романа Парпалака прочитал про «простейший HTTP-прокси». Ну нет, действительно простейший HTTP-прокси как-то я изобрёл, когда надо было обновить сервер у одного из заказчиков, а там интернета не было. Я тогда запустил этот прокси у себя и прокинул соединение к себе через SSH-туннель.

Выглядит он так:

<?php readfile($_SERVER["REQUEST_URI"]);

Запускается так:

php -S 127.0.0.1:8080 proxy.php

А вот так работает:

Скриншот терминала: PHP-сервер на localhost:8080, curl-запрос к lib.ru с конвертацией koi8-r, вывод с HTML-заголовком «Lib.Ru: Библиотека Максима Мошкова».

4 комментария

Ещё о печати строк в SectorC (лонгрид)

Недавно познакомился с интересным компилятором подмножества языка Си — SectorC. Он интересен тем, что влезает в один сектор (512 байт), но позволяет писать вполне реальные программы. В реализованном языке очень многого нет, тем не менее, это очень интересное достижение и мне было интересно поразбираться как всё сделано. Кстати, результат автора мне удалось в несколько приёмов уменьшить на несколько байт.

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

Для того, чтобы рассказать в чём смысл, надо для начала немного углубиться в то как работает этот компилятор.

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

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

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

Идём дальше.

В языке есть любопытная операция — &, позволяющая получить адрес переменной, который, напомню, равен одновременно хешу (atoi) к её имени. Для однобуквенных имён это позволяет по полученному адресу восстановить код символа — надо поделить полученное значение на два и добавить 48 — код символа 0.

Таким образом, передав в функцию адреса & H, & e, & l, & l, & o, мы сможем восстановить из них символы и составить из них слово Hello. Если записать эти адреса в переменные, которые располагаются в памяти подряд, можно, читая память последовательно, выводить закодированную строку.

Есть ли в языке способ прочитать что-то по адресу? Как ни странно, есть — токен *(int*) позволяющий это сделать.

Теперь всё вышесказанное можно соединить в следующий довольно компактный код:

void print_str()
{
    print_str_pointer = & _0;
    while( *(int*) print_str_pointer ){
        print_ch = ( *(int*) print_str_pointer >> 1 ) + 48; print_char();
        print_str_pointer = print_str_pointer + 2;
    }
}

void main()
{
    _0 = & H; _1 = & e; _2 = & l; _3 = & l; _4 = & o; _5 = 0;
    print_str(); // Hello
}

Оставить комментарий

Фотографии из дома на Маяковского, 26

Три года назад меня как-то приглашали осмотреть дом на Маяковского, 26. Его расселили и собирались реставрировать, а меня пригласили из-за моей тяги к старине, по дружбе.

Мне там удалось найти парочку почти целых газет за обоями, многочисленные кирпичные клейма, сфотографировать старинные обои и обзавестись парочкой интересных фотографий.

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

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

Почерневшая, помятая и потрескавшаяся старинная групповая фотография: много женщин и девушек в одежде начала XX века стоят и сидят в комнате с вышивками на стене.
Фотография без надписей, я надеялся, что есть что-нибудь на обратной стороне, но отогнув аккуратно углы, ничего не увидел
Группа из десяти человек в рабочей одежде, сидящих и стоящих на фоне студии; внизу надпись: «Группа работников закрытый рабочий Кооператив Вахитовец».
«Группа работников. Закрытый рабочий кооператив „Вахитовец“»

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

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

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

Вряд ли удастся что-то выяснить по первому фото, а во второму удалось узнать, что «Вахитовец» просуществовал всего год — в 1935 году, на излёте существования кооперативов такого рода. Они оказались малоэффективными и были упразднены.

Оставить комментарий

Чтение в параллель с размышлением

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

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

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

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

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

2 комментария

Плюсы контрастного душа

Вот уже три месяца каждое утро начинаю с контрастного душа.

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

Мне стало не особо холодно при +15 в одной футболке — в одну прогулку пришлось это узнать на опыте, резко похолодало, а дочка было легко одета, да и последствия переохлаждения на мне уже не так сказываются, — в прошлую поездку на рыбалку был дождь с ветром и довольно прохладно, но на следующий день со мной всё было в порядке. У меня наследственно слабые гланды и раньше я бы легко не отделался.

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

Оставить комментарий

You're welcome

Посмотрел сегодня фильм «Ренфилд», про который слышал, что Николас Коппола вновь в нём хорошо играет. Мне очень нравится этот актёр в своих ранних ролях, поэтому не мог упустить.

Очень классная задумка (не спойлер) — взгляд на вампира и фамильяра через современное представление о созависимых отношениях, — групповая терапия, книжки, попытки преодоления, вот это всё. Я смеялся, но очень жаль, что не посмотрел вместе с женой, — она получила высшее по психологии, практикует и мне нравится с ней делиться такими находками по этой теме.

Коврик у входа с надписью «Welcome! COME ON IN!» на фоне бетонного пола и дверного проёма.
Коврик из фильма «Ренфилд» (2023)

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

Оставить комментарий

Петлевой детектор транспорта

Чудо-чудное, в России, оказывается, уже несколько лет используются петлевые детекторы транспорта, — закопанные под дорожным полотном провода, которые помогают оптимизировать работу светофоров.

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

4 комментария

Бревно с клеймом «ТВЧ»

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

Первое подобное клеймо я увидел в историческом районе Рахматуллина, в 2016-м году, там район заброшек, кажется до сих пор по ним никакого движения, всё стоит в том же состоянии. Фотография того клейма чудом уцелела в краеведческой группе Казани, выложу его тоже попозже.

Там охрана, тогда меня туда разок пустили реставраторы, было очень интересно. Собирался туда как-нибудь ещё раз, но за все эти годы так и не сподобился.

Крупный план торца старого деревянного бревна с видимыми годовыми кольцами, трещинами и царапинами на поверхности.
Бревно с клеймом «ТВЧ», чердак дома на Волкова, 40

Новое клеймо найдено на чердаке дома на Волкова, 40. Дом расселили и нас пустили туда с разрешения нового владельца — глянуть нет ли на чердаке чего-то, что стоит сохранить.

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

Оставить комментарий

← сюда туда →