PascalABC.NET официальный канал
1.61K subscribers
447 photos
9 files
322 links
Официальный канал языка и системы программирования PascalABC.NET
Download Telegram
Эффективные решения с КЕГЭ 2024 года

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

Так, в базовой части задача номер 8, посвященная комбинаторике, эффективно и изящно решается в одну строчку. Вот пример:

8 номер. Определите количество девятеричных шестизначных чисел, которые не начинаются с нечетных цифр, не оканчиваются цифрами 2 или 9, содержат не менее двух цифр 1.

// Автор решения: Ипатов Ю.А.
## uses School;
'012345678'
.Cartesian(6)
.Where(x->x[1] not in '01357')
.Where(x->x[^1] not in '29')
.Where(x->x.CountOf('1')>=2)
.Count
.Print;


Автор: Ипатов Юрий
https://www.youtube.com/@infup
Эффективные решения с КЕГЭ 2024 года - II часть

Продолжаем публикацию решений из КЕГЭ 2024.

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

Задание 14
Значение арифметического выражения 3**100-x, где x – целое положительное число, не превышает 2030, записано в троичной системе счисления. Определите наименьшее значение x, при котором в троичной записи числа содержится два нуля. В ответе число записать в десятичной системе счисления.

// Автор решения: Ипатов Ю.А.
## uses school;
(1..2030).Where(x->ToBase(3bi**100-x,3).CountOf('0')=2).Min.Print;


Автор: Ипатов Юрий
https://www.youtube.com/@infup
Декодирование URL-строк

uses System;

function URLDecode(s: string) := Uri.UnescapeDataString(s);

begin
Println(URLDecode('http%3A%2F%2Ffoo%20bar%2F'));
Println(URLDecode('google.com/search?q=%60Abdu%27l-Bah%C3%A1'));
Println(URLDecode('%25%32%35'));
end.


https://rosettacode.org/wiki/URL_decoding#PascalABC.NET

В рейтинге популярности Rosetta Code язык PascalABC.NET уже на 222 месте
Эффективные решения с КЕГЭ 2024 года - III часть

Продолжаем публикацию решений из КЕГЭ 2024.

В заданиях с высоким уровнем сложности по версии ФИПИ были традиционные задачи, формулировки которых встречались до экзамена и с минимальными корректировками, хорошо решаются средствами PascalABC.NET. Вот пример формулировки и его решения:

Задача 24
Текстовый файл состоит из заглавных латинских букв A, B, C, D, E и F. Определите максимальное количество идущих подряд символов в прилагаемом файле, среди которых пара DE (в указном порядке) встречается не более 240 раз. Для выполнения задания следует писать программу.

// Автор решения: Ипатов Ю.А.
##
ReadAllText('1.txt')
.Replace('DE','D E')
.Split
.Nwise(241)
.Select(x->x.jointostring('').length)
.Max
.Print;


Автор: Ипатов Юрий
https://www.youtube.com/@infup

#ЕГЭ
Перенос текста по словам

В решении используется генератор последовательности.

// https://rosettacode.org/wiki/Word_wrap#PascalABC.NET

function Wrap(words: sequence of string; lineWidth: integer): sequence of string;
begin
var currentWidth := 0;
foreach var word in words do
begin
if currentWidth <> 0 then
if currentWidth + word.Length < lineWidth then
begin
currentWidth += 1;
yield ' ';
end
else
begin
currentWidth := 0;
yield NewLine;
end;
currentWidth += word.Length;
yield word;
end;
end;

