LINUX.ORG.RU

Вышло издание 2,92 книги «Программирование: введение в профессию» А. В. Столярова

 , , ,

Вышло издание 2,92 книги «Программирование: введение в профессию» А. В. Столярова

4

5

Тихо и незаметно 30 апреля 2026 года вышло издание 2.92, которое наконец включает в себя читаемый текстовый слой.

Исправлены опечатки и ошибки, обнаруженные в предыдущих изданиях, в частности 2.91 (где введена кликабельная навигация) и 2.9 (первое чисто электронное издание).

Книга предназначена для самообучения основам программирования и в отличии от многих других изданий предполагает фундаментальный подход — вначале основы дискретной математики и использования GNU/Linux или BSD с командной строкой, затем паскаль, потом ассемблер и только потом Си, системное программирование и альтернативные парадигмы (функциональное, логическое и так далее).

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

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

>>> Ссылка на страницу издания

>>> Альтернативные способы скачивания

>>> Новость на сайте автора

★★★★★

Проверено: dataman ()
Последнее исправление: CrX (всего исправлений: 10)
Ответ на: комментарий от algo

Ну да, fpc-3.2.2.win32.and.win64.exe 93.9 MB жирновато, но это не 10 гигабайт MS Visual Studio, а в сотню раз меньше. И при этом гораздо удобнее и проще. А как редактор можно взять какой-нибудь порт gvim или на худой конец geanie.

Xenius ★★★★★
() автор топика
Ответ на: комментарий от algo

SystemD ненужон. Можно Alpine Linux поставить если тебе место важно. На гигабайтную флешку влезет и FPC и ОС и редактор и место останется под программы.

Xenius ★★★★★
() автор топика
Ответ на: комментарий от algo

А Linux с дистрами что ли нужон?

Если ты не хочешь любоваться на синий экран BIOS Setup, нужен. Альтернатив линуксу как бы и нет или они сильно нишевые/экспериментальные (BSD, OpenSolaris, Haiku и тд)

Xenius ★★★★★
() автор топика
Ответ на: комментарий от Xenius

Если гигабайтный дистро может запуститься без постороннего, то 100-мегабайтный FreePsscal тем более сможет

algo
()
Ответ на: комментарий от Xenius

Я думаешь наизусть все его аргументы помню?

Конечно помнишь, ты ж сектант. Собственно, ты и нашел. Давай посмотрим:

С технической точки зрения до введения VLA имя локальной переменной при трансляции в объектный код естественным образом превращалось в константное смещение относительно стекового фрейма. После введения VLA имя локальной переменной может превратиться в выражение произвольной сложности, в том числе такое, промежуточные результаты которого не поместятся в регистрах. Как следствие, Си при наличии ЭТОГО перестаёт быть низкоуровневым языком, т.е. заменителем ассемблера; но Си ни в каком другом качестве не нужен

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

Но кстати в той же MS Visual C 6.0 не поддерживается C99, так что вот тебе аргумент не от Столярова, а от его противоположности.

Здесь вообще никакого аргумента нет. Хлам от МС вышел в 1998 году, а стандарт C99 был принят в 2000 году.

И я еще раз повторю свой вопрос, который ты проигнорировал:

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

Ну?

liksys ★★★★
()
Ответ на: комментарий от Xenius

SystemD ненужон.

Мамкиному админу локалхоста, может, и не нужен. А вот строителям десктопных и серверных систем - очень даже нужен.

liksys ★★★★
()
Ответ на: комментарий от liksys

А паскалевским хелловордшикам не нужон не только системд

algo
()
Ответ на: комментарий от bloody_enterprise

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

Расскажи кстати, какая у тебя среда? Надеюсь нормальный fpc под GNU/Linux, а не какой-нибудь ABC, который вообще не паскаль, просто так называется?

Задание 5.5. Ввести четырехзначное целое число и определить, является ли оно палиндромом (например, числа 6666 и 3223). Для выделения разрядов числа используются операции div и mod.

