2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1 ... 41, 42, 43, 44, 45, 46, 47 ... 53  След.

А вам пакет PARI/GP интересен?
Да 82%  82%  [ 56 ]
Нет 6%  6%  [ 4 ]
Не уверен(а) 12%  12%  [ 8 ]
Всего голосов : 68
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение21.05.2023, 17:58 
Заслуженный участник


20/08/14
11179
Россия, Москва
gris в сообщении #1594605 писал(а):
Как укорачивать вектор?
Код:
? v=[1,2,3,4,5]; print(v[2..4])
[2, 3, 4]
В качестве последнего элемента можно указывать например его размер #v.
Можно конечно и переменные использовать вместо конкретных чисел.

gris в сообщении #1594605 писал(а):
Отбросить или начало или хвост.
Код:
? v=[1,2,3,4,5]; print(v[3..#v])
[3, 4, 5]
? v=[1,2,3,4,5]; print(v[1..3])
[1, 2, 3]

gris в сообщении #1594605 писал(а):
Как напечатать число 23454567654 в виде
23 454 567 654 с помощью printf?
Если речь про разделители групп разрядов, то никак.
Обходной манёвр: перевести число в массив цифр по модулю 1000, потом объединить массив в строку с разделителями пробелом (или любым другим):
Код:
? x=1234567890123456; d=digits(x,1000); print(d); s=strjoin(d," "); print(s)
[1, 234, 567, 890, 123, 456]
1 234 567 890 123 456

Вообще связка strsplit/strjoin весьма мощная, хоть и медленная, можно делать много красивых вещей.

Теперь по сортировке.
Преобразование вектора чисел в одно число с последующей сортировкой и преобразованием обратно -- вполне нормальный подход. Тем более что можно выбрать в каком порядке преобразовывать числа для их правильной сортировки.
Преобразовать строку в длинное число можно так:
Код:
? s="34332 3 5 433 445 678"; v=eval(strsplit(s," ")); x=fromdigits(v,10^6)
34332000003000005000433000445000678
Преобразовать обратно уже показывал, но ещё раз:
Код:
? x=34332000003000005000433000445000678; d=digits(x,10^6); print(d); s=strjoin(d," "); print(s)
[34332, 3, 5, 433, 445, 678]
34332 3 5 433 445 678
Чтобы последующая сортировка была в порядке 2,3,4,5,6,1 столбцов, надо перед объединением вектора в одно число переставить его элементы желаемым образом, например так:
Код:
? s="34332 3 5 433 445 678"; v=eval(strsplit(s," ")); v=concat(v[2..6],v[1])
[3, 5, 433, 445, 678, 34332]

На самом деле для сортировки массива векторов вовсе не обязательно их преобразовывать в числа, можно и сразу vecsort натравить:
Код:
? v=[[3,5,433,445,678,34332],[3,5,46,33,366,5639],[3,5,46,55,78,456]]; print(v); print(vecsort(v))
[[3, 5, 433, 445, 678, 34332], [3, 5, 46, 33, 366, 5639], [3, 5, 46, 55, 78, 456]]
[[3, 5, 46, 33, 366, 5639], [3, 5, 46, 55, 78, 456], [3, 5, 433, 445, 678, 34332]]

Если бы у Вас был не вектор/массив векторов, а матрица, то подматрицы (в том числе отдельные строки или столбцы) из неё можно вытаскивать так:
Код:
? m=matrix(4,3,x,y,y*5+x)
[6 11 16]
[7 12 17]
[8 13 18]
[9 14 19]
? m[,2]
[11, 12, 13, 14]~
? m[,2..3]
[11 16]
[12 17]
[13 18]
[14 19]
? m[2..4,1]
[7, 8, 9]~
? m[2..4,1..2]
[7 12]
[8 13]
[9 14]
? m[2..4,]
[7 12 17]
[8 13 18]
[9 14 19]

А чтобы vecsort не хапала слишком много памяти под результат (если он большого размера, не просто вектор чисел), то можно вместо готовой перестановки получать лишь порядок индексов и потом идти в указанном им порядке по исходному вектору и сохранять данные куда и как надо:
Код:
? v=[[3,5,433,445,678,34332],[3,5,46,33,366,5639],[3,5,46,55,78,456]]; print(v); ind=Vec(vecsort(v,,1)); print(ind); foreach(ind,i, print(v[i]););
[[3, 5, 433, 445, 678, 34332], [3, 5, 46, 33, 366, 5639], [3, 5, 46, 55, 78, 456]]
[2, 3, 1]
[3, 5, 46, 33, 366, 5639]
[3, 5, 46, 55, 78, 456]
[3, 5, 433, 445, 678, 34332]


-- 21.05.2023, 18:09 --

Dmitriy40 в сообщении #1594640 писал(а):
Обходной манёвр: перевести число в массив цифр по модулю 1000, потом объединить массив в строку с разделителями пробелом (или любым другим):
К сожалению это часто работает некорректно:
Код:
? x=1234567890023456; d=digits(x,1000); print(d); s=strjoin(d," "); print(s)
[1, 234, 567, 890, 23, 456]
1 234 567 890 23 456
Ну тогда можно преобразовать каждую "цифру" в строку отдельно через strprintf, а потом уж объединить в единую строку:
Код:
? x=1234567890023456; d=digits(x,1000); for(i=2,#d, d[i]=strprintf("%03d",d[i]);); d[1]=Str(d[1]); print(strjoin(d," "));
1 234 567 890 023 456
Это правильно работает и для чисел до 1000 (и до 10 тоже).

-- 21.05.2023, 18:48 --

Вашу задачу -- сортировку массива векторов чисел из текстовых строк по 2, 5, 1 элементу (ну для примера) -- можно решить в одну строчку:
Код:
? s=["34332 3 5 433 445 678", "5639 3 5 46 33 366", "456 3 5 46 55 78"] \\Реально заменимо на s=readstr(file); вообще без всяких циклов
["34332 3 5 433 445 678", "5639 3 5 46 33 366", "456 3 5 46 55 78"]
? vecextract(s,vecsort(eval(apply(t->vecextract(strsplit(t," "),[2,5,1]),s)),,1))
["5639 3 5 46 33 366", "456 3 5 46 55 78", "34332 3 5 433 445 678"]
Тут сначала делим строки на кусочки, выбираем только нужные столбцы (и в нужном для сортировки порядке), преобразуем строки в числа, получаем вектор перестановок для отсортированного результата, ну и переставляем исходный массив строк в желаемом порядке.

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение21.05.2023, 18:57 
Заслуженный участник
Аватара пользователя


13/08/08
14457
Dmitriy40
Спасибо. Возьмусь за внимательное изучение. Насчёт сокращения вектора вот что понималось. Скажем, поступает вектор с длинным нулевым хвостом неизвестной длины. Я делал так: в цикле находил первый от конца ненулевой элемент. А далее переносил вектор в другой соответствующей длины. А мне казалось, что встречал где-то функцию усекновения нулевого начала или хвоста.
Вот понял, что можно вырезать три элемента:
a=concat( a[1..5], a[9..2000] ) :-)

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение21.05.2023, 19:16 


05/09/16
11541
gris в сообщении #1594620 писал(а):
В PARI многие вещи делаются одной функцией, но надо до неё добраться.
Ну вот, например,
[ 111, 22, 33 ]
[ 11, 543, 77 ]
[ 111, 22, 32 ]
после сортировки
[ 11, 543, 77 ]
[ 111, 22, 32 ]
[ 111, 22, 33 ]

Вот так попробуйте:
? v=[[111,22,33],[11,543,77],[111,22,32]];
? print(vecsort(v,[2,3]))
[[111, 22, 32], [111, 22, 33], [11, 543, 77]]

В доках есть объяснение по функции vecsort(x, {cmpf}, {flag = 0}) . Если параметр cmpf присутвует, то
Цитата:
* a vector: sort lexicographically according to the components listed in the vector. For example, if cmpf = [2,1,3], sort with respect to the second component, and when these are equal, with respect to the first, and when these are equal, with respect to the third.

gris в сообщении #1594605 писал(а):
Надо их отсортировать по возрастанию сначала по второму элементу, потом вложенно по остальным (как это правильно называется?).

То, что вы хотите, уже есть в vecsort() - для вектора векторов можно "штатно" указать порядок компонентов по которым сортировать.

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение21.05.2023, 19:42 
Заслуженный участник
Аватара пользователя


13/08/08
14457
wrest
спасибо.
я, правда, потыкал и понял, что мне нужно
vecsort(v,[1..3]), но по вашему намёку осознал, что нужно и RTFMить иногда :oops: .
Мне надо потеребить эту штуку практически.
vecsort(v,[3,2,1]) понравились.
А если сортировать тысячу векторов? А попробую

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение21.05.2023, 19:49 


05/09/16
11541
gris в сообщении #1594650 писал(а):
А если сортировать тысячу векторов?

Дык какая разница сколько сортировать... Если конечно сортировать гигабайты, тогда наверное будет заметно, а так-то мгновенно всё.

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение21.05.2023, 20:08 
Заслуженный участник
Аватара пользователя


13/08/08
14457
да я не о времени, а о подготовке.
Хотя, наверное, по мотивам сегодняшнего урока можно собрать игрушку:
Код:
v=[];
for( i=1,20,
   v=concat(v,[[random(10),random(10),random(10)]]); 
);
print(v);
print(vecsort(v,[1,2,3]))

Получилось интересненько.

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение21.05.2023, 20:15 
Заслуженный участник


20/08/14
11179
Россия, Москва
А concat-то зачем? Он же страшно медленный! Можно же проще:
v=vector(20,i,[random(10),random(10),random(10)]);

wrest
Кстати спасибо, тоже не знал про vecsort(,[]).

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение21.05.2023, 20:42 
Заслуженный участник
Аватара пользователя


13/08/08
14457
а я хотел из файла считывать
Код:
{
  tin= fileopen("C:/GRIS/list_of_12.txt");
  a=[];

  while (str = filereadstr(tin),
    a=concat( a,[eval(strsplit(str, " "))] );
  );

  a=vecsort(a,[2..12]);
  for( i=1,k, print(a[i]) ); 
}

И работает! Спасибо Dmitriy40 и wrest :-) :-) :-)

