Range с шагом
В PascalABC.NET есть функция Range, которая позволяет получить последовательность вещественных чисел в заданном диапазоне с определенным шагом.
Традиционный цикл для этого не очень подходит, поскольку провоцирует ошибки.
Вывод. Если вам нужна последовательность с шагом, пользуйтесь PascalABC.NET. А в нём - пользуйтесь функцией Range.
Ну и читайте наш канал - здесь плохому не научат :)
В PascalABC.NET есть функция Range, которая позволяет получить последовательность вещественных чисел в заданном диапазоне с определенным шагом.
Традиционный цикл для этого не очень подходит, поскольку провоцирует ошибки.
Вывод. Если вам нужна последовательность с шагом, пользуйтесь PascalABC.NET. А в нём - пользуйтесь функцией Range.
Ну и читайте наш канал - здесь плохому не научат :)
Ввод boolean
В PascalABC.NET можно вводить значение типа boolean.
И не как 0 или 1 как в этих новомодных скриптовых языках, а как True и False.
Явное приведение к типу integer переводит False в 0, а True - в 1.
В PascalABC.NET можно вводить значение типа boolean.
И не как 0 или 1 как в этих новомодных скриптовых языках, а как True и False.
Явное приведение к типу integer переводит False в 0, а True - в 1.
Сериализация полиморфного списка
Чтобы сериализовать список полиморфных объектов, пользуемся функцией Serialize, а для десериализации - Deserialize.
Типы должны быть помечены атрибутом [Serializable]
https://rosettacode.org/wiki/Object_serialization#PascalABC.NET
Мы в Rosetta Code на 133 месте!
Чтобы сериализовать список полиморфных объектов, пользуемся функцией Serialize, а для десериализации - Deserialize.
Типы должны быть помечены атрибутом [Serializable]
https://rosettacode.org/wiki/Object_serialization#PascalABC.NET
Мы в Rosetta Code на 133 месте!
type
[Serializable]
Base = class
public
fb: integer;
constructor (fb: integer) := Self.fb := fb;
function ToString: string; override := fb.ToString;
end;
[Serializable]
Derived = class(Base)
public
fd: real;
constructor (fb: integer; fd: real);
begin
inherited Create(fb);
Self.fd := fd;
end;
function ToString: string; override := inherited ToString + ',' + fd.ToString;
end;
begin
var lst := new List<Base>;
lst.Add(new Base(3));
lst.Add(new Derived(4,5.5));
lst.Add(new Base(6));
lst.Add(new Derived(7,8.8));
lst.Println;
Serialize('objects.dat',lst);
var lst1 := DeSerialize('objects.dat') as List<Base>;
lst1.Println;
end.
Количество вхождений подстроки в строку
В PascalABC.NET у строк есть хорошая функция IndicesOf, возвращающая все позиции вхождений подстроки в строку. Она позволяет в частности считать, сколько раз подстрока входит в строку.
В PascalABC.NET у строк есть хорошая функция IndicesOf, возвращающая все позиции вхождений подстроки в строку. Она позволяет в частности считать, сколько раз подстрока входит в строку.
Оптимизировано множественное присваивание
Закончена работа по оптимизации множественного присваивания. Один из результатов можно видеть на скриншоте: данная программа ускорена примерно в 2 раза.
Нетрудно проверить, что аналогичная программа, написанная на C#, работает в 2 раза медленнее.
Это - основной результат выпускной работы бакалавра направления ФИИТ мехмата ЮФУ Филонова Александра: https://pascalabc.net/downloads/Diploms/Opt_Tuple_Assignment_Filonov.pdf
#новое
Закончена работа по оптимизации множественного присваивания. Один из результатов можно видеть на скриншоте: данная программа ускорена примерно в 2 раза.
Нетрудно проверить, что аналогичная программа, написанная на C#, работает в 2 раза медленнее.
Это - основной результат выпускной работы бакалавра направления ФИИТ мехмата ЮФУ Филонова Александра: https://pascalabc.net/downloads/Diploms/Opt_Tuple_Assignment_Filonov.pdf
#новое
Функция суффикса числительного
Для заданного n написать функцию, дописывающую к нему суффикс вида 1'st 2'nd 3'rd 4'th и т.д.
Решение - на скриншоте.
Можно короче. Но некуда!
https://rosettacode.org/wiki/N%27th#PascalABC.NET
Мы в Rosetta Code на 129 месте и вплотную подобрались к Modula 2!
Для заданного n написать функцию, дописывающую к нему суффикс вида 1'st 2'nd 3'rd 4'th и т.д.
Решение - на скриншоте.
Можно короче. Но некуда!
https://rosettacode.org/wiki/N%27th#PascalABC.NET
Мы в Rosetta Code на 129 месте и вплотную подобрались к Modula 2!
Тёмные стороны PascalABC.NET
В PascalABC.NET можно перегрузить оператор :=. Это никто не знает, но это факт.
На скриншоте демонстрируется эта безобразная возможность. Удивительно, как разработчики ещё такое не запретили.
В PascalABC.NET можно перегрузить оператор :=. Это никто не знает, но это факт.
На скриншоте демонстрируется эта безобразная возможность. Удивительно, как разработчики ещё такое не запретили.
Манипуляция csv-файлами
В PascalABC.NET нет модуля манипуляции csv-файлами, но это можно легко сделать
Исходный файл:
Результат:
// https://rosettacode.org/wiki/CSV_data_manipulation#PascalABC.NET
В PascalABC.NET нет модуля манипуляции csv-файлами, но это можно легко сделать
begin
var lines := ReadLines('data.csv').Select((line,i) -> begin
if i = 0 then
Result := line + ',SUM'
else Result := line + ',' + line.Split(',').Sum(x -> x.ToInteger);
end);
WriteLines('outdata.csv',lines);
lines.PrintLines;
end.
Исходный файл:
C1,C2,C3,C4,C5
1,5,9,13,17
2,6,10,14,18
3,7,11,15,19
4,8,12,16,20
Результат:
C1,C2,C3,C4,C5,SUM
1,5,9,13,17,45
2,6,10,14,18,50
3,7,11,15,19,55
4,8,12,16,20,60
// https://rosettacode.org/wiki/CSV_data_manipulation#PascalABC.NET
Изменения, связанные со словарями
Готовимся к версии 3.10.
Из Kotlinа перекочевал ряд методов, конструкций и операций со словарями.
Вывод:
#новое
Готовимся к версии 3.10.
Из Kotlinа перекочевал ряд методов, конструкций и операций со словарями.
begin
// Новая операция 1 to 2 - синоним KV(1,2)
var d := Dict('cat' to 'кошка', 'dog' to 'собака');
// Новая функция Pair - синоним KV
var d0 := Dict(Pair('cat', 'кот'), Pair('camel', 'верблюд'));
// Более сложная структура
var dd := Dict('Иванов' to |5, 3, 3|, 'Петров' to |4, 4|);
// Копия словаря
var d1 := Dict(d);
// Инициализация массивами ключей и значений
var d2 := Dict(|11, 22|, |333, 444|);
// Обновление значений и добавление новых
d.Update(d0);
// То же
d += d0;
// Слияние словарей
var d3 := d + Dict('world' to 'мир', 'cloud' to 'облако');
Println(d3);
// Вычитание пар с данными ключами
d3 -= Seq('cat', 'camel');
Println(d3);
d3 := d3 - 'world';
Println(d3);
end.
Вывод:
{(cat,кот),(dog,собака),(camel,верблюд),(world,мир),(cloud,облако)}
{(dog,собака),(world,мир),(cloud,облако)}
{(dog,собака),(cloud,облако)}
#новое
Архимедова спираль
Архимедова спираль имеет очень простые параметрические уравнения: x = t * cos(t); y = t * Sin(t).
Нарисовать её проще всего с помощью модуля PlotWPF.
https://rosettacode.org/wiki/Archimedean_spiral#PascalABC.NET
Архимедова спираль имеет очень простые параметрические уравнения: x = t * cos(t); y = t * Sin(t).
Нарисовать её проще всего с помощью модуля PlotWPF.
uses PlotWPF,GraphWPF;
begin
Window.SetSize(600,600);
var seq := Range(0,20,0.1);
var xx := seq.Select(t -> t * Cos(t));
var yy := seq.Select(t -> t * Sin(t));
LineGraphWPF.Create(xx,yy,Colors.Black);
end.
https://rosettacode.org/wiki/Archimedean_spiral#PascalABC.NET
WPF - пример с радиокнопками
Новые элементы и методы в модуле WPF. Радиокнопки, граница, метод Bordered.
Новые элементы и методы в модуле WPF. Радиокнопки, граница, метод Bordered.
uses WPF;
begin
MainWindow.FontSize := 16;
MainWindow.Title := 'Радиокнопки, Border, Bordered, три панели';
var grid := Panels.Grid(1,3);
MainWindow.Content := grid;
var st0 := Panels.StackPanel(Margin := 10, HAlign := HA.Center, VAlign := VA.Center);
var rbs := Controls.RadioButtons(|'Alpha','Beta','Gamma','Delta'|, GroupName := 'GreekLetters');
rbs[1].IsChecked := True;
st0.AddElements(rbs);
var st1 := Panels.StackPanel(Margin := 10, HAlign := HA.Center, VAlign := VA.Center);
var rbs1 := Controls.RadioButtons(|'One','Two','Three','Four','Five'|, GroupName := 'Numbers');
rbs1[0].IsChecked := True;
st1.AddElements(rbs1);
grid.Add(st0.Bordered(3,Brushes.Blue,20),0,0);
grid.Add(Controls.Border(Background := Brushes.LightGreen, Margin := |0,20,0,20|),0,1);
grid.Add(st1.Bordered(3,Brushes.Blue,20),0,2);
end.
Количество простых делителей и простых факторов в натуральном числе
Изменения в библиотеке School
Английское слово
Факториал натурального числа n, как известно, есть произведение всех натуральных чисел от единицы до n включительно. В факториале каждый сомножитель и есть тот самый "фактор".
Под факторизацией натурального числа n понимается его возможное представление в виде некоторого количества сомножителей, опять же, "факторов". Нас будут интересовать только такие сомножители-факторы, которые являются простыми числами.
Основная теорема арифметики гласит, что любое натуральное число большее единицы может быть представлено в виде произведения простых множителей, причём единственным образом, с точностью до порядка множителей. Процесс нахождения всех таких множителей для натурального числа n называется факторизацией. Для простых чисел приведенное выше определение оказывается неточным, ведь у простого числа только два делителя - единица и само это число. Вот только единица не является простым числом.
За факторизацию в библиотеке School отвечает функция
Функция
Функция
Все три вышеупомянутые функции имеют расширения, позволяющее встраивать их в цепочки с точечной нотацией:
Ниже приводится пример, демонстрирующий работу трех упомянутых функций. Отмечу, что в качестве n можно использовать тип
Изменения в библиотеке School
Английское слово
factor
означает "множитель". От него берут свои названия и факториал, и факторизация.Факториал натурального числа n, как известно, есть произведение всех натуральных чисел от единицы до n включительно. В факториале каждый сомножитель и есть тот самый "фактор".
Под факторизацией натурального числа n понимается его возможное представление в виде некоторого количества сомножителей, опять же, "факторов". Нас будут интересовать только такие сомножители-факторы, которые являются простыми числами.
Основная теорема арифметики гласит, что любое натуральное число большее единицы может быть представлено в виде произведения простых множителей, причём единственным образом, с точностью до порядка множителей. Процесс нахождения всех таких множителей для натурального числа n называется факторизацией. Для простых чисел приведенное выше определение оказывается неточным, ведь у простого числа только два делителя - единица и само это число. Вот только единица не является простым числом.
За факторизацию в библиотеке School отвечает функция
Factorize( )
. Знак числа она игнорирует. Для n = 0
возвращается 0, для n = 1
возвращается 1, для простого n возвращается n. Если абсолютное значение составного числа больше 3, возвращается список, содержащий все простые сомножители-факторы в порядке неубывания. Например, для n = 4
возвращается [2,2]
, а для n = 6
возвращается [2,3]
.Функция
PrimeDivisorsCount(n)
возвращает количество уникальных сомножителей из списка, полученного при факторизации. Для n = 4
возвращается 1, для n = 6
возвращается 2. Для n < 2
возвращается ноль.Функция
PrimeFactorsCount(n)
возвращает общее количество сомножителей из списка, полученного при факторизации. Для n = 4
возвращается 2, для n = 6
также возвращается 2. Для n < 2
возвращается ноль.Все три вышеупомянутые функции имеют расширения, позволяющее встраивать их в цепочки с точечной нотацией:
n.Factorize, n.PrimeDivisorsCount, n.PrimeFactorsCount
.Ниже приводится пример, демонстрирующий работу трех упомянутых функций. Отмечу, что в качестве n можно использовать тип
integer
, либо иной, приводящийся к нему числовой тип, занимающий в памяти не более четырех байт.## uses School;
foreach var n in Range(-2, 16) + Range(MaxInt, Maxint - 10, -1) do
Println(n, n.Factorize, n.PrimeFactorsCount, n.PrimeDivisorsCount);
{
-2 [2] 0 0
-1 [1] 0 0
0 [0] 0 0
1 [1] 0 0
2 [2] 1 1
3 [3] 1 1
4 [2,2] 2 1
5 [5] 1 1
6 [2,3] 2 2
7 [7] 1 1
8 [2,2,2] 3 1
9 [3,3] 2 1
10 [2,5] 2 2
11 [11] 1 1
12 [2,2,3] 3 2
13 [13] 1 1
14 [2,7] 2 2
15 [3,5] 2 2
16 [2,2,2,2] 4 1
2147483647 [2147483647] 1 1
2147483646 [2,3,3,7,11,31,151,331] 8 7
2147483645 [5,19,22605091] 3 3
2147483644 [2,2,233,1103,2089] 5 4
2147483643 [3,715827881] 2 2
2147483642 [2,23,46684427] 3 3
2147483641 [2699,795659] 2 2
2147483640 [2,2,2,3,5,29,43,113,127] 9 7
2147483639 [7,17,18046081] 3 3
2147483638 [2,2969,361651] 3 3
2147483637 [3,3,3,13,6118187] 5 3
}
Мужчина или мальчик
Тест Дональда Кнута позволяет выявить компиляторы, корректно реализующие рекурсию с нелокальными переменными.
Изначально тест был написан на Algol-60:
PascalABC.NET успешно проходит этот тест:
и выводит верное значение -67
https://rosettacode.org/wiki/Man_or_boy_test#PascalABC.NET
Тест Дональда Кнута позволяет выявить компиляторы, корректно реализующие рекурсию с нелокальными переменными.
Изначально тест был написан на Algol-60:
begin
real procedure A (k, x1, x2, x3, x4, x5);
value k; integer k;
real x1, x2, x3, x4, x5;
begin
real procedure B;
begin k:= k - 1;
B:= A := A (k, B, x1, x2, x3, x4)
end;
if k <= 0 then A:= x4 + x5 else B
end;
outreal (A (10, 1, -1, -1, 1, 0))
end
PascalABC.NET успешно проходит этот тест:
function A(k: integer; x1, x2, x3, x4, x5: function: integer): integer;
begin
var B: function: integer;
B := () -> begin
k := k - 1;
Result := A(k, B, x1, x2, x3, x4);
end;
Result := if k <= 0 then x4() + x5() else B()
end;
begin
Print(A(10, () -> 1, () -> -1, () -> -1, () -> 1, () -> 0))
end.
и выводит верное значение -67
https://rosettacode.org/wiki/Man_or_boy_test#PascalABC.NET
Определение сбалансированности скобок
Данная программа генерирует скобочные выражения, а потом проверяет их на расстановку скобок. Для решения этой задачи традиционно используется стек.
// https://rosettacode.org/wiki/Balanced_brackets#PascalABC.NET
Данная программа генерирует скобочные выражения, а потом проверяет их на расстановку скобок. Для решения этой задачи традиционно используется стек.
function GenBracketExpr(n: integer): string;
begin
var a := Arr('[',']')*n;
Shuffle(a);
Result := a.JoinToString
end;
function IsBalanced(s: string): boolean;
begin
Result := True;
var st := new Stack<char>;
foreach var c in s do
if c = '[' then
st.Push(c)
else if (st.Count > 0) and (st.Peek = '[') then
st.Pop
else begin
Result := False;
exit
end;
end;
begin
loop 10 do
begin
var s := GenBracketExpr(Random(2,5));
Println(s, IsBalanced(s));
end;
end.
// https://rosettacode.org/wiki/Balanced_brackets#PascalABC.NET
Множество всех подмножеств
Рекурсивная функция генерации последовательности всех подмножеств заданного множества. Используется
Вывод:
https://rosettacode.org/wiki/Power_set#PascalABC.NET
Рекурсивная функция генерации последовательности всех подмножеств заданного множества. Используется
yield sequence
.function AllSubSets<T>(a: array of T; i: integer; lst: List<T>): sequence of List<T>;
begin
if i = a.Length then
begin
yield lst;
exit;
end;
lst.Add(a[i]);
yield sequence AllSubSets(a, i + 1, lst);
lst.RemoveAt(lst.Count-1);
yield sequence AllSubSets(a, i + 1, lst);
end;
begin
AllSubSets(Arr(1..4),0,new List<integer>).Print;
end.
Вывод:
[1,2,3,4] [1,2,3] [1,2,4] [1,2] [1,3,4] [1,3] [1,4] [1] [2,3,4] [2,3] [2,4] [2] [3,4] [3] [4] []
https://rosettacode.org/wiki/Power_set#PascalABC.NET
Общая часть путей
Задача. Дан массив директорий. Найти общую часть их путей
Решение. Превратим все пути в последовательности строк, обрежем их по минимальной длине и транспонируем.
Будем брать только те строки, в которых все элементы совпадают, а потом оставим у них первые элементы и превратим их в путь.
https://rosettacode.org/wiki/Find_common_directory_path#PascalABC.NET
Задача. Дан массив директорий. Найти общую часть их путей
Решение. Превратим все пути в последовательности строк, обрежем их по минимальной длине и транспонируем.
Будем брать только те строки, в которых все элементы совпадают, а потом оставим у них первые элементы и превратим их в путь.
function CommonPrefix(arrs: array of array of string): array of string;
begin
var min: integer := arrs.Min(a -> a.Length);
var at := ArrGen(min, j -> ArrGen(arrs.Length, i -> arrs[i][j]));
Result := at.TakeWhile(x -> x.Skip(1).All(y -> y = x.First)).Select(a -> a[0]).ToArray
end;
function CommonDirectoryPath(paths: array of string; sep: char := '/'): string;
begin
var arrs := paths.Select(a -> a.Split(sep)).ToArray;
Result := CommonPrefix(arrs).JoinToString(sep);
end;
begin
Print(CommonDirectoryPath(|
'/home/user1/tmp/coverage/test',
'/home/user1/tmp/covert/operator',
'/home/user1/tmp/coven/members'|))
end.
https://rosettacode.org/wiki/Find_common_directory_path#PascalABC.NET
Фрактальное дерево
Нарисуем фрактальное дерево? Это просто!
https://rosettacode.org/wiki/Fractal_tree#PascalABC.NET
Мы в Rosetta Code на 120 месте!
Нарисуем фрактальное дерево? Это просто!
uses Turtle,GraphWPF;
procedure FractalTree(n: integer; len,angle: real);
begin
if n = 0 then exit;
len := len * 0.8;
Turn(angle);
Forw(len);
FractalTree(n-1,len,angle);
Turn(180);
Forw(len);
Turn(180-2*angle);
Forw(len);
FractalTree(n-1,len,angle);
Turn(180);
Forw(len);
Turn(180+angle);
end;
begin
Window.Title := 'Fractal Tree';
var len := 100;
var angle := 22;
ToPoint(400,500);
Turn(-90);
Down;
Forw(100);
FractalTree(10,len,angle);
end.
https://rosettacode.org/wiki/Fractal_tree#PascalABC.NET
Мы в Rosetta Code на 120 месте!
Загрузка JSON-строки
С помощью стандартной библиотеки System.Web.Extensions.dll можно манипулировать JSON-объектами: сериализовать их в JSON-формат из строки и словаря, а также десериализовать их
Результат:
https://rosettacode.org/wiki/JSON#PascalABC.NET
С помощью стандартной библиотеки System.Web.Extensions.dll можно манипулировать JSON-объектами: сериализовать их в JSON-формат из строки и словаря, а также десериализовать их
{$reference System.Web.Extensions.dll}
uses System.Web.Script.Serialization;
begin
var serializer := new JavaScriptSerializer;
var people := new Dictionary<string, object>;
people.Add('1', 'John');
people.Add('2', 'Susan');
var json := serializer.Serialize(people);
Println(json);
var res := serializer.Deserialize&<Dictionary<string, object>>(json);
Println(TypeName(res));
Println(res);
var jsonObject := serializer.DeserializeObject('{ "foo": 1, "bar": [10, "apples"] }')
as Dictionary<string, object>;
Println(jsonObject);
var arr := jsonObject['bar'] as array of object;
arr.Println;
end.
Результат:
{"1":"John","2":"Susan"}
Dictionary<string, Object>
{(1,John),(2,Susan)}
{(foo,1),(bar,[10,apples])}
10 apples
https://rosettacode.org/wiki/JSON#PascalABC.NET
Преобразование в римские числа
Составим функцию, преобразующую арабские числа в римские и применим её на списке чисел. Кто-нибудь напишет короче?
https://rosettacode.org/wiki/Roman_numerals#PascalABC.NET
Составим функцию, преобразующую арабские числа в римские и применим её на списке чисел. Кто-нибудь напишет короче?
https://rosettacode.org/wiki/Roman_numerals#PascalABC.NET
var anums := |1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1|;
var rnums := 'M CM D CD C XC L XL X IX V IV I'.split;
function ToRoman(x: integer): string;
begin
Result := '';
foreach var (a,r) in anums.Zip(rnums) do
begin
var n := x div a;
x := x mod a;
Result += r * n;
end;
end;
begin
var test := |1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 25, 30, 40,
50, 60, 69, 70, 80, 90, 99, 100, 200, 300, 400, 500, 600, 666, 700, 800, 900, 1000,
1009, 1444, 1666, 1945, 1997, 1999, 2000, 2008, 2010, 2011, 2500, 3000, 3999|;
foreach var x in test do
Println($'{x} - {ToRoman(x)}')
end.