Ну, пока у нас нет срезов, - надо использовать фильтрацию с индексом.
begin
var s := Seq(6,2,8,1,4,9,3,7,5);
var hs := HSet(s.Where((x,i)->i mod 2 = 0));
hs.Println
end.
Ну, пока у нас нет срезов, - надо использовать фильтрацию с индексом.
begin
var s := Seq(6,2,8,1,4,9,3,7,5);
var hs := HSet(s.Where((x,i)->i mod 2 = 0));
hs.Println
end.
Спасибо за красивое решение! Использовать лямбду с двумя параметрами, а работать только с одним в голову не пришло. Только для “каждый второй” надо условие на <> поменять или просто взять Odd(i). Тут же счет с нуля идет, а не с единицы.
Попутно вопрос возник. Или я чего-то не понимаю - и тогда все эти SeqGen - обезьяна с гранатой, или я все понимаю правильно, и это ошибка.
begin
var s:=SeqGen(7,1,t->t+1);
s.Select((x,i)->Rec(x,i)).Println;
s.Select((x,i)->Rec(x,i)).Println;
end.
Выдача:
(1,0) (2,1) (3,2) (4,3) (5,4) (6,5) (7,6)
(8,0) (9,1) (10,2) (11,3) (12,4) (13,5) (14,6)
А теперь так:
begin
var s:=Seq(1,2,3,4,5,6,7);
s.Select((x,i)->Rec(x,i)).Println;
s.Select((x,i)->Rec(x,i)).Println;
end.
И выдача:
(1,0) (2,1) (3,2) (4,3) (5,4) (6,5) (7,6)
(1,0) (2,1) (3,2) (4,3) (5,4) (6,5) (7,6)
Я понимаю. что лямбда t->t+1 “толкает” к наращиванию генерируемых значений на единицу (она с этой целью и писалась), понимаю, что механизм вычисления членов последовательности “ленивый” (и это отлично), но почему при повторном обращении к последовательности игнорируется установка начального значения в единицу? Когда SeqRandom - там вопросов нет, но тут-то?
Ну, это ошибка в реализации. Неожиданная - на ровном месте. Ищем.
Ошибку с последовательностями исправили
Ну, это ошибка в реализации. Неожиданная - на ровном месте. Ищем.
Еще один “сюрпризец”. Неожиданный, раньше работало нормально.
// PascalABC.NET 3.1, сборка 1171 от 15.02.2016
type
tM=array[1..3,1..3] of integer;
begin
var a:array[1..3,1..3] of integer:=
((1,2,3),(4,5,6),(7,8,9));
Writeln('a: ',a);
var b:tM:=((1,2,3),(4,5,6),(7,8,9));
Writeln('b: ',b);
end.
Результат выполнения программы:
a: [[1,2,3],[4,5,6],[7,8,9]]
b: ([[1,2,3],[4,5,6],[7,8,9]],1,3)
Известно, что для нахождения суммы членов последовательности можно использовать метод .Sum, для нахождения среднего арифметического - метод .Average. А вот с произведением все оказывается далеко не так красиво. То ли его решили изначально в LINQ не вводить из-за возможности неконтролируемого арифметического переполнения в операции умножения целых (обычно в целях эффективности контроль переполнения разрядной сетки не делается), то ли еще какая-то есть причина, - но так, или иначе, метода .Prod у нас нет. И приходится выкручиваться. Поскольку разработчикам лучше, чем кому бы то ни было, известна внутренняя “кухня” реализации, хотелось бы получить рекомендацию, как эффективнее (и красивее) находить произведение членов числовой последовательности. И необязательно даже по критерию отбора: ведь его при необходимости можно организовать через предшествующий .Where.
Product
это, как и Sum
, как и многое другое, это экземпляр свёртки (fold, в Линке это называется Aggregate
). Примерно так.
a.Aggregate(1, (prod, x) -> prod * x);
(Надеюсь, с синтаксисом нигде не напутал, WDE не работает, чтобы проверить.)
Есть известная байка на схожую тему в мире функционального программирования.
fac n = product [1…n] - вот это как раз то, чего бы хотелось увидеть))) А байку оценил, “внушаить” (с)
И - да, спасибо, работает выражение.
Гхм, такого количества способов я не видел. Спасибо! Интересный материал.
Print() удобен тем, что он разделяет пробелом выводимые значения, но это хорошо лишь для целых величин и, возможно, символов. А для вещественных это зло… Вот если бы имелся какой-то PrintReal, выводящий вещественные (с автоприведением к ним целочисленных) значения, у которого первый параметр задавал бы число знаков в дробной части (в целой не надо, потому что Print’ом таблицы все равно не рисуют), это было бы превосходно.
В .Net это делается переопределением метода ToString или добавлением строки форматирования к тому же complex.ToString("{0:MyComplex}"). Не много замарочливо, но возможно каждому самому под себя делать любой вывод в зависимости от типа Возможно ли это реализовать тут?
Всё, что есть в библиотеке .NET, будет работать и тут
Обновился сегодня до последней версии и заметил одну странность - есть у меня один проект WinForms - компилируется он успешно, а при запуске падает по System.ArgumentNullException: Value cannot be null.
Внутренняя ошибка компилятора в модуле [pabcnetc.exe] :'System.Exception: System.ArgumentNullException: Value cannot be null.
Parameter name: key
at System.Collections.Generic.Dictionary`2.FindEntry(TKey key)
at System.Collections.Generic.Dictionary`2.ContainsKey(TKey key)
at PascalABCCompiler.NETGenerator.ILConverter.ConvertFromTree(IProgramNode p, String TargetFileName, String SourceFileName, CompilerOptions options, String[] ResourceFiles)
at PascalABCCompiler.CodeGenerators.Controller.Compile(IProgramNode ProgramTree, String TargetFileName, String SourceFileName, CompilerOptions options, Hashtable StandartDirectories, String[] ResourceFiles)
at PascalABCCompiler.Compiler.Compile()'
и потом уже ничего не собирается. при этом собранный exe’шник запускается и работает нормально, проблема только при попытке запуска прямо из IDE. раньше это работало.
Это странно. У нас все проекты WinForms работают
А это пасхалочка от разработчиков такая? промахнулся и качай в 10 раз больше?) а я нашел) Случайно увидел что ссылка при наведении не целиком подсвечивается.
Тут вот у @Ret_ReT была проблема с запуском приложения с использованием CRT, я попробовал запустить свой проект winForms без связи с оболочкой, появилась консоль ProgramRunner.exe с единственной строкой - программа завершена, нажмите любую клавишу… - как будто запускается пустая программа типа begin end. То есть вроде бы ничего общего, но на мысли наталкивает.
В последних версиях появились операции, порождающие из обычной последовательности “последовательности последовательностей” или разбивающие её на несколько последовательностей. Возник вопрос: как эффективно “собрать назад” такие конструкции?
// PascalABC.NET 3.1, сборка 1200 от 13.03.2016
begin
var a:=Range(0,11); // Sequence of integer (по Intellisence)
Writeln(a); // [0,1,2,3,4,5,6,7,8,9,10,11]
var b:=a.SplitAt(4); // System.Tuple<integer>
Writeln(b); // ([0,1,2,3],[4,5,6,7,8,9,10,11])
var b1:=b.Item1+b.Item2; // integer - ОШИБКА Intellisence?
Writeln(b1); // [0,1,2,3,4,5,6,7,8,9,10,11]
var c:=a.Batch(4); // Sequence of integer
Writeln(c); // [[0,1,2,3],[4,5,6,7],[8,9,10,11]]
// как все это собрать "назад" в исходную последовательность?
end.
SelectMany
А нельзя дописать этот самый SelectMany, как он должен выглядеть в предложенной программе?