Чем мне нравится ПАРИ. Можно не долго думая накидать программку и она порадует. Потом, обратившись за советом к докам (во всех смыслах :-) ) и старательно впитав новые знания, можно улучшить эту программку и забыть её, но в следующий раз всё будет лучше. ВотЪ.

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение21.05.2023, 20:43 


05/09/16
11541
gris в сообщении #1594653 писал(а):
да я не о времени, а о подготовке.

Так вы писали что уже всё готово:
gris в сообщении #1594605 писал(а):
Они сидят в текстовом файле по одному вектору в строке.

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение21.05.2023, 20:49 
Заслуженный участник


20/08/14
11179
Россия, Москва
gris
Из файла прекрасно читаются прямо в вектор строк: a=readstr("C:/GRIS/list_of_12.txt");
После чего вектор строк сортируется по числам в столбцах 2,5,1: aa=vecextract(a,vecsort(eval(apply(t->strsplit(t," "),a)),[2,5,1],1));

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение21.05.2023, 21:17 


05/09/16
11541
gris в сообщении #1594658 писал(а):
а я хотел из файла считывать

Если, кстати, у вас текстовый файл вот такого вида, например vector.txt буквально такой, т.е. со скобками и запятыми (можете добавить или убрать пробелы по вкусу):
Код:
[111,22,33]
[11,543,77]
[111,22,32]

