Как стать автором
Обновить
209.77

Ненормальное программирование *

Извращения с кодом

Сначала показывать
Порог рейтинга
Как можно видеть, строки 5 и 6 используют вдобавок уменьшенный интервал.
Как можно видеть, строки 5 и 6 используют вдобавок уменьшенный интервал.

Была даже абсолютно безумная мысль замутить электронную книжку на таком вот сегментном принципе, но не знаю, что меня больше останавливает: глазоломность шрифта или перспектива паять около 10 000 светодиодов в размере 0402 (или хотя бы 0603).

ЗЫ: добавил «ненормальное программирование» просто потому, что оно напрашивается сначала в эмуляции погонять и оценить степень невыносимости такого шрифта.

Теги:
+12
Комментарии2
Оппа! Не зря мне чудилось, не зря. Что-то глюкнуло и прямо по среди кода ответ на китайском!!!
Оппа! Не зря мне чудилось, не зря. Что-то глюкнуло и прямо по среди кода ответ на китайском!!!

Gork-ушены-ли странности?
Пробуя вайбить Горкушей, обнаружил странные параллели с поведением Синего Кита.

1. "прощупывание пользователя", скобочку там не закрыть, тут инклюд не помянуть, и всё такое-прочее, очевидное и не доставляющее проблем даже джунам, но способное напугать посторонних полотном "ужасных" ошибок ;-)
ДжиПетто вроде подобное тоже вытворяло (не знаю как сейчас), но там на общем фоне остального написанного это выглядело скорее как реальные косяки, а не издёвка...
А вот синий кит, через некоторое время чистого вайба, начинает откровенно жечь!

2. похожие "чудачества в коде", пруф к сожалению привести не могу, он из реальной жизни, и не гуглится, но всё подобное, обычно делается простым и понятным способом, создаётся структура, в которой описывается сколько бит что означает, и вместо разбора пакета, он просто рассматривается через эту структуру и вообще удобненько. Gorkуше был предоставлен пример кода, в котором именно так всё было сделано, и он этим даже воспользовался пару раз, но потом, таки переписал, устроив программный разбор пакета битовыми операциями, и конечно-же криво на столько, что ошибки самостоятельно исправить был уже не в силах, ни за сколько итераций. Что самое поразительное, абсолютно аналогичное поведения я наблюдал у Синего Кита несколько дней назад, вот прямо такой-же код, и такой-же косячный. Логично предположить что он был откуда-то сдёрнут, но нет, ничего подобного не гуглится, да и вообще может-ли такой изврат человеку в голову придти?

3. Я люблю Кита за сравнительную трезвость, позволяющую куда-то его запрягать даже по делу, у Горкуши с этим к стати хуже но, тупят они поразительно похожим образом.
Давеча попросил сделать демона общающегося с железом и что-то шарящего в мемори для других процессов. Read only вестимо, об этом было прямо сказано в промпте, но эти "двое из ларца" мьютиксов туда намутили, поразительно похожим образом!
И ладно-бы это был-бы какой-то пример из книжки переписанный на 100500 сайтах, но нет, там и косяки одинаковые, и по поводу мьютиксов на каждом заборе популярно написано, что в таких ситуациях "скрипач не нужен, родной"...

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

Я начал мучить Горкушу ещё в X использовал преимущественно для самери поиска, а тут он вдруг резко так поумнел перед открытием, демонстрируя сходное с синим китом поведение, вот прямо в деталях. Так что не знаю прямо что и думать ;-)

PS. Протестировал профессионального Джимми 2.5, и кое-что из грядущего, слава Богам! Он действительно с виду более профессиональный НО, без образца проблему не решает, хотя это и ожидаемо, там где осмысленная архитектурная многоходовочка требуется...
...но в отличии от от Кита и Горкуши, Джимми дали мне ссылку на ту отраву, которой они все походу обожрались. Ok это отрава, бывает, но непонятно всё-же, с какого, если в сети есть большое количество годных примеров, берётся один, но гадкий? И как-же так вышло, что его сожрали все, такие разные ;-)