Program palindrome;
Uses math;
Const base = 10;
Var n, m, a, b, c, d: integer;
Begin
	write('Enter 4-digit whole number: ');
	readln(n);
	if (n < base**3) or (n > base**4) then begin
		writeln('Error: ', n, ' is not a 4-digit number.');
		halt(1)
	end;
	m:=n;
	d:=m mod base;
	m:=m div base;
	c:=m mod base;
	m:=m div base;
	b:=m mod base;
	m:=m div base;
	a:=m mod base;
	m:=m div base;
	if (a=d) and (b=c) then
		writeln(n, ' is a palindrome!')
	else
		writeln(n, ' is not a palindrome, sorry.')
End.

А с этим разобрался? Тут желательно массив и цикл взять, конечно. Интересно @liksys опять скажет, что говнокод?

Задание 5.6. Ввести три числа A, B, C. Если ни одно из чисел не равно нулю, то в переменную K записать среднее арифметическое трех чисел.

Тут наверное тип Real. Только там небольшая засада с точным равенством. И как проверять переменную K? Отладчиком пользоваться? В задании не сказано его вывести.

Задание 5.7. Ввести значение X и, используя график функции, определить значение Y. Требуется заполнить блок-схему алгоритма.

Program piecewise_function;
Uses math;
Var x, y: real;
Begin
	readln(x);
	if x <= -1 then
		y := -2
	else if x <= 2 then
		y := x-1
	else
		y := (x-2)**2 + 1;
	writeln(y:1:4);
End.

Лучше конечно так в данном случае:

Program piecewise_function;
Uses math;

function f(x: real): real;
begin
	if x <= -1 then
		f := -2
	else if x <= 2 then
		f := x-1
	else
		f := (x-2)**2 + 1;
end;

Var x, y: real;
Begin
	readln(x);
	y := f(x);
	writeln(y:1:4);
End.
Xenius ★★★★★
() автор топика
Ответ на: комментарий от Xenius

А с этим разобрался? Тут желательно массив и цикл взять, конечно. Интересно @liksys опять скажет, что говнокод?

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

int number;

scanf("%d", &number);
if (number < 1000 || number > 9999) {
    puts("Yobu dal");
    return;
}

int left = number / 100;
int right = number % 100;
int mirror_right = (right / 10 + (right % 10) * 10);

if (left == mirror_right) {
    puts("Yes");
} else {
    puts("No");
}

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

liksys ★★★★
()
Последнее исправление: liksys (всего исправлений: 2)
Ответ на: комментарий от liksys

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

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

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

Qui-Gon ★★★★★
()
Ответ на: комментарий от Qui-Gon

посмотреть на скорость и ужор ресурсов

Его 4 операции деления против 8 выше. Остальное - стат.погрешность.

SkyMaverick ★★★★★
()
Последнее исправление: SkyMaverick (всего исправлений: 3)
Ответ на: комментарий от Qui-Gon

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

К слову, у него еще и проверка входных значений неправильная. Условие (n < base**3) or (n > base**4) не сработает на ввод 10000. И на кой хрен там нужно возведение в степень (у меня в посте описка - я там обозвал это делением) - вообще не понятно.

liksys ★★★★
()
Ответ на: комментарий от liksys

Проверка на число разрядов выглядит как полная срань.

Ага, и написал точно такую же. Хотя да, надо было n >= base**4, тут я ошибся.

int mirror_right = (right / 10 + (right % 10) * 10);

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

Операции деления по модулю там не нужны.

Ага, и сам же используешь операцию деления по модулю. / % — это что такое по-твоему? Это и есть аналоги паскалевских div и mod.

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

И на кой хрен там нужно возведение в степень (у меня в посте описка - я там обозвал это делением) - вообще не понятно.

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

$ ./ushakov5.4-palindrome
Enter 4-digit whole number: 0x9F8
2552 is a palindrome!

