Home

Advertisement

Customize

Previous 20

Nov. 26th, 2009

Что такое ОО

(...) the difference between OO and the Haskell way; it's the difference between
metaphysical engineering and constructive mathematics.


Термин metaphysical engineering мне понравился :)
Tags:

Nov. 24th, 2009

"Apple вешает трубку"

Продажи третьего поколения iPhone — 3GS не начнутся в России не только до Нового года, но могут и не состояться вовсе. "Большая тройка" не готова продавать трубки по цене рекомендованной Apple. Стоимость самой дорогой модели iPhone 3GS с памятью 32 Гб будет превышать в рознице 40 тыс. руб. Участники рынка считают, что при такой цене большого спроса на смартфоны ожидать не стоит

Да уж, за 40 штук вряд ли очередь будет стоять:)

Apple настаивал на следующих расценках: за модель с объемом памяти 8 Гб — €400, за 16 Гб — €460, а за 32 Гб — €530

Минуточку. А откуда 40 тыр??!!

с учетом НДС (18%), таможенной пошлины (23%) и маржи оператора, которая оценивается в 38%

это многое объясняет. добавленная стоимость, защита таможенными пошлинами отечественного производителя, ну и маржа, оно понятно.

В США модель с 16 Гб памяти стоит $199, а с 32 Гб — $299. Такие цены предлагаются вместе с двухлетним контрактом оператора AT&T.

Добро пожаловать в эту страну

Nov. 21st, 2009

Haskell 101

Ребенок по долгу службы борется с простыми числами и факторизацией целых (сокращает дроби, ищет НОК и НОД). В порядке общего образования решил написать ему программку для этих целей.

Для объяснения неиспорченному человеку решето Эратосфена, при всей своей неэффективности, подходит хорошо, им мы и воспользуемся для генерации простых чисел.

Весь этот текст - "литеральный хаскель", т.е. его можно спокойно скормить компилятору с расширением lhs и он скомпилируется. При этом все строчки, начинающиеся со значка цитирования, воспринимаются как текст программы, остальное - как просто текст. Также код может быть скрещен не с текстом, а с TeX. Я приведу текст программы целиком, а потом мы разберем его подробно:
canBeDividedBy n m    =  n `mod` m == 0

possibleDivisors n    =  takeWhile (<= half) primes
    where half = n `div` 2

findDivisor n         =  find (canBeDividedBy n) (possibleDivisors n)

primes                =  2 : primes' 3
    where 
        primes' n = case (findDivisor n) of
            Nothing -> n : primes' (n+2)
            Just _  -> primes' (n+2) 

factor n              =  factor' (possibleDivisors n) n

factor' []                 n           = [n]
factor' _                  1           = []
factor' p@(divisor : rest) n 
   |canBeDividedBy n divisor = divisor : factor' p (n `div` divisor)
   | otherwise               = factor' rest n


Немного об указании типов в программе. Вообще говоря, оно не обязательно - компилятор выведет их сам. Но я буду указывать сигнатуры везде (о них можно спросить компилятор).

Нам потребуется функциональность из пары модулей (из Control.Monad - исключительно для
функции main, смысловой нагрузки не несет)

> import Control.Monad
> import Data.List


По ходу алгоритма нам зачастую придется проверять на делимость. Выразим это функией canBeDividedBy n m. Функция будет возвращать истину, если n делится без остатка на m и ложь в противном случае. Сигнатура (имя и тип) функции выглядит так:

> canBeDividedBy        :: (Integral n)=>n->n->Bool


Здесь сделано утверждение, что имеется функция canBeDividedBy, которая для любого типа n (n - переменная типа, т.е. обозначает некий конкретный тип), относящегося к классу целочисленных типов, отображает два значения типа n в значение типа Bool. Более корректно это прочитать следующим образом: n->(n->Bool). Т.е. значение типа n отображается в функцию из n в Bool. Фактически, все функции в Haskell имеют один аргумент. Целочисленных типов может быть много (Integer - с произвольной точностью, Int - машинное, переполнящееся,
Int32, Int16, Word8 и т.д. и никто не мешает наштамповать своих).

Применение функции в хаскеле записывается следующим образом: f arg1 arg2 .. argn, т.е. никаких скобок не ставится (только для обеспечения приоритета операций). Применение функции имеет приоритет, больший, чем любая операция, поэтому если первым аргументом мы хотим передать сумму, то должны записать так:

f (arg1 + arg2)  arg3


Без скобок это выражение будет проинтерпретировано как (f arg1) + (arg2 arg3) что приведет к ошибке типизации при компиляции.

'+' в данном случае - инфиксная функция с "двумя аргументами" (см. выше). Но любая такая функция может быть записана в традиционном виде:
(+) 3 2