Теги:
Всего голосов 7: ↑1 и ↓6-5
Комментарии8

Упоротый дизайнер занимается вайб-кодингом

Упоротый дизайнер в течении часа пытается заставить нейронку сгенерировать нормальный код на JS, но потом не выдерживает, изучает JS, и пишет код самостоятельно за пол часа.

Финальный промпт:

Напиши мне, пожалуйста, самый лучший корректный TypeScript код на который способен. Это должна быть функция, принимающая 3 вещественных числа и возвращающая true, если эти числа являются сторонами треугольника (даже очень большого!), и false в противном случае. Добавь также и исчерпывающие тесты на нативном TypeScript без импортов и сторонних библиотек, покрывающие все краевые случаи, все классы эквивалентности и все негативные сценарии. Протестируй также и с максимально возможными сторонами. Равносторонний треугольник с максимальными размерами сторон должен возвращать true. Протестируй также погрешность округления для сторон 0.1, 0.2 и 0.3 и учти это в коде функции. Не дублируй тестами статическую типизацию. Код должен работать максимально быстро. Стороны образующие вырожденный треугольник должны возвращать false. Не пиши избыточные бесполезные комментарии. Минимизируй аллокации памяти. Это вопрос жизни и смерти!! Умоляю тебя, сделай всё хорошо! Отформатируй код красиво, со строками не более 100 символов.

Упомянутые питерские митапы:

https://t.me/PiterJS - для JS-еров

https://t.me/PiterUX - для дизайнеров

Теги:
Всего голосов 6: ↑5 и ↓1+5
Комментарии3

Частично переписал рейкаст по Брезенхему-Доку (нет, ну правда, «колесо пред-рассчитанных лучей» от @Swamp_Dokдало прямо роскошный буст к скорости) под чистые 8 бит старого доброго 6502-го.

Всё, как и обещал в камменте: 16 бит в первом приближении как бы не быстрее 8 бит, потому что выковыривать нибблы из байта на процессоре, который даже сместить на 4 бита одной командой не может (надо использовать 4 сдвига на 1 бит) — такое себе, а в этих 16 битах старший и младший байты живут в основном самостоятельными жизнями, довольно редко взаимодействуя в переносе (что ещё больше углубляет мой восторг от гениальности алгоритма «Брезентыча», если это вообще возможно). Я уже мысленно собрал уровни из тех замечательных крошек-чанков 16х16 клеточек и даже продумал, как бы нам хранить в одном байте 4 клетки, чтобы пореже из памяти тянуть (итого 2 бита на клетку — пустота, стенка, первый моб и второй моб из двух возможных на один чанк), да и даже как именно нам связывать такие чанки, как анимировать переходы и т. д, но, судя по всему — не пригодится. Не похоже, чтобы было где хранить данные для повторного использования, не похоже, чтобы можно было быстро вытащить нужные биты.

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

Дам этот кейс скрином, ибо.
Дам этот кейс скрином, ибо.

Координаты игрока мы храним нормальными 16-битными, 8 бит на номер клетки и 8 бит на координаты в ней. Работать с ними мы будем один раз — в рамках физики. Для рейкаста они нужны отдельно в виде старшего байта, отдельно в виде младшего. Три из них мы видим в трёх верхних строчках, где они копируются в координаты луча. Четвёртая — чуть ниже, где BrezToStart вычисляется «по-старинке», там я ещё не изжил пекашный код. Зато смещение мы берём (четвёртая строчка) уже из «колеса», расчётов — ноль!

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

Дальше мы делаем 8-битное сложение. Первая величина — младший байт координаты смещения POS PIX, вторая — (long)BrezToStart*(long)RayDY/RayDX. Её я тоже пока вычисляю явно — но она, несомненно, напрашивается на табличное представление. В результате имеем новый POS PIX и флаг переноса.

Тут, как я уже намекал, мы можем не проверять память, если не было переноса. Ну, и полного 16-битного суммирования не делаем, максимум — инкремент (в отличие от компилятора, мы знаем, какие бывают суммы, а какие — нет).