function Wrap(text: string; lineWidth: integer): string
:= Wrap(text.ToWords(' '#13#10),lineWidth).JoinToString('');

begin
var text := '''
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas varius sapien
vel purus hendrerit vehicula. Integer hendrerit viverra turpis, ac sagittis arcu
pharetra id. Sed dapibus enim non dui posuere sit amet rhoncus tellus
consectetur. Proin blandit lacus vitae nibh tincidunt cursus. Cum sociis natoque
penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nam tincidunt
purus at tortor tincidunt et aliquam dui gravida. Nulla consectetur sem vel
felis vulputate et imperdiet orci pharetra. Nam vel tortor nisi. Sed eget porta
tortor. Aliquam suscipit lacus vel odio faucibus tempor. Sed ipsum est,
condimentum eget eleifend ac, ultricies non dui. Integer tempus, nunc sed
venenatis feugiat, augue orci pellentesque risus, nec pretium lacus enim eu
nibh.
''';
Wrap(text,50).Println;
end.


https://rosettacode.org/wiki/Word_wrap#PascalABC.NET

В рейтинге Rosetta Code PascalABC.NET уже на 205 месте
Как представляются числа в памяти

Метод BitConverter.GetBytes позволяет посмотреть, как представляются числа в памяти компьютера
Квайны на PascalABC.NET

Квайн
(quine) - это программа, печатающая свой текст. При этом запрещено использовать технические приёмы (например, считывание из файла) или специфические хакерские приемы конкретного языка программирования.

Ниже приводится короткий квайн на PascalABC.NET. Он переделан из аналогичного примера на Algol68.

## var a:='## var a:='';print(2*a[:12]+2*a[11:])';print(2*a[:12]+2*a[11:])


https://rosettacode.org/wiki/Quine#PascalABC.NET

Читателям канала предлагается в комментариях публиковать свои квайны
Решето Эратосфена на хорошем ПаскальАБЦНетском

Кто про что - а мы про ПаскальАБЦНетский диалект того самого Паскаля. Вот и решето Эратосфена на нём. Тут старое и новое идут так сказать рядом.

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

function Eratosthenes(N: integer): List<integer>;
type primetype = (nonprime,prime);
begin
var sieve := |nonprime|*2 + |prime|*(N-1);
for var i:=2 to N.Sqrt.Round do
if sieve[i] = prime then
for var j := i*i to N step i do
sieve[j] := nonprime;
Result := new List<integer>;
for var i:=2 to N do
if sieve[i] = prime then
Result.Add(i);
end;

begin
Eratosthenes(1000).Println
end.


https://rosettacode.org/wiki/Sieve_of_Eratosthenes#PascalABC.NET

Мы кстати в Rosetta Code уже на 181 месте. А могли бы быть и выше!
Эффективные решения с КЕГЭ 2024 года - IV часть

Продолжаем публикацию решений из КЕГЭ 2024.

К неожиданным «сюрпризам» в задачах на обработку строк (24 номер) была принципиально новая формулировка, которая вызвала у меня много вопросов. Вот её условия:

Задача 24
Найти подпоследовательность максимальной длины, которая имеет арифметический смысл и содержит только цифры 6, 7, 8, 0 и знаки операций «−», «*». При этом должны выполняться следующие условия:

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

Пример правильного выражения: 6787-86.

Пример неправильного выражения: 6786*−78 (содержит повторяющиеся знаки операции и отрицательное число).

##
// Автор анализа: Ипатов Ю.А.
{Генерация}
var s:string;
loop 81 do s+='6780-*'[Random(1,6)];
println(s);
{Решение}
s
.Replace('*-','* -')
.Replace('-*','- *')
.Replace('**','* *')
.Replace('--','- -')
.Replace('0*','0 *')
.Replace('0-','0 -')
.Replace('*0','* 0')
.Replace('-0','- 0')
.Split
.Where(t->t[1] <> '*')
.Where(t->t[^1] not in '-*')
.Select(t->(t.length,t))
.OrderByDescending(t->t[0])
.Take(10)
.PrintLines(t->$'{t[1]} {t[0]}');


Автор: Ипатов Юрий
https://www.youtube.com/@infup

#ЕГЭ
Новый метод строк ToLines

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

Это удобно также при считывании файла как отдельной строки:

ReadAllText('a.txt').ToLines

#новое
Эффективные решения с КЕГЭ 2024 года - V часть

Скоро пересдача КЕГЭ 2024. Многих мучает вопрос - надо ли пересдавать? Или оставить старый балл? Какие риски? Дело новое - мало кто может просчитать.

А мы публикуем последнее задание по следам КЕГЭ 2024.

Задание на нахождение делителей традиционно хорошо решается средствами современного Паскаля. Вот примеры:

25 номер.
Найдите 5 чисел больших 500000, таких, что среди их делителей есть число, оканчивающееся на 8, при этом этот делитель не равен 8 и самому числу. В качестве ответа приведите 5 наименьших чисел, соответствующих условию. Формат вывода: для каждого из найденных чисел в отдельной строке запишите само число, а затем минимальный делитель, оканчивающийся на 8, не равный 8 и самому числу.

// Автор решения: Ипатов Ю.А.
## uses School;
(500001..1000000000)
.Where(t->t.Divisors[:^1].Where(x->(x mod 10=8) and (x<>8)).count>=1)
.Take(5)
.PrintLines(t->$'{t} {t.Divisors[:^1].Where(x->(x mod 10=8) and (x<>8)).min}')


// Автор решения: Осипов А.В.
## uses School;
var MinD: integer -> integer := n -> n.Divisors[1:^1]
.Where(d -> (d mod 10 = 8) and (d <> 8)).DefaultIfEmpty.Min;
500_001.Step.Where(n -> MinD(n) > 0).Take(5)
.PrintLines(n -> $'{n} {MinD(n)}')


Подводя промежуточные итого можно сказать, что синтаксис и функциональная оснащённость PascalABC.NET дает возможность эффективно справляться с заданиями компьютерного ЕГЭ, а также решать широкий класс алгоритмических задача в изучении программирования. Многие ученики используют этот язык, как мощный инструментарий на практике.

Автор: Ипатов Юрий
https://www.youtube.com/@infup
Целые с ограниченным диапазоном

В PascalABC.NET отсутствуют целые с ограниченным диапазоном, однако их легко можно определить

type RangeInt = record
n: integer;
public
constructor(nn: integer);
begin
if nn not in 1..10 then
raise new System.ArgumentOutOfRangeException;
n := nn;
end;
function ToString: string; override := n.ToString;
static function operator implicit (n: integer): RangeInt := new RangeInt(n);
static function operator+(a,b: RangeInt): RangeInt := a.n + b.n;
static function operator-(a,b: RangeInt): RangeInt := a.n - b.n;
static function operator*(a,b: RangeInt): RangeInt := a.n * b.n;
static function operator/(a,b: RangeInt): real := a.n / b.n;
end;

begin
var a: RangeInt := 7;
var b: RangeInt := 3;
Print(a + b, a - b);
Print(a * b); // ArgumentOutOfRangeException exception
end.


https://rosettacode.org/wiki/Define_a_primitive_data_type#PascalABC.NET

В RosettaCode PascalABC.NET - на 161 месте и сравнялся с Free Pascal! Догоним и перегоним!
Попечатаем?

Хотите напечатать на принтере строчку текста? Пожалуйста! Вот код:

{$reference 'System.Drawing.dll'}

uses System.Drawing;
uses System.Drawing.Printing;

begin
var doc := new PrintDocument();
doc.PrintPage += (s,e) -> begin
e.Graphics.DrawString('Hello World!', new Font('Arial', 14), Brushes.Black, 0, 0);
end;
doc.Print;
end.
Задача. Вывести стороны всех прямоугольных треугольников с целыми сторонами, не превосходящими 20

Решение
##
(1..20).CartesianPower(3).Where(\(x,y,z) -> (x*x + y*y = z*z) and (x < y)).PrintLines


Вывод:
[3,4,5]
[5,12,13]
[6,8,10]
[8,15,17]
[9,12,15]
[12,16,20]


https://rosettacode.org/wiki/List_comprehensions#PascalABC.NET

У нас 153 место в Rosetta Code.
Типы-суммы

Как в PascalABC.NET создать тип, который может хранить одно из значений разных типов?
А так же как в C#:

uses System.Runtime.InteropServices ;

type
[StructLayout(LayoutKind.Explicit)]
Union = record
[FieldOffset(0)]
i: integer;
[FieldOffset(0)]
r: real;
[FieldOffset(0)]
d: DateTime;
end;

begin
var x: Union;
x.i := 1;
Println(x.i);
x.r := 2.5;
Println(x.r);
x.d := DateTime.Now;
Println(x.d);
end.


https://rosettacode.org/wiki/Sum_data_type#PascalABC.NET

146 место в Rosetta Code с 202 задачами!
Переменное число параметров - особенности

Переменное число параметров в подпрограмме достигается последним параметром типа массив с ключевым словом params.

Есть одна важная особенность, которую можно увидеть на скриншоте.

Если вызвать процедуру с параметром ровно того типа, который заявлен в параметре params (в данном случае это - array of integer), то он подставится целиком вместо формального параметра-массива (он будет включать всё переменное количество параметров)

Если же фактический параметр-массив будет другого типа, то он станет первым параметром в процедуре ppp типа "массив". Наконец, если передать два параметра типа array of object, то разумеется они и будут элементами переменного числа параметров.
Range с шагом

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

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

Вывод. Если вам нужна последовательность с шагом, пользуйтесь PascalABC.NET. А в нём - пользуйтесь функцией Range.

Ну и читайте наш канал - здесь плохому не научат :)
Сколько раз каждая буква встречается в строке

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

Решение на удивление короткое. Очень. Такому точно нельзя учить школьников :)
Ввод boolean

В PascalABC.NET можно вводить значение типа boolean.

И не как 0 или 1 как в этих новомодных скриптовых языках, а как True и False.

Явное приведение к типу integer переводит False в 0, а True - в 1.
Как изменить приватное поле в классе

Для этого используется так называемое отражение (Reflection) - механизм, позволяющий манипулировать членами объекта во время выполнения.

На скриншоте показано, как поменять значение приватного поля.