Верно и обратное: имея фунцию от двух аргументов с "нормальным" именем, мы можем использовать ее в инфиксном виде, заключив в обратные апострофы. Теперь, собственно, код:

> canBeDividedBy n m    =  n `mod` m == 0

mod - разумеется, функция получения остатка от деления

Мы будем пользоваться функией possibleDivisors. Она возвращает список простых чисел, которые могут быть делителями данного числа. Мы полагаем, что это первые простые числа, не превышающие половины числа.

> possibleDivisors      :: (Integral n)=>n->[n]

Сигнатура говорит нам, что для целочисленного n возвращается список значение типа n.

Код функции:

> possibleDivisors n    =  takeWhile (<= half) primes
>   where half = n `div` 2

Функция takeWhile - библиотечная. Она имеет следующую сигнатуру:
takeWhile :: (a->Bool)->[a]->[a]

Переводя на русский: отобрать из списка первые значения, удовлетворяющие некоторому условию.
Условие передается первым аргументом, это должна быть функция, проверяющая "подходящесть"
своего аргумента. В данном случае, это (<= half). Тут мы воспользовались синтаксическим
сахаром, который позволяет нам удобным образом частично применять инфиксные операции.
Называется такая форма sections. Таким образом, (<= half) - нужная нам функция. half
описан во второй строчке - это деленный нацело пополам аргумент. Без использования section
мы могли бы описать нашу функцию-условие следующим манером:
lessOrEqual a b = b <= a

Сигнатура того, что написано выше:
lessOrEqual::(Ord a)=>a->a->Bool

Частично примененная версия:
l = lessOrEqual 10
l :: (Num n)=>n->Bool

Мы могли бы не присваивать нашей функции имя, воспользовавшись lambda-выражением:
takeWhile (\a -> a <= half) primes

знак \ выбран за сходство с недописанной лямбдой.

Кроме того, мы могли бы написать нужное нам условие еще и так:
((>=) half) 

Тут мы записали (>=) в стандартном (префиксном) виде и частично применили его (из двух аргументов передали один). Your mileage may vary.

Самое интересное в этом коде - primes. Это список всех простых чисел в природе. Его
мы опишем ниже.

> findDivisor           :: (Integral n)=>n->Maybe n

Функция, отыскивающая делитель для числа среди его возможных делителей. Интересен возвращаемый тип: Maybe n. Maybe выражает концепцию данных, которых может и не быть. Значения могут принимать два вида (есть два конструктора):

Just a - все в порядке, значение есть
Nothing - значения нет

Maybe - это конструктор типов (тип, kind которого *->*). Не может быть значений типа Maybe, но могут быть значения типа Maybe Int, Maybe String, Maybe Bool.

> findDivisor n         =  find (canBeDividedBy n) (possibleDivisors n)


find - библиотечная функция:
find :: (a->Bool)->[a]->Maybe a


Первый аргумент ее - критерий поиска, второй - список, в котором ищем. Результат - возможно, найденное значение. В нашем случае в качестве условия мы пользуемся частично примененный canBeDividedBy (добавь делитель - получишь ответ), а в качестве списка передаем список возможных делителей.

Переходим к самому интересному. Нам нужен список _всех_ простых чисел :) Да,именно так.

> primes                :: (Integral n)=>[n]


Значение primes - полиморфно, т.е. существует для всех целочисленных типов. Это список целых. Немного о списках. Список, как и Maybe - конструктор типов. Не бывает значений типа "список", но бывают списки целых ([Int]), строк ([String]) и т.д. Так же, как и в случае с Maybe, значения могут быть двух видов:

[] - пустой список
x : xs - x, за которым следует еще список.

Мы можем записывать списки следующим образом: [1,2,3]. Это синтаксический сахар для "истинной" записи:

1 : (2 : ( 3 : [])) -- (операция (:) правоассоциативна)

Итак, код:

> primes                =  2 : primes' 3
>   where 
>       primes' n = case (findDivisor n) of
>           Nothing -> n : primes' (n+2)
>           Just _  -> primes' (n+2) 

primes сообщает нам следующее: список всех простых чисел есть список, начинающийся с 2, за которой идет список, полученный как "вызов" primes' 3. primes' - вспомогательная функция описанная ниже. Она вычисляет список простых чисел начиная со своего аргумента. Как она это делает? Она ищет делитель своего
аргумента, пользуясь findDivisor. Да, findDivisor, сама пользуется primes, но нас это не смущает :) Мы считаем, что этот список существует (для его построения мы пользуемся корекурсией). Если делитель отсутствует (случай Nothing) то результат - наш аргумент к которому приписан результат primes' (n+2) (четные числа пропускаем). Если делитель найден (случай Just _), то результат просто равен результату primes' (n+2). Подчеркивание означает, что нас не интересует собственно найденный делитель, важно, что он есть. Вместо формы Just _ мы могли бы написать ключевое слово otherwise, т.е. для случая Nothing одно, для остальных - вот это

