пятница, 30 мая 2008 г.

Project Euler, problem 191

Давно не заходил на Project Euler, успел опуститься до 3й сотни.
Проблема оказалась простой. Как обычно просмотр решений был гораздо интереснее.
Больше всего понравилось одно из решений на С++. Это было самое быстрое решение. Понравилось настолько что приведу его...

int euler_191()

{

    int O,Oa,Oaa,L,La,Laa,SO,SL,Result;

    O=1;

    Oa=1;

    L=1;

    SO=2;

    SL=1;

    for (i=2, i<=30,i++)

    {

       Oaa=Oa;

       Oa=O;

       O=SO;

       Laa=La;

       La=L;

       L=SL+SO;

       SO=O+Oa+Oaa;

       SL=L+La+Laa;

    }

    return SO+SL;

}



Думаю оно не очень понятно...поэтому обьяснение.
here are only 6 states in which strings can exist, divided into two groups. Three of those states are those where the strings don't contain any LATE occurence. The other three are those where the strings already contain one LATE occurence. Within each group, one state is when the string does not end with an absence, another when the string ends with only one absence, and the third when the string ends with two absences. Let's denote them as O, Oa, Oaa, L, La and Laa. Let's denote the sums of these two groups as SO and SL.

The initial states after the first day would be O=1, Oa=1 and L=1(all other states =0). The initial sums would be SO=2 and SL=1.
a) If absent on the following day, all strings in state Oa would become Oaa strings and all strings in state O would become Oa strings. Similarly, all strings in state La would become Laa strings and all strings in state L would become La strings.
b) If late on the following day, all strings in group O would become L strings.
c) If neither late nor absent on the following day, all strings in group O would become O strings (O=SO), and all strings in group L would become L strings in addition to (b) above such that L=SL+SO.

The following algo should produce the answer within 1 ms with most (if not all) programming languages. zeycus and logopetria have already posted similar algos in their own programming language.


Также понравилось рекурсивное решение.

int blah(int d, int a, bool l)

{

    return d == 0 ? 1 : (blah(d - 1, 0, l) + (a >= 2 ? 0 : blah(d - 1, a + 1, l)) + (l ? 0 : blah(d - 1, 0, true)));

}

понедельник, 26 мая 2008 г.

C++ интересный трюк с приведением типов

Нагло сперто с RSDN.

Возьмём простенький пример:

enum colors {red, green, blue};

 

struct proxy

{

    operator colors () const

    {

        return red;

    }

};

 

proxy f()

{

    return proxy();

}

 

int main()

{

    colors c = f(); // хорошо

    int i = f(); // спорно, но компилируется

    std::cout << f(); // спорно, но компилируется

    unsigned u = f() + 1; // совсем спорно, но компилируется

    if (f()) // совсем спорно, но компилируется

        std::cout << "if\n";

}



Теперь немного допилим напильником:

struct proxy

{

    operator colors () const

    {

        return red;

    }

 

    private: template<typename T> operator T () const;

};

 

int main()

{

    colors c = f(); // хорошо

    int i = f(); // не компилируется

    std::cout << f(); // не компилируется

    unsigned u = f() + 1; // не компилируется

    if (f()) // не компилируется

        std::cout << "if\n";

}



Получается что-то типа explicit conversion operator. Автоматически приводится только, если тип полность совпадает, в противном случае надо писать явный каст:

int main()

{

    std::cout << (colors)f(); // ок

}


Таким же образом можно определить несколько типов, для которых должен быть неявное приведение:

class proxy

{

    public: operator char const* () const

    {

        return "hello from proxy";

    }

 

    public: operator wchar_t const* () const

    {

        return L"hello from proxy";

    }

 

    private: template<typename T> operator T () const;

};



красота...

четверг, 24 апреля 2008 г.

Два слова...

"перетурбации"
"претубирации"

Написал в письме слово "претубирации". Задумался - правильно ли написал. Коллега не знал, предложил заменить словом "перетурбации". Ну в принципе подходит...но.
Тут я задумался - а что это за слова такие..., что они означают, откуда я их знаю...
На слово "претубирации" гугль выдает всего 32 упоминания.
На "перетурбации" гугль выдает 3 тысячи.
slovari.yandex.ru таких слов не знает.
Не знает и gramota.ru.
Зато gramota.ru знает слово ПЕРТУРБАЦИЯ. По смыслу то же самое. А гугль на это слово выдает "аж" 40 тыс. ссылок. И slovari.yandex.ru об этом слове молчать не стал...
Вывод - слов "перетурбации" и "претубирации" нет. Есть слово "ПЕРТУРБАЦИЯ".