Вот например по умолчанию десятичная система. А если base сделать не константой можно например перебирать основания и находить числа которые являются палиндромами в n-ричной системе.

Xenius ★★★★★
() автор топика
Последнее исправление: Xenius (всего исправлений: 3)
Ответ на: комментарий от Xenius

Ага, и написал точно такую же

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

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

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

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

Если нужен будет строго восьмизначный - то примерно то же можно и написать. Если переменной длины - то с циклом с перебором меньше половины.

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

В условиях задачи этого нет. Ты усложнил код на ровном месте.

И я всё еще жду ответ на вопрос, который ты старательно игнорируешь:

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

liksys ★★★★
()
Последнее исправление: liksys (всего исправлений: 1)
Ответ на: комментарий от liksys

И я всё еще жду ответ на вопрос, который ты старательно игнорируешь

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

достаточно разобрать половину.

А потом собрать обратно. Экономия сомнительная. Последние две строки вычислений, кстати, в моей программе не нужны, поскольку m уже однозначное и можно было присваивать сразу цифре a. В итоге операций, если считать и деления и умножения будет поровну примерно. Но однотипные операции понятнее разнотипных.

Ты усложнил код на ровном месте.

Ну можно было 10, 1000 и 10000 вынести в отдельные константы.

потому что имена переменных должны быть говорящими.

Это если код длинный и переменные используются далеко от того места, где объявлены. Чем твой number лучше простого n?

Кроме того, ты сам себя запутал и в итоге написал некорректное условие.

Вовсе не поэтому. У меня изначально было 10000 написано и только потом я исправил на base**4.

Xenius ★★★★★
() автор топика
Последнее исправление: Xenius (всего исправлений: 1)
Ответ на: комментарий от Xenius

Потому что вопрос некорректный

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

А потом собрать обратно. Экономия сомнительная.

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

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

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

Чем твой number лучше простого n?

Тем, что нельзя перепутать его с m.

Вовсе не поэтому. У меня изначально было 10000 написано и только потом я исправил на base**4.

То есть, ты внес сложности в код еще до того, как убедился, что он работает.

liksys ★★★★
()
Последнее исправление: liksys (всего исправлений: 2)
Ответ на: комментарий от liksys

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

Тогда почему в математике и физике формулы пишутся через однобуквенные переменные. F=ma, а не Force = mass × acceleration, но это ладно, ещё удобоваримо. А ты попробуй «говорящими именами» уравнение Эйнштейна или Шрёдингера записать.

Или x²+5x-14=0 почему-то пишут, а не unknown_variable × unknown_variable + 5 × unknown_variable - 14 = 0

Странно, да?

Для машины - быстрее

Не исключено, но это важно только в цикле на 100500 итераций, да и то не факт.

и код мой - короче и проще для чтения.

А вот с проще для чтения — нет. На формуле (right / 10 + (right % 10) * 10) спотыкаешься и думаешь что тут происходит. Ну и напиши-ка такую же формулу для трёх или пяти цифр.

Тебе показывают, как надо писать

Кому надо?

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

Где объективно — да, = пропустил после > не ухожу. А по остальному — это не «объективно», а лично твоё мнение.

Xenius ★★★★★
() автор топика
Последнее исправление: Xenius (всего исправлений: 2)
Ответ на: комментарий от Xenius

Тогда почему в математике и физике

Это не физика и не математика, это программирование, причем прикладное. Совершенно отдельная дисциплина.

А вот с проще для чтения — нет.

Проще, проще.

Ну и напиши-ка такую же формулу для трёх или пяти цифр.

Я тут либо цикл заиспользую, либо макросы.

liksys ★★★★
()
Ответ на: комментарий от Xenius

Или x²+5x-14=0 почему-то пишут

Потому что математики ленивые. И учат, как надо лениться, своих учеников.