Итак, список получается бесконечный. но мы можем взять его, скажем, тысячный элемент:
primes !! 1000 == 7927

Мы можем попробовать его напечатать:
primes ==[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47....

Процесс печати, разумеется, займет бесконечное время.
Возможность поступать таким образом дает нам свойство вычислительной семантики хаскеля, называемое laziness, то бишь ленивость. Ничто не считается, пока не понадобится. Допустим, мы решили напечатать наш бесконечный список. Для этого нам потребуется напечатать первый элемент, а потом напечатать остаток списка (печать рекурсивна).

Первый элемент известен из выражения 2 : primes' 3, это 2. Ее печать вопросов не вызывает.

Теперь нам нужно напечатать следующий элемент. Как его найти? Это первый элемент в списке primes' 3. Чтобы его определить, сначала нужно поискать делитель 3. Для этого нам нужен кусок списка, не в котором простые числа, не превышающие половины 3. Этот кусок нам, разумеется уже известен (он пустой, у нас есть даже больше - целая 2 вначале). Таким образом, делитель не найден, поэтому результат (primes' 3) равен (3 : primes' 5), т.е. 3, за которой идет результат primes' 5. Дальше процесс повторяется.

Важно понимать, что primes не "вызывается" каждый раз при использовании. Понятие quot;вызова"
несколько надуманно для хаскеля. primes просто есть с момента своего описания. Просто он еще не вычислен до конца. И будет вычисляться по мере использования.

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

Переходим к разложению числа на простые множители.

> factor                :: (Integral n)=>n->[n]
> factor n              =  factor' (possibleDivisors n) n

Функция factor ничего умного не делает. Она "вызывает" вспомогательную функцию factor', передавая ей помимо числа еще и список возможных делителей этого числа.

> factor'               :: (Integral n)=>[n]->n->[n]


Как работает функция factor'? Если список возможных делителей пуст, то результат (список делителей) состоит из самого числа (единицу мы старательно игнорируем):

> factor' []                    n           = [n]


Второй случай. Нас не интересует список возможных делителей, но само число равно 1. Результат закономерен - пустой список:

> factor' _                     1           = []


Рассмотрев тривиальные случаи, переходим к интересным:

> factor' p@(divisor : rest)    n 
>  | canBeDividedBy n divisor    = divisor : factor' p (n `div` divisor)
>  | otherwise                   = factor' rest n

первый аргумент factor' записан интересным образом: p@(divisor : rest). Эта запись означает, что список, как минимум, не пуст, а состоит из чего-то, называемого divisor, за которым следует rest. Кроме того, на весь список мы можем ссылаться по имени p. Дальше идет рассмотрение случаев:

если n может быть поделен на divisor, то результат - divisor, за которым идет результат factor' с тем же набором потенциальных делителей, но числом, уже поделенным на делитель.

если n не делится на первый возможный делитель в списке, то результат - factor' для того же n но уже без "неудачного делителя".

Вот, собственно, и все. Сама программа очень коротенкая, описание заняло много. Пример:
factor 231132 ==  [2,2,3,11,17,103]


Функция main до бесконечности читает строчку за строчкой, раскладывает на множители и все сначала:

> main = forever (do
>   num <- readLn
>   print (factor num))
Tags:

Oct. 29th, 2009

Приплылинах

Мы используем более гуманные, а не сомнительные методы для решения вопроса [вместо метадона], — заявил руководитель Роспотребнадзора, добавив, что страна возлагает «большие надежды» на своих религиозных лидеров: — Русская православная церковь около трех лет назад представила концепцию работы с ВИЧ-инфицированными людьми и профилактики. Наша страна обращается от атеизма к вере. Это хорошо и полезно.

пруфлинк

Oct. 26th, 2009

Все яйца в одной корзине...

Оказывается из купленной за пару пива FreeBSD машины и найденной в ящике dlink wifi платы получается минимальными затратами вполне себе точка доступа. Несчастный комп теперь:

- dns cервер пары доменов/кэширующий dns
- imap/smtp
- postgresql
- samba
- качает торренты
- торрент-трекер
- узел tor
- web-сервер
- хостит darcs
- хостит trac
- имеет пару ssh аккаунтов для разных людей
- рутер/traffic shaper/шлюз ipv6
- dhcp сервер для локалки
- принимает ipsec снаружи
- принимает openvpn снаружи
- WPA/WPA2 точка

пора задуматься о резервировании :)

Oct. 17th, 2009

Буковки :)

Обнаружил тут к своему удивлению:
map (toEnum . succ . fromEnum) "HAL"  -- IBM