Проверка памяти требует вычислить довольно длинный адрес. Тут я хочу пойти на грязный хак: возможно, сделать карту [32][256], чтобы ничего не умножать на 64, и старший байт писать прямо в код, в тело инструкции LDA. Кармак в Wolf3D, помнится, раздухарился ещё жёстче… да, хранение переменной прямо в коде, да ещё в 4 разных местах — тоже потребует копирования её туда-сюда. Но после входа в «основной цикл шагания» обратно мы уже не возвращаемся — возможно, я придумаю способ держать её и в коде, и в одном экземпляре. Это позволит проверять карту простым LDA $DEAD, X (где X — вторая координата, которая до 256, а вместо $DEAD мы подкидываем нашу переменную, в case 0 это будет POS CELL, которая меняется от адреса карты до него же плюс 32<<8). Хотя, возможно, через Indirect я это сделаю ещё быстрее! Не попробуешь — не узнаешь, собственно, почему я и «подсел» на эту задачу. Никакие Factorio рядом не валялись :)

Функция AddToZBuffer8Bit тоже демонстративно отрицает 16-битное суммирование — фишка в том, что переносов там не возникает! Поэтому все аргументы вычисляются через 8-битные суммы.

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

Теги:
Всего голосов 4: ↑4 и ↓0+6
Комментарии16

Бинго разработчика: ставь лайк зачеркивай, если было

В выходные не работаем, но развлекаемся, поэтому предлагаем вам сыграть в бинго разработчика! Правила — простые:

  1. сохраняйте/делайте скрин картинки из поста;

  2. отмечайте клеточки с вашей разработческой жизой;

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

Ждем того, кто соберет все ачивки!

А как закончите с бинго — в нашем TG‑канале есть еще одна занимательная игра с кубиком и картами инженерного таро, которые предскажут ваше будущее! Переходите по ссылке и развлекайтесь, на канал тоже подписывайтесь, там часто бывает всякое интересное.

Теги:
Всего голосов 22: ↑21 и ↓1+20
Комментарии1

Я тут опубликовал библиотеку для программирования в парадигме потоков данных (dataflow) на микроконтроллерах: https://github.com/Zubax/ramen

Она чрезвычайно проста (один заголовочный файл) и работает на любой платформе без портирования.

Простейший пример --- сумматор:

               ┌────────┐
       (float) │ Summer │ (float)
 in_a ◄────────┤        │◄──────── out_sum
               │        │
       (float) │        │
 in_b ◄────────┤        │
               └────────┘
struct Summer
{
    ramen::Puller<float> in_a;
    ramen::Puller<float> in_b;
    ramen::Pullable<float> out_sum = [this](float& out) { out = *in_a + *in_b; };
};

Больше примеров, а также объяснение зачем это нужно при наличии альтернатив, по ссылке. Всем спасибо.

Теги:
Всего голосов 5: ↑4 и ↓1+3
Комментарии0
Я отмоделировал на выходных, как должен смотреться «Вольф на Денди».
Я отмоделировал на выходных, как должен смотреться «Вольф на Денди».

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