То считать его и сразу сортировать по-вашему можно прямо так, как вы любите, в одну строку, без создания (явного) промежуточного вектора строк и парсинга каждой строки :mrgreen: :
? v=vecsort(readvec("vector.txt"),[2,3]);
? print(v)
[[111, 22, 32], [111, 22, 33], [11, 543, 77]]

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение21.05.2023, 21:41 
Заслуженный участник
Аватара пользователя


13/08/08
14457
красивое.
wrest, попробовал и это. исходные данные подредактировал и вот оно:
Код:
v=vecsort( readvec("C:/GRIS/list_of_12.txt"),[3..12] );
for( i=1,#v, print(v[i]) ); 

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение21.05.2023, 22:56 


05/09/16
11541
gris в сообщении #1594668 писал(а):
исходные данные подредактировал

Если, кстати, вы будете часто манипулировать текстом

(Оффтоп)

(ну типа заменить пробелы на запятые, добавить скобки и т.п.) то в линуксе (ну и в виндовсе наверное, есть аналоги) есть чрезвычайно могучие штуки которые это умеют.
Например ваша задача с прежним исходным файлом vector.txt с содержанием
Код:
[111,22,33]
[11,543,77]
[111,22,32]

легко сортируется командой sort так как вы хотели:
Код:
~ $ sort -t ',' -nk2 -nk3 vector.txt
[111,22,32]
[111,22,33]
[11,543,77]
~ $

Это конечно немного офтоп, но просто pari/gp не слишком заточен на манипуляцию строками, хотя и может.
Ну и awk с sed-ом конечно... Могут всё :roll:
С другой стороны, чтобы вам не манипулировать при вводе, делайте промежуточные файлы подходящими при выводе, ведь вы выводите тоже из pari/gp так что можете сделать нужный для ввода формат сразу при выводе.

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение22.05.2023, 10:07 
Заслуженный участник
Аватара пользователя


13/08/08
14457
Под впечатлением от вчерашнего решил побаловаться с векторами. Типа трёхмерных

a=[
[[111,112,113],[121,122,123],[131,132,133]],
[[211,212,213],[221,222,223],[231,232,233]],
[[311,312,313],[321,322,323],[331,332,333]]];
print( a[1][2] );
print( a[2][3][1] );
print( sum( i=1,3, a[i][i][i]) );

[121, 122, 123]
231
666

Есть ли в этом какой-то смысл? К чему можно применять? Какие есть средства обработки?

 Профиль  
                  
 
 Re: интерактивный курс: введение в программирование на PARI/GP
Сообщение22.05.2023, 12:47 
Заслуженный участник


20/08/14
11179
Россия, Москва
Смысл есть всегда. Или его можно придумать. Или он сам появится из решаемой задачи.
Например уже в известной Вам задаче быстрого (на самом деле быстрого, а не на PARI) поиска симметричных цепочек возникают четырёхмерные структуры данных.
Учитывая отсутствие стандартных типов данных для матриц размерности выше второй, только на векторах их и строить.
Любое пространственное скалярное поле уже требует трёхмерной матрицы, а если поле не скалярное или не одно (нужно несколько величин в каждой точке), то и четырёхмерной (точнее чаще трёхмерной матрицы векторов с разнородными элементами). И кстати нередко вектор векторов удобнее матрицы - если матрица нужна не строго прямоугольная, хороший и известный Вам пример - список допустимых остатков по модулю простого для конкретного паттерна, для каждого простого он своей длины, а если паттернов больше одного, то вот уже и трёхмерная структура.
Средства обработки или отсутствуют (как и сами такие типы данных), или базируются на том что это всё же вектора.
Но можно считать что если вы не знаете зачем это нужно -- то оно вам и не нужно. ;-) Т.е. потребность может идти от задачи, а не от теоретических измышлений.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 781 ]  На страницу Пред.  1 ... 41, 42, 43, 44, 45, 46, 47 ... 53  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: gris


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group