- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
digits n = reverse $ map (`mod` 10) (takeWhile (/= 0) (iterate (`div` 10) n))
fromDigits l = sum $ zipWith (*) (reverse l) (map (10^) [0..])
isPalindromic x = digits x == (reverse $ digits x)
f :: Integer -> [[Integer]] -> [Integer] -> Int -> [[Integer]]
f x founded lookedup niter
| niter > 50 = [notlychers, [x] ++ lychers ++ lookedup, zs]
| nextX `elem` notlychers = [[x] ++ notlychers ++ lookedup, lychers, zs]
| nextX `elem` lychers = [notlychers, [x] ++ lychers ++ lookedup, zs]
| isPalindromic nextX = [[x] ++ notlychers ++ lookedup, lychers, zs]
| otherwise = f nextX founded (x : lookedup) (niter+1)
where nextX = x + fromDigits (reverse $ digits x)
notlychers = founded !! 0
lychers = founded !! 1
zs = founded !! 2
g :: [[Integer]] -> [[Integer]]
g founded = f (x-1) [xs, ys, [x-1]] [] 0
where x = zs !! 0
xs = founded !! 0
ys = founded !! 1
zs = founded !! 2
gg n = g [[],[],[n+1]]
isLycher n = null $ (gg n) !! 0
wvxvw 23.04.2012 14:40 # −1
roman-kashitsyn 23.04.2012 15:09 # +2
wvxvw 23.04.2012 20:09 # 0
А вот теперь сравните, любой код на Яве длиной 29 строчек с хорошим форматированием и короткими строчками. Кроме того, тут почти половина посвящается конкатенации строчек и их печатанию. При чем тут нету какого-то нагромождения редко используемых функций типа всяких операций с перемещением битов в байтах.
Для того чтобы понять что код делает нужно не просто усилие приложить. Это пытка такое читать.
roman-kashitsyn 23.04.2012 20:51 # 0
wvxvw 23.04.2012 21:04 # +1
JavaGovno 23.04.2012 21:19 # 0
это ви про founded?
wvxvw 23.04.2012 22:32 # +1
TheHamstertamer 25.04.2012 14:20 # 0
3.14159265 25.04.2012 14:49 # +1
Lure Of Chaos 25.04.2012 23:55 # +3
а "трушные", наоборот, понимают высокоабстрагированный код и ругают спагетти-код.
что это? ООП головного мозга и падение профессионализма с опытом?
roman-kashitsyn 25.04.2012 23:59 # +4
wvxvw 25.04.2012 15:21 # +1
Например, выражение a b c d e может быть валидной программой в Хаскелле, Си, Лиспе и Баше, но когда Си-программист увидит такую программу, он будет с утюгом бегать за мудаком, который придумал такой шаблон. Примерно то же самое будет делать лиспер в поисках того, кто придумал такой ридер макрос. На Баше - это норма жизни, потому что интерпретация однозначная - a(b, c, d, e) - т.е. вызывается функция a с параметрами b, c, d, e. В Хаскелле - это тоже, по-своему, норма жизни, единственное, интерпретаций есть несколько: a(b(c, d, e)), a(b(c), d(e))... и т.д.
Т.е. идиотское желание убрать скобки делает язык похожим на то, как говорит Ёда.
Но если вам кажется, что это не достаточно убедительный аргумент - сравните, например: практически любой другой язык возможно автоматически отформатировать - Хаскелл в принципе не возможно. Автокомплит? - размечтались... Компьютер на уровне исходного кода вообще не понимает, что происходит в программе пока она не написана и не работает правильно. Сообщения об ошибках - как правило не то, что не указывают на строку с ошибкой, они вообще функцию правильно угадать не могут. Даже PHP в этом смысле лучше.
roman-kashitsyn 25.04.2012 15:33 # +1
Всё гораздо лучше, чем вы описали. Язык прекрасен, основная проблема - отсутствие стабильной инфраструктуры. Попробуйте установить текстовый редактор Yi (не на винде, там он вообще не соберётся, на OpenSUSE или Fedora, к примеру), и вы поймёте, о чём я. Сравните с vim/emacs. Вот, что действительно демотивирует.
wvxvw 25.04.2012 16:50 # 0
Первое и самое устойчивое сравнение которое возникает при виде программы на Хаскеле - клинопись (я, кстати могу читать некоторые древние симитские языки, не только иврит - так что знаю из первоисточника, на что это похоже). Только там это было объяснимо потому, что писать пупым гвоздем по камню - особо не разбежишься, а когда то же самое делают в 21м веке - это идиотизм.
Я пробовал leksah - Yi не пробовал, но не горю желанием. Разве что если я когда-нибудь возьмусь придумывать систему магии и алхимии для ролевых игр, и мне не будет хватать пиктрограм.
wvxvw 25.04.2012 17:27 # 0
PS. Вот, кстати, офигенная иллюстрация тому, как ИДЕ написаная на Хаскеле понимает синтаксис языка - не сложно догадаться, что лямбды там не было, это слеши которые нужны для того, чтобы записать многострочный строковый литерал - потому что кавычек явно не хватило...
roman-kashitsyn 25.04.2012 17:43 # +2
От синтаксиса лично у меня никакого баттхёрта нет.
TarasB 23.04.2012 15:11 # +5
lucidfoxGovno 26.04.2012 03:14 # −2
guest 23.04.2012 23:21 # +2
// к слову есть модуль с digits / unDigits, то запарка тут чуть ниже
guest 23.04.2012 23:22 # 0
roman-kashitsyn 23.04.2012 23:26 # 0
wvxvw 24.04.2012 00:56 # 0
Исключительно для примера (можно было оптимизировать, чтобы строку не создавать каждый раз, но это мелочи по сравнению с ненужной проверкой половины строки:
ПС. И lychrels, а не lychers :).
ППС. И структура такаяже черззаборногузадерическая - нужно угадывать что происходит после чего и где функция а где аргументы.
guest 24.04.2012 01:03 # +3
Premature-optimisation ;). Здесь конкретная задача, а на списках так проще.
> lychrels
Ага, текст по ссылке по диагонали прочитал. Подхватил ошибку из приведенного кода.
guest 24.04.2012 01:13 # 0
wvxvw 24.04.2012 01:26 # 0
we shall assume that a number is Lychrel
Где в конкретной задаче вообще говорится об использовании списков? Ну, если проще сделать хуже - то в чем собственно оправдание? Да, как правило проще сделать хуже.
Про решето Эратосфена - имелось в виду не проверять суммы от уже проверенных слагаемых? Если да - то, вобщем, имеет смысл, но с другой стороны не-палиндромов не так-то и много, как оказалось (меньше 400), так что это как раз не принципиально (по сравнению с потенциальными ненужными 500000 проверками).
guest 24.04.2012 01:36 # 0
Про цепочки: для каждого числа - проверяем 50 последующих, то есть для второго проверено 49, проверив ~64 вместо 50 можно снизить число операций (вроде раз в 10).
// Проверьте, что-то ваш код много выдает, вроде 249 должно быть.
guest 24.04.2012 01:39 # 0
wvxvw 24.04.2012 01:57 # 0
Раз уж такое дело :)
ЗЫ. Где и кто определил приемлимое время?
roman-kashitsyn 24.04.2012 09:45 # +1
на projecteuler.net и определено:
Each problem has been designed according to a "one-minute rule", which means that although it may take several hours to design a successful algorithm with more difficult problems, an efficient implementation will allow a solution to be obtained on a modestly powered computer in less than one minute.
Мне экономия на стравнении полиномов не кажется хорошей стратегией оптимизации, поскольку она не даёт ни выигрыша в порядке роста, ни даже особого выигрыша в константе (в два раза точно быстрее не заработает, тут полно более затратных операций).
я бы решил задачу в точности так же, как guest:
Результат выполнения:
т.е. даже при использовании языка с "динамической" типизацией на современной машине такое решение поставленной задачи требует около полусекунды (измерял несколько раз, было и 221.99 ms). Я считаю это вполне приемлимым.
wvxvw 24.04.2012 10:36 # 0
При всем желании, я не вижу смысла делать лишнюю по определению проверку, даже если бы это не занимало столько времени. Это просто глупо.
roman-kashitsyn 24.04.2012 10:57 # 0
но на ней крутится tomcat с нехилым приложением, запущено несколько проектов IntelliJ IDEA и браузер.
Давайте посмотрим в ideone, думаю, там примерно одинаковые машины выполняют код (хоть конкретных характеристик я и не нашёл): Жаль, что у ребят стоит clisp, он вроде только интерпретирует код, не компилирует. Не знаю, почему ваш код возвращает 9648, я в него не вникал, просто скопировал и добавил format. К сожалению, вывести время непосредственного выполнения куска кода в CL не так просто, суммарное время на компиляцию и запуск у программ примерно одинаковое.
roman-kashitsyn 24.04.2012 11:02 # +1
> Это просто глупо
наличие этой "лишней" проверки существенно упрощает алгоритм, кроме того, оно гораздо лучше сочетается с функциональной парадигмой.
В индустрии ПО очень много "лишних" действий (разбиение приложение на слои, всякие там шаблоны вместо свитчей), но удобство и скорость разработки программ нынче гораздо важнее потерянных миллисекунд.
wvxvw 24.04.2012 11:05 # 0
Скомилировать можно, но там этого никто не даст сделать.
Я распечатал все найденые палиндромы и числа из которых они были получены, проверил - все сошлось 352. Не знаю как у вас получается что-то другое.
roman-kashitsyn 24.04.2012 11:06 # +1
wvxvw 24.04.2012 11:36 # 0
Как проверял :)
roman-kashitsyn 24.04.2012 11:41 # +1
кажется, здесь что-то не так: число нужно складывать с инверсией его самого:
> 47 + 74 = 121
wvxvw 24.04.2012 11:50 # 0
wvxvw 25.04.2012 15:44 # 0
Около 90 миллисекунд.
roman-kashitsyn 25.04.2012 15:56 # 0
Жаль, в CL нет поддержки ленивых последовательностей из коробки, хоть при наличии макросов их и можно реализовать в виде библиотеки.
P.S. я бы на вашем месте не использовал конструкцию (if (cond) (progn ...)), ведь есть более короткий и удобочитаемый (when (cond) ...), который развернётся в ту же конструкцию
wvxvw 25.04.2012 17:00 # 0
ЗЫ. (when (cond ...)) совсем не то же самое что (if (cond) ...) уже хотя бы потому, что это тот же if, только с одной веткой, а в коде их две :S
roman-kashitsyn 25.04.2012 17:31 # 0
>> SICP (Structure and Interpretation of Computer Programs)
> в коде их две
У вас форматирование поехало, incf на одном уровне с if, а скобочки я не считал. Извиняюсь.
wvxvw 25.04.2012 17:42 # 0
roman-kashitsyn 25.04.2012 17:53 # 0
wvxvw 25.04.2012 20:07 # 0
roman-kashitsyn 24.04.2012 11:55 # 0
занятная очепятка add-xyes
wvxvw 24.04.2012 12:17 # 0
wvxvw 24.04.2012 02:01 # 0
Может зависеть от того, что подразумевается под палиндромом. Только wxxw или так же и wvxvw.
wvxvw 24.04.2012 01:31 # 0