Досбокс кладёт наглухо — код «буквально-учебно-школьный», оптимизации ровно ноль. Чтобы лучше читалось, ага. Так что если оська в принципе не умеет в DOS16 — будет пошаговая стратегия :(

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

Теги:
Всего голосов 5: ↑5 и ↓0+9
Комментарии22

Очень быстрая графика в Matplotlib (Python). Достигли 2-х кратного ускорения в сравнении с предыдущей версией. Python исходник в моем телеграм

Теги:
Всего голосов 2: ↑1 и ↓1+1
Комментарии1

Хочу поделиться своим максимально ненужным проектом на Python, под названием flexpasm.

Это билдер кода для FASM под Linux. Работает ограниченно, но вроде-бы работает.

Проект, лично для меня, интересный.

Установить эту библиотеку можно через PyPi:

from flexpasm import ASMProgram
from flexpasm.constants import LinuxInterrupts
from flexpasm.instructions.registers import get_registers
from flexpasm.instructions.segments import Label
from flexpasm.mnemonics import IntMnemonic, MovMnemonic, XorMnemonic
from flexpasm.settings import Settings


def main():
    settings = Settings(
        title="Example ASM Program",
        author="alexeev-prog",
        filename="example.asm",
        mode="64",
    )
    asmprogram = ASMProgram(settings, __name__)
    regs = get_registers(settings.mode)

    start_lbl = Label("start")

    start_lbl.add_instruction(MovMnemonic(regs.AX, 4))
    start_lbl.add_instruction(MovMnemonic(regs.CX, "message"))
    start_lbl.add_instruction(MovMnemonic(regs.DX, "message_size"))
    start_lbl.add_instruction(IntMnemonic(LinuxInterrupts.SYSCALL))
    start_lbl.add_instruction(MovMnemonic(regs.AX, 1))
    start_lbl.add_instruction(XorMnemonic(regs.BX, regs.BX))
    start_lbl.add_instruction(IntMnemonic(LinuxInterrupts.SYSCALL))

    asmprogram.add_label(start_lbl)
    asmprogram.main_rws.add_string("message", "Hello, World!")

    asmprogram.save_code()
    # asmprogram.restore_backup()


if __name__ == "__main__":
    main()
$ fasm example.asm example
$ ld example -o example
$ ./example

Hello, World!

А сам код генерируется такой:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Author: alexeev-prog                                                                                               ;;
;; Example ASM Program                                                                                                ;;
;; Program generated by FLEXPASM (github.com/alexeev-pro/flexpasm)                                                    ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

format ELF64 executable 3;                      ; ELF64 EXECUTABLE
entry start                                     ; Set Start Entry


;; Segment readable executable in FASM is a directive for defining a section of code with readable and executable attributes.
segment readable executable

start:                                          ; Label start with 7 commands
    MOV RAX, 4                                      ; Loading 4 value into RAX register.
    MOV RCX, message                                ; Loading message value into RCX register.
    MOV RDX, message_size                           ; Loading message_size value into RDX register.
    INT 128                                         ; Call software interrupt 128: SYSCALL
    MOV RAX, 1                                      ; Loading 1 value into RAX register.
    MOV RBX, RBX                                    ; Exclusive OR operation RBX and RBX using XOR
    INT 128                                         ; Call software interrupt 128: SYSCALL


;; Segment readable writeable in FASM is a definition of a segment of program data codes, where the attributes readable (the contents of the segment can be read) and writeable (program commands can both read codes and change their values) are specified for it.
segment readable writeable

message db 'Hello, World!', 0xA                 ; Var message (string)
message_size = $-message                        ; Var message (string) length

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

github.com/alexeev-prog/flexpasm

Теги:
Всего голосов 5: ↑4 и ↓1+3
Комментарии0

Итак, пятница уже не первый час шагает по глобусу, поэтому держите свеженький выстрел в мозги ;)

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

Разумеется, решение для искусственно самоограниченной задачи, когда ручка движется строго по горизонтали и бумага после каждого прохода подаётся на один диаметр шарика ручки — элементарное. Берём RLE и Флойда-Стейнберга, за 15 минут пишем этот код:

#define	SQUARE(x) ((x)*(x))
#define	MAXERROR 256	//for RLE

static unsigned char Grayscale8Bit[HEIGHT][WIDTH], Dithered8Bit[HEIGHT][WIDTH];
static signed short AdditionalError[2][WIDTH];