algo
()
Ответ на: комментарий от Xenius

Тогда почему в математике и физике формулы пишутся через однобуквенные переменные.

Им не приходится шерстить MLOC+ sources на предмет «а где оно используется». Это наверное главная причина использовать «достаточно-уникальные» имена. Ну, и попробуйте разобраться что код делает глядя на него после обфускации - тоже довольно поучительно.

bugfixer ★★★★★
()
Ответ на: комментарий от Xenius

Тогда почему в математике и физике формулы пишутся через однобуквенные переменные.

На это есть разные причины. Основная — так исторически сложилось.

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

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

Так вот, в достаточно простой программе можно как и в физике с математикой обозначить, скажем, координаты на экране привычными x и y, цвет пикселя, например z, а итератор в цикле i — и будет норм. Если к ним добавить какой-нибудь счётчик c и состояния a и b, тоже будет вполне терпимо и понятно. Для совсем простых программ это годится. Но когда у тебя десятки объектов с сотней полей, десятки функций, каждая принимает по несколько аргументов, то этот путь ведёт в совершенно определённую точку — к головной боли — только запутаешься окончательно и всё. Вот тут на помощь и приходят осмысленные имена переменных. Дело ведь не в количестве символов в имени, а в его осмысленности, понятности с первого взгляда. Просто в физике для осмысленности может хватать и одной буквы, а в компьютерной программе, если она не примитивная — не может. Кстати, в областях науки, изучающих значительно более сложные системы, чем физика, одиночными буквами обычно ничего не обозначают — даже в химии на элементы букв не хватает, и они обозначаются то одной то двумя буквами, а в какой-нибудь, скажем, биологии, уже никаких однобуквенных обозначений нет, латынь сплошная длинная.

CrX ★★★★★
()
Последнее исправление: CrX (всего исправлений: 1)
Ответ на: комментарий от liksys

Я тут либо цикл заиспользую, либо макросы.

Ну напиши. Мне почему-то кажется, что это будет нечитаемо.

Xenius ★★★★★
() автор топика
Ответ на: комментарий от Xenius

Разверну мысль вдобавок ко всему вышесказанному. Проблема однобуквенных переменных в том, что из легко спутать между собой замыленным глезом (что ведет к семантической ошибке), и легко забыть, что делала конкретная переменная. А еще куски кода должны иметь группировку по смыслу. Твой говнокод можно легко превратить в хороший код, если сделать вот так:

rest := number;

d3 := rest mod base;
rest := rest div base;

d2 := rest mod base;
rest := rest div base;

d1 := rest mod base;
rest := rest div base;

d0 := rest mod base;
rest := rest div base;

Или как-то так:

#define NEXT(d) { d = rest % base; rest = rest / base; }
get_next(d3);
get_next(d2);
get_next(d1);
get_next(d0);
#undef NEXT

Или вообще уже цикл.

Если какой-то код дублируется - то его надо выносить в макрос или функцию.

liksys ★★★★
()
Последнее исправление: liksys (всего исправлений: 1)
Ответ на: комментарий от CrX

координаты на экране привычными x и y, цвет пикселя, например z, а итератор в цикле i — и будет норм.

Вот-вот! А @liksys этого не понимает.

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

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

Xenius ★★★★★
() автор топика
Ответ на: комментарий от Xenius

Вот-вот! А @liksys этого не понимает.

Я всё прекрасно понимаю и выше уже объяснил. В идущих подряд вычислениях очень легко перепутать i/j/m/n. Поэтому переменные должны быть говорящими и отличимыми друг от друга.

liksys ★★★★
()
Ответ на: комментарий от Xenius

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

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

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

CrX ★★★★★
()
Последнее исправление: CrX (всего исправлений: 3)
Ответ на: комментарий от liksys

В идущих подряд вычислениях очень легко перепутать i/j/m/n.

Ты уже перепутал get_next и NEXT

