Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, thesz, Вы писали:
К>>>Тривиальная? Вон Булат с разбега дал красивое и неправильное решение. А nikov-у пришлось прибегнуть к арифметике. T>>Это получение 2^n, по-моему. Вся сложность в трудности проверок. К>Поясни. Не понял твою мысль насчёт трудности проверок.
Большой размер получающихся данных.
Как доказать, что subsequences [1..n] совпадает с первыми 2^n элементами subsequences [1..n+1].
T>>Второе: http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-List.html#v%3Asubsequences T>>Проблемы могут быть с бесконечностью, тут уже начинаются нюансы. К>Не просто могут быть, а сразу есть. К>subsequences[0..] рожает [] и затем бесконечный поток одноэлементных списков [0],[1],...
Вот это, как раз, и есть нюанс.
Что лучше — бесконечный поток одноэлементных списков, или бесконечный поток каких-либо других списков?
Начало subsequences [1..n] совпадает с началом subsequences [1..n+1]. Поэтому я считаю, что ты проверял свои выкладки на каком-то неправильном subsequences.
Тот, что в Data.List, хороший. Тот, что использовал ты, не очень.
T>>Здесь может помочь http://hackage.haskell.org/package/control-monad-omega К>Прикольно. А можешь избавить меня от труда по вчитыванию в предмет, и на пальцах рассказать и показать про эту монаду Омега? Буду премного благодарен.
Вот выражение:
do
x <- list_a
y <- list_b
return $ f x y
Обычная монада списка сперва выберет все элементы из list_a, а потом все элементы из list_b. Если list_a бесконечен, то мы получим на выходе map (\x -> f x (head list_b)) list_a, элементы второго списка перебираться не будут.
diagonal позволяет выбирать элементы "по диагонали", перебирая пары "в ширину".
Для переборных алгоритмов самое то.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[5]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, hexamino, Вы писали:
H>Надо написать функцию, которая, получив на вход список (конечный или бесконечный), вернет список всех его конечных подпоследовательностей. Для бесконечного исходного списка подпоследовательностей должно быть, естественно, бесконечно много. Помогите, пожалуйста.
sub (x:xs) = [[x]] ++ concatMap (\a -> [x:a,a]) (sub xs)
sub [] = []
Люди, я люблю вас! Будьте бдительны!!!
Re[2]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, Quintanar, Вы писали:
H>>Надо написать функцию, которая, получив на вход список (конечный или бесконечный), вернет список всех его конечных подпоследовательностей. Для бесконечного исходного списка подпоследовательностей должно быть, естественно, бесконечно много. Помогите, пожалуйста.
Q>Для бесконечного списка — это несчетное множество, что делает задачу несколько бессмысленной.
Множество всех подмножеств счетного множества — несчетно. А множество конечных подмножеств счетного множества — счетно.
Re[6]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, Quintanar, Вы писали:
Q>Хмм, да. Но все равно смысла в такой постановке задачи мало — как я уже сказал, я могу возвращать Q>сначала все одноэлементные подмножества. Это значительно проще, а условию не противоречит.
Противоречит
Приведенное Булатом решение за конечное время добирается до любой наперед заданной подпоследовательности, то есть решает поставленную задачу нахождения всех конечных подпоследовательностей. Твое решение этого не делает.
Re[4]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, Quintanar, Вы писали:
H>>Надо написать функцию, которая, получив на вход список (конечный или бесконечный), вернет список всех его конечных подпоследовательностей. Для бесконечного исходного списка подпоследовательностей должно быть, естественно, бесконечно много. Помогите, пожалуйста.
Q>Для бесконечного списка — это несчетное множество, что делает задачу несколько бессмысленной.
А по-моему, счётное.
Каждой подпоследовательности поставим в соответствие двоичную дробь вида 0.xyz.... где i-й разряд выставлен в 1, если этот i-й элемент списка включён в подпоследовательность, и 0, если не включён.
У конечной подпоследовательности, очевидно, конечное количество единичек, и после последней единички идут одни нули.
Таким образом, всем конечным подпоследовательностям соответствуют конечные двоичные дроби — это подмножество рациональных чисел, а рациональные числа счётны.
Ну а если мы воспользуемся тем, что последовательность кодируется конечным двоичным вектором, то отзеркалим дробь 0.xy...z1 --> 1z...yx.0 и получим натуральное число.
Несложно показать, что такие натуральные числа взаимно-однозначно определяют последовательности — т.е. любому числу соответствует какая-то уникальная последовательность, и любой последовательности соответствует какое-то уникальное число.
Отсюда очень просто написать функцию
nth_subseq :: Integer -> [a] -> [a]
nth_subseq 0 _ = []
nth_subseq k (x:xs) = if odd k then x:rest else rest where rest = nth_subseq (k`div`2) xs
nth_subseq _ _ = error"index out of range"
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Re: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, hexamino, Вы писали:
H>Надо написать функцию, которая, получив на вход список (конечный или бесконечный), вернет список всех его конечных подпоследовательностей. Для бесконечного исходного списка подпоследовательностей должно быть, естественно, бесконечно много. Помогите, пожалуйста.
Конечная подпоследовательность — подпоследовательность, содержащаяся в конце списка.
На конце списка всегда находится пустой список. [].
Единственная подпоследовательность, содержащаяся в пустом списке, это пустой список.
Надо написать функцию, которая, получив на вход список (конечный или бесконечный), вернет список всех его конечных подпоследовательностей. Для бесконечного исходного списка подпоследовательностей должно быть, естественно, бесконечно много. Помогите, пожалуйста.
Re: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, hexamino, Вы писали:
H>Надо написать функцию, которая, получив на вход список (конечный или бесконечный), вернет список всех его конечных подпоследовательностей. Для бесконечного исходного списка подпоследовательностей должно быть, естественно, бесконечно много.
finiteSublists :: [a] -> [[a]]
finiteSublists xs = concat f
where f = [[]] : [map (++[x]) $ concat $ take (n+1) f | (x,n) <- zip xs [0..]]
Re: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, hexamino, Вы писали:
H>Надо написать функцию, которая, получив на вход список (конечный или бесконечный), вернет список всех его конечных подпоследовательностей. Для бесконечного исходного списка подпоследовательностей должно быть, естественно, бесконечно много. Помогите, пожалуйста.
План такой: для каждого элемента списка найти все последовательности головной части списка, не доходящей до него, плюс этот элемент.
splits :: [a] -> [([a],a)] -- разбивает на сочетания (префикс, голова суффикса)
splits xs = splits' [] xs where
splits' _ [] = []
splits' ys (z:zs) = (ys,z) : splits' (ys++[z]) zs
finites :: [a] -> [[a]]
finites xs =
[[]] -- пустая есть всегда
++
concat (map make' pairs') where
make' (ys,z) = map (++[z]) (subsequences ys)
pairs' = splits xs
subsequences xs = finites xs -- либо любой другой алгоритм (который может уже заложиться на то, что xs конечный)
Можно попробовать всё это добро выразить в линзах-бананах или ZF-нотации. Но, боюсь, понятность кода от этого проиграет.
Проверяем
test xs = do
putStrLn $ "source is " ++ show xs
let q___q = map (const '-') $ show xs
putStrLn q___q
let ss = finites xs
mapM_ (putStrLn . show) ss
putStrLn q___q
main = do
test ""
test "abcd"
на выходе
source is ""
--
""
--
source is "a"
---
""
"a"
---
source is "abcd"
------
"" -- первый (особый) случай
"a" -- разбили на "",'a',...
"b" -- разбили на "a",'b',...
"ab"
"c" -- разбили на "ab",'c',...
"ac"
"bc"
"abc"
"d" -- разбили на "abc",'d',...
"ad"
"bd"
"abd"
"cd"
"acd"
"bcd"
"abcd"
------ -- могли бы и дальше перебирать, но здесь суффикс внезапно иссяк
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Re[2]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, thesz, Вы писали:
T>Здравствуйте, hexamino, Вы писали:
H>>Надо написать функцию, которая, получив на вход список (конечный или бесконечный), вернет список всех его конечных подпоследовательностей. Для бесконечного исходного списка подпоследовательностей должно быть, естественно, бесконечно много. Помогите, пожалуйста.
T>Конечная подпоследовательность — подпоследовательность, содержащаяся в конце списка.
Нет, конечная — это содержащая конечное (не бесконечное) число элементов.
Re[2]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, thesz, Вы писали:
T>Здравствуйте, hexamino, Вы писали:
H>>Надо написать функцию, которая, получив на вход список (конечный или бесконечный), вернет список всех его конечных подпоследовательностей. Для бесконечного исходного списка подпоследовательностей должно быть, естественно, бесконечно много. Помогите, пожалуйста.
T>Конечная подпоследовательность — подпоследовательность, содержащаяся в конце списка.
T>На конце списка всегда находится пустой список. [].
T>Единственная подпоследовательность, содержащаяся в пустом списке, это пустой список.
Прикольный ответ, конечно, хотя автор имел в виду не такое понимание "конечных подпоследовательностей"
Но если принять Ваш вариант ТЗ, то вот решение короче:
f xs = []
Re[3]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, geniepro, Вы писали:
G>Здравствуйте, thesz, Вы писали:
T>>Здравствуйте, hexamino, Вы писали:
T>>Конечная подпоследовательность — подпоследовательность, содержащаяся в конце списка.
G>Прикольный ответ, конечно, хотя автор имел в виду не такое понимание "конечных подпоследовательностей" G>Но если принять Ваш вариант ТЗ, то вот решение короче:
G>
f xs = []
К сожалению, это не проходит для бесконечной последовательности.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[4]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, hexamino, Вы писали:
H>Здравствуйте, thesz, Вы писали:
T>>Здравствуйте, hexamino, Вы писали:
H>>>Надо написать функцию, которая, получив на вход список (конечный или бесконечный), вернет список всех его конечных подпоследовательностей. Для бесконечного исходного списка подпоследовательностей должно быть, естественно, бесконечно много. Помогите, пожалуйста.
T>>Конечная подпоследовательность — подпоследовательность, содержащаяся в конце списка. H>Нет, конечная — это содержащая конечное (не бесконечное) число элементов.
Дополнительные навыки: C++, Java, Scala, Haskell, F#, VB.NET, JavaScript, HTML, XML/XSLT, T-SQL; работа с базами данных, разработка web-приложений, обработка финансовых данных.
Я считаю, что ты наврал в рекламе самого себя, поскольку спрашиваешь решение тривиальной задачи.
Я считаю, что это плохо. Поэтому я не буду решать эту и другие задачи, которые ты здесь будешь излагать.
Yours truly, Serguey Zefirov (thesz NA mail TOCHKA ru)
Re[2]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, BulatZiganshin, Вы писали:
H>>Надо написать функцию, которая, получив на вход список (конечный или бесконечный), вернет список всех его конечных подпоследовательностей. Для бесконечного исходного списка подпоследовательностей должно быть, естественно, бесконечно много. Помогите, пожалуйста.
Здравствуйте, thesz, Вы писали:
T>Видим там вот такое:
Дополнительные навыки: C++, Java, Scala, Haskell, F#, VB.NET, JavaScript, HTML, XML/XSLT, T-SQL; работа с базами данных, разработка web-приложений, обработка финансовых данных.
T>Я считаю, что ты наврал в рекламе самого себя, поскольку спрашиваешь решение тривиальной задачи.
А что мне думать о тебе, после того, как ты даже не смог понять ее условие?
На самом деле, у меня было свое решение, но оно было более громоздкое, чем приведенные в этой ветке. К сожалению, Haskell — не мой основной навык, о чем я и написал в своем блоге.
Re[3]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, thesz, Вы писали:
T>>Я считаю, что ты наврал в рекламе самого себя, поскольку спрашиваешь решение тривиальной задачи.
К>Тривиальная? Вон Булат с разбега дал красивое и неправильное решение. А nikov-у пришлось прибегнуть к арифметике.
Это получение 2^n, по-моему. Вся сложность в трудности проверок.
Здравствуйте, thesz, Вы писали:
К>>Тривиальная? Вон Булат с разбега дал красивое и неправильное решение. А nikov-у пришлось прибегнуть к арифметике.
T>Это получение 2^n, по-моему. Вся сложность в трудности проверок.
Здравствуйте, Кодт, Вы писали:
К>Странно... видать, где-то я очепятнулся.
Блин. Колдунство какое-то
sub (x:xs) = [[]] ++ concatMap (\a -> [x:a,a]) (sub xs)
sub [] = []
test fun xs = do
putStrLn $ "source is " ++ show xs
let q___q = map (const '-') $ show xs
putStrLn q___q
let ss = fun xs
mapM_ (putStrLn . show) ss
putStrLn q___q
main = do
test sub ['A'..'Z']
Выводит с дырками.
А если вбить let sub[]=[]; sub(x:xs)=..... в интерпретаторе руками — то без дырок.
Ниччего не понимаю.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Re[8]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, hexamino, Вы писали:
H>Надо написать функцию, которая, получив на вход список (конечный или бесконечный), вернет список всех его конечных подпоследовательностей. Для бесконечного исходного списка подпоследовательностей должно быть, естественно, бесконечно много. Помогите, пожалуйста.
Для бесконечного списка — это несчетное множество, что делает задачу несколько бессмысленной. Для конечного
списка задача кажется мегатривиальной.
Re[2]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, deniok, Вы писали:
D>Здравствуйте, Quintanar, Вы писали:
Q>>Для бесконечного списка — это несчетное множество, что делает задачу несколько бессмысленной.
D>И какие же конечные ненулевые подпоследовательности пропускает
Подмножества бесконечного множества — это набор бесконечных последовательностей из 0 и 1, т.е.
вещественные числа. Это несчетное множество и хоть я не могу сказать, что именно пропускает эта прога,
она обязательно что-то пропускает, поскольку программа может перенумеровать только счетное множество.
Она неверна в принципе при такой постановке задачи. Надо явно оговаривать, что она должна работать
именно так, а то я, например, считаю, что сначала должны возвращаться все одноэлементные подмножества
и это тоже будет верное решение.
Re[4]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, Quintanar, Вы писали:
Q>Подмножества бесконечного множества — это набор бесконечных последовательностей из 0 и 1, т.е. Q>вещественные числа.
Не, там в условии "список всех его конечных подпоследовательностей".
Re[5]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, deniok, Вы писали:
D>Здравствуйте, Quintanar, Вы писали:
Q>>Подмножества бесконечного множества — это набор бесконечных последовательностей из 0 и 1, т.е. Q>>вещественные числа.
D>Не, там в условии "список всех его конечных подпоследовательностей".
Хмм, да. Но все равно смысла в такой постановке задачи мало — как я уже сказал, я могу возвращать
сначала все одноэлементные подмножества. Это значительно проще, а условию не противоречит.
Re[7]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, deniok, Вы писали:
D>Противоречит D>Приведенное Булатом решение за конечное время добирается до любой наперед заданной подпоследовательности, то есть решает поставленную задачу нахождения всех конечных подпоследовательностей. Твое решение этого не делает.
Не очень существенное замечание, поскольку требования вернуть любую наперед заданную последовательность в задаче нет.
А возвращать множества, удовлетворяющие условию задачи, моя программа может сколь угодно долго.
Re[8]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, Quintanar, Вы писали:
D>>Противоречит D>>Приведенное Булатом решение за конечное время добирается до любой наперед заданной подпоследовательности, то есть решает поставленную задачу нахождения всех конечных подпоследовательностей. Твое решение этого не делает.
Q>Не очень существенное замечание, поскольку требования вернуть любую наперед заданную последовательность в задаче нет.
В условии есть слово "всех". Очевидно, что предложенный тобой алгоритм никогда не вернет некоторые из конечных последовательностей.
Re[9]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, nikov, Вы писали:
Q>>Не очень существенное замечание, поскольку требования вернуть любую наперед заданную последовательность в задаче нет.
N>В условии есть слово "всех". Очевидно, что предложенный тобой алгоритм никогда не вернет некоторые из конечных последовательностей.
Это очевидно, если признавать операции с бесконечностью. А теперь представим, что я выдал этот
алгоритм тебе в черном ящике. Сможешь ли ты доказать, что он чего-то не вернет, пусть даже
за бесконечное время? Нет. Значит, это правильный алгоритм.
Re[10]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, Quintanar, Вы писали:
Q>Здравствуйте, nikov, Вы писали:
Q>>>Не очень существенное замечание, поскольку требования вернуть любую наперед заданную последовательность в задаче нет.
N>>В условии есть слово "всех". Очевидно, что предложенный тобой алгоритм никогда не вернет некоторые из конечных последовательностей.
Q>Это очевидно, если признавать операции с бесконечностью. А теперь представим, что я выдал этот Q>алгоритм тебе в черном ящике. Сможешь ли ты доказать, что он чего-то не вернет, пусть даже Q>за бесконечное время? Нет. Значит, это правильный алгоритм.
Но и ты не сможешь опровергнуть утверждение, что этот алгоритм выдает только одноэлементные последовательности (не решая, тем самым, задачу). Утверждения о черных ящиках они такие
Re[10]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, Quintanar, Вы писали:
Q>А теперь представим, что я выдал этот Q>алгоритм тебе в черном ящике. Сможешь ли ты доказать, что он чего-то не вернет, пусть даже Q>за бесконечное время? Нет.
Если у меня нет возможности анализировать код алгоритма, а только его поведение, то про очень многие алгоритмы нельзя доказать, что они неправильные. Например
subs = subs
А если еще запретить смотреть на результаты, так и вообще...
Re[11]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, deniok, Вы писали:
D>Но и ты не сможешь опровергнуть утверждение, что этот алгоритм выдает только одноэлементные последовательности (не решая, тем самым, задачу). Утверждения о черных ящиках они такие
Я не должен ничего опровергать. Я утверждаю, что мой алгоритм решает поставленную задачу. Конструктивного
способа доказать обратное нет (или пока не привели такое). А доказательства оперирующие бесконечностью я
не принимаю, ведь мы находимся в мире алгоритмов
Я бы даже сказал, что моя программа намного лучше, поскольку она потребляет меньше ресурсов
и более короткая и понятная.
Re[12]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, Quintanar, Вы писали:
Q>Здравствуйте, deniok, Вы писали:
D>>Но и ты не сможешь опровергнуть утверждение, что этот алгоритм выдает только одноэлементные последовательности (не решая, тем самым, задачу). Утверждения о черных ящиках они такие
Q>Я не должен ничего опровергать. Я утверждаю, что мой алгоритм решает поставленную задачу.
А я утверждаю, что он решает другую, несовместимую задачу (выдача одноэлементных последовательностей).
Для проверки мы запускаем его и видим, что мое утверждение столь же обосновано, сколь твое
Re[11]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, nikov, Вы писали:
N>Если у меня нет возможности анализировать код алгоритма, а только его поведение, то про очень многие алгоритмы нельзя доказать, что они неправильные. Например
N>
N>subs = subs
N>
N>А если еще запретить смотреть на результаты, так и вообще...
Код не поможет. Я мог бы взять какую-нибудь нерешенную математическую задачу, которую
можно вычислительно проверять для последовательности чисел и поставить условие —
если эта гипотеза неверна для текущего N, то переключаемся на алгоритм Булата.
Re[13]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, deniok, Вы писали:
Q>>Я не должен ничего опровергать. Я утверждаю, что мой алгоритм решает поставленную задачу.
D>А я утверждаю, что он решает другую, несовместимую задачу (выдача одноэлементных последовательностей). D>Для проверки мы запускаем его и видим, что мое утверждение столь же обосновано, сколь твое
Ну да, мой алгоритм решает обе задачи, хе-хе. Бесконечность она такая штука...
Re[14]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, Quintanar, Вы писали:
Q>Здравствуйте, deniok, Вы писали:
Q>>>Я не должен ничего опровергать. Я утверждаю, что мой алгоритм решает поставленную задачу.
D>>А я утверждаю, что он решает другую, несовместимую задачу (выдача одноэлементных последовательностей). D>>Для проверки мы запускаем его и видим, что мое утверждение столь же обосновано, сколь твое
Q>Ну да, мой алгоритм решает обе задачи, хе-хе. Бесконечность она такая штука...
К сожалению такого не бывает. Решения у этих задач разные, так что больше одной не выйдет.
Re[9]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, Кодт, Вы писали:
H>>>Надо написать функцию, которая, получив на вход список (конечный или бесконечный), вернет список всех его конечных подпоследовательностей. Для бесконечного исходного списка подпоследовательностей должно быть, естественно, бесконечно много. Помогите, пожалуйста.
Q>>Для бесконечного списка — это несчетное множество, что делает задачу несколько бессмысленной.
К>А по-моему, счётное.
я думаю, он перепутал с подмножествами. здесь же бе всяких хистростев имеем N^2, где N — мощность счётного множества. для подмножеств же будет несчётное 2^N
Люди, я люблю вас! Будьте бдительны!!!
Re[4]: [Haskell] Найти все конечные подпоследовательности
Здравствуйте, BulatZiganshin, Вы писали:
BZ>я думаю, он перепутал с подмножествами. здесь же бе всяких хистростев имеем N^2, где N — мощность счётного множества. для подмножеств же будет несчётное 2^N
Конечные/бесконечные подпоследовательности списка-как-последовательности суть конечные/бесконечные (соответственно) подмножества списка-как-множества.
И ровно тем же способом проецируются на [0;1] и [0..]
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Re: [Haskell] Найти все конечные подпоследовательности
От:
Аноним
Дата:
09.11.09 16:54
Оценка:
Здравствуйте, hexamino, Вы писали:
H>Надо написать функцию, которая, получив на вход список (конечный или бесконечный), вернет список всех его конечных подпоследовательностей. Для бесконечного исходного списка подпоследовательностей должно быть, естественно, бесконечно много. Помогите, пожалуйста.
filterM (const [False,True])
Re[2]: [Haskell] Найти все конечные подпоследовательности