На что мне один выпускник физтеха тут же подкинул:
М(А) = Б
М(Б) = В
М(ФТИ) = ?

Oct. 1st, 2009

Так, что-то стало холодать

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

В связи с этим вопрос к юридически подкованным:
- как вообще этот вопрос регламентируется? Договор с ЖКХ (если в доме нет ТСЖ)?
- как бы кого-нибудь посадить уволить или поставить на баблосы (лучше и то и другое)?

Sep. 23rd, 2009

Как вы думаете...

Доживем ли мы до времени, когда пользуясь Word, люди не будут пользоваться для форматирования пробелами и "вводом", писать от руки номера пунктов, изменять шрифты и выравнивание и вообще начнут использовать стили? Или это принципиально непобедимо?
Tags:

Sep. 22nd, 2009

Опробована Yota

Под Snow Leopard их бздычка не работает, "разработка ведется", сроков нет. Что говорит сильно в их пользу.

Понес сдавать.

Sep. 12th, 2009

Дожили :) С наступающим, господа!

В пятницу президент России Дмитрий Медведев подписал указ об учреждении Дня программиста в качестве официального профессионального праздника.

Как сообщается в пресс-релизе Министерства связи и массовых коммуникаций РФ, День программиста будет праздноваться в 256-й день года -13 сентября или 12 сентября, если год високосный.

Хотя первая пятница сентября представлялась более удобным выбором...

Sep. 3rd, 2009

Годовщина ...

2 года, как пропал (теперь уже знаем, что погиб) Стив Фоссет. Грустно... Мощный был дядька.

Sep. 1st, 2009

О виноватых

Все-таки фраза "молоко прокисло" совершенно неправильно передает ситуацию. Правильно так: "кто-то сожрал мое молоко!!!" :)

Aug. 29th, 2009

Афоризм

"Императивное программирование - программирование в кредит" (С) братец. Контекст там был несколько шире, но звучит прикольно.

Aug. 28th, 2009

Ребят из Купертино - с релизом!



Таким же ненормальным, как я: в Питере коробочку обещают 4 сентября, цена вопроса - 990 деревянных (курс получается 34 с копейками :)) Апдейт на леопард, освобождает, грят, 7 гигов на диске :) Еще (тсс!) говорят, что на тигра тоже ставится :)

Бугога :) Поржем :)

В свете "подрисовки доказательств": вот зря тотально все материалы с Луны не заперли подальше "для следующих поколений ученых":

Хранящийся в Голландском национальном музее Rijksmuseum образец лунного камня, привезенного первой экспедицией на Луну, оказался куском окаменелого дерева.
Экспонат был передан бывшему премьер-министру Нидерландов Виллему Дрейсу в ходе миссии доброй воли тремя астронавтами, принимавшими участие в памятном полете на борту корабля «Аполлон-11».


«Это хорошая история, в которой многие вопросы пока остаются без ответа, — говорит Ксандра ван Гельдер, курировавшая расследование, показавшее, что камень вовсе не с Луны и совсем не камень. — Лучше всего над этим просто посмеяться».

Поржем, ага :)

Американские чиновники не могут объяснить «голландское открытие».



Aug. 18th, 2009

Саяно-Шушенская

Ее больше нет. Плотина, к счастью, на месте. Погибших около десятка и пропавших безвести 50-60 (!) человек.

А я еще помню стройку...

Я, конечно, переигрываю сейчас, но "мосты начинают рушится"...

Видео момента: http://vkontakte.ru/video-11141555_122047608
Подборка статей о ГЭС (по-моему, очень интересно): http://4044415.livejournal.com/tag/Саяно-Шушенская+ГЭС

Aug. 10th, 2009

Трубка!!!

Завязать с курением не получилось, посему опять прибретена трубка (чтоб ты сдох, нарколог, посоветовавший мне выбросить две отличные штуки!)...

Какой же кайф!!!

Aug. 3rd, 2009

Все фантастичнее и фантастичнее

Если запуск частной ракеты-носителя, выведшей спутник на орбиту, кажется чем-то далеким лично от Вас - нет проблем. Нет желания запустить свой спутник? Цена вопроса - 8 килобаксов.

http://lenta.ru/news/2009/08/03/minisats/

Jul. 30th, 2009

Литеральный Haskell

Во! Мне всегда казалось, что Haskell отлично подходит для изложения концепций :)

http://bsd.piter.perikov.ru/~pavel/QuantumVector.html

Если взять этот html, переименовать в lhs и скормить компилятору - получится работающий модуль QuantumVector.

http://bsd.piter.perikov.ru/~pavel/QuantumVector.lhs

Jul. 23rd, 2009

3D фотографию и кино - в массы!

Погнали!

Previous 20

Advertisement

Customize