Re[3]: Пояснение по условию
От: Кодт Россия  
Дата: 04.12.05 22:29
Оценка: 1 (1)
Здравствуйте, reductor, Вы писали:

R>perm :: [Int] -> [Int]
R>perm zs = perm' zs (tails zs)
R>    where perm' [] _ = []
R>          perm' _ [] = []
R>          perm' (x:xs) (y:ys) = map ((+) x . sum) ys ++ perm' xs ys

В сторону: это что, общепринятый стиль письма на Хаскелле — минимально информативные имена давать переменным?
Пришлось немного на бумажке пописать, чтобы вникнуть в происходящее. Впрочем, для языковой практики это полезно

А по сути: если zs (неотрицательные и отсортированы по убыванию) или (неположительные и отсортированы по возрастанию), то вся выходная последовательность тоже отсортирована по убыванию или возрастанию, соответственно.

В противном случае последовательность не отсортирована.
А поскольку её размер — экспоненциальный, то сортировка (требующая присутствия всех элементов в памяти) накроется медным тазом.
WinHugs обломился вот на таком: length (sort [1..33340]) ещё выдерживает, а 33341 уже нет. Значит, входной список из 17 элементов — накроет его медным тазом.
Перекуём баги на фичи!
Re[4]: Пояснение по условию
От: reductor  
Дата: 04.12.05 23:38
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, reductor, Вы писали:


К>
R>>perm :: [Int] -> [Int]
R>>perm zs = perm' zs (tails zs)
R>>    where perm' [] _ = []
R>>          perm' _ [] = []
R>>          perm' (x:xs) (y:ys) = map ((+) x . sum) ys ++ perm' xs ys
К>

К>В сторону: это что, общепринятый стиль письма на Хаскелле — минимально информативные имена давать переменным?
К>Пришлось немного на бумажке пописать, чтобы вникнуть в происходящее. Впрочем, для языковой практики это полезно :)

К>А по сути: если zs (неотрицательные и отсортированы по убыванию) или (неположительные и отсортированы по возрастанию), то вся выходная последовательность тоже отсортирована по убыванию или возрастанию, соответственно.


К>В противном случае последовательность не отсортирована.

К>А поскольку её размер — экспоненциальный, то сортировка (требующая присутствия всех элементов в памяти) накроется медным тазом.
К>WinHugs обломился вот на таком: length (sort [1..33340]) ещё выдерживает, а 33341 уже нет. Значит, входной список из 17 элементов — накроет его медным тазом.

Я кстати неправильно написал...
Re[5]: Пояснение по условию
От: Кодт Россия  
Дата: 05.12.05 01:00
Оценка: 1 (1)
Здравствуйте, reductor, Вы писали:

R>Я кстати неправильно написал...


Это ещё один камень в огород нотации "к-сть — с-а т.!"

Возможно, что изначально задумывалась такое
listsums :: (Num elt) => [elt]{-входные данные-} -> [elt{-сумма комбинации-}]{-для разных комбинаций-}

-- суммы комбинаций как минимум двух элементов
listsums [] = []
listsums [x] = []
listsums x1:x2:xs =  (listsums2 (x1+x2) xs) -- взяли два первых элемента, находим суммы комбинаций длиной >= 0
                  ++ (listsums1 x1 xs) -- взяли первый элемент, пропустили второй, суммы комбинаций длиной >= 1
                  ++ (listsums  x2:xs) -- пропустили первый элемент, находим суммы комбинаций длиной >= 2
  where
    -- суммы комбинаций как минимум одного элемента, плюс константа
    listsums1 :: elt{-прибавка к сумме-} -> [elt]{-хвост-} -> [elt]{-суммы комбинаций-}
    listsums1 x0 [] = []
    listsums1 x0 [x] = [x0+x]
    listsums1 x0 x1:xs = (listsums2 (x0+x1) xs) ++ (listsums1 x0 xs)
    -- суммы комбинаций в том числе нуля элементов, плюс константа
    listsums2 :: elt{-прибавка к сумме-} -> [elt]{-хвост-} -> [elt]{-суммы комбинаций-}
    listsums2 x0 [] = [x0]
    listsums2 x0 x:xs = (x0+sum(x:xs)) : (listsums2 x0 xs)
    -- listsumsN, N означает, сколько элементов уже учтено

После чего выражаем всё это хозяйство через foldr. И тихо плачем, когда нужно будет что-нибудь пофиксить.

Кстати, а компилятор Хаскелла умеет заменять пассинг биндингом и распознавать какие-то характерные приёмы программирования?
Перекуём баги на фичи!
Re[2]: Пояснение по условию
От: Трурль  
Дата: 05.12.05 08:46
Оценка:
Здравствуйте, Mamut, Вы писали:

M>Как оказалось, условие я и сам неправильно понял. Оказалось, что надо не просто суммы смежных двоек, троек и т.д., а все гораздо хуже Необходимо суммы всех возможных групп чисел вообще. Т.е. а1 + а2, а1 + а3, а1 + а4, ...., а1 + а2 + а3, а1 + а3 + а4, ..., а2 + а3, ..., а2 + а4 + а5, ...


M>И потом получившиеся суммы поставить в порядке возрастания. На вопрос "а нафига это надо", друг не ответил, сказал, что надо А я уже обещался помочь



allsums ([])= []
allsums ([a])= []
allsums ([a,b])= [a+b]
allsums (a:as)=  (allsums as)++(map (a+) as)++(map (a+) (allsums as))

main = interact (unwords.(map show).sort.allsums.(map read).words)
Re[3]: Пояснение по условию
От: reductor  
Дата: 05.12.05 11:11
Оценка:
Здравствуйте, Трурль, Вы писали:

Т>Здравствуйте, Mamut, Вы писали:


M>>Как оказалось, условие я и сам неправильно понял. :shuffle: Оказалось, что надо не просто суммы смежных двоек, троек и т.д., а все гораздо хуже :) Необходимо суммы всех возможных групп чисел вообще. Т.е. а1 + а2, а1 + а3, а1 + а4, ...., а1 + а2 + а3, а1 + а3 + а4, ..., а2 + а3, ..., а2 + а4 + а5, ...


M>>И потом получившиеся суммы поставить в порядке возрастания. На вопрос "а нафига это надо", друг не ответил, сказал, что надо :xz: А я уже обещался помочь :shuffle:


Т>
Т>allsums ([])= []
Т>allsums ([a])= []
Т>allsums ([a,b])= [a+b]
Т>allsums (a:as)=  (allsums as)++(map (a+) as)++(map (a+) (allsums as))

Т>main = interact (unwords.(map show).sort.allsums.(map read).words)
Т>


Во!
гениально

еще можно (для эффективности?) сократить последнее так:
allsums (a:as) = subs ++ map (a+) (as ++ subs)
    where subs = allsums as


Не очень хорошо я хаскель знаю, мда...
Re[3]: Пояснение по условию
От: Кодт Россия  
Дата: 05.12.05 11:50
Оценка:
Здравствуйте, Трурль, Вы писали:

Те же возражения. Сортировка результирующей гигантской последовательности.
-- это чтобы с консоли можно было играться
answer {-xs-} = (sort.allsums) {-xs-}

протокол работы
A> length$answer [1..14]
(секунду подумал)
16369

A> answer [1..14]
(секунду подумал)
(следует дамп из 16 тысяч чисел)

A> answer [1..15]
ERROR - Garbage collection fails to reclaim sufficient space
Перекуём баги на фичи!
Re[4]: Пояснение по условию
От: Трурль  
Дата: 05.12.05 12:36
Оценка: 93 (2)
Здравствуйте, Кодт, Вы писали:


К>Те же возражения. Сортировка результирующей гигантской последовательности.


Ну, чтобы долго не думать.
merge [] ys = ys 
merge xs [] = xs
merge (x:xs) (y:ys) = if x<=y then x:(merge xs (y:ys)) else y: (merge(x:xs)  ys)

allsums ([])= []
allsums ([a])= []
allsums ([a,b])= [a+b]
allsums (a:as) = merge subs (map (a+) (merge as  subs))
    where subs = allsums as

allsums применять к отсортированному списку.
Re[4]: Пояснение по условию
От: Трурль  
Дата: 05.12.05 13:02
Оценка: :))
Здравствуйте, Кодт, Вы писали:

К>Те же возражения. Сортировка результирующей гигантской последовательности.

Кстати, сама по себе сортировка не так уж страшна.