тут мы читаем из файла Grayscale8Bit, этот код я приводить не буду

	memset (AdditionalError, 0, 2*WIDTH*sizeof(short));	//Even/odd lines buffer
	for (int y=0; y<HEIGHT; y++)
	{
		int RLEError=0;
		int PenColor = 255*(Grayscale8Bit[y][0]>127);	//Pen color can be either 0 or 255
		for (int x=0; x<WIDTH; x++)
		{
			int PixelValue = (int)Grayscale8Bit[y][x] + AdditionalError[y&1][x];	//Exact pixel value plus Floyd-Steinberg error from the prev. line
			RLEError += SQUARE (PixelValue - PenColor);	//To avoid missing contrast details such as thin vertical lines, RLE error counted as square.
			if (RLEError > SQUARE (MAXERROR))
			{
				PenColor = 255-PenColor;		//Inverse pen position (up/down)
				RLEError = SQUARE (PixelValue - PenColor);	//Begin counting new RLE error immediately
			}
			Dithered8Bit[y][x]=PenColor;		//Put proper color into the output array
			AdditionalError[!(y&1)][x] = (PixelValue - PenColor)/2;		//Put remaining error into next line buffer, not exactly Floyd-Steinberg but sort of.
			if (x) AdditionalError[!(y&1)][x-1] = (PixelValue - PenColor)/4;
			if (x<WIDTH-1) AdditionalError[!(y&1)][x+1] = (PixelValue - PenColor)/4;
		}
	}

тут мы пишем в файл Dithered8Bit, этот код тоже у каждого свой получится

Код без каких-либо капризов, отладки и подбора параметров сразу выдаёт результат:

Сверху, как нетрудно догадаться, оригинал.
Сверху, как нетрудно догадаться, оригинал.

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

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

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

Теги:
Всего голосов 3: ↑3 и ↓0+5
Комментарии3

Необычное! Исходник прототипа игры Пинг-Понг на MatPlotLib (научная графика на python) с высоким FPS .

Ранее в моей >>статье на Хабр было рассмотрено применение PyGame для построения графиков, а теперь, наоборот, делаем игру на системе построения научных графиков. В предыдущей версии при попытке вывода текста с высоким FPS возникали сильные "тормоза", В текущей версии эта проблема решена.

В коде для отрисовки всех элементов игры используются только объекты MatPlotLib: теннисные ракетки - это столбцовые диаграммы, мячик - это scatter диаграмма, само игровое поле - это объект figure из MatPlotLib, текст также выводится через встроенные в MatPlotLib функции. Для анимации используется встроенный в MatPlotLib объект Animation + update(). FPS=40 (сорок!).

P.S. желтая столбцовая диаграмма - это распределение координат по оси Y, в которых ракетка отбивает мячик. Обновляется при каждом ударе ракеткой по мячику.

Теги:
Всего голосов 5: ↑3 и ↓2+2
Комментарии1

Энтузиасты запустили Doom с помощью типов TypeScript.

Проект запуска Doom исключительно в системе ввода TypeScript занял 12 дней по 18 часов в сутки. Разработчики провели проверку 3,5 триллиона строк текста, создали виртуальную машину WebAssembly на основе TypeScript и 177 ТБ типов TypeScript.

Теги:
Всего голосов 2: ↑2 и ↓0+4
Комментарии2

Ближайшие события

Ещё раз о количестве способов набрать сдачу в n рублей из заданного набора монет/купюр

 Вот известная задача: «Имеется неограниченное количество монет достоинством 1, 2, 5 и 10 рублей. Определить, сколькими способами можно ими выдать сдачу в n рублей».

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

Возможно, эта идея будет полезна в других задачах.

Итак.

При n = 7 все варианты следующие:

1 + 1 + 1 + 1 + 1 + 1 + 1

1 + 1 + 1 + 1 + 1 + 2

1 + 1 + 1 + 2 + 2

1 + 2 + 2 + 2

1 + 1 + 5

2 + 5

 Среди них можно выделить те, в которых минимальным слагаемым является 1. Их – 5. В оставшемся шестом варианте минимальным слагаемым является 2. Вариантов, в которых минимальным слагаемым является 5 и 10, в данном случае нет.

При n = 10 все варианты следующие (без знака +):

1111111111, 111111112, 11111122, 1111222, 112222, 111115, 11125, 1225, 22222, 55, 10,

то есть

количество вариантов с минимальным слагаемым 1 равно 8;

количество вариантов с минимальным слагаемым 2 равно 1;

количество вариантов с минимальным слагаемым 5 равно 1;

количество вариантов с минимальным слагаемым 10 равно 1.

 Подумав (😊), можем сказать, что при n = 11:

· количество вариантов с минимальным слагаемым 1 будет таким же, как общее число всех вариантов для n = 10 (так как разность 11 – 10 не превышает 1);