А где макрос для твоего подхода? Разбор на цифры выглядит ОК, но если тебе их надо собрать обратно, мне кажется будет уже нетак читаемо.

Поэтому переменные должны быть говорящими и отличимыми друг от друга.

Может быть. Но кстати ты всё-таки написал d0, а не digit0 и кстати в этом случае их было бы правильнее считать с младшего разряда (d0 — коэффициент при 10⁰, d1 при 10¹ и тд)

Xenius ★★★★★
() автор топика
Последнее исправление: Xenius (всего исправлений: 2)
Ответ на: комментарий от Xenius
const int len = 4;
int d[len];
int rest = number;
for (int i = 0; i < len; ++i) {
    d[i] = rest % base;
    rest = rest / base;
}

bool poly = true;
for (int i = 0; i < len / 2; ++i) {
    if (d[i] != d[len - 1 - i]) {
        poly = false;
        break;
    }
}

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

liksys ★★★★
()
Ответ на: комментарий от Xenius

Ты уже перепутал get_next и NEXT

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

А где макрос для твоего подхода?

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

liksys ★★★★
()
Последнее исправление: liksys (всего исправлений: 1)
Ответ на: комментарий от liksys

Если требует - упакую в один цикл и уполовиню итерации.

Если длина известна - можно вообще без циклов. Если неизвестна - полтора прохода сделать придётся по-любому. Не?

bugfixer ★★★★★
()
Ответ на: комментарий от bugfixer

Ага, типа того. Но опять же, зависит от того, надо ли оптимизировать.

liksys ★★★★
()
Ответ на: комментарий от Xenius

расчехляя саблю

Program palindrome(input,output);
var n : integer
Begin
	write('Enter 4-digit whole number: ');
	readln(n);/* по условию задачи ввод корректен */
	if (n mod 1001 mod 110=0) then 
		writeln(n, ' is a palindrome!')
	else
		writeln(n, ' is not a palindrome, sorry.')
End.
зы: div (как и скрипач) оказался крестьянской теореме остатков не нужен

как и в примере с min3 очередное подтверждение что программерам запрещают пользоваться арифметикой - ох лёл

pspsp кстати -y где y четырёхзначное натуральное полиндромище - моей расчехлённой саблей признаётся палиндромом в отличие от двух авторов ранее решений :)

pspsps если минус считать за знакоместо тогда нужно тестить for n<0 :=> abs(n)%101%10==0 Ж)

qulinxao3 ★☆
()
Последнее исправление: qulinxao3 (всего исправлений: 9)
Ответ на: комментарий от wandrien

ВНЕЗАПНО, оказались заблокированы gin-gonic.com и gorm.io. Похоже на заговор )

LongLiveUbuntu ★★★★★
()
Ответ на: комментарий от vbr

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

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

Для rust есть mrustc, go сам собирается. С ada сложнее, но вроде есть исходник версии для спарк который транслируется в C. А тут просто самовоспроизводимый компилятор который больше ничем опенсорсным не собрать.

Даже ocaml вроде как собрали полностью из исходного кода, правда, не самый свежий.

Slackware_user ★★★★★
()
Последнее исправление: Slackware_user (всего исправлений: 1)
Ответ на: комментарий от Xenius

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

А char можно? Ну и в принципе наверное short везде два байта и int везде кроме DOS четыре байта, исходя из того что под 8, 16, 32 бита нужны отдельные целые типы и кроме этих трёх других подходящих базовых нет.

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

А если надо 64 можно везде писать long long на всякий случай, хотя было бы логичнее сделать long 64-битным, а long long 128-битным. Интересно 128-битные целые в C вообще есть?

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

Интересно 128-битные целые в C вообще есть?

В стандарте C23 появился тип _BitInt(N) - где N - число бит. Так что теперь (там где он поддерживается) можно писать :

    signed _BitInt(12) a = -1500; //-2048 ... 2047
    unsigned _BitInt(128) b = UINT64_MAX * 10;