sort:{x[<x]}
allsum:{:[(#x)<2;();(#x)=2;+/x; t, (*x)+(1_ x),t:_f[1_ x] ]}

  #allsum[!22]
4194281
  \t sort[allsum[!22]]
250 - время в ms
Re[5]: Пояснение по условию
От: reductor  
Дата: 05.12.05 13:15
Оценка:
Здравствуйте, Трурль, Вы писали:

Т>Здравствуйте, Кодт, Вы писали:


К>>Те же возражения. Сортировка результирующей гигантской последовательности.

Т>Кстати, сама по себе сортировка не так уж страшна.

Т>
Т>sort:{x[<x]}
Т>allsum:{:[(#x)<2;();(#x)=2;+/x; t, (*x)+(1_ x),t:_f[1_ x] ]}
Т>  #allsum[!22]
Т>4194281
Т>  \t sort[allsum[!22]]
Т>250 - время в ms
Т>


а вот сортировка и примеры на Q — это запрещенный прием
Re[5]: Пояснение по условию
От: Кодт Россия  
Дата: 05.12.05 14:23
Оценка:
Здравствуйте, Трурль, Вы писали:

<>

Кстати говоря. Условие задачи можно трактовать так, чтобы получить упорядоченное множество сумм — то есть дубликаты неплохо бы выбрасывать.

Для этого придётся пофиксить merge...
Перекуём баги на фичи!
Re[6]: Пояснение по условию
От: Кодт Россия  
Дата: 05.12.05 14:24
Оценка:
Здравствуйте, reductor, Вы писали:

R>а вот сортировка и примеры на Q — это запрещенный прием


Это K.

Оффтопичный вопрос: а APL на такое способен?
Перекуём баги на фичи!
Re[6]: Пояснение по условию
От: Mamut Швеция http://dmitriid.com
Дата: 06.12.05 08:11
Оценка:
К><>

К>Кстати говоря. Условие задачи можно трактовать так, чтобы получить упорядоченное множество сумм — то есть дубликаты неплохо бы выбрасывать.


К>Для этого придётся пофиксить merge...


Я уже решил это все дело написать на С++ Потому что сделал вид, что умею думать и начертил вот такое:



Лучше уж я буду сохранять промежуточные результаты
... << RSDN@Home 1.2.0 alpha rev. 619>>


dmitriid.comGitHubLinkedIn
Re[7]: Пояснение по условию
От: Кодт Россия  
Дата: 06.12.05 11:29
Оценка: 2 (1)
Здравствуйте, Mamut, Вы писали:

К>>Кстати говоря. Условие задачи можно трактовать так, чтобы получить упорядоченное множество сумм — то есть дубликаты неплохо бы выбрасывать.


К>>Для этого придётся пофиксить merge...


M>Я уже решил это все дело написать на С++ Потому что сделал вид, что умею думать и начертил вот такое:

<>
M>Лучше уж я буду сохранять промежуточные результаты

Не нужно сохранять промежуточные результаты. Если у тебя есть N генераторов, объединённых в сеть merge — как выше, то делаем
unique :: (Eq elt) => [elt] -> [elt]

unique []              = []
unique x:[]            = x
unique x:x':xs | x==x' = unique x:xs -- выбрасываем дубликат
unique x:xs            = x : unique xs

mergeunique {-xs-} {-ys-} = unique.merge

Причём выход сети фильтровать обязательно надо, а входы (генераторы) и промежуточные потоки — на усмотрение.
Фильтрование выходной последовательности в С++ — дело плёвое. Фильтрование генераторов — тоже, в общем, несложно.
Перекуём баги на фичи!
Re[7]: Пояснение по условию
От: Трурль  
Дата: 06.12.05 12:21
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Оффтопичный вопрос: а APL на такое способен?


Способен. Но писать на APL в форумах
Re[6]: Пояснение по условию
От: Трурль  
Дата: 06.12.05 12:24
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Кстати говоря. Условие задачи можно трактовать так, чтобы получить упорядоченное множество сумм — то есть дубликаты неплохо бы выбрасывать.


К>Для этого придётся пофиксить merge...


Прикольно. Я как раз фиксил merge, чтобы она не выбрасывала дубликаты.
Re[8]: Пояснение по условию
От: Кодт Россия  
Дата: 06.12.05 12:38
Оценка:
Здравствуйте, Трурль, Вы писали:

К>>Оффтопичный вопрос: а APL на такое способен?

Т>Способен. Но писать на APL в форумах

Я, увы, не знаток APL — видел его в книжках и однажды играл под ДОС в совершенно убойной среде (cga 320*200).
Но неужели нет версии APL для нормальных ascii-шных пацанов?
Перекуём баги на фичи!
Re[9]: Пояснение по условию
От: Трурль  
Дата: 06.12.05 12:59
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Но неужели нет версии APL для нормальных ascii-шных пацанов?

Вроде, нет. Если не считать таковыми J,K,Q,R.
Re[10]: Пояснение по условию
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 07.12.05 11:24
Оценка:
Трурль,

К>>Но неужели нет версии APL для нормальных ascii-шных пацанов?

Т>Вроде, нет. Если не считать таковыми J,K,Q,R.

A+ =?= APL
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[11]: Пояснение по условию
От: Трурль  
Дата: 07.12.05 12:40
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>Трурль,


К>>>Но неужели нет версии APL для нормальных ascii-шных пацанов?


LCR>A+ =?= APL

В некотором смысле APL > A+ > K.
Но A+ не ascii-шный.
Re[5]: Пояснение по условию
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 08.12.05 04:53
Оценка:
Трурль,

Т>
Т>sort:{x[<x]}
Т>allsum:{:[(#x)<2;();(#x)=2;+/x; t, (*x)+(1_ x),t:_f[1_ x] ]}

Т>  #allsum[!22]
Т>4194281
Т>  \t sort[allsum[!22]]
Т>250 - время в ms
Т>


Что то слишком многословно
m=:1 7 4 5 2 0 6 6       NB. пример списка
x=:(2:+i.@-&2@#)+/\]     NB. магия
/:~@-.&0,x m
2 6 7 7 8 8 9 11 11 11 12 12 12 13 14 16 17 17 18 18 19 19 19 23 24 25 30
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.