· количество вариантов с минимальным слагаемым 2 будет равно сумме количеств с минимальными слагаемыми 2, 5 и 10 для n = 9 (так как разность 11 – 9 не превышает 2);

· количество вариантов с минимальным слагаемым 5 будет равно сумме количеств с минимальными слагаемыми 5 и 10 для n = 6  (так как разность 11 – 6 не превышает 5);

· количество вариантов с минимальным слагаемым 10 будет равно такому же количеству для n = 1 (так как разность 11 – 1 не превышает 10).

 Приведённые рекуррентные зависимости применимы для всех значений n, но с некоторыми исключениями – при n = 1 количество вариантов с минимальным слагаемым 1, при n = 2 количество вариантов с минимальным слагаемым 2, при n = 5 количество вариантов с минимальным слагаемым 5 и при n = 10 количество вариантов с минимальным слагаемым 10 будет равно 1 (в перечисленных случаях соответствующие слагаемые появляются впервые).

Допустим, что максимальное значение n равно 99.

В программе, реализующей описанную идею для такого случая, можно использовать двумерный массив из 109 строк и пяти столбцов (10 начальных строк массива являются условными для рекуррентного расчёта значений при n = 1..99).

Вся программа на так называемом «школьном алгоритмическом языке» (система программирования КуМир):

алг
нач цел таб м[-9:99, 1:5], цел n, j
  | Нули, в том числе в фиктивных строках   

нц для n от -9 до 99
    нц для j от 1 до 5
      м[n, j] := 0
    кц
  кц

  | Расчёты
  нц для n от 1 до 99
    если n = 1
      то
        м[n, 1] := 1
      иначе | Рекуррентная зависимость
        м[n, 1] := м[n - 1, 5]
    все
    если n = 2
      то
        м[n, 2] := 1       иначе
        м[n, 2] := м[n - 2, 2] + м[n - 2, 3] + м[n - 2, 4]
    все
    если n = 5
      то
        м[n, 3] := 1
      иначе
        м[n, 3] := м[n - 5, 3] + м[n - 5, 4]
    все
    если n = 10
      то
        м[n, 4] := 1
      иначе
        м[n, 4] := м[n - 10, 4]
    все
    | Последний столбец
    м[n, 5] := м[n, 1] + м[n, 2] + м[n, 3] + м[n, 4]    
  кц
  | Вывод всех значений
  нц для n от 1 до 99
    вывод нс, n, " | ", м[n, 5]
  кц
кон

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

 Спасибо.

Теги:
Всего голосов 3: ↑2 и ↓1+2
Комментарии2

«Пушим байты» в сугробы: новогодняя демосцена 2025

Признанная классика демосцены — PICO-8, в арсенале которой сотни игр разной сложности. Мы же пойдем более оригинальным путем и напишем новогоднюю демку для BytePusher. Эта приставка включает 8-битный процессор, предлагает разрешение 256x256 и 8-битный цвет. Но самое интересное в ней — это OISC-архитектура ByteByeJump (BBJ).

OISC, One-Instruction Set Computer, известна гораздо меньше, чем RISC или CISC. Ее простота, очевидная из названия, привлекает немного энтузиастов, судя по странице BytePusher. Тем интересней будет сделать что-нибудь для нее с нуля.

Этим и занялся в своей статье Пётр Советов, специалист в области разработки DSL-компиляторов и старший научный сотрудник лаборатории специализированных вычислительных систем РТУ МИРЭА. Написал ассемблер на Python, разобрался с вычислениями без АЛУ и «отрисовал» классическое демо с падающим снегом. Еще и со «звездочкой» в виде сугробов и статичных цифр.

Читать полное руководство →

Теги:
Всего голосов 3: ↑3 и ↓0+3
Комментарии0

Привет, часто в скриптах встречаю бесполезное использование кавычек, вот такое вот:

var_b="$var_a"
var_c="$(...)"

Понятно с какой целью это делается, типа вдруг дам пробелы и оно сломается, давайте посмотрим сломается или нет:

$ echo $var_a
1 2

