Форум программистов, компьютерный форум, киберфорум
Алгоритмы
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.72/25: Рейтинг темы: голосов - 25, средняя оценка - 4.72
6 / 6 / 5
Регистрация: 29.01.2015
Сообщений: 467

Как научиться олимпиадному программированию

15.03.2016, 07:08. Показов 6267. Ответов 63
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Что делать, если я уже более 5 лет пишу код в веб, c++, но, я не умею решать задачи из олимпиад? Какие сайты изучить?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.03.2016, 07:08
Ответы с готовыми решениями:

Можно ли научиться программированию???
Здравствуйте, интерисует мнение прогаммистов: как вы считаете, можно ли научиться программировать и стать профессионалом путем большой...

Хочу научиться программированию. Какой язык выбрать?
Какой язык выбрать с учётом того, что я ничего про это не знаю.... :p Хочу научиться писать хотя-бы примитивные проги. :rolleyes: ...

Как научиться проектировать свои приложения?
Доброго времени суток! Недавно начал писать программу для взаимодействия с базой MongoDB (задание в университете), простой аналог...

63
18.03.2016, 12:33
Студворк — интернет-сервис помощи студентам

Не по теме:

Shamil1, Fulcrum_013, бокс по переписке продолжается.

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

0
1978 / 834 / 115
Регистрация: 01.10.2012
Сообщений: 5,171
Записей в блоге: 2
18.03.2016, 12:53
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Во первых это если вам два ядра доступно безраздельно. Во вторых чтобы оно в два потока посчиталось, массив по любому нужно разделить на две части (ну или на n по количеству доступных ядер), произвести подсчет по каждой части по отдельности, потом найти максимальное из результатов.
Совсем не по-любому, нагрузка может пере-распределяться (напр schedule dynamic в omp). Вообще такие задачи плохо масштабятся (слишком мал кластер). Кстати считать максимум при параллельном выполнении не так уж просто, умеете?
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
18.03.2016, 14:25
Цитата Сообщение от Igor3D Посмотреть сообщение
Кстати считать максимум при параллельном выполнении не так уж просто, умеете?
Ну там для этих целей и приделан operator << (const TMax& R); чтобы результаты параллельно посчитанных частей объединять. Ну или вообще разнородных последовательностей.

Добавлено через 24 минуты
Цитата Сообщение от Igor3D Посмотреть сообщение
нагрузка может пере-распределяться
все в зависимости от зависимости как планировщику приспичит в корреляции с 4-ой производной от темепературы на поверхности Марса (ну исходим от того что температура на поверхности Марса таки зависит от мощности солнечного излучения, а температура проца таки коррелирует с количеством оного, при этом планировщик предполагает а термодатчик располагает ).

Добавлено через 2 минуты

Не по теме:


Цитата Сообщение от DeadPenguin Посмотреть сообщение
бокс по переписке продолжается.
Ведь бокс не драка. это спорт отважных и т.д. (C) В.Высоцкий.
Цитата Сообщение от DeadPenguin Посмотреть сообщение
Казалось бы, причём тут Лужков олимпиадное программирование?
Ну дык мер Киева таки по совместительству чемпион мира по боксу и доктор наук.

0
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,912
18.03.2016, 15:52
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Свертками всех нужных типов обхода не запасешся, а тем более даже в одномерный массив все возможные варианты не упихнешь, не то что в двухмерный или что то посложнее. У вас есть свертка для итерации в обратную сторону? Или четных/нечетных? Или матрицы по двойной спирали?
У меня есть свёртки на все случаи жизни. Всего таких случаев четыре: слева/справа и с начальным значением/без начального значения.

Видимо, Вы не правильно поняли суть этой абстракции. Объект либо можно, сворачивать, либо нельзя. Промежуточных вариантов типа "свернуть часть" или "второй свежести" нет.

"Или четных/нечетных?"
В этом случае надо поменять функцию (ведь нам нужен результат другого типа - не число, а пара чисел). Вы, кстати, сделали то же самое: поменяли функцию с "Max<<Array[i]" на "(i&1?MaxOdd:MaxEven)<<Array[i]".

"Или матрицы по двойной спирали?"
В этом случае надо поменять выборку. Полагаю, что Вы бы тоже поменяли выборку с "for (int i=0;i<Array.Length;i++)" на что-нибудь, что выдавало бы элементы массива в нужном порядке.
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
19.03.2016, 07:37
Цитата Сообщение от Shamil1 Посмотреть сообщение
В этом случае надо поменять выборку.
т.е. алгоритм обхода программировать по любому.
Цитата Сообщение от Shamil1 Посмотреть сообщение
Полагаю, что Вы бы тоже поменяли выборку с "for (int i=0;i<Array.Length;i++)" на что-нибудь, что выдавало бы элементы массива в нужном порядке.
Да. Запросто. При этом можно поменять и количество параллельно работающих при одном проходе счетчиков, либо как в этом примере за один проход подсчитать счетчики фактически по двум выборкам сразу.
Цитата Сообщение от Shamil1 Посмотреть сообщение
У меня есть свёртки на все случаи жизни. Всего таких случаев четыре: слева/справа и с начальным значением/без начального значения.
А для 2D? Ведь в общем случае придется сделать выборку не только самих элементов но и их соседей учитываемых в вычислении значений. Мало того, количество соседей участвующих в функции может быть переменным в зависимости от других параметров. О чем и речь - все эти свертки хороши только в сферическом вакууме.
В реальной же жизни придется программировать топологию выборки на каждом шагу. Причем далеко не всегда результаты пригодны для записи их в 1D массив индексов, хотя бы потому что придется записать и индексы соседей, участвующих в расчете функции. Почему и привел пример с 4-х связной топологией. А если связность/количество слоев связности меняется в зависимости от значений конкретного элемента или даже состояния самого счетчика? А если при этом от значения счетчиков меняется еще и алгоритм обхода выборки как в огромном количестве алгоритмов работающих на 2D растре? Не проще ли сделать какой либо более менее универсальный и легко расширяемый набор счетчиков который можно пользовать прямо в алгоритме обхода, причем с возможностью взаимодействия алгоритма со значением счетчиков, а то и возможностью выбора счетчиком алгоритма расчета следующего шага?
Вся песня в том что все это ФП растет от первого английского компа - Колосса. Который проектировался и использовался для одной задачи - расшифровки шифрограмм записанных на телеграфной перфоленте. У него других методов обхода быть просто не могло. При этом учитывая что расшифровка велась брутфорсом, т.е. перебором всех возможных ключей с подсчетом количества совпадений по всей ленте, и тот факт что шифр постоянно усложнялся, таки приходилось лепить функцию поверх функции, не удивительно что основной задачей их было оценить возможно ли вообще при дальнейшем усложнении шифра, доделкой блоков вычисления поверх существующих пользовать тот же комп, или лучше сразу начать готовить его на свалку и изобретать что то новое, типа польских 2D шифрокарт, которые накладываясь друг на друга со смещением отсекали группы неприменимых ключей. Дальнейшее развитие компьютерной техники было связано в первую же очередь опять же с шифробаталиями между вчерашними союзниками (т.е. те же грабли - отсюда и все это лямбда-свистопляска и необходимость доказательста вычислимости, для универсального же компьютера вычислимость доказана один раз - определением УМТ), и счету артиллерийских таблиц (ну тут как бы тоже банальная табуляция функции нескольких независимых переменных), причем все это естественно в сферическом вакууме от реального мира, в котором нужно отслеживать объекты и моделировать их взаимодействие и перемещение.
Появилась RAM а тем более хранение данных в RAM и алгоритмы использующие случайный доступ и все это ФП оказалось проще выбросить чем перекрутить 2 и более D топологии под свертки. Кстати что самое интересное это понимали еще создатели первого компа с электронной памятью как данных так и программы Z4 так и первого в мире высокоуровнего языка Планкалкуль, И что самое интересное, этот комп использовался для создания первого в мире станка с ЧПУ (1944-ый год). А когда в этом плане опомнились лентомататели? 60-е а то и 70-е? Не удивительно что Германия до сих пор лидер в плане средств промавтоматики и робототехники. Потому что они этим лентомотанием просто не занимались. Хотя бы потому что тут другие задачи - параллельный расчет функций с взаимозависимыми параметрами.
Да для примера, решите как систему линейных уравнений методом Гаусса средствами ФП. Решить в принципе можно, но придется так с бубном поплясать что проще в разработке и эффективнее при вычислениях, таки методами с системой состояний и указателями. И С++ тут будет гораздо эффективнее чем Haskell а тем более Lisp.
Я же не против пользования каллбэками там где они нужны. Например при обработке изменения состояний внешних устройств, ну или оповещениях между объектами. Но как бы при чем тут куцие обрубки объектов под названием замыкание? А тем более солитеры из таких обрубков?

Добавлено через 28 минут
Цитата Сообщение от Shamil1 Посмотреть сообщение
Всего таких случаев четыре: слева/справа и с начальным значением/без начального значения.
слева-справа - для того чтобы не перезаправлять перфоленту шифрограммы после каждого прохода в ручную, пытались ее мотать вперед/назад. Потом на это плюнули и просто закольцевали саму ленту.
С начальным значением/без начального значения. Индикаторная процедура тоже менялась. По одним из них ключ тоже входил в сообщение по другим нет.
Да для такой узкоспециализированной и бесполезной задачи как расшифровка шифрограмм полученных путем параметрической замены символов таки все случаи жизни.
Но если будет банально перестановка символов... а не замена кода....

Добавлено через 22 минуты
Цитата Сообщение от Shamil1 Посмотреть сообщение
В этом случае надо поменять выборку.
Естественно. При этом в общем случае алгоритм выборки зависит от состояния счетчика на каждом шаге.

Добавлено через 10 минут
Поэтому взаимонезависимыми черными ящиками счетчик и алгоритм обхода могут быть исключительно в сферическом вакууме с квазистационарной степенью анизотропности вращения ротора в потоке дивергенции гравискаляра, при условии отрицательности постоянной Авогадро.

Добавлено через 22 минуты
Цитата Сообщение от Igor3D Посмотреть сообщение
Кстати считать максимум при параллельном выполнении не так уж просто, умеете?
Не разделяя последовательность без лока записи в счетчики не получится. А соответственно будет тормознее чем если разделить последовательности на куски, а потом объединить результаты.
Опять же. Есть параллелить нужно там где нужно. К примеру сколько уже бьются над задачей толковой многопоточной компиляции? т.е. пытаются разделить что то на микроуровне, но остается общий словарь типов глобальных переменных и т.п. запись в который требует лока. При этом напрочь забывая что компиляция каждого модуля - по сути отдельная задача, и чтобы при современных мощностях процу надо было бы ускорять компиляцию, то размер кода должен быть таким что количество модулей превысит количество доступных ядер в десятки раз, у каждого из которых словарь свой по определению, должно быть в десятки раз больше количества ядер. т.е. придумали как компиляцию параллелить по большому счету не сейчас, а тогда когда изобрели раздельную компиляцию моулей. По банальной причине. Так быстрее пересчитывать (перекомпилировать) изменения. Ну а линковка не настолько напряжная задача чтобы ее необходимо было параллелить, причем гораздо проще это сделать на старте проги (т.е. динамическая линковка), когда опять же подгрузка каждого модуля по сути отдельная задача, во всяком случае если модуля грузятся однотипно. Нетипичную подгрузку встречал только для OpenGL.
т.е. есть несколько задач - считай каждую на своем ядре. Быстрее будет, чем каждую на кучу ядер завешивать причем пытаясь перпендикуляр распараллелить, в результате только растет ожидание на локах и тасксвитчинг.
0
1978 / 834 / 115
Регистрация: 01.10.2012
Сообщений: 5,171
Записей в блоге: 2
19.03.2016, 10:21
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Не проще ли сделать какой либо более менее универсальный и легко расширяемый набор счетчиков который..
Нет. Надо тупо копи-пастить код пока это не достанет. Я намеренно "сгущаю краски", т.к. прекрасно знаю сколько бед приносит "преждевременное обобщение". Это масса потерянного времени, нервов и классы типа Вашего TMax, о который др программисты будут разбивать ноги.

3D модель - весьма консервативная сущность, мало что в ней изменилось за последние 20 лет. Поэтому если мы считаем bounding box(es) суб-мешей - мы можем и должны забить на всякую общность. Задача должна быть решена за час (максимум). И код должен быть компактный и выразительный, без всяких "турусов на колесах". А то
А если то.. или се.. Так что, тогда придется дублить код? (ой как плоооохо). Ой параметры/callback'и несолидно. не айс!
Поверьте, на практике все это (включая тупое copy-paste) куда лучше и быстрее чем увлечение абстракцией. Общность должна "созреть", до этого нечего рыпаться
0
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,912
19.03.2016, 18:41
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
А для 2D? Ведь в общем случае придется сделать выборку не только самих элементов но и их соседей учитываемых в вычислении значений.
Какой общий случай? Видимо, Вы не поняли, что такое "свёртка".

Посмотрите на свой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class TTreeNode{
       TList<TTreeNode*> FNodes;
       int value;
       ............    
       template <class traverser>void Traverse(traverser &result){ 
                 result<<value; 
                 for (int i=0;Nodes->Count;i++)Nodes->Items[i]->Traverse(result);
       };
       .............
} 
void main(){
      TTreeNode* Nodes;
      ..........
      TMax<int> Max;
      Nodes->Traverse(Max);
}
Обратите внимание "Nodes->Traverse()".
Ваше дерево само знает, как его обходить. А мне Вы предлагаете написать код, который будет обходить экземпляр любого типа данных, который могут написать в будущем?

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
т.е. алгоритм обхода программировать по любому
Тот, кто создаёт тип данных, может указать к каким классам (в математическом смысле, а не ООП) он принадлежит. Если создатель типа укажет, что тип Сворачиваемый, то мне не нужно программировать алгоритм обхода. В этом смысл абстракции Свёртка - её можно применять к Сворачиваемым объектам.

В C++ тоже есть возможность, использовать функциональный стиль. Для этого ввели функцию std::accumulate. Обратите внимание, что итератор обычно предоставляет создатель класса. Вместо Вашего велосипедного Traverse Вам было достаточно добавить в класс Traverse метод, возвращающий итератор.
Преимущества такого подхода по сравнению с велосипедами:
1. Вы сразу получаете доступ к ряду стандартных функций высшего порядка, принимающих итератор.
2. Тому, кто посмотрит на интерфейс Вашего класса, сразу понятно, что делает итератор. А что делает Ваш Traverse и что за traverser ему можно подавать на вход (подойдёт ли мой класс MyClass?) не понятно без дополнительных исследований (кода и/или документации).

Добавлено через 7 минут
Весь текст, написанный Вами дальше основан на неверных предпосылках и потому лишён смысла.

В частности:
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Поэтому взаимонезависимыми черными ящиками счетчик и алгоритм обхода могут быть исключительно в сферическом вакууме
Вод код, который обходит матрицу в хитровывернутом порядке:
C#
1
matrix.Select(cleverlyTurned).Aggregate(Max2)
Добавлено через 4 часа 4 минуты
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Да для примера, решите как систему линейных уравнений методом Гаусса средствами ФП.
Введём новые типы данных:
Haskell
1
2
3
4
type Number = Double   -- число - это число с плавающей точкой
type Vector = [Number] -- вектор - это список чисел
type Row    = [Number] -- строка - это список чисел
type Matrix = [Row]    -- матрица - это список строк
Для примера напишем функцию умножения матрицы на вектор (в алгоритме Гаусса она нам не понадобится):
Haskell
1
2
multiply :: Matrix -> Vector -> Vector
multiply m v = [sum (zipWith (*) row v) | row <- m]
Первая (необязательная) строка указывает, что функция multiply принимает Matrix и Vector, а возвращает Vector.
Во второй строке написано: для каждой строки row матрицы m ("| row <- m") попарно умножаем ("zipWith (*)") все элементы с элементами вектора и суммируем результаты (sum).

А вот код для решения системы линейных уравнений (в рациональных числах, представленных в виде дробей):
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
type Number = Rational
type Vector = [Number]
type Row    = [Number]
type Matrix = [Row]
 
gauss :: Matrix -> Vector -> Vector
gauss a b = resubstitute $ triangular $ zipWith (++) a $ map (\y -> [y]) b
 
triangular :: Matrix -> Matrix
triangular [] = []
triangular m  = row:(triangular $ map f rows)
    where
    (row:rows) = rotatePivot m
    rotatePivot (row:rows)
        | (head row) /= 0 = (row:rows)
        | otherwise       = rotatePivot (rows ++ [row])
    f bs
        | (head bs) == 0 = drop 1 bs
        | otherwise      = drop 1 $ zipWith (-) (map (*c) bs) row
        where 
        c = (head row)/(head bs)  
 
resubstitute :: Matrix -> Vector
resubstitute = reverse . resubstitute' . reverse . map reverse
    where
    resubstitute' [] = []
    resubstitute' (row:rows) = x:(resubstitute' $ map substituteUnknown rows) 
        where 
        x = (head row)/(last row)
        substituteUnknown (a1:(a2:as')) = ((a1-x*a2):as')
        
 
m1 = [[1,1,0], [0,1,1], [1,0,1]] :: Matrix
v1 = [2,3,4] :: Vector
main = print $ gauss m1 v1
Гаусс: Дописываем к матрице справа вектор. Триангулируем матрицу. Обратной заменой получаем ответ.
Триангуляция: Выбираем опорную строку (с ненулевым первым элементом). Каждую строку умножаем на коэффициент c = a1/ai. Повторяем для подматрицы без первой строки и первого столбца.
Выбор опорной строки: пока a1 = 0 убираем строку вниз.
Обратная замена: Для удобства сначала разворачиваем матрицу. На каждом шаге заменяем текущий элемент.

Ответ:
[3 % 2,1 % 2,5 % 2]
то есть,
x1 = 3/2, x2 = 1/2, x3 = 5/2

Добавлено через 22 минуты
p.s. Поменял Double на Rational

Добавлено через 14 минут
http://ideone.com/Bihfof
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
20.03.2016, 00:37
Цитата Сообщение от Shamil1 Посмотреть сообщение
Тому, кто посмотрит на интерфейс Вашего класса, сразу понятно, что делает итератор. А что делает Ваш Traverse и что за traverser ему можно подавать на вход (подойдёт ли мой класс MyClass?) не понятно без дополнительных исследований (кода и/или документации).
Только вот есть одна проблемка с итераторами - их операторы ++ и -- не зависят от состояния счетчика. и состояния элементов которые они обходят. Мало того они становятся не валидны при любом изменении
последовательности. Если алгоритм перестраивает последовательность то итераторы неприменимы.
Цитата Сообщение от Shamil1 Посмотреть сообщение
Если создатель типа укажет, что тип Сворачиваемый, то мне не нужно программировать алгоритм обхода.
К примеру есть тип матрица. Обходить его можно по разному. При этом существует огромное количество алгоритмов обхода при котором индекс следующего в последовательности элемента выбирается в зависимости как от состояния (значения) элемента матрицы так и от состояния счетчика.
Мало того, на практике очень часто встречаются задачи синхронного обхода нескольких последовательностей, при которых следующий шаг обхода (выбор следующего элемента), зависит от состояния счетчиков обхода других последовательностей.
Цитата Сообщение от Shamil1 Посмотреть сообщение
Выбор опорной строки: пока a1 = 0 убираем строку вниз.
Нормальные люди опорную строку по другому ищут. Находят строку с максимальным модулем ведущего элемента и обменивают со строкой в нужной позиции.

Добавлено через 4 минуты
Цитата Сообщение от Igor3D Посмотреть сообщение
мы можем и должны забить на всякую общность
При чем тут меши? Есть общность алгоритма поиска максимума последовательности. надеюсь понятно что подать N-ую точку на вход счетчика минимума / максимума а то и того и другого сразу избавит от кучи ошибок, дав возможность просто сконцентрироваться на описании алгоритма обхода меша, а не на встройке в него алгоритма счетчика.

Добавлено через 25 минут
Цитата Сообщение от Shamil1 Посмотреть сообщение
Какой общий случай
Ну общий случай машины Тюринга. Например с 2D (ND) лентой или с несколькими параллельно обрабатываемыми лентами. Я же говорю - вся эта ФП ахинея растет от задачи у которой была последовательность одной редко встречаемой топологии при этом исключалась перестановка элементов последовательности.

Добавлено через 3 минуты
Цитата Сообщение от Shamil1 Посмотреть сообщение
Если создатель типа укажет, что тип Сворачиваемый, то мне не нужно программировать алгоритм обхода.
Каждый тип последовательности (даже банальный вектор) имеет бесконечное множество вариантов обхода.

Добавлено через 33 минуты
Цитата Сообщение от Igor3D Посмотреть сообщение
Это масса потерянного времени, нервов и классы типа Вашего TMax, о который др программисты будут разбивать ноги.
Все зависит от способности программистов к абстрактному мышлению.
Напомню - абстрактное мышление - способность создавать новые системы отсчета.
В ФП система отсчета в последовательности одна. Соответсвенно ФП непригоден для абстракции.
0
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,912
20.03.2016, 00:41
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Нормальные люди опорную строку по другому ищут. Находят строку с максимальным модулем ведущего элемента и обменивают со строкой в нужной позиции.
Это делается для того, чтобы уменьшить погрешность. В моём случае в этом нет необходимости, так как погрешность равна нулю.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
К примеру есть тип матрица. Обходить его можно по разному. При этом существует огромное количество алгоритмов обхода при котором индекс следующего в последовательности элемента выбирается в зависимости как от состояния (значения) элемента матрицы так и от состояния счетчика.
Вы так ничего и не поняли про свёртку. Все эти варианты обхода не имеют никакого отношения к сворачиваемости объекта.
Зато теперь понятно, почему Вы с таким недоверием относитесь к ФП. Вы просто его не понимаете и не верите, что это работает.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Только вот есть одна проблемка с итераторами - их операторы ++ и -- не зависят от состояния счетчика. и состояния элементов которые они обходят. Мало того они становятся не валидны при любом изменении последовательности. Если алгоритм перестраивает последовательность то итераторы неприменимы.
Я слышал, что один чудак летом сандалии не носит, потому что зимой в них холодно.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Каждый тип последовательности (даже банальный вектор) имеет бесконечное множество вариантов обхода.
Получили русские мужики электропилу из Японии. Положили бревно:
- Вжик! - сказала пила, и бревно пополам.
- Ух ты! - сказали мужики и положили бревно потолще.
- Вжжжик! - сказала пила и ... бревно пополам.
- Ого! - сказали мужики и положили рельсу.
- Вжж-крях! - сказала пила и поломалась.
- Ага!!! - сказали мужики, - То-то же...
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
20.03.2016, 01:57
Цитата Сообщение от Shamil1 Посмотреть сообщение
Ваше дерево само знает, как его обходить
это частный случай.
в общем случае
C++
1
2
3
4
5
6
7
8
9
10
class TTreeNode{
       TList<TTreeNode*> FNodes;
       int value;
       ............    
       template <class traverser>void Traverse(traverser &result){ 
                 Next=SelectNext(result<<value);
                 Next->Traverse(result);                  
       };
       .............
}
Добавлено через 12 минут
Цитата Сообщение от Shamil1 Посмотреть сообщение
Зато теперь понятно, почему Вы с таким недоверием относитесь к ФП.
Оно работает исключительно при нулевой связности элеметов последовательности. Но ведь нулевая связность это далеко не общий случай.
Цитата Сообщение от Shamil1 Посмотреть сообщение
Я слышал, что один чудак летом сандалии не носит, потому что зимой в них холодно.
А я не использую итераторы во первых потому что они unsafe, мало того их и приткнуть то толком некуда. Единственный вид где подобную конструкцию можно пользовать - курсоры БД, но при этом в отличии от итератора в курсор встроено слежение за жизненным циклом элементов последовательности, что по большому счету та еще свистопляска, которая оправдана только на достаточно масштбных задачах. Опять же курсор обычно имеет возможность random-access навигации по последовательности в отличии от итератора, что делает его применимым в последовательностях с ненулевой связностью.

Добавлено через 5 минут
Цитата Сообщение от Shamil1 Посмотреть сообщение
Получили русские мужики электропилу из Японии. Положили бревно:
- Вжик! - сказала пила, и бревно пополам.
- Ух ты! - сказали мужики и положили бревно потолще.
- Вжжжик! - сказала пила и ... бревно пополам.
- Ого! - сказали мужики и положили рельсу.
- Вжж-крях! - сказала пила и поломалась.
- Ага!!! - сказали мужики, - То-то же...
Ну а потом началась практика.
И пиляют бородатые русские мужики этой пилой по 10 кубов леса в день каждый.
А чукча по 100.
Изловчились русские мужики и давай по 20 пилять.
А чукча 200.
Раздолбали бородатых мужиков на партсобрнии, и давай они по 40 пилять.
А чукча 400.
Ну в общем приехала комиссия из Кремля смотреть как чукча так ударником производства стал.
Ну говорят чукча показывай.
Хватает чукча пилу и давай лес валить.
- ****ть, - изумилась комиссия, - если бы он ее еще и ВКЛЮЧАЛ!!!

Добавлено через 4 минуты
Цитата Сообщение от Shamil1 Посмотреть сообщение
Все эти варианты обхода не имеют никакого отношения к сворачиваемости объекта.
Ну да. Типа от порядка обработки элементов и от соседних элементов типа ничего не зависит. Такое бывает только при нулевой связности элементов. Но еще раз повтаряю - это редко встречаемый частный случай.

Добавлено через 41 минуту
Цитата Сообщение от Shamil1 Посмотреть сообщение
В моём случае в этом нет необходимости, так как погрешность равна нулю
Погрешность зависит от набора исходных данных. Даже если оперируете дробями то рискуете влететь в переполнение делителя вверх. Вы б еще римские цифры приплели для минимизации погрешности.

Добавлено через 9 минут
Цитата Сообщение от Shamil1 Посмотреть сообщение
Вод код, который обходит матрицу в хитровывернутом порядке:
т.е. для того чтобы обойти матрицу таки придется программировать алгоритм обхода. или cleverlyTurned по вашему возникает из сферического вакуума по воле божьей без строчки кода? Соответсвенно вопрос - а зачем мне тогда посредник, который мало того что пользует кучу Indirect Call там где они не нужны, так еще и отправляет элемент и алгоритм выборки в сферический вакуум относительно самой последовательности и друг друга?
0
1978 / 834 / 115
Регистрация: 01.10.2012
Сообщений: 5,171
Записей в блоге: 2
20.03.2016, 10:18
Цитата Сообщение от Shamil1 Посмотреть сообщение
А вот код для решения системы линейных уравнений (в рациональных числах, представленных в виде дробей):
Ничего не понимаю в хаскел, но все равно - впечатляет. Только вот ЗАЧЕМ? Впрочем и на плюсах я ни разу не писал Гаусса/инверсию - всегда под рукой было готовое. Да, вероятно написав сам, я получил бы больше понимания и постиг бы тонкости мат аппарата, что вообще-то полезно. Но с др стороны это время было бы вычеркнуто из работы - и это важно.

Есть масса людей усердно изучающих каждую std-вывеску (типа std::accumulate), а некоторые вообще владеют неск языками Я с уважением отношусь к их знаниям, но вот беда - делать ничего они не хотят. Цель - изучать бесконечно, неуклонно повышать свою (безмерно крутую) квалификацию. А конкретные результаты, выход их мало волнует. Этим пусть кто-то другой занимается, ведь овладевать все новыми и новыми знаниями куда легче
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
20.03.2016, 14:45
Цитата Сообщение от Igor3D Посмотреть сообщение
Впрочем и на плюсах я ни разу не писал Гаусса/инверсию
А лабораторки в универе? в районе 4-ой или 5-ой лабы по С++ обычно Гаусс

Добавлено через 3 минуты
Цитата Сообщение от Igor3D Посмотреть сообщение
std-вывеску
STD - sexually transmitted disease - заболевания передающиеся половым путем. толковый словарь английского языка.

Добавлено через 1 минуту
Цитата Сообщение от Igor3D Посмотреть сообщение
Цель - изучать бесконечно, неуклонно повышать свою (безмерно крутую) квалификацию.
Крутая квалификация - это когда свои динамические массивы удобнее и надежнее чем std::vector

Добавлено через 35 минут
Цитата Сообщение от Igor3D Посмотреть сообщение
Но с др стороны это время было бы вычеркнуто из работы - и это важно
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
template<typename Type>
bool Gauss(TMatrix<Type>& A,TVector<Type>& B,TVector<Type>& X){
        if (A.ColsCount!=A.RowsCount||A.ColsCount!=B.Count) return false;
        X.Count=B.Count;
    for(int i=0;i<A.ColsCount;i++){
        TMax Max;
        for (int j=i;j<A.ColsCount;j++)Max<<fabs(A[i][j]);
        if (!Max.Value) return false;
        A.SwapRows(i,Max->Id+i);
        B.Swap(i,Max.Id+i);
        for (int j=i+1;j<A.ColsCount;j++){
             Matrix.Row[j]-=Matrix.Row[i]*(Matrix[i][j]/Matrix[i][i]);
             B[i]-=B[i]*Matrix[i][j]/Matrix[i][i];
        };      
    };
    for (int i=A.ColsCount-1;i>0;i--){
        Type S=B[i];
        for (int j=i+1;j<A.ColsCount;j++) S-=A[i][j]*X[j];   
        X[i]=S/A[i][i];
    };
}
Примерно вот так, при готовых классах вектор и матрица, которые при серъезной работе все равно надо иметь под рукой.
0
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,912
20.03.2016, 14:57
Цитата Сообщение от Igor3D Посмотреть сообщение
Ничего не понимаю в хаскел, но все равно - впечатляет. Только вот ЗАЧЕМ? Впрочем и на плюсах я ни разу не писал Гаусса/инверсию - всегда под рукой было готовое.
В Haskell тоже есть готовое (пакет hmatrix). Дело не в конкретной функции, а в способе написания функций (парадигме программирования). Используя этот способ, Вы можете писать свои функции - те, что нужны Вам прямо сейчас для решения Вашей текущей задачи. И на каждой функции экономить время.
Причём, для этого Вам не нужно переходить на функциональный ЯП, так как элементы ФЯП добавляются прямо в C++. Это лямбды, это абстракции высокого уровня (std::accumulate и другие).
И для этого Вам не нужно отказываться от ООП, если Вы его используете. Пишите свой класс, а при реализации некого метода используете приёмы ФП.

Ведущие ООП программисты осознают преимущество такого подхода. И поэтому в самых популярных ООЯП (Java, C#, C++) с каждой версией появляется всё больше элементов ФП.
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
20.03.2016, 15:38
Цитата Сообщение от Shamil1 Посмотреть сообщение
Ведущие ООП программисты осознают преимущество такого подхода.
Скажем так, у меня обычно связность структур данных с которыми работают алгоритмы гораздо выше нулевой. От ФП при таких раскладах больше вреда чем пользы.
Зачем мне посредник, который мало того что пользует кучу Indirect Call там где они не нужны, так еще и отправляет элемент и алгоритм выборки в сферический вакуум относительно самой последовательности и друг друга?
А для того чтобы события и т.п. использовть на делегатах мне лямбдо-костыли не нужны. Потому как пользую продвинутый C++ компилятор в котором делегаты нативные, т.е. без всяких std-костылей.

Добавлено через 3 минуты
Цитата Сообщение от Shamil1 Посмотреть сообщение
Это лямбды
Зачем мне куцый обрубок объекта если я могу делегировать метод полноценного объекта? Мало того, такое место где таки лямбда с замыканием может заменить делегата только одно и то в практически невстречаемом частном случае.

Добавлено через 3 минуты
Цитата Сообщение от Shamil1 Посмотреть сообщение
std::accumulate и другие
Маразм крепчает.
0
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,912
20.03.2016, 18:01
Fulcrum_013,
Я не вижу смысла что-то Вам объяснять. Всё равно Вы не читаете, а если и читаете, то даже не пытаетесь понять.

Я в качестве примера описал Вам одну из абстракций и её использование. Но Вы не можете понять пользу этой абстракции, потому что заняты исключительно придумыванием ситуаций, в которых она не работает.
Очевидно же, что нет универсального приёма на все случаи жизни. Точно так же каждый из ООП паттернов имеет строго ограниченную область применения. На каждую пилу найдётся рельс.

Я Вам уже писал, что при вызове Aggregate() нет никаких indirect calls. Вы это проигнорировали, а теперь опять выдумываете косвенные вызовы.
Тем более, что Вы пишите на С++. В библиотеке STL в подобных методах используются параметры шаблона, компилятор получает полную информацию о типах и, как правило, производит разворачивание (inlining) кода предиката, тем самым полностью исключая затраты на вызов метода. Никаких косвенных вызовов (и никаких "куцых обрубков объекта").

А Ваша реплика "Нормальные люди опорную строку по другому ищут."? Хотели показать, что я плохо знаю алгоритм Гаусса? Но какое отношение к ФП имеет моё знание или незнание этого алгоритма?
К тому же в данном случае предлагаемый Вами поиск максимума был бы пустой тратой ресурсов.

Ваша аргументация по стилю напоминает шулерство.
Вы высказываете какое-то спорное утверждение (например, "у меня обычно связность структур данных с которыми работают алгоритмы гораздо выше нулевой") и выдаёте его за аксиому, не нуждающуюся в доказательстве. А затем делаете из него абсолютно нелогичный вывод: "От ФП при таких раскладах больше вреда чем пользы". Какая связь? И откуда Вы можете знать, если Вы совершенно не знаете ФП.
Вы задаёте вопросы в стиле "Вы уже перестали пить коньяк по утрам?". Например "Зачем мне куцый обрубок объекта". И как на него отвечать, если лямбда не является "куцым обрубком объекта"?
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
20.03.2016, 18:58
Цитата Сообщение от Shamil1 Посмотреть сообщение
если лямбда не является "куцым обрубком объекта"
А чем является по вашему лябда с замыканием? Автоматически созданный компилятором объект с единственным методом. А соответсвенно абсолютно неуправляемый.

Добавлено через 8 минут
Цитата Сообщение от Shamil1 Посмотреть сообщение
производит разворачивание (inlining) кода предиката, тем самым полностью исключая затраты на вызов метода
Адрес функции передается? Передается. А значит вызывается она исключительно через Indirect Call.

Добавлено через 16 минут
Цитата Сообщение от Shamil1 Посмотреть сообщение
А затем делаете из него абсолютно нелогичный вывод:
Итак. Простейшая последовательность из 2-х объектов. Моделируем их поведение. Автопилот объекта А удерживает нулевые производные углов визирования на объект Б. Пилот объекта Б активно маневрируя старается избежать встречи с объектом А. Каким образом в моделировании мне поможет свертка при обходе этих объектов если она изолирует их друг от друга и самой последовательности в которой они должны друг друга обнаруживать? Мало того, в процессе всей этой песни объект Б на своем шаге может добавлять в последовательность кучу объектов С (тепловых ловушек), которые по истечении определенного времени самостоятельно из последовательности удаляются на очередном шаге.
0
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,912
20.03.2016, 22:20
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Адрес функции передается? Передается. А значит вызывается она исключительно через Indirect Call.
Вы прочитали то, что цитируете? "производит разворачивание (inlining) кода". Куда и какой адрес, по Вашему мнению передаётся, если вообще нет вызова функции?

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Indirect Call
Вы виртуальные функции вообще не используете?

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Каким образом в моделировании мне поможет свертка
Ваш вывод основан на предположении, что "свёртка" - единственный приём, используемый в ФП.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
при обходе этих объектов
Каких объектов? Я не могу догадаться, каким образом Вы пилота преобразовываете в объект.
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
21.03.2016, 06:10
Цитата Сообщение от Shamil1 Посмотреть сообщение
Вы виртуальные функции вообще не используете?
Использую но там где они нужны. т. е при обработке последовательностей разнородных элементов и работе с даннымми тип которых не известен при компиляции. Ну и естественно для переопределяемых в рантайме связей.
Цитата Сообщение от Shamil1 Посмотреть сообщение
Я не могу догадаться, каким образом Вы пилота преобразовываете в объект.
Элементарно. Любой пилот это абстрактный контроллер поведения объекта. А че он там делает - шарманку крутит електромоторчиком, микрочипом компъютит или рычаги управления дергает (т.е. компьютит нейросетью на биологической элементарной базе) - ну это уже не столь важно

Добавлено через 3 минуты
Цитата Сообщение от Shamil1 Посмотреть сообщение
Вы прочитали то, что цитируете? "производит разворачивание (inlining) кода". Куда и какой адрес, по Вашему мнению передаётся, если вообще нет вызова функции?
Цитата Сообщение от Shamil1 Посмотреть сообщение
что "свёртка" - единственный приём, используемый в ФП.
Ну да есть еще "карринг" который заключается в том чтобы вместо того чтобы просто посчитать функцию нескольких переменных поплясать с бубуном

Добавлено через 45 минут
Цитата Сообщение от Shamil1 Посмотреть сообщение
Куда и какой адрес, по Вашему мнению передаётся, если вообще нет вызова функции?
Ото разве что в std::accumulate. Да и то потому что там на вход класс подается а не функция. да и то с кучей ограничений. К примеру нельзя ни последовательности изменять, ни по значению аккумулятора принимать решения об продолжении обхода. Поздравляю, создатели std::accumulate почти осилили функционал первого компутера.
А вот на то же самое с управляемым аккумулятором, по значению которого можно принимать решение о продолжении/выборе следующего элемента при обходе/ сбросе аккумулятора вы хай подняли.
0
1978 / 834 / 115
Регистрация: 01.10.2012
Сообщений: 5,171
Записей в блоге: 2
21.03.2016, 06:41
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
А лабораторки в универе? в районе 4-ой или 5-ой лабы по С++ обычно Гаусс
Да бог с Вами, когда я учился С++ еще не успело родиться Был курс АЯиП, не пользующийся никаким авторитетом, программирование считалось женской специальностью, а мужчина должен был сидеть с паяльником.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
template<typename Type>
bool Gauss(TMatrix<Type>& A,TVector<Type>& B,TVector<Type>& X){
if (A.ColsCount!=A.RowsCount||A.ColsCount!= B.Count) return false;
X.Count=B.Count;
for(int i=0;i<A.ColsCount;i++){
TMax Max;
for (int j=i;j<A.ColsCount;j++)Max<<fabs(A[i][j]);
if (!Max.Value) return false;
A.SwapRows(i,Max->Id+i);
B.Swap(i,Max.Id+i);
for (int j=i+1;j<A.ColsCount;j++){
Matrix.Row[j]-=Matrix.Row[i]*(Matrix[i][j]/Matrix[i][i]);
B[i]-=B[i]*Matrix[i][j]/Matrix[i][i];
};
};
for (int i=A.ColsCount-1;i>0;i--){
Type S=B[i];
for (int j=i+1;j<A.ColsCount;j++) S-=A[i][j]*X[j];
X[i]=S/A[i][i];
};
}
Ох и отпороли бы в нашей команде за такой текст Первым делом бы сказали типа
Знаешь что, дружок, а ну-ка ставь пробелы и сноси строки как у нас положено. Ты тут не один
Потом бы за темплейты надавали. Типичный пример липовой общности. Объявление ф-ции обещает что можно подавать и то и се, а в реализации глухая специфика заточенная на конкретный класс (Count, RowCount и.т.п.). Ну и чего было городушку городить? Делали бы это методом класса. И что это за махровый public доступ? Хоть я и не фанат геттеров/сеттеров, но зачем вот так нарываться на обвинения в безграмотности (пусть и формальные)?

И вот как только такие простейшие вещи будут решены, и все будет аккуратно разложено по полочкам - необходимость в каком-то умничании отпадет сама собой
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
21.03.2016, 07:31
Цитата Сообщение от Igor3D Посмотреть сообщение
Хоть я и не фанат геттеров/сеттеров, но зачем вот так нарываться на обвинения в безграмотности (пусть и формальные)
Я из борланда пришел. Т.е. в public секции переменных нет по определению, только свойства.
Цитата Сообщение от Igor3D Посмотреть сообщение
Специфика заточенная на конкретный класс
Дык этот класс в заголовке и указан. Ну а вобзем случае да, методом. А еще лучше оператором вектора /

Добавлено через 2 минуты
Цитата Сообщение от Igor3D Посмотреть сообщение
наешь что, дружок, а ну-ка ставь пробелы и сноси строки как у нас положено
Для этого форматер кода существует. Каждый как ему читать удобно одной кнопкой форматирует.

Добавлено через 10 минут
Цитата Сообщение от Igor3D Посмотреть сообщение
Был курс АЯиП, не пользующийся никаким авторитетом, программирование считалось женской специальностью,
Когда я учился уже по другому считали - женщина за компьютером - угроза для общества. За редким исключением только подтверждающим правило.

Добавлено через 41 секунду
Цитата Сообщение от Igor3D Посмотреть сообщение
а мужчина должен был сидеть с паяльником
Ну это когда было... теперь настоящие мужики с феном сидят.

Добавлено через 1 минуту
Цитата Сообщение от Igor3D Посмотреть сообщение
И вот как только такие простейшие вещи будут решены, и все будет аккуратно разложено по полочкам - необходимость в каком-то умничании отпадет сама собой
Умничают как раз те кто начинают разводить сказки что всякие тюринговские трясины могут быть лучше чем ООП.

Добавлено через 24 минуты
Цитата Сообщение от Igor3D Посмотреть сообщение
Первым делом бы сказали типа
На Full HD мониторе удобнее читать более широкий текст. У меня форматер обычно на ширину 160 символов настроен. Больше функций на экран помещается. И единственная разумная альтернатива повернуть монитор на 90 градусов. Но вот одна незадача - подставка у основного моника фиксированная, если поворачивать то или на стену вешать или вместо клавы положить только вертикально. На стену не фонтан, бо как за ним системник, а если системник по другому повернуть до боковых мониторов кабеля дотянуть та еще пляска с бубном.
Аки клаву тоже не айс. И сенсор не ахти, винда его через раз теряет, и печатать на экране тактильных ощущений нет, и виртуальная клава тоже часть места займет.

Добавлено через 4 минуты
Да и поле зрения по горизонтали больше чем по вертикали. Вобщем единственная разумная альтернатива глобально перейти на японскую/китайску письменность. имеется в виду не иероглифы а направление строк. Строки сверху вниз, скролл влево-вправо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
21.03.2016, 07:31

Как научиться программировать как БОГ?
Всем привет! Прошу советов от опытных программистов данного форума. Дело в том что я уже вдоль и поперек изучил основы программирования...

Задача по олимпиадному программированию
Помогите решить задачу. Я имел идею перебирать все варианты, которое заходит только на 10%. Мост между островами Тысячи и тысячи лет...

Шарики(Задача по олимпиадному программированию)
Решение(не идеально,я знаю): #include &lt;iostream&gt; #include &lt;stdio.h&gt; #include &lt;math.h&gt; using namespace std; int main(){ ...

Ищу людей для подготовки по олимпиадному программированию
Здравствуйте.Заранее прошу прощения у модераторов - я не знаю, куда эту тему выкладывать. Перенесите её, пожалуйста. В чём суть.Я...

Как научиться программированию на С++
Как научиться программированию на С++, как за месяц более менее освоить этот язык.программирования.


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru