rust

Brainfuck в шрифте

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

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

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

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

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

Интернет-время «Своч»

Интересно насколько по-разному люди записывают время. Если я пишу от руки, предпочитаю писать минуты в верхнем индексе — «8³⁵». Более свежие люди так не делают, пишут «8:35» или, гораздо реже, «8.35».swatch internet time

Последняя форма записи подтолкнула мои размышления к тому, какой у нас, в сущности, странный способ измерения времени.

«8.35» похоже на десятичную дробь, но на самом деле основание дробной части тут — 60, а у целой — 12 или 24, в зависимости от обстоятельств. Наверняка все об этом думают время от времени.

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

Серебристый с чёрными вставками пейджер Ericsson с антенной, на экране которого отображается текст «WORLD @618», значок сигнала и заряда батареи.
Интернет-время на экране телефона Ericsson T20e

Швейцарская компания «Своч» (Swatch) занимается наручными часами. Не знаю как у неё сейчас с известностью, а конце 90-х—начале 2000-х, у нас в стране она была очень узнаваемой, думаю, как и во всём мире.

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

Идея была в том, чтобы разделить сутки на тысячу «битов» — от нуля до 999, каждый «бит» (beat) равнялся 86,4 секунды, при этом отсчёт начинался с часового пояса UTC+01:00.

Время записывалось, начиная с символа «@» (он тогда прочно ассоциировался с интернетом) и добивалось нулями до трёх разрядов. Например: «@007», «@013» и так далее.

Вот небольшая программа на «Расте» для вывода текущего времени в этом формате:

use chrono::{Utc, Timelike, Duration as D};
use std::thread;
use std::time::Duration;

fn main() {
    const SECS_IN_BEAT: f64 = 86.4;

    loop {
        let seconds = (Utc::now() + D::hours(1)).num_seconds_from_midnight() as f64;
        let beat = (seconds / SECS_IN_BEAT).floor();

        print!("🕰️ @{}\n\x1b[A\x1b[G", format!("{:03}", beat));

        let duration = (1. + beat) * SECS_IN_BEAT - seconds;
        thread::sleep(Duration::from_secs_f64(duration));
    }
}

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

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

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

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

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

WASM в шрифтах

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

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

В общем, в шрифтах появился свой язык программирования.

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

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

Скриншот программы FontGoggles: в поле ввода текст «BOLK», ниже отображён шрифт Morse-Regular.ttf, где буквы закодированы точками и тире азбуки Морзе.
Азбука Морзе отрисовывается через ВебАссемблер (WASM)

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

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

Файл, состоящий из нулей

Аниме-персонаж в очках с удивлённым лицом протягивает руку к жёлтой бабочке с цифрой 0, спрашивая: «Is this a zero?
Если вы не понимаете, что тут делает эта картинка, не пугайтесь, это мем, их развелось столько, что обо всех и не узнаешь

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

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

В общем, попробовал написать нужную утилиту на «Расте», если кто его вдруг знает, покритикуйте, кода там совсем немного.

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

99 бутылок: Rust

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

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

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

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

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

// Beer song. Evgeny Stepanischev, 2018
fn bottles(beer: u8) -> String {
    match beer {
    	0 => "no bottles".to_string(),
    	1 => "1 bottle".to_string(),
    	_ => format!("{} bottles", beer)
    }
}

fn main() {
	let mut beer = 99;
	while beer > 0 {
	    println!("{} of beer on the wall, {0} of beer.", bottles(beer));
	    beer -= 1;
	    println!("Take one down and pass it around, {} of beer on the wall.\n", bottles(beer));
	}

	println!("No more bottles of beer on the wall, no more bottles of beer.");
	println!("Go to the store and buy some more, 99 bottles of beer on the wall.");
}

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