...to C++. Как только его стандартная библиотека станет более самодостаточной.
C# меня ужасает своей негибкостью.
Во-первых, нет никакого аналога привычному scanf (или cin - кому как), и массивы приходится считывать какими-то извращенскими методами (разбивание строки методом Split и последующее конвертирование элементов массива строк в массив того_что_мне_нужно. То есть - лишняя память и угрызения совести, потому что можно же сделать лучше, чёрт возьми...)
Но это ещё цветочки.
Во-вторых, какая-то нахальная политика в плане перегрузки операторов. А именно: я не могу перегрузить operator+=, operator-= и всё в таком духе. Видите ли, компилятор позаботится, применив перегруженный operator+/operator-. Нет, ну нихера себе забота! operator+ создаёт новый объект, который никому нафиг не сдался: если операцию можно проводить in-place, то это нехилая потеря производительности. И это не пустая болтология, человек вот по этой ссылке утверждает, что падение в скорости работы доходило до 50 раз!!! Дикость. И самая жесть в том, что никто это менять не собирается, судя по ответу Microsoft в том треде. А дело было ещё в 2005 году.
Tuesday, October 26, 2010
Sunday, October 24, 2010
Выбор между Java и C#
Как ни странно, С++ мне уже не хватает. Казалось бы, нет более гибкого языка. Но...
Для решения всяких мелких (а порой и не очень) прикладных задач я обычно использую Python/Ruby. Однако после поступления в универ понадобилось нечто среднее между ними и С++, ибо:
1) в компьютерных классах попросту нет этих самых Python/Ruby;
2) всё-таки нужна производительность. Увы, скриптовые языки в этом плане от С++ отстают на порядок. Основной помехой в этом, наверное, является. концепция "всё что угодно есть объект". Теоретически — это изумительно: ах, вы только поглядите, у числа "2" вон сколько методов! А в Ruby on Rails и вовсе чёрт-те что можно творить, скажем, 2.hours вернёт 7200, а 7200.from_now вернёт время, которое будет через два часа. Так что вообще можно писать 2.hours.from_now. Изящно? А то! Но когда эти числа-объекты используются при перемножении матриц, весь их объектный характер нахрен никому не сдался, а лишние память и время жрутся.
А отчего же не продолжать использовать С++? Дело в том, что:
1) его стандартная библиотека содержит мало что. После использования Python кажется, что там вообще почти ничего нету. Java в этом плане великолепна.
2) непонятно, когда наконец выйдет новый стандарт, содержащий в себе кучу вкусностей — C++0x. А я тащусь от лямбда-функций, замыканий и всего такого. Кроме того, в стандарте С++ нет такой стандартнейшей (сорри за каламбур) вещи, как Dictionary (хэш-таблица). И меня убивает, когда только из-за этого к алгоритму добавляется логарифмический множитель.
Возможные варианты перехода — С#, Java, Delphi. Последний отпадает моментально, потому что... Да хотя бы потому, что мне лень эти проклятые begin-end-ы писать. Так что остаются первые два.
Так вот, результаты сравнения Java и C# (большое спасибо английской Википедии):
Java привлекает своей офигенной по размеру стандартной библиотекой. Прям как Python, идущий "с батарейками". Также здорово, что имена методов пишутся с маленькой буквы (я ж лентяй, шифт нажимать влом). Т.е. System.out.println мне нравится куда больше, чем System.Console.WriteLine.
Однако C# содержит вещи, без которых кодинг — тоска зелёная. Как можно жить без operator overloading, вы мне скажите, а?! Среди приятных вещей (в отличие от Java) также есть properties (ням-ням-ням!), лямбда-функции и замыкания, а также комплексные числа (начиная с .NET 4.0).
Так что, несмотря на всю свою нелюбовь к Microsoft и .NET, я пришёл к выводу, что пришла пора учить C#. Вот так вот.
Для решения всяких мелких (а порой и не очень) прикладных задач я обычно использую Python/Ruby. Однако после поступления в универ понадобилось нечто среднее между ними и С++, ибо:
1) в компьютерных классах попросту нет этих самых Python/Ruby;
2) всё-таки нужна производительность. Увы, скриптовые языки в этом плане от С++ отстают на порядок. Основной помехой в этом, наверное, является. концепция "всё что угодно есть объект". Теоретически — это изумительно: ах, вы только поглядите, у числа "2" вон сколько методов! А в Ruby on Rails и вовсе чёрт-те что можно творить, скажем, 2.hours вернёт 7200, а 7200.from_now вернёт время, которое будет через два часа. Так что вообще можно писать 2.hours.from_now. Изящно? А то! Но когда эти числа-объекты используются при перемножении матриц, весь их объектный характер нахрен никому не сдался, а лишние память и время жрутся.
А отчего же не продолжать использовать С++? Дело в том, что:
1) его стандартная библиотека содержит мало что. После использования Python кажется, что там вообще почти ничего нету. Java в этом плане великолепна.
2) непонятно, когда наконец выйдет новый стандарт, содержащий в себе кучу вкусностей — C++0x. А я тащусь от лямбда-функций, замыканий и всего такого. Кроме того, в стандарте С++ нет такой стандартнейшей (сорри за каламбур) вещи, как Dictionary (хэш-таблица). И меня убивает, когда только из-за этого к алгоритму добавляется логарифмический множитель.
Возможные варианты перехода — С#, Java, Delphi. Последний отпадает моментально, потому что... Да хотя бы потому, что мне лень эти проклятые begin-end-ы писать. Так что остаются первые два.
Так вот, результаты сравнения Java и C# (большое спасибо английской Википедии):
Java привлекает своей офигенной по размеру стандартной библиотекой. Прям как Python, идущий "с батарейками". Также здорово, что имена методов пишутся с маленькой буквы (я ж лентяй, шифт нажимать влом). Т.е. System.out.println мне нравится куда больше, чем System.Console.WriteLine.
Однако C# содержит вещи, без которых кодинг — тоска зелёная. Как можно жить без operator overloading, вы мне скажите, а?! Среди приятных вещей (в отличие от Java) также есть properties (ням-ням-ням!), лямбда-функции и замыкания, а также комплексные числа (начиная с .NET 4.0).
Так что, несмотря на всю свою нелюбовь к Microsoft и .NET, я пришёл к выводу, что пришла пора учить C#. Вот так вот.
Sunday, October 17, 2010
[c++] век живи — век учись...
Сколько себя помню, всегда писал в циклах for постинкрементный оператор. А вот оказывается, лучше использовать преинкремент и предекремент:
//make all characters in the list uppercase list::iterator pos; for (pos = coll.begin(); pos != coll.end(); ++pos) { *pos = toupper(*pos); }
Note that the preincrement operator (prefix ++) is used here. This is because it might have better performance than the postincrement operator. The latter involves a temporary object because it must return the old position of the iterator. For this reason, it generally is best to prefer ++pos over pos++.Так-то!
Friday, September 24, 2010
О достаточности буквы ы и <Shift>
Вот некоторые говорят, что общение посредством одной буквы "ы" невозможно. Может, оно и так. Но если добавить хоть ещё один символ (скажем, "Ы") в алфавит, то вполне достаточно: действительно, отобразим {(a₁, a₂, ..., a₈) | a_i ∊ {'ы', 'Ы'} } в, скажем, набор cp1251 (однобайтная кодировка) таким образом: i-й бит нашего байта равен 0, если a_i = 'ы', и 1 в противном случае. Очевидно, что такое отображение биективно. (Если кому-то так же, как мне, не хватает cp1251, используйте просто отображение {'ы','Ы'} → {0,1} и UTF-8. Идея тут ясна.)
...теперь про изображения. Конечно, можно и тупо все байты в кучу 'ы' и 'Ы' перегнать, но это же так скучно, правда?..
Так что предлагаю рассмотреть следующий язык для рисования чёрно-белых изображений. Представим себе черепашку (как в Лого Мирах, лол), которая начинает из верхнего левого угла картинки идти вниз (для определённости) с поднятым пером. Введём следующие команды:
ы - поворот против часовой стрелки на 90°
Ы - прохождение на один пиксел в текущем направлении.
Теперь смотрите. Если мы натыкаемся на "ыыыы" в исходной строке (естественно, окружённую не 'ы'), будем считать это командой "инвертировать состояние пера": действительно, поворот на 360° — совершенно бессмысленное занятие, так что лучше бы эта подпоследовательность что-нибудь значила.
Аналогично, бессмысленную команду "ыыыыыыыы" задействуем в качестве команды окончания рисунка.
Т.е.: если менее 4 'ы' подряд — всё ОК, 4 'ы' - инвертирование пера, от 4 до 7 'ы' включительно - инвертирование пера + поворот (заметим, что поскольку поворот не меняет состояние рисунка, эти два действия можно выполнять в любой последовательности, так что двусмысленность отсутствует), 8 'ы' и более - завершаем выполнение программы.
*фух, выдохнул*
...теперь про изображения. Конечно, можно и тупо все байты в кучу 'ы' и 'Ы' перегнать, но это же так скучно, правда?..
Так что предлагаю рассмотреть следующий язык для рисования чёрно-белых изображений. Представим себе черепашку (как в Лого Мирах, лол), которая начинает из верхнего левого угла картинки идти вниз (для определённости) с поднятым пером. Введём следующие команды:
ы - поворот против часовой стрелки на 90°
Ы - прохождение на один пиксел в текущем направлении.
Теперь смотрите. Если мы натыкаемся на "ыыыы" в исходной строке (естественно, окружённую не 'ы'), будем считать это командой "инвертировать состояние пера": действительно, поворот на 360° — совершенно бессмысленное занятие, так что лучше бы эта подпоследовательность что-нибудь значила.
Аналогично, бессмысленную команду "ыыыыыыыы" задействуем в качестве команды окончания рисунка.
Т.е.: если менее 4 'ы' подряд — всё ОК, 4 'ы' - инвертирование пера, от 4 до 7 'ы' включительно - инвертирование пера + поворот (заметим, что поскольку поворот не меняет состояние рисунка, эти два действия можно выполнять в любой последовательности, так что двусмысленность отсутствует), 8 'ы' и более - завершаем выполнение программы.
*фух, выдохнул*
Sunday, September 5, 2010
[Real World Haskell] Йоу, я осилил третью главу =)
(Если кто не знает, "Real World Haskell" — это название одной очумительной книжки).
На последнее задание (13-е) угробил несколько часов. Требовалось написать алгоритм построения выпуклой оболочки по Грэхему. Код жуткий, но работает =)))
На последнее задание (13-е) угробил несколько часов. Требовалось написать алгоритм построения выпуклой оболочки по Грэхему. Код жуткий, но работает =)))
import Data.List (sortBy, minimumBy)
-- 10 --
data Direction = DirLeft | DirRight | DirStraight
deriving (Eq, Show)
data Point = Point {
xcoord :: Double,
ycoord :: Double
} deriving (Eq, Show)
minus (Point x1 y1) (Point x2 y2) = Point (x1-x2) (y1-y2)
cross (Point x1 y1) (Point x2 y2) = x1*y2 - x2*y1
-- 11 --
dirTriple :: Point -> Point -> Point -> Direction
dirTriple a b c
| crossprod < 0 = DirRight
| crossprod > 0 = DirLeft
| otherwise = DirStraight
where crossprod = (b `minus` a) `cross` (c `minus` b)
-- 12 --
dirListTriple :: [Point] -> [Direction]
dirListTriple (x:y:z:xs) = [dirTriple x y z] ++ dirListTriple (y:z:xs)
dirListTriple _ = []
-- 13 --
comparePointsByPos (Point x1 y1) (Point x2 y2)
| cmpYResult == EQ = compare x1 x2
| otherwise = cmpYResult
where cmpYResult = compare y1 y2
mostBottomLeft x = minimumBy comparePointsByPos x
sortByAngle p ps = p: (sortBy cmpByAngle (filter isNotMin ps)) ++ [p]
where findCos x = (xcoord x - xcoord p)/(sqrt (distSqPoints p x))
distSqPoints (Point x1 y1) (Point x2 y2) = (x2-x1)**2+(y2-y1)**2
isNotMin x = x/=p
cmpByAngle a b
| cmpCosRes /= EQ = cmpCosRes
| otherwise = compare (distSqPoints p a) (distSqPoints p b)
where cmpCosRes = compare (findCos b) (findCos a)
sortPoints ps = sortByAngle p ps
where p = mostBottomLeft ps
convexHull a = init (reverse (__convexHull (reverse (take 2 zs)) (drop 2 zs)))
where zs = sortPoints a
__convexHull (t1:t2:ts) (x:xs)
| dirTriple t2 t1 x == DirRight = __convexHull (t2:ts) (x:xs)
| otherwise = __convexHull (x:t1:t2:ts) xs
__convexHull ys _ = ys
--------------------------------------------------------------------------------
plist = [(Point 100 50), (Point 110 70), (Point 110 40),
(Point 112 55), (Point 120 100), (Point 125 70),
(Point 128 10), (Point 129 50), (Point 139 91),
(Point 140 45), (Point 145 75), (Point 150 60),
(Point 160 35), (Point 165 45), (Point 170 45),
(Point 180 60), (Point 200 30), (Point 210 55)]
main = putStr (show (convexHull plist))
Monday, August 16, 2010
CHDK — "прокачиваем" Canon-овские мыльницы.
CHDK == Canon Hacker Development Kit. Суть этой приблуды в том, чтобы обеспечить доступ ко всем возможным настройкам фотоаппарата.
Если с английским совсем плохо — зайдите на chdk.clan.su Официальная же wiki находится по адресу chdk.wikia.com
Преимущества следующие:
a. Enhanced ways of recording images - you can capture still pictures in RAW format (as well as JPEG), and for video images you can have increased recording time and length (1 hour or 2 GB), and a greatly increased range of compression options.
- b. Additional data displays on the LCD screen - histogram, battery life indicator, depth of field, and many more.
- c. Additional photographic settings that are not available on the camera by itself - longer exposure times (up to 65 seconds), faster shutter speeds (1/25,000 sec, and faster in some cases), automatic bracketing of exposure, etc.
- d. The ability for the camera to run programs ('scripts', written in a micro-version of the BASIC language) stored on the memory card - these programs allow you to set the camera to perform a sequence of operations under the control of the program. For example, a camera can be programmed to take multiple pictures for focus bracketing, or take a picture when it detects that something in the field of view moves or changes brightness.
- e. The ability to take a picture, or start a program on the memory card, by sending a signal into the USB port - you can use the USB cable to take a picture remotely.
- f. The ability to do a number of other more useful (and fun) things, such as act as a mini file browser for the memory card, let you play games on the LCD screen, etc.
Для автоматической загрузки со своей старенькой 16GB SDHC воспользовался этой инструкцией.
Русский язык во всех новых менюшках, между прочим, поддерживается, так что тем, кто не в ладах с английским, бояться нечего =)
Friday, July 23, 2010
Subscribe to:
Posts (Atom)