какое же это было бессмысленное занятие писать это бессмысленное сообщение...

среда, 23 апреля 2008 г.

Новый консольный шрифт для Windows

"Дайте глазкам отдохнуть"
скриншоты шрифта можно посмотреть по ссылке, там же ссылка на скачивание и инструкции по установке.
Любителям Far можно не беспокоиться...при этом шрифте неправильно отображается оформление окна (бордюры).

вторник, 22 апреля 2008 г.

иногда я совсем не понимаю микрософтофобов

Микрософт выпускает 7й оффис с поддержкой ooxml который на момент выхода 7го оффиса не был стандартом. В процессе обсуждения находят некоторое количество проблемных мест ooxml. Микрософт некоторое количество исправляет. В результате ooxml формат меняется. Вроде даже в лучшую сторону. Соответственно ooxml на момент его принятия отличается от того ooxml что был предложен на рассмотрение (и реализован в 7м оффисе).

Вывод: ха-ха-ха, 7й оффис не поддерживает нормальную реализацию ooxml формата. А будет ли поддерживать? Ну мы же знаем этот M$...Никогда они нормальную поддержку не сделают. Ну неужели сложно было реализовать в 7м оффисе полную поддержку ooxml формата? Своего же формата? Причем в том виде как он принят в стандарте, а не как его видет M$. Ну мы же знаем что M$ вечно меняет стандарты под себя, данный случай не исключение. Нужно ждать нормальной реализации от OpenOffice - вот это Продукт.

четверг, 17 апреля 2008 г.

Еще интересных задачек. С решениями.

Оригинал.

Есть лошади, которые бегают с разной скоростью и никогда не устают. Лошади могут учавствовать в забегах, в одном забеге может участвовать не более N лошадей. Результатом забега является очередность, в которой лошади дошли до финиша, то есть на выходе - список, на каком месте была какая лошадь в забеге.
Всего лошадей N^2.
Спрашивается - за какое минимальное количество забегов можно найти M лучших их них?

Разбиваем на N групп. В каждой проводим забег. Итого N забегов. Берем из каждой группы победителя. Проводим среди них забег. Победитель есть абсолютный победитель. Запоминаем, победителя удаляем, добавляем второго из его группы. Проводим еще один забег...короче M+N
Есть односвязный список, у которого в каждом элементе есть еще один указатель на некоторый элемент этого списка. То есть, кроме next в ноде есть еще один мембер, который указывает на любой элемент списка. Может сам на себя, могут несколько таких указателей указывать на один элемент, как угодно. Хочется создать копию этого списка, разумеется, со скопированными ссылками в элементах. За линейное время и без дополнительной памяти, кроме как на саму копию.


Код (всякие мелкие очевидные фукнции я убрал, rlist->n - следующий элемент, rlist->r - случайный элемент, предполагается что в исходном списки r!=0 никогда)

rlist* rrcopy(rlist* base_head)

{

    rlist* copy_head = clone_rlist(base_head);

    rlist* b,*c,*t;

 

    for(b=base_head,c=copy_head;b;b=b->n){

        t=c->n;

        c->r=b->r;

        c->n=b->r;

        b->r=c;

        c=t;

    }

 

    for(b=base_head;b;b=b->n){

        c=b->r;

        c->r=c->n->r;

    }

 

    for(b=base_head;b;b=b->n){

        c=b->r;

        t=c->n;

        c->n=b->n?b->n->r:0;

        b->r=t;

    }

    return copy_head;

}

Даны три массива целых положительных чисел длиной N.
Нужно выбрать из каждого из них по одному числу так, чтобы сумма равнялась некоторому данному C.
С константными затратами памяти и сложностью O(N^2).

Хинт - если два массива отсортировать то для двух таких массивов задачу можно решить за O(N). Соответственно вместе с третьим получается O(N^2)
Если массивы сортировать нельзя - не знаю :)

Видео-пираты, аудио-пираты

Мои 5 копеек.
Когда-то давно, когда деревья были ну просто намного выше а трава такая ярко-зеленая что глаза резало зародилось программирование. Появились программисты и начали писать программы. Потом кому-то пришло в голову что программу можно не только писать и раздавать но и продавать. И появилась индустрия программного обеспечения.

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

И разработчик задумался - как бы сделать так чтобы друго пользователя не смог пользоваться программой не заплатив за нее. Так появилась защита програмного обеспечения от "несанкционированного" использования. Появилась. Защита. А не движения за искоренение пиратства и суды над друзьями которые записали себе нужную программу. Защита програмного обеспечиния очень и очень непростой процесс.

Защита постоянно эволюционирует. Способов защиты много и они разные. Есть правильные, удобные, есть и раздражающие. Но главное - они существуют. И совершенствуются.

Индустрия программного обеспечения не перекладывает заботу о том чтобы защитить програму от взлома на пользователя.

Тем же самым должна заниматься и медиа-индустрия. Есть такое понятие - DRM. Находится оно конечно в зачаточном состоянии, его существующие реализации в разной степени ужасны. Но именно этим и стоит заниматься. А не бороться с bittorrent и прочими напстерами. И уж конечно не бороться с конечными пользователсями.

вторник, 15 апреля 2008 г.

Новая статья Пола Грахэма (Pol Graham)

Называется "Почему нет других "Гуглов" (Why there aren't more Googles). Отвечает на многие вопросы. Освещает многие проблемы венчурного финансирования. Можно узнать много интересного про его компанию.
После прочтения открытым остается только один вопрос - so....why there aren't more Googles?

пятница, 11 апреля 2008 г.

Google BigTable против RDBMS

Оригинальная статья (основной посыл - Relational Databases are Dead).
Обсуждение на reddit

От себя - в этом как и в большенстве подобных случаев мало кто задумывается о сущности проблемы. Мнение первых сводится в основном к "Гугль это круто потому что Гугль это круто". Мнение вторых - "а как же без join и нормализации делать сложные запросы? Раз нельзя, значит BigTable в пролете".
Попробую собрать свои мысли на эту тему .

Пусть у нас "стандартная" база данных - products,customers,orders. Данные у нас скорее всего будут огранизованны следующим образом - таблица products, таблица customers, таблица orders, и всячиские таблица productid->orderid и т.д. Интерес представляют последнии. Зачем они собственно нужны? Ответ - время выборки. Допустим нам нужно посмотреть все заказы по данному продукту. Без таблиц типа productid->orderid это будет примерно так - берем productid, идем по всем записам в таблице orders, выбираем такие у которых совпадает productid. Время поиска O(n). При наличии productid->orderid найти все orderid у которых соответствующий productid можно гораздо быстрее. Соответственно скорость работы запроса намного больше. Как это сделать на BigTable без join запросов и первоначальной нормализаци базы? Да никак. Если все делать "в лоб" скорость выполнения запросов в BigTable гораздо ниже. Итого - BigTable в пролете?

Не совсем...давайте посмотрим на задачу повнимательнее. В первых мы говорили только о поиске и выборке. Что если количество операции "вставка" сопостовимо с количеством операций выборка? Причим количество таких операций в секунду достаточно велико? Случится неприятность...
Добавим "если". Что если обьем данных очень велик? Что если частота различных запросов различна? Что если их частота сильно различна?
Далее - что если нам не обязательно получить "точную" выборку. Приблизительная очень даже подойдет. А что если у нас нет таблицы products а есть только customers и orders/pictures/comments/...

Все эти вопросы могут очень сильно повлиять на дизайн базы данных. А также на саму структуру запросов и огранизацию данных.

Здесь важно следующее - задачи, возникающие перед современными веб-приложениями, работающими под польшой нагрузкой "классической" RDBMS решаются со скрипом. Это прежде всего потому что RDBMS не подходит для этих задач. Описать эти задачи можно так - огромный обьем данных, частые операции вставки/удаления, отсутствие необходимости в точном результате выборки (подойдет достоверный).

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

Выводы.:)

Cможет ли BigTable решать эти вопросы более быстро и качественно чем RDBMS? А не знаю я. Возможно и сможет. Даже скорее всего сможет. А если и не сможет - тогда возникнет что-то что cможет. Потому что необходимость есть...
Составляют ли подобные веб-приложения большенство? Скорее всего нет.
Найдет ли BigTable свое применение? Найдет.
Означает ли BigTable конец RDBMS? Тут однозначно нет.
Сузится ли круг задач решаемых с помощью RDBMS? Тут однозначное да. Причем не обязательно под влиянием BigTable. Есть еще in cloud computing. Или OODBMS. Или еще чего нибудь...