среда, 29 октября 2008 г.

Задача о шляпах от Microsoft

На лестнице стоят 4 человека. Самый верхний стоит на ступеньке, спрятанной за непроницаемой стеной и не видит никого. Все остальные видят только вышестоящих: A видит B и С, B видит C, С видит стену.

На каждом из человечков одета шляпа. На двоих красные шляпы, на других двоих черные. Кто из них первый поймет какого цвета у него шляпа, если никто не может ее снять и посмотреть?

Дополнительные условия: человечки не могут поворачиваться, не могут переговариваться и перемещаться по лестнице, так же они не могут блефовать и ломать стену.

ЗЫ: Выглядит это примерно так:

понедельник, 27 октября 2008 г.

Поиск последовательности в массиве

Задача

Есть массив положительных и отрицательных чисел. Нужно найти последовательность значений, сумма которой будет наибольшая. Например, для массива [-2, 5, -5, 8, -1, 3, 2, 6] наибольшая сумма будет для последовательности [8, -1, 3, 2, 6].


// допускаем, что данные всегда передаются валидные
// src_array - исходный массив
// len - его длина
// sindex, eindex - результат поиска - начальный и
// конечный индексы последовательности
void sub_array(int *src_array, int len,
int &sindex, int &eindex)
{
int sum = src_array[0];
sindex = 0;
eindex = 0;

// проверяем наличие положительных значений
bool has_positive = false;
for(int i=0;i < len;i++)
if(src_array[i]>0)
{
has_positive = true;
break;
}

for(int i=0;i < len;i++)
{
int ssum = src_array[i];
if(has_positive && ssum < 0) continue;

for(int j=i;j < len;j++)
{
ssum += j>i?src_array[j]:0;
if(ssum>=sum)
{
sum = ssum;
sindex = i;
eindex = j;
}
}
}
}

Read More...

воскресенье, 26 октября 2008 г.

Поиск дубликатов в массиве

Задача

Есть массив целых от 1 до N. Нужно определить, есть ли в этом массиве повторяющиеся значения.

Read More...

суббота, 25 октября 2008 г.

Абстрактный класс VS интерфейс

Недавно меня озадачили вопросом: чем отличается абстрактный класс от интерфейса в С++? Я вроде бы не настолько забыл С++, что бы помнить об абстрактных классах, но не помнить об интерфейсах.

В С++ есть понятие абстрактного класса - класс, у которого есть хотя бы одна чисто виртуальная функция и, соответственно, нельзя создать объект этого класса. Иногда еще говорят о чисто абстрактных классах, у которых все функции чисто виртуальные, но это скорее искусственное понятие, в большинстве случаев ничем не отличающееся от просто абстрактных классов.

An abstract class can also be used to define an interface for which derived classes provide a variety of implementations.

Все остальное - это проблемы семантики. Например, в пределах команды (компании), можно принять, что чисто абстрактные классы - это классы, у которых все функции чисто абстрактные, а чисто абстрактные классы, у которых нет не-константных членов данных и все функции public - это интерфейсы. Или под интерфейсами могут подразумеваться просто абстрактные классы и даже COM-интерфейсы.

Лично я придерживаюсь мнения, что интерфейс - это любой класс, у которого есть хотя бы одна виртуальная функция. Клиенту, который ориентируется на этот интерфейс используя указатель на базовый класс, по барабану, есть ли у базового класса члены данных и если у него не чисто виртуальные функции. Кроме того, с позиции клиента, все доступные методы объекта - это интерфейс, даже если объект описывается классом без виртуальных функций.

Так что ответить о разнице между абстрактными классами и интерфейсом в С++ не так просто, так как может быть несколько правильных точек зрения. Кроме того, возможно путаются понятия ОО концепции и реализации этой концепции в конкретном языке программирования. А может, спрашивающий джавист...

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

Read More...

четверг, 16 октября 2008 г.

Windows исключения

Интересное описание устройства исключений в Windows (не тех, которые C++-исключения): А что, собственно, происходит, когда бросается исключение?

PyQt in-depth: типы signal-slot соединений

В Qt слоты и сигналы являются платформенно-независимым средством обмена сообщениями между объектами. Подробнее писать о них я не собираюсь, так это хорошо сделали до меня прямо в документации Qt или, например, вот здесь. Я хочу выделить некоторые особенности их использования, с которыми мне удалось столкнуться.

Signal-slot механизм - это не просто вызов колбеков в чистом виде. Между сигналом и слотом устанавливается соединение, которое может быть 4-х типов:


  • DirectConnection - прямое соединение, когда сигнал моментально обрабатывается слотом;

  • QueuedConnection - сигнал добавляется в очередь и ожидает своего "выхода" в очереди сообщений, при этом поток, в котором возник сигнал не блокируется;

  • BlockingQueuedConnection - то же, что и QueuedConnection, но вызывающий поток блокируется, пока сигнал не будет обработан;

  • AutoConnection - автоматически выбирается DirectConnection, если сигнал вызывается из того же потока, в котором живет приемник, и QueuedConnection, если используются разные потоки.

Read More...

среда, 15 октября 2008 г.

Неосторожность с lambda

Все утро боролся с кодом, в котором вроде как все правильно, но работал не так как надо. Выглядел он примерно так:

Но результат выполнения этого кода получился неожиданный:

item a result c
item c result c
item b result c


Проблема оказалась в строке:
m.addAction(item, lambda : item)

lambda использует переменную item из контекста вызывающей функции. Переменная изменяется в цикле и к моменту вызова lambda в item сохраняется значение последней итерации.

Отсюда вывод - смешивание функционального подхода и "обычного" может привести к самым неожиданным результатам. Для того, что бы избежать такого смешивания, достаточно заменить цикл на map:
map(lambda item: m.addAction(item, lambda : item), lst)