{$HiddenIdents}
unit SPythonSystem;
// В SPython данной версии нет возможности использовать пространства имен
// {$reference '%GAC%\System.dll'}
// {$reference '%GAC%\mscorlib.dll'}
// {$reference '%GAC%\System.Core.dll'}
// {$reference '%GAC%\System.Numerics.dll'}
interface
// uses PABCSystem;
// Basic IO methods
function input(): string;
function input(s: string): string;
///-
type kwargs_gen<T> = class
public !kwargs: Dictionary<string, T>
:= new Dictionary<string, T>();
constructor Create(
keys: array of string;
params values: array of T
);
begin
for var i := 0 to keys.count() - 1 do
!kwargs[keys[i]] := values[i];
end;
keys: array of char;
constructor Create(); begin end;
function all(s: sequence of boolean): boolean;
function all(s: sequence of integer): boolean;
function any(s: sequence of boolean): boolean;
function any(s: sequence of integer): boolean;
function enumerate<T>(s: sequence of T; start: integer := 0): sequence of (integer,T);
function filter<T>(cond: T -> boolean; s: sequence of T): sequence of T;
function sorted<T>(s: sequence of T; reverse: boolean := false): sequence of T;
function sorted<T,T1>(s: sequence of T; key: T -> T1; reverse: boolean := false): sequence of T;
function int(val: string): integer;
function int(val: real): integer;
function int(b: boolean): integer;
function str(val: object): string;
function float(val: string): real;
function float(x: integer): real;
function bool(val: integer): boolean;
function round(val: real): integer;
function split(s: string): sequence of string;
function get_keys<K, V>(dct: Dictionary<K, V>): sequence of K;
function get_values<K, V>(dct: Dictionary<K, V>): sequence of V;
function &type(obj: object): string;
// Basic sequence functions
function range(s: integer; e: integer; step: integer): sequence of integer;
function range(e: integer): sequence of integer;
function range(s: integer; e: integer): sequence of integer;
function !format(obj: object; fmt: string): string;
function !format(i: integer; fmt: string): string;
function !format(val: real; fmt: string): string;
//------------------------------------
// Standard Math functions
/// Возвращает абсолютное значение числа
function abs(x: integer): integer;
function abs(x: real): real;
/// Возвращает x в степени y
function pow(x,y: real): real;
/// Возвращает x в целой степени n
function pow(x: real; n: integer): real;
function pow(x: BigInteger; n: integer): BigInteger;
{$region STANDARD CONTAINERS}
type list<T> = class(IEnumerable<T>)
private
wrappee : PABCSystem.List<T>;
constructor Create(l : PABCSystem.List<T>) := wrappee := l;
function GetItem(ind : integer) : T := wrappee[ind];
procedure SetItem(ind : integer; newItem : T) := wrappee[ind] := newItem;
public
static function operator implicit(l : PABCSystem.List<T>) : list<T> := new list<T>(l);
constructor Create() := wrappee := new PABCSystem.List<T>();
constructor Create(capacity : integer) := wrappee := new PABCSystem.List<T>(capacity);
constructor Create(collection : sequence of T) := wrappee := new PABCSystem.List<T>(collection);
property ByIndex[ind : integer] : T read GetItem write SetItem; default;
///--
property !count : integer read wrappee.Count;
procedure append(item : T) := wrappee.Add(item);
procedure extend(seq : sequence of T) := wrappee.AddRange(seq);
procedure clear() := wrappee.Clear();
procedure insert(index : integer; item : T) := wrappee.Insert(index, item);
procedure remove(item : T);
if not wrappee.Remove(item) then
raise new System.ArgumentException($'ValueError: {item} is not in list');
function pop() : T;
var lastIndex := wrappee.Count - 1;
Result := wrappee[lastIndex];
wrappee.RemoveAt(lastIndex);
function pop(index : integer) : T;
Result := wrappee[index];
wrappee.RemoveAt(index);
function index(item : T) : integer := index(item, 0, wrappee.Count);
function index(item : T; start : integer) : integer := index(item, start, wrappee.Count);
function index(item : T; start : integer; &end : integer) : integer;
Result := wrappee.IndexOf(item, start, &end - start);
if Result = -1 then
function count(item : T) : integer;
var comparer := System.Collections.Generic.EqualityComparer&<T>.Default;
Result := 0;
for var i := 0 to wrappee.Count - 1 do
if comparer.Equals(wrappee[i], item) then
Result += 1;
procedure sort() := wrappee.Sort();
procedure sort(reverse : boolean) := wrappee.OrderByDescending(x -> x);
procedure sort<TKey>(key : T -> TKey) := wrappee.OrderBy(key);
procedure sort<TKey>(key : T -> TKey; reverse : boolean) := wrappee.OrderByDescending(key);
procedure reverse() := wrappee.Reverse();
function copy() : list<T> := new list<T>(wrappee.ToList());
function GetEnumerator() : IEnumerator<T> := wrappee.GetEnumerator();
function System.Collections.IEnumerable.GetEnumerator() : System.Collections.IEnumerator := GetEnumerator();
type &set<T> = record(IEnumerable<T>)
wrappee : PABCSystem.HashSet<T>;
constructor Create(h : PABCSystem.HashSet<T>) := wrappee := h;
constructor Create() := wrappee := new PABCSystem.HashSet<T>();
constructor Create(collection : sequence of T) := wrappee := new PABCSystem.HashSet<T>(collection);
constructor Create(collection : sequence of T; comparer : PABCSystem.IEqualityComparer<T>) := wrappee := new PABCSystem.HashSet<T>(collection, comparer);
constructor Create(comparer : PABCSystem.IEqualityComparer<T>) := wrappee := new PABCSystem.HashSet<T>(comparer);
procedure add(elem : T) := wrappee.Add(elem);
procedure remove(elem : T);
if not wrappee.Remove(elem) then
raise new System.Collections.Generic.KeyNotFoundException('KeyError: ' + elem.ToString());
procedure discard(elem : T) := wrappee.Remove(elem);
if wrappee.Count = 0 then
raise new System.Collections.Generic.KeyNotFoundException('KeyError: ''pop from an empty set''');
Result := wrappee.First();
wrappee.Remove(Result);
function copy() : &set<T> := new &set<T>(wrappee.ToHashSet());
static function operator in(elem: T; Self: &set<T>): boolean;
Result := Self.wrappee.Contains(elem);
function setOperation1(op : (HashSet<T>, sequence of T) -> (); params others : array of sequence of T) : &set<T>;
Result.wrappee := wrappee.ToHashSet();
foreach var seq in others do
op(Result.wrappee, seq);
procedure setOperation2(op : (HashSet<T>, sequence of T) -> (); params others : array of sequence of T);
op(wrappee, seq);
function intersection(params others : array of sequence of T) : &set<T> := setOperation1((h1, h2) -> h1.IntersectWith(h2), others);
function union(params others : array of sequence of T) : &set<T> := setOperation1((h1, h2) -> h1.UnionWith(h2), others);
function difference(params others : array of sequence of T) : &set<T> := setOperation1((h1, h2) -> h1.ExceptWith(h2), others);
function symmetric_difference(params others : array of sequence of T) : &set<T> := setOperation1((h1, h2) -> h1.SymmetricExceptWith(h2), others);
procedure update(params others : array of sequence of T) := setOperation2((h1, h2) -> h1.UnionWith(h2), others);
procedure update(other : sequence of T) := wrappee.UnionWith(other);
procedure intersection_update(params others : array of sequence of T) := setOperation2((h1, h2) -> h1.IntersectWith(h2), others);
procedure intersection_update(other : sequence of T) := wrappee.IntersectWith(other);
procedure difference_update(params others : array of sequence of T) := setOperation2((h1, h2) -> h1.ExceptWith(h2), others);
procedure difference_update(other : sequence of T) := wrappee.ExceptWith(other);
procedure symmetric_difference_update(params others : array of sequence of T) := setOperation2((h1, h2) -> h1.SymmetricExceptWith(h2), others);
procedure symmetric_difference_update(other : sequence of T) := wrappee.SymmetricExceptWith(other);
function isdisjoint(other : sequence of T) : boolean;
function issubset(other : sequence of T) : boolean := wrappee.IsSubsetOf(other);
function issuperset(other : sequence of T) : boolean := wrappee.IsSupersetOf(other);
static function operator=(s1 : &set<T>; s2 : &set<T>) : boolean := s1.wrappee.SetEquals(s2.wrappee);
static function operator<>(s1 : &set<T>; s2 : &set<T>) : boolean := not (s1 = s2);
static function operator<=(s1 : &set<T>; s2 : &set<T>) : boolean := s1.issubset(s2);
static function operator<(s1 : &set<T>; s2 : &set<T>) : boolean := (s1 <= s2) and (s1 <> s2);
static function operator>=(s1 : &set<T>; s2 : &set<T>) : boolean := s1.issuperset(s2);
static function operator>(s1 : &set<T>; s2 : &set<T>) : boolean := (s1 >= s2) and (s1 <> s2);
static function operator or(s1 : &set<T>; s2 : &set<T>) : &set<T> := s1.union(s2);
function !orEqual(other : &set<T>) : &set<T>;
update(other);
Result := Self;
static function operator and(s1 : &set<T>; s2 : &set<T>) : &set<T> := s1.intersection(s2);
function !andEqual(other : &set<T>) : &set<T>;
intersection_update(other);
static function operator-(s1 : &set<T>; s2 : &set<T>) : &set<T> := s1.difference(s2);
static function operator -=(var s1 : &set<T>; s2 : &set<T>) : &set<T>;
s1.difference_update(s2);
static function operator xor(s1 : &set<T>; s2 : &set<T>) : &set<T> := s1.symmetric_difference(s2);
function !xorEqual(other : &set<T>) : &set<T>;
symmetric_difference_update(other);
// static function operator:=(var s1: &set<T>; s2: &set<T>): &set<T>;
// begin
// s1.wrappee := s2.wrappee.ToHashSet();
// end;
static function operator implicit(s : HashSet<T>) : &set<T> := new &set<T>(s);
type dict<K, V> = class(IEnumerable<PABCSystem.KeyValuePair<K, V>>)
wrappee : PABCSystem.Dictionary<K, V>;
constructor Create(d : PABCSystem.Dictionary<K, V>) := wrappee := d;
function GetValue(key : K) : V := wrappee[key];
procedure SetValue(key : K; val : V) := wrappee[key] := val;
constructor Create() := wrappee := new PABCSystem.Dictionary<K, V>();
constructor Create(capacity : integer) := wrappee := new PABCSystem.Dictionary<K, V>(capacity);
constructor Create(comparer : PABCSystem.IEqualityComparer<K>) := wrappee := new PABCSystem.Dictionary<K, V>(comparer);
constructor Create(capacity : integer; comparer : PABCSystem.IEqualityComparer<K>) := wrappee := new PABCSystem.Dictionary<K, V>(capacity, comparer);
constructor Create(params pairs: array of (K, V));
wrappee := new PABCSystem.Dictionary<K, V>();
for var i := 0 to pairs.Length - 1 do
wrappee[pairs[i].Item1] := pairs[i].Item2;
constructor Create(seqOfPairs : sequence of (K, V));
foreach var p in seqOfPairs do
wrappee[p.Item1] := p.Item2;
property ByKey[key : K] : V read GetValue write SetValue; default;
static function operator in(key: K; Self: dict<K, V>): boolean;
Result := Self.wrappee.ContainsKey(key);
function copy() : dict<K, V> := new dict<K, V>(new Dictionary<K,V>(wrappee));
static function fromkeys(sq : sequence of K; val : V := default(V)) : dict<K, V>;
Result := new dict<K, V>();
foreach var key in sq do
Result[key] := val;
function get(key : K; &default : V := default(V)) : V;
var val : V;
if wrappee.TryGetValue(key, val) then
Result := val
else
Result := &default;
function items() : sequence of KeyValuePair<K, V> := wrappee;
function keys() := wrappee.Keys;
function pop(key : K) : V;
Result := wrappee[key];
wrappee.Remove(key);
function pop(key : K; &default : V) : V;
Result := val;
end
function popitem() : KeyValuePair<K, V>;
Result := wrappee.Last();
wrappee.Remove(Result.Key);
function setdefault(key : K; &default : V := default(V)) : V;
wrappee[key] := &default;
procedure update(params pairs: array of (K, V));
procedure update(seqOfPairs : sequence of (K, V));
function values() := wrappee.Values;
static function operator or(d1 : dict<K, V>; d2 : dict<K, V>) : dict<K, V>;
Result := new dict<K, V>(d1.wrappee);
foreach var p in d2.wrappee do
Result[p.Key] := p.Value;
static function operator implicit(d : PABCSystem.Dictionary<K, V>) : dict<K, V> := new dict<K, V>(d);
function GetEnumerator() : IEnumerator<KeyValuePair<K, V>> := wrappee.GetEnumerator();
{$endregion STANDARD CONTAINERS}
//Standard functions with Lists
function len<T>(lst: list<T>): integer;
function len<T>(st: &set<T>): integer;
function len<K, V>(dct: dict<K, V>): integer;
function len<T>(arr: array of T): integer;
function len(s: string): integer;
function sorted<T>(lst: list<T>): list<T>;
function sum(s: sequence of boolean): integer;
function sum(s: sequence of integer): integer;
function sum(s: sequence of real): real;
function !assign<T>(var a: T; b: T): T;
function !pow(x, n: integer): integer;
function !pow(x, n: biginteger): biginteger;
function !pow(x: integer; y: real): real;
function !pow(x: real; y: real): real;
function bigint(x: integer): biginteger;
function !pow_recursion(x, n: integer): integer;
function !pow_recursion(x, n: biginteger): biginteger;
// TUPLES BEGIN
function !CreateTuple<T>(v: T): System.Tuple<T>;
function !CreateTuple<T1, T2>(
v1: T1; v2: T2
): System.Tuple<T1, T2>;
function !CreateTuple<T1, T2, T3>(
v1: T1; v2: T2; v3: T3
): System.Tuple<T1, T2, T3>;
function !CreateTuple<T1, T2, T3, T4>(
v1: T1; v2: T2; v3: T3; v4: T4
): System.Tuple<T1, T2, T3, T4>;
function !CreateTuple<T1, T2, T3, T4, T5>(
v1: T1; v2: T2; v3: T3; v4: T4; v5: T5
): System.Tuple<T1, T2, T3, T4, T5>;
function !CreateTuple<T1, T2, T3, T4, T5, T6>(
v1: T1; v2: T2; v3: T3; v4: T4; v5: T5; v6: T6
): System.Tuple<T1, T2, T3, T4, T5, T6>;
function !CreateTuple<T1, T2, T3, T4, T5, T6, T7>(
v1: T1; v2: T2; v3: T3; v4: T4; v5: T5; v6: T6; v7: T7
): System.Tuple<T1, T2, T3, T4, T5, T6, T7>;
// TUPLES END
type
biginteger = PABCSystem.BigInteger;
tuple = System.Tuple;
!tuple1<T> = System.Tuple<T>;
!tuple2<T1, T2> = System.Tuple<T1, T2>;
!tuple3<T1, T2, T3> = System.Tuple<T1, T2, T3>;
!tuple4<T1, T2, T3, T4> = System.Tuple<T1, T2, T3, T4>;
!tuple5<T1, T2, T3, T4, T5> = System.Tuple<T1, T2, T3, T4, T5>;
!tuple6<T1, T2, T3, T4, T5, T6> = System.Tuple<T1, T2, T3, T4, T5, T6>;
!tuple7<T1, T2, T3, T4, T5, T6, T7> = System.Tuple<T1, T2, T3, T4, T5, T6, T7>;
empty_list = class
class function operator implicit<T>(x: empty_list): list<T>;
Result := new list<T>();
empty_set = class
class function operator implicit<T>(x: empty_set): &set<T>;
Result := new &set<T>();
empty_dict = class
class function operator implicit<K, V>(x: empty_dict): dict<K, V>;
function !empty_list(): empty_list;
function !empty_dict(): empty_dict;
implementation
PABCSystem.Print();
Result := PABCSystem.ReadlnString();
PABCSystem.Print(s);
function enumerate<T>(s: sequence of T; start: integer): sequence of (integer,T)
:= s.Numerate(start);
function filter<T>(cond: T -> boolean; s: sequence of T): sequence of T
:= s.Where(cond);
function sorted<T>(s: sequence of T; reverse: boolean): sequence of T
:= reverse ? s.OrderDescending : s.Order;
function sorted<T,T1>(s: sequence of T; key: T -> T1; reverse: boolean): sequence of T
:= reverse ? s.OrderByDescending(key) : s.OrderBy(key);
function int(val: string): integer := integer.Parse(val);
function int(val: real): integer := round(val);
if b then
Result := 1
Result := TypeName(obj)
.Replace('<', '[')
.Replace('>', ']')
.Replace('empty_list', 'list[anytype]')
.Replace('empty_set', 'set[anytype]')
.Replace('empty_dict', 'dict[anytype]')
.Replace('integer', 'int')
.Replace('string', 'str')
.Replace('real', 'float')
.Replace('boolean', 'bool')
.Replace('System.Numerics.BigInteger', 'bigint');
function int(obj: object): integer := Convert.ToInt32(obj);
function str(val: object): string := val.ToString();
function float(val: string): real := real.Parse(val);
function float(x: integer): real := PABCSystem.Floor(x);
function bool(val: integer): boolean := Convert.ToBoolean(val);
Result := PABCSystem.Range(s, e - PABCSystem.Sign(step), step);
Result := PABCSystem.Range(s, e - 1);
Result := PABCSystem.Range(0, e - 1);
function abs(x: integer): integer := if x >= 0 then x else -x;
function abs(x: real): real := PABCSystem.Abs(x);
function pow(x,y: real): real := PABCSystem.Power(x,y);
function pow(x: real; n: integer): real := PABCSystem.Power(x,n);
function pow(x: BigInteger; n: integer): BigInteger := PABCSystem.Power(x,n);
function len<T>(lst: list<T>): integer := lst.!count;
function len<T>(st: &set<T>): integer := st.!count;
function len<K, V>(dct: dict<K, V>): integer := dct.!count;
function len<T>(arr: array of T): integer := arr.Length;
function len(s: string): integer := s.Length;
var newList := lst.copy();
newList.sort();
Result := newList;
function sum(s: sequence of boolean): integer := s.Select(x -> Convert.ToInt32(x)).Sum();
function sum(s: sequence of integer): integer := s.Sum();
function sum(s: sequence of real): real := s.Sum();
a := b;
Result := a;
if (n < 0) then
raise new System.ArgumentException('возведение в степень не работает для целой отрицательной степени типа bigint.');
Result := !pow_recursion(x, n);
if (n = 0) then
else begin
Result := !pow_recursion(x, n div 2);
Result *= Result;
if ((n mod 2) = 1) then
Result *= x;
raise new System.ArgumentException('возведение в степень не работает для целой отрицательной степени, используйте привидение к типу с плавающей точкой.');
function !pow(x: integer; y: real): real := Power(x, y);
function !pow(x: real; y: real): real := Power(x, y);
Result := x;
function &set<T>.isdisjoint(other : sequence of T) : boolean;
if other = nil then
raise new System.ArgumentNullException('other', 'Null object is not iterable');
var c1 := wrappee.Count;
var c2 := other.Count();
if (c1 = 0) or (c2 = 0) then
Result := true
if c1 >= c2 then
Result := other.All(elem -> not wrappee.Contains(elem))
var otherSet := new HashSet<T>(other);
Result := wrappee.All(elem -> not otherSet.Contains(elem));
function get_keys<K, V>(dct: Dictionary<K, V>):= dct.keys;
function get_values<K, V>(dct: Dictionary<K, V>):= dct.values;
function !CreateTuple<T>(v: T): System.Tuple<T> := Tuple.Create(v);
): System.Tuple<T1, T2>
:= (v1, v2);
): System.Tuple<T1, T2, T3>
:= (v1, v2, v3);
): System.Tuple<T1, T2, T3, T4>
:= (v1, v2, v3, v4);
): System.Tuple<T1, T2, T3, T4, T5>
:= (v1, v2, v3, v4, v5);
): System.Tuple<T1, T2, T3, T4, T5, T6>
:= (v1, v2, v3, v4, v5, v6);
): System.Tuple<T1, T2, T3, T4, T5, T6, T7>
:= (v1, v2, v3, v4, v5, v6, v7);
Result := true;
foreach var elem in s do
if (not elem) then
Result := false;
break;
function all(s: sequence of integer): boolean := all(s.Select(x -> Convert.ToBoolean(x)));
if (elem) then
function any(s: sequence of integer): boolean := any(s.Select(x -> Convert.ToBoolean(x)));
function ToDictionary<T, U>(Self: sequence of System.Tuple<T, U>): dict<T, U>; extensionmethod;
Result := Self.ToDictionary(x->x[0],x->x[1]);
function !empty_list(): empty_list := new empty_list();
function !empty_dict(): empty_dict := new empty_dict();
function round(val: real): integer := PABCSystem.round(val);
var temp := '';
var i := 0;
while i <= s.Length - 1 do
if (i <= s.Length - 1) and (s.Substring(i, 1) = ' ') then
yield temp;
temp := '';
i += 1;
temp += s[i];
if ((fmt.ToLower() = 'x') or (fmt = 'b') or (fmt = 'd')) then
var HexChars := '0123456789abcdef';
if (fmt = 'X') then
HexChars := HexChars.ToUpper();
var value := Cardinal(i);
var radix := 10;
if (fmt.ToLower() = 'x') then radix := 16;
if (fmt = 'b') then radix := 2;
if value = 0 then
Result := '0';
Exit;
while value > 0 do
var digit := value mod radix;
Result := HexChars[digit + 1] + Result;
value := value div radix;
if (fmt[1] = '.') then
Result := !format(i + 0.0, fmt);
raise new System.ArgumentException('Неверный формат для целочисленного аргумента');
var digits: integer;
if (fmt.Length >= 3) and (fmt[1] = '.') and (fmt.EndsWith('f')) then
var numStr := fmt.Substring(1, fmt.Length - 2);
if TryStrToInt(numStr, digits) then
var intPart := Trunc(val);
if (digits = 0) then
Result := intPart.ToString;
var frac := Abs(val - intPart);
var fracPart := Round(frac * Power(10, digits));
var fracStr := fracPart.ToString;
while fracStr.Length < digits do
fracStr := '0' + fracStr;
Result := intPart.ToString + '.' + fracStr;
raise new System.ArgumentException('Неверный формат для вещественного аргумента');
Result := '';
raise new System.ArgumentException('Формат не соответствует типу данных выражения в f-строке');
end.