В gcc и clang давно уже были расширения с типом __int128

anonymous_incognito ★★★★★
()
Ответ на: комментарий от Xenius

d %1
dd %11
ddd %101%10
dddd см в 
ddddd %10001%1010%100 

эх школа

ps[гы гы] - дочитал до последнего абцаца и обнаружил что деление на «11"и его 101... колег не привязано к десятке а привязано к позиционной нотации :)


Теорема: исползуя mod достаточно (n+b) mod для натурально длиной 2n+b и сравнения на нули ( где b из {0,1} )
qulinxao3 ★☆
()
Последнее исправление: qulinxao3 (всего исправлений: 3)
Ответ на: комментарий от qulinxao3

последний абзац огонь

Беспочвенный апломб посрамлён?

algo
()
Ответ на: комментарий от qulinxao3

Теорема:

Торопимся. Для нечётных длин as-is точно не работает. Контр пример: 201. Но идея красивая, аплодирую :)

bugfixer ★★★★★
()
Последнее исправление: bugfixer (всего исправлений: 1)
Ответ на: комментарий от bugfixer

Ой да,

Промеж(с задержкой что соответствующий div меньше base) эхь

qulinxao3 ★☆
()
Ответ на: комментарий от bugfixer

А для чётных длин можно подобрать какое-нибудь основание, при котором работает не всегда?

vM ★★★
()
Ответ на: комментарий от qulinxao3

зы: div (как и скрипач) оказался крестьянской теореме остатков не нужен

Отлично. Но у этого кода есть один небольшой недостаток. Чтобы понять как работает, то что у меня нужно примерно 20 секунд, понять версию @liksys — где-то 200 секунд, а на твою ушло около 2000 секунд.

Ну то есть китайская (или всё-таки крестьянская?!) теорема об остатках конечно есть, но к чему она тут я не понял.

Но суть в том, что остаток от 1001 проверяет сходятся ли первая и последняя цифра, если нет, то в конце будет не ноль, если да, они обнулятся. А остаток от деления на 110 будет равен нулю только если последняя цифра 0 и цифры десятков и сотен совпадает. То есть да, если не проверять диапазон, должно работать.

как и в примере с min3 очередное подтверждение что программерам запрещают пользоваться арифметикой - ох лёл

А где твой код для max(A,B,C)?

Xenius ★★★★★
() автор топика
Ответ на: комментарий от Xenius

По первому абзацу: в этом и заключается образование .

qulinxao3 ★☆
()
Ответ на: комментарий от Xenius

Отлично. Но у этого кода есть один небольшой недостаток. Чтобы понять как работает, то что у меня нужно примерно 20 секунд, понять версию @liksys — где-то 200 секунд, а на твою ушло около 2000 секунд.

Как раз в контексте использования каких-нибудь обскурных теорем, рядом с кодом надо оставлять комментарий, ссылающийся на математику, которая там использовалась. Мой пример тривиален, очевиден и самодокументируем, пример @qulinxao3 - вообще нет.

liksys ★★★★
()
Ответ на: комментарий от liksys

Мой пример тривиален, очевиден и самодокументируем

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

Сразу сравнивать цифры исходной цепочки.

vM ★★★
()
Ответ на: комментарий от vM

там чтение строки с двух краёв ( по модному two pointers) или даже загоняем последовательность цифр в очередь ( например Кафку) и читаем парами с краёв пока есть и пока равны - если очередь стала короче 2 успех в остальных случаях - не пали ндром

проблема обучения настоящая - иметь адекватные примеры

psps: если заранее известна длина(2n+b) - то достаточно застекать n цифр и если b=1 drop ( ибо ость остальное) пока стек не пусть читаем и сравниваем с pop пока равны -

стек пуст - пали

нет - бенгали

qulinxao3 ★☆
()
Последнее исправление: qulinxao3 (всего исправлений: 1)
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)