$ var_b=$var_a
$ echo $var_b
1 2

$ var_c=$(echo 3 4)
$ echo $var_c
3 4

Вроде не сломалось и без кавычек все прекрасно уместилось в переменные.
Кавычки нужны только для "склеивания" данных или переменных:

$ var_a="1 2"
$ echo $var_a
1 2

#а без кавычек:
$ var_a=1 2
2: команда не найдена

#и с переменными:
var_a="$var_b $var_c"

#без кавычек:
$ var_a=$var_b $var_c
3: команда не найдена

Творите, выдумывайте, пробуйте!)

Теги:
Всего голосов 2: ↑1 и ↓10
Комментарии4

Чебурашка

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

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

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

Пересылать фото банкомата в секретных чатах? Это не путь настоящего обнальщика.

Схема такая: Сервер для обмена видео по RSTP + Фельдману и Шило по Android телефону, где отправителю денег предаётся видео через эмулирование камеры с камеры получателя.

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

MVP проекта (вход рубль - выход десять лет по 7 части статьи 159 УК РФ)

Теги:
Всего голосов 6: ↑4 и ↓2+5
Комментарии1

В одной из недавних статей узнал про сайт HighLoad.fun, было интересно решить несколько задач и забраться в лидеры. Если кто-то любит highload задачи, то зову принять участие. Общался с автором проекта HL в телеграме - отзывчивый добродушный человек, планируется версия сервера 2.0 с новыми плюшками. Может и выглядит как реклама, но моя заинтересованность чисто спортивная, я решаю такие задачи сколько себя помню, это как кроссворды для меня, а без конкуренции нет желания улучшать результат. В секции C++ конечно соревновательный дух активнее, но я пишу на C# и там результатов не так много.

Теги:
Всего голосов 2: ↑2 и ↓0+3
Комментарии5

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

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

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

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

Которые, возможно,модсостав одобрит для всех.

Теги:
Всего голосов 2: ↑2 и ↓0+2
Комментарии13

Тестировал всякое для ATARI XL/XE и написал небольшую демку в 106 Байт.

Чтобы понимать куда именно смотреть - тут экран 48х24, то есть 1152 байта, но в ОЗУ весь экран представлен всего 48 байтами, еще 78 байт (кто захочет посчитать 48+78=126, тут просто кодом реализованы однотипные строки) для программирования видеочипа, которому объяснено, что каждая строка на экране смотрит на одну и ту же часть ОЗУ, так мы заполняем весь экран. Для получения нестандартного узора используется 8 байт и перепрограммирование таблицы символов. Рисунок изначально подбирается так чтобы формировался равномерный узор. Для плавности движения используется VSYNC, анимация реализована битовым сдвигом.

.include "atari.asm"
    *= $3000
	lda #48
?copy
	sta screen-1, y
	dey
	bpl ?copy
;	ldy #$00
	iny
?copydl
	lda #$42
	sta dlist2, y
	iny
	lda #<screen
	sta dlist2, y
	iny
	lda #>screen
	sta dlist2, y
	iny
	cpy #72
	bne ?copydl
	lda #>font_data
	sta CHBAS
	lda #$23
	sta SDMCTL
	lda #<dlist
	sta SDLSTL
	lda #>dlist
	sta SDLSTL+1
?main
	ldx #1
?start
	lda RTCLOK+2
?wait
	cmp RTCLOK+2
	beq ?wait
	dex
	bpl ?start
?ring
    lda font_data, x
	asl
	adc #00
	sta font_data, x
	inx
	cpx #08
	bne ?ring
	beq ?main
dlist
	.byte $70, $70, $70
dlist2
	*= dlist2+72
	.byte $41, <dlist, >dlist
screen
	*= $7400
font_data
	.byte ~11000011
	.byte ~10011001
	.byte ~00100100
	.byte ~01000010
	.byte ~01000010
	.byte ~00100100
	.byte ~10011001
	.byte ~11000011

upd: -1 байт от @vadimr

upd: -1

Теги:
Всего голосов 14: ↑14 и ↓0+17
Комментарии1
1