- 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
import Control.Monad
import Control.Arrow
import Data.List
solve' :: [String] -> [[String]]
solve' = nub . filter (
and . uncurry (
zipWith (
(.head) . (==) . last
)
) . (id &&& tail)
) . uncurry ($) . (
last . (((
map (
last . fst &&& uncurry (++) . (init . fst &&& snd)
) . tail . uncurry (zipWith (,)) . (inits &&& tails)
) >=> (uncurry map) .
((:) *** solve')
):
) . (uncurry takeWhile) . (
const . null &&& const [const [[]]]
) &&& id
)
main = print $ solve' ["123","321","123"]
Dummy00001 21.02.2013 18:52 # +1
3.14159265 21.02.2013 19:01 # +2
Кресты тоже эзотерика, до тех пор пока значки не выучишь. Тут та же проблема - аинтуитивность обозначений.
Кстати я заметил что тут многие любители С++ изучили и хацкиль. Повторюсь: тут очень кошерно отформатирован код, даже местами прослеживается следование заветам тарасоформатирования.
> nub . filter
bormand 21.02.2013 22:14 # +2
Очень даже неплохой. Меня отфильтровал, т.к. я не знаю, что делают >=> , &&& и ***. А читать про них что-то влом.
LispGovno 21.02.2013 23:27 # 0
LispGovno 21.02.2013 23:28 # −3
LispGovno 21.02.2013 23:29 # −3
http://rchan.ws/pr/src/1361391985569.png
LispGovno 21.02.2013 23:42 # −3
HaskellGovno 22.02.2013 23:34 # 0
Стареешь, бор. Какой уж десяток разменял?
bormand 22.02.2013 00:18 # +4
Блок 13-22 прогоняет аргумент через композицию last, 14-19, uncurry takeWhile и 21, и возвращает результат в виде тупла, наряду с исходным аргументом.
uncurry (zipWith (,)) . (inits &&& tails) - функция, возвращающая все варианты разбиения списка на два, tail отбросит случай с пустым первым списком, а map преобразует каждый тупл: \(x, y) -> (last x, init x ++ y). В результате получаем функцию, которая возвращает все варианты выборки одного элемента - для [1,2,3] она вернет [(1, [2, 3]), (2, [1, 3]), (3, [1, 2])].
(uncurry map) . ((:) *** solve') это \(x, y) -> map (x:) $ solve' y. Объединив этот блок с предыдущим с помощью >=> получим функцию, которая вынимает каждый элемент списка, выполняет solve' над оставшимися, и к каждому результату приклеивает в начало вынутый элемент.
const . null это \x -> \_ -> null x, а const [const [[]]] это \_ -> [\_ -> [[]]] поэтому строка 21 переписывается как \x -> (\_ -> null x, [\_ -> [[]]]). Композиция этой фигни с uncurry takeWhile даст нам \x -> takeWhile (\_ -> null x) [\_ -> [[]]]. Если x пуст, мы получим список из одной функции: [\_ -> [[]]], иначе - пустой список.
В итоге строки 12-23 возвращают [[]] для пустого списка, а для непустого вынимает каждый элемент списка, выполняет solve' над оставшимися, и к каждому результату приклеивает в начало вынутый элемент. Перепишем эти строки как to be continued...
bormand 22.02.2013 00:35 # +3
В результате получаем вот такой код: А задача была примерно такой - "найти все перестановки исходных строк, при которых они будут правильно сцеплены (последний символ предыдущей равен первому символу следующей)".
bormand 22.02.2013 00:42 # +3
HaskellGovno 22.02.2013 06:30 # 0
Yuuri 22.02.2013 10:56 # 0
guest 22.02.2013 13:11 # 0
Что это и где это?
bormand 22.02.2013 14:25 # +1
P.S. Но юзать лямбдабота не спортивно ;)
HaskellGovno 22.02.2013 23:32 # 0
bormand 22.02.2013 23:46 # 0
HaskellGovno 22.02.2013 23:52 # 0
guest 23.02.2013 16:46 # +2
LispGovno 23.02.2013 18:43 # −2
roman-kashitsyn 23.02.2013 19:09 # +3
LispGovno 23.02.2013 20:01 # 0
...
Троллить вечно
Yuuri 22.02.2013 14:28 # +1
guest 22.02.2013 15:19 # 0