Blog about programming for beginners and beyond / Блог о программировании. Для начинающих и не только.
вторник, 31 августа 2010 г.
Chaos Construction
Один из конкурсов, от которого меня реально вставляет – это Realtime Chip Hack.
Вкратце суть: вам дается тестер, пара проводков и светодиодов. С помощью данного нехитрого набора требуется в некоторой реальной работающей схеме определить тип микросхемы, маркировка которой спилена. Еще как вариант – дается устройство-индикатор обратного отсчета (типа бомба). И надо с таким же набором юного сапера ее обезвредить (перерезать дорожку, или наоборот добавить проводок). Но, например, неверное действие может ускорить «бомбу» или просто сразу ее взорвать.
Я однозначно нахожу это крайне близкой темой к reverse-engineer’ингу, где надо просто взять и разобраться, как программа, например, проверяет ключ, и написать ключелку или битхак.
И прелесть тут в том, что все, что отделяет тебя от победы – это не мегабайты кода, а всего 1-2 байтика (или проводочка), которые найти и исправить.
четверг, 26 августа 2010 г.
Снова головоломки или сайт hackquest.com
На этот раз это сайт hackquest.com. Не знаю, сколько он уже существует, но я только сейчас о нем узнал.
Итак, это сборник разнообразных головоломок на около компьютерные тематики: логика, JavaScript, Java, reverse engineering, криптография, интернет, взломы, Flash, программирование и т.д.
Я вчера посидел пару часов и порешал задачки из своей любимой темы reverse engineering'а. Получил удовольствие.
Рекомендую.
четверг, 19 августа 2010 г.
Роб Пайк критикует С++ и Java
Вобщем, я становлюсь фанатом этого дядьки.
Update: А комментарий с семью различными типами умных указателей в Бусте - это вообще шедевр.
вторник, 10 августа 2010 г.
Решение кубика Рубика максимум на 20 шагов
Update: У нас тут есть свои блумберговские кубики, на грани которых кроме цвета нанесена корпоративная атрибутика. Подобное "улучшение" сильно осложняет сборку, так как необходимо правильно сориентировать остов до начала сборки слоев. Причем данная ориентация может съехать при неосторожной попытке сборки начального слоя.
воскресенье, 8 августа 2010 г.
Странные скобки в С++
#include <iostream>
int x;
struct A {
A(int a) {
x = a;
}
};
struct B {
B(A a) {
A local_a = a;
}
};
int main() {
x = 0;
std::cout << "Case #0: " << x << std::endl;
B b1(A(1));
std::cout << "Case #1: " << x << std::endl;
int t;
t = 2;
B b2(A(t));
std::cout << "Case #2: " << x << std::endl;
t = 3;
B b3((A(t)));
std::cout << "Case #3: " << x << std::endl;
return 0;
}
Как вы думаете, что должна вывести эта программа? Числа 0, 1, 2 и 3 последовательно для каждого случая?
А она печатает:
Case #0: 0
Case #1: 1
Case #2: 1
Case #3: 3
Почему для случая #2 не произошло присваивание? Куда делась двойка?
Ответ на этот вопрос кроется в наличии рудиментов языка С в грамматике С++.
вторник, 3 августа 2010 г.
Поиск подстроки в строке: алгоритм Кнута-Морриса-Пратта
Один из частых вопросов, которые задают у нас в Блумберге на интервью в плане так называемого coding exercise (это когда надо на бумаге или на доске написать почти реальный кусок кода) - это поиск строки в подстроке. Это абсолютно жизненная задача.
Подавляющее число людей пишут первое, что приходит в голову - это два вложенных цикла, когда искомая строка последовательно "прикладывается" с каждой позиции исходной строки. Такой подход дает сложность O(M*N), и, очевидно, что в жизни он нереален, если строки более менее длинные. Хотя все при этом знают, что любой hex-вьювер спокойно ищет в огромных файлах за явно линейное время.
Итак, для эффективного поиска строки в подстроке есть алгоритм Кнута-Морриса-Пратта, который решает проблему не за O(N*M), а за O(N+M).
Построенный на префикс-функции, данный алгоритм является классичесим примером динамического программирования, когда результаты решения задачи малой размерности используются для решения задачи большей размерности.
P.S. Сразу скажу, у нас никто не просит по памяти писать КМП. И если человек после написания простого O(N^2) решения также скажет, что есть метод быстрее, и сможет описать его идею - этого вполне достаточно.
воскресенье, 1 августа 2010 г.
volatile - это очень сильный модификатор в С++
#include <iostream>
volatile const char* p = "0";
int main() {
std::cout << p << std::endl;
return 0;
}
Для получение схожего эффекта в GCC надо заменить "0" на "false".