• Как подсчитать объем?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Достаточно для каждой грани
    vertex x1 y1 z1
    vertex x2 y2 z2
    vertex x3 y3 z3
    посчитать величину Vj=(x1*(y2*z3-y3*z2)+x2*(y3*z1-y1*z3)+x3*(y1*z2-y2*z1))/6, и найти сумму этих величин (часть из них будет отрицательной, но это не страшно). Для замкнутой модели она и будет искомым объёмом.

    Работать проще с бинарным STL - там не нужно тратить силы на синтаксический разбор.
    Ответ написан
    6 комментариев
  • Как найти все комбинации символов?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Такие матрицы, судя по всему, описывают возможные бинарные операции на множестве {'a','b','c'}, т.е. функции от двух переменных из этого множества, принимающие значения в этом же множестве.
    Всего таких функций будет 3^9=19683. Поэтому достаточно перебрать числа от 0 до 3^9-1, и троичную запись каждого из них превратить в матрицу. На C# это бы выглядело так:
    char[,] matr=new char[3,3];
        for(int i=0;i<19683;i++){
            int a=i;
            for(int j=9;--j>=0;){
                matr[j/3,j%3]=(char)('a'+a%3);
                a/=3;
            }
            Process(matr);
        }
    Ответ написан
    4 комментария
  • Как решается уравнение x^x?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Уравнение x*ln(x)=c решать проще. Можно методом Ньютона. А можно и итерациями: x_{n+1}=c/ln(x_n), сходиться должно очень быстро.
    UPD. Хотя нет, оно будет сходиться только при c>e. Метод Ньютона, всё-таки, надёжнее:
    x_{n+1}=(c+x_n)/(ln(x_n)+1)
    Ответ написан
    Комментировать
  • А вы знаете стандартные структуры и алгоритмы?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Некоторые стандартные структуры и алгоритмы знаю. Но в работе использую редко: обычно ситуации возникают такие, что непосредственное применение стандартного алгоритма будет не очень эффективным (или по какой-то причине вообще не подойдёт), так что приходится строить более специальные структуры и алгоритмы - обычно как комбинацию стандартных приёмов, но не обязательно.
    Из стандартных приходилось писать, разве что, приоритетную очередь: почему-то в C# её не сделали. И QR-алгоритм для собственных значений матрицы (про мелочи типа многомерного метода Ньютона не говорю - они попадаются регулярно, и каждый раз со своими особенностями).
    Сортировку в последний раз писал с полгода назад. Получился монстр на полтысячи строк, но он работал.
    Сортировку пузырьком (или простыми вставками) приходится писать когда по какой-то причине неудобно вызывать стандартный Sort. Например, при сортировке фрагмента массива с нестандартной функцией сравнения - опять же, в C# этот метод не вывели. Там проще написать три строчки в коде, чем оформлять класс-компаратор.
    Ответ написан
    Комментировать
  • Как найти мантиссу десятичного числа?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Здесь "изящное" и "быстроработающее" - слегка противоречивые требования. Быстрее всего будет определить число знаков делением пополам за 3-4 сравнения:
    double mantissa(int c){
      int a=abs(c);
      int b=1;
      if(a>=100000){
        if(a>=10000000){
          if(a>=1000000000) b=1000000000;
          else if(a>=100000000) b=100000000;
          else a=10000000;
        }else if(a>=1000000) b=1000000;
        else b=100000;
      }else{
        if(a>=100){
          if(a>=10000) b=10000;
          else if(a>=1000) b=1000;
          else a=100;
        }else if(a>=10) b=10;
      }
      return (double)c/b;
    }

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

    Можно, конечно, и через float. Но там после вычисления порядка надо будет возвести 10 в нужную степень, а функция pow может оказаться для этого слишком долгой.

    double mantissa(int a){
    	if(a==0) return 0;
    	float f=a;
    	int b=((*(int*)&f&0x7fffffff)-0x40cd3ed7)/0x019a7daf;
    	double d=a*pow(0.1,b);
    	if(fabs(d)>=10) d/=10;
    	return d;
    }
    Ответ написан
    Комментировать
  • Какую кривую эффективнее построить на множестве [0; 1] - Безье, нецелочисленную степенную или гиперболу?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Если надо, чтобы кривую можно было провести через любую точку квадрата, то гипербола, пожалуй, лучше. Уравнение выглядит привлекательно: (a^2-1)*x*y+(x-a^2*y)=0, найти значение a для любой точки, через которую проходит кривая, несложно. Немного сложнее её нарисовать, чтобы точки были расположены с нужной густотой.
    Я думал над чем-нибудь вроде y^a+(1-x)^a=1, но оно вряд ли подойдёт, хоть и симметрично: семейства кривых при a<1 и a>1 получаются не симметричными друг другу.
    Ответ написан
  • Как составить все возможные комбинации размещения 10 яблок на 21 тарелке?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    На C это бы выглядело так:
    int k=21,m=10,s,h;
    	for(s=(1<<m)-1;s<(1<<k);){
    		printf("%x ",s);
    		h=s&-s;
    		s+=h;
    		s+=(s&-s)/(2*h)-1;
    	}
    	printf("\n");

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

    Mrrl
    @Mrrl
    Заводчик кардиганов
    В качестве расстояния можно взять что-нибудь вроде суммы модулей разностей положения каждого элемента в этих перестановках. То есть, если A, B - исходные перестановки, а A*, B* - обратные к ним, то dist(A,B)=sum_k |A*(k)-B*(k)|.
    Для перестановок 9 5 4 1 2 3 6 8 7 и 9 7 4 1 3 8 6 2 5 это будет 0+3+1+0+7+0+7+2+0=20.
    Ответ написан
    Комментировать
  • Какой выбрать алгоритм для решения задачи?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Если есть память N*2^N, где N - число городов, то можно воспользоваться динамикой по набору пройденных городов плюс последнему городу, где оказался коммивояжер. Для каждого такого сочетания запоминаем минимальное количество топлива, которое потребовалось, чтобы добраться до этой ситуации и город, из которого приехали в последний город. Потом для всех ситуаций проезжаем из последнего города по всем рёбрам, и попадаем в ситуации, где посещённых городов на 1 больше. Снова для каждой находим оптимальный (по топливу) путь, по которому мы туда попали... и так, пока топливо не кончится. После чего проходимся по всему списку, и смотрим, где больше собрано призов.
    До 20-25 городов должно работать разумное время. Дальше придётся искать эвристики.
    Ответ написан
    Комментировать
  • Найти количество чисел заданного порядка, модуль разницы соседних цифр которых не больше 1

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Формула, несомненно, существует. Правда, в ней будут присутствовать корни многочлена (z^5-6*z^4+10*z^3-z^2-6*z+1)*(z^5-4*z^4+2*z^3+5*z^2-2*z-1) (неразрешимого в радикалах), и выписать её совсем не просто. Но, при большой необходимости, возможно.
    Впрочем, если в формуле может присутствовать матрица, то ответ такой:

    (1 1 1 1 1 1 1 1 1 1)*(M^(n-1))*transpose(0 1 1 1 1 1 1 1 1 1),

    где M - матрица 10х10, в которой в клетках (m,n), для которых abs(m-n)<2, стоят единицы, а в остальных клетках - нули.
    Ответ написан
  • Сколько треугольников на картинке?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Если искать ответ в виде формулы - то [n*(n+2)*(2*n+1)/8]
    Там для чётных и нечётных n получаются разные серии, поэтому приходится брать целую часть (или мудрить с (-1)^n).
    Ответ написан
    Комментировать
  • Как построить конечные поля (Поля Галуа)?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Не получится. Нужен неприводимый многочлен, а x^5+x+1=(x^2+x+1)*(x^3+x^2+1).
    Ответ написан
  • Доверительный интервал

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Без априорной вероятности тут тяжело. Одно наблюдение (или любое число наблюдений) может уточнить вероятность той или иной ситуации, но определить её с нуля не сможет.
    Например, в случае лотереи. Одно дело, когда вы считаете, что вероятность выигрыша может быть любой, скажем, от 1/100 до 1/1000, причём вероятности этих значений примерно одинаковы. Тогда, после своих наблюдений, вы можете сказать, что вероятность, скорее всего, близка к 1/550, и даже определить распределение этой вероятности. Другое дело, когда вы знаете, что в лотерее может быть вероятность выигрыша только 1/200, 1/500 или 1/1000, но не знаете, в какую из лотерей играете (хотя шансы на то, что вам подсунули каждую из них, равны). Тогда ваши наблюдения покажут, что вероятность, скорее всего, 1/500 (а вовсе не 1/550 - так как такого исхода в списке не было).
    Так что надо взять или придумать априорные вероятности моделей, и воспользоваться формулой Байеса.
    Ответ написан
    Комментировать
  • Как реализовать создание ортогонального массива?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Насколько я понимаю, подобные массивы описываются здесь: habrahabr.ru/post/187882 Правда, там рассматривается частный случай - когда для каждой пары столбцов требуются все комбинации, а не только присутствующие в другом массиве. Но это не делает задачу легче.
    А ортогональность (в смысле линейной алгебры) тут вообще ни при чём.
    Ответ написан
    1 комментарий
  • Сколько существует различных уникальных подпоследовательностей из последовательности цифр длиной N?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Хорошая задачка, жаль, что я её раньше не заметил.
    Решение за O(N):
    static long nways(string seq) {
        long[] sum=new long[10];
        long cursum=1;
        foreach(char c in seq) {
            int d=c-'0';
            long x=cursum-sum[d];
            sum[d]=cursum;
            cursum+=x;
        }
        return cursum-1;
    }
    Ответ написан
    1 комментарий
  • В какой области программирования используется физика?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Софт для измерительных приборов и для прочих механизмов, в которых есть движущиеся части (от проекторов до роботов и космических аппаратов) - как embedded, так и на PC. Для корректного управления и корректной интерпретации показаний датчиков физика очень полезна.
    Ответ написан
    Комментировать
  • Как составить программу "Расставить знаки арифметических операций и скобки чтобы выполнялось равенство"?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Если в формулировке "расставить знаки, чтобы получить 100", то у меня осталось что-то такое:
    https://www.dropbox.com/s/vktq0cllod4d34s/LuckyTic...
    Ответ написан
    Комментировать
  • Как расставить шесть чисел так, чтобы сумма первых трех была примерно равна сумме остальных?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Отсортировать в порядке убывания, потом первые два элемента положить в разные кучки, а каждый следующий - в ту из кучек, где сумма на данный момент меньше. Работать будет не всегда (например, 25,25,20,20,9,1), зато не требует перебора.
    Ответ написан
    Комментировать
  • Есть ли реализация на любом языке программирования немного изменённой головоломки "Ханойская башня"?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Назовем столбики A,B,C (A в начале непустой).
    Введем операции:
    А->С() - переложить один диск с А на С
    top(A), top(C) - размер верхнего диска А или С. Если столбик пуст, то этот размер - MaxInt.
    В->С(К) - переложить с В на С все диски, размер которых меньше К (мы это можем сделать, если верхие диски А и С не меньше К)
    swap() - переставить столбики В и С (или переименовать их- нам ведь все равно, где окажутся диски)
    while(A) - цикл пока А не пуст.
    Тогда работает такой алгоритм:
    while(A){
      K=top(A);
      while(top(C) < K){
          B->C(top(C));
          swap();
      }
      A->C();
    }
    while(C){
      B->C(top(C));
      swap();
    }
    Ответ написан
    Комментировать
  • Есть ли алгоритм поиска элементов, однозначно определяющих судоку?

    Mrrl
    @Mrrl
    Заводчик кардиганов
    Боюсь, что количество вариантов, даже если искать минимальные, будет сравнимо с 2^80 (или, хотя бы, 2^60) - замучаетесь искать. Но если очень хочется, то можно попробовать так:
    - пусть у вас есть решатель (оптимизированный до предела), который по заданному набору клеток говорит ответ - 0 решений, одно или больше одного.
    Ищете перебором по дереву. Сначала про первую клетку предполагаете, открыта она или нет, потом для обоих случаев - про вторую, и т.д.
    Для любого набора открытых клеток в процессе перебора есть не меньше двух решений (иначе если оно одно - мы получили вариант ответа, а нуля не бывает, мы идём от известного решения).
    Когда мы решаем, открывать ли следующую клетку, делаем следующее:
    1) предположим, что мы не хотим её открывать. Откроем все клетки, идущие за ней, и посмотрим, сколько у нас решений. Если два - значит эту клетку нужно открыть обязательно, если нет, то можно и не открывать.
    2) посмотрим, нужно ли открывать эту клетку. Для этого подставляем в неё по очереди все цифры, кроме правильной, и смотрим, есть ли решение. Если хотя бы один раз оно есть, то клетку можно и открыть. Если ни разу решения не нашлось (например, эта клетка - 9-я в ряду, в котором уже открыто 8 клеток), то открывать её не нужно, поскольку иначе набор будет не минимальным.

    Таким образом, на каждом шагу мы получаем либо один, либо два варианта дальнейшего перебора. По хорошему, после того, как мы открыли очередную клетку, надо перепроверить все открытые ранее клетки методом из пункта (2), и если хотя бы одну из них открывать было не надо, значит, мы уже в не минимальном наборе, и продолжать перебор этой ветки не имеет смысла. Может быть, делать такую проверку не каждый раз (она очень дорогая), а, например, если число открытых клеток делится на 4.
    Ответ написан
    Комментировать