Версия PascalABC.NET 3.2

Да, выложил с Fill. Поторопился…

1 лайк

Спасибо, работает. Но, быть может, в данном случае было бы более последовательным писать так:

begin
  var a := MatrRandom(4,3,10,50); 
  a.Println; Writeln;
  var b := a.Rows.Select(x->x.ToArray).ToArray;
  Sort(b,(x,y)->x[0]-y[0]);
  a.Fill((i,j)->b[i][j]);
  a.Println;
end.

Все же у нас получается у b тип System.Int32[][], поэтому и b[i][j]

Из любопытства сравнил производительность.

begin
  Milliseconds;
  var a:=MatrRandom(100,100,-1000,1000);
  for var i:=1 to 10000 do begin
    var b := a.Rows.Select(x->x.ToArray).ToArray;
    Sort(b,(x,y)->x[1]-y[1]);
    a.Fill((i,j)->b[i,j]);
    end;
  var t:=MillisecondsDelta;
  Writeln(t);
end.

Время выполнения 6859

function MatrSortByCol<T>(Self:array [,] of T; n:integer):
    array [,] of T; extensionmethod;
begin
  Result:=new T[Self.RowCount,Self.ColCount];
  var v:=Self.Col(n).Select((x,i)->(x,i)).OrderBy(xi->xi[0]).ToArray;
  for var i:=0 to Self.RowCount-1 do
    Result.SetRow(i,Self.Row(v[i][1]))
end;

begin
  Milliseconds;
  var a:=MatrRandom(100,100,-1000,1000);
  for var i:=1 to 10000 do
    a.MatrSortByCol(1);
  var t:=MillisecondsDelta;
  Writeln(t);
end.

Время выполнения 2125

Понятно, что это всего лишь 0.21с против 0.69с на матрице 100х100, но все же тройная разница…

Ну тогда так:

begin
  Milliseconds;
  var a:=MatrRandom(100,100,-1000,1000);
  for var i:=1 to 10000 do 
  begin
    var b := ArrGen(a.RowCount,k->a.Row(k));
    Sort(b,(x,y)->x[1]-y[1]);
    a.Fill((i,j)->b[i][j]);
  end;
  var t:=MillisecondsDelta;
  Writeln(t);
end.
2 лайка

А вот это “правильное решение” - 2766, т.е. 0.28c, вполне сопоставимое с 0.21с, но зато имеющее более короткую запись. Плюс, чисто в функциональном стиле.

3 сообщения перенесены в новую тему: Что-то не работает, потом напишу

Цикл loop появился :slight_smile:

Спасибо, будем иметь в виду. Не знаю, из какого языка он пришел в таком синтаксисе, но жаль, что не из Бейсика))) Там, конечно, вещь…

DO [WHILE булево] [UNTIL булево]
   тело цикла
LOOP [WHILE булево] [UNTIL булево]

Можно сконструировать, что угодно.

Хотя, если подумать, do while и repeat until и так есть. Пожалуй, хотелось бы только “эстетический вариант” бесконечного цикла

loop
   тело цикла

а что он делает? можно пример использования?

loop 5 do
  Print(1)
2 лайка

расскажите предысторию. почему loop do? очень интересно откуда пришло

Не знаю никакой предыстории. Нужен был цикл для начинающих - когда никаких переменных. Ну и просто для использования. loop - цикл, do - по аналогии с еще двумя циклами. Русский перевод - повторить n раз. Скажем, вот пример:

var p := 1.0;
loop 10 do
begin
  Print(p);
  p += 0.1;
end;

Если делать с for, то переменная цикла for - лишняя

Хороший сахарок, теперь бы в PABCSystem.pas во всех методах типа operator*<T>() заменить циклы for var i:=1 to n do на loop n do в качестве наглядного пособия :wink: Я насчитал 10 таких мест.

Да, неплохая идея. Для того и делалось

Даже если loop появится, то в ОГЭ по информатике он явно не скоро войдёт :laughing:

Это нас не заботит.

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

1 лайк

А туда вообще наверно процентов 80-85 PascalABC.NET не входит. Но это вовсе не означает, что их в ответе использовать нельзя (см. методические указания ФИПИ)

Попалась на глаза вот такая задачка:

Создать матрицу с нулями внутри, и единицами на границах.

Увидел реализацию на Питоне и почувствовал, что ко мне вплотную подкралось известное земноводное в готовности приобнять за шею…

import numpy as np Z = np.ones((10,10)) Z[1:-1,1:-1] = 0

Что до первых двух строк, мы так тоже можем, и даже изящнее: var Z:=MatrFill(10,10,1); а вот последняя строка… срезы в двумерном массиве, да еще и в левой части!

Какие будут мысли кроме предложений нагромоздить кучу кода?

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

Конечно, не так коротко:

begin
  var (m,n) := (10,10);
  var a := MatrGen(m,n,(i,j)->(i=0)or(j=0)or(i=m-1)or(j=m-1)?1:0);
  a.Print(1)
end.
1 лайк

Я думал, будет существенно хуже. Сейчас это решение кажется “простым и естественным”. Значит, скорее всего, оно - лучшее. Спасибо еще раз. Наверно, Вы хотели написать

begin
  var (m,n) := (10,10);
  var a := MatrGen(m,n,(i,j)->(i=0)or(j=0)or(i=m-1)or(j=m-1)?1:0);
  a.Print
end.

Иначе можно без var (m,n) := (10,10); обойтись.