Haskell. Вопросик новичка
От: Mamut Швеция http://dmitriid.com
Дата: 03.12.05 07:00
Оценка:
Значит, друг задал задачу. С клавиатуры вводится некоторая последовательность чисел, которые загоняются в массив. Потом все числа в этом массиве складываются сначала попарно, потом по три, потом по четыре и так далее.

То есть получается что-то вроде
[x(i) + x(i+1) : x(i) + x(i+1) + x(i+2) : x(i) + x(i+1) + x(i+2) + x(i+3) : ...]
i = 0..length


После этого массив получившихся чисел сортируется по возрастанию и выводится на экран.

Длинна массива и числа для массива вводятся с клавиатуры.

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

Не швырнете в меня кодом? Или кусками кода
... << RSDN@Home 1.2.0 alpha rev. 619>>


dmitriid.comGitHubLinkedIn
Re: Haskell. Вопросик новичка
От: Костя Ещенко Россия  
Дата: 03.12.05 11:12
Оценка: 18 (1)
Здравствуйте, Mamut, Вы писали:

M>Значит, друг задал задачу. С клавиатуры вводится некоторая последовательность чисел, которые загоняются в массив. Потом все числа в этом массиве складываются сначала попарно, потом по три, потом по четыре и так далее.


M>То есть получается что-то вроде

M>
M>[x(i) + x(i+1) : x(i) + x(i+1) + x(i+2) : x(i) + x(i+1) + x(i+2) + x(i+3) : ...]
M>i = 0..length
M>


M>После этого массив получившихся чисел сортируется по возрастанию и выводится на экран.


M>Длинна массива и числа для массива вводятся с клавиатуры.


M>У меня есть как бы пару идей. Как сортировать и выводить я знаю А вот ввод и нахождение сумм — . Вернее, как минимум сегодня, нет времени над этим подумать А решить хочется сегодня


M>Не швырнете в меня кодом? Или кусками кода


Чтобы не усложнять, можно(?) изменить формат вводимых данных на что-то вроде
[1,2,15,20]
и тогда весь список читается одним вызовом read. Вот для затравки код ввода/вывода, а определение yourFunc за тобой
yourFunc :: [Int]->[Int]
yourFunc x = x

main = getLine >>= putStrLn.show.yourFunc.read

Оператор "точка" — это композиция функций, т.е. вместо sin(cos x) позволяет писать (sin.cos) x
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re[2]: Haskell. Вопросик новичка
От: Mamut Швеция http://dmitriid.com
Дата: 03.12.05 11:20
Оценка:
КЕ>Чтобы не усложнять, можно(?) изменить формат вводимых данных на что-то вроде
[1,2,15,20]
и тогда весь список читается одним вызовом read.


О! Не знал. Думаю, это обсуждаемо.

КЕ>Вот для затравки код ввода/вывода, а определение yourFunc за тобой

КЕ>
КЕ>yourFunc :: [Int]->[Int]
КЕ>yourFunc x = x

КЕ>main = getLine >>= putStrLn.show.yourFunc.read
КЕ>

КЕ>Оператор "точка" — это композиция функций, т.е. вместо sin(cos x) позволяет писать (sin.cos) x

Ага. getLine передается в read, результат которого в yourFunc и так далее. Так, надо почитать документацию в области >>= повнимательнее (вернее, по монадам вообще — все не дойду )
... << RSDN@Home 1.2.0 alpha rev. 619>>


dmitriid.comGitHubLinkedIn
Re: Haskell. Вопросик новичка
От: Кодт Россия  
Дата: 03.12.05 13:17
Оценка: 27 (1)
Здравствуйте, Mamut, Вы писали:

M>Значит, друг задал задачу. С клавиатуры вводится некоторая последовательность чисел, которые загоняются в массив. Потом все числа в этом массиве складываются сначала попарно, потом по три, потом по четыре и так далее.


Получаем список списков, да? Суммы смежных пар, суммы смежных троек, и т.д.?

plus_elts :: (Num elt)
    => [elt] -- суммы с прошлого раза
    -> [elt] -- данные из исходного массива
    -> [elt] -- новые суммы

plus_elts [_] [] = 0 -- ниже дадим гарантию, что списки отличаются на 1 элемент
plus_elts (x:xs) (y:ys) = (x+y):(plus_elts xs ys)

list2sums :: (Num elt)
    => [elt] -- исходный массив
    -> [[elt]] -- массив сумм, начиная с суммы пар

list2sums []  = [] -- два дефолтных случая, когда просто нечего делать
list2sums [_] = [] -- впрочем, этот случай является завершением рекурсии ниже
list2sums d = list2sums' d (tail d) -- складываем со сдвигом: [1,2,3,...] + [2,3,4,...]
  where
    -- вход: список сумм с прошлого раза (s) и хвост массива исходных данных (d)
    -- выход: список списков сумм n-ок, начиная со следующей
    -- предусловие: (length s) == (length d)+1
    -- постусловие: голова результата (передаваемая дальше) s', (length s')==(length d)==(length s)-1
    list2sums' s [] = [] -- нечего больше складывать (кстати, можно проверить, что s содержит ровно один элемент)
    list2sums' s d =
      let s' = (plus_elts s d) -- length s' == length d
      in s' : (list2sums' s' (tail d)) 
  -- первый раз мы вызвали list2sums' где s - входные данные, т.е. суммы групп по одному :)


Далее тебе нужно отсортировать этот список. Поскольку его элементы — списки, то требуется лексикографическая сортировка.
Надо поискать в библиотеках — наверняка есть и лексикографическое сравнение, и сортировка.
Или самому руками написать.
Перекуём баги на фичи!
Re[2]: Haskell. Вопросик новичка
От: Кодт Россия  
Дата: 03.12.05 14:07
Оценка: 27 (1)
Здравствуйте, Кодт, Вы писали:

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


M>>Значит, друг задал задачу. С клавиатуры вводится некоторая последовательность чисел, которые загоняются в массив. Потом все числа в этом массиве складываются сначала попарно, потом по три, потом по четыре и так далее.


К>Получаем список списков, да? Суммы смежных пар, суммы смежных троек, и т.д.?


Возможно, я неправильно понял условие.
Если первый список — это x1+x2:x1+x2+x3:..., второй x2+x3:x2+x3+x4 и т.д., то алгоритм чуть-чуть отличается.
src = x1 : x2 : x3 : ...

s1 = x1+x2 : x1+x2+x3 : x1+x2+x3+x4 : ...

s2 =            x2+x3 :    x2+x3+x4 : ...
   =         s11-x1   : s12-x1      : ... = (tail s1) `decrement_by` (head x)

s3 =                          x3+x4 : ...
   =                    s21-x2      : ... = (tail s2) `decrement_by` (head (tail x))

причём
s1 = x1+x2 : (s1_1+x3) : (s1_2+x4) : ...

То есть, индукция налицо.
Причём можно выделить паттерн этой индукции.
integrator f x0 []      = []
integrator f x0 (x1:xs) = x0' : integrator x0' xs
  where x0'= x0 `f` x1
-- как-то можно выразить через foldr. как именно? лень думать, однако.

-- первая серия - это список частичных сумм
partialsums (x1:xs) = integrator (+) x1 xs

-- все серии
allsums []   = [] -- нет данных
allsums [x1] = [] -- недостаточно данных
allsums xs   = s1 : integrator s1 iter xs
  where
    s1 = partialsums xs
    -- и собственно операция скрещивания
    sk `iter` xk = (tail sk) `decrement_by` xk
    s `decrement_by` x = map (\si -> si-x) s

Кажется, вот так.
Перекуём баги на фичи!
Re: Haskell. Вопросик новичка
От: Трурль  
Дата: 03.12.05 14:46
Оценка:
Здравствуйте, Mamut, Вы писали:

Если я правильно понял условие, что-то вроде
ssum n l = (sum l1): ssum (n+1) l2 
  where (l1,l2)= splitAt n l

f = fromInt.sort.(ssum 2).toInt.words -- или .lines, если по строкам

main = interact f

(Насчет правильных имен для toInt etc. не ручаюсь.)
Re[2]: Haskell. Вопросик новичка
От: Трурль  
Дата: 03.12.05 16:33
Оценка: :))
Здравствуйте, Трурль, Вы map-ы забыли поставить:

f = (map fromInt).sort.(map ((ssum 2).toInt).words
Re: Haskell. Вопросик новичка
От: Кодт Россия  
Дата: 03.12.05 23:47
Оценка:
Здравствуйте, Mamut, Вы писали:

M>Значит, друг задал задачу. С клавиатуры вводится некоторая последовательность чисел, которые загоняются в массив. Потом все числа в этом массиве складываются сначала попарно, потом по три, потом по четыре и так далее.

M>После этого массив получившихся чисел сортируется по возрастанию и выводится на экран.

В какой-то момент я подумал — а может быть, задача состоит в том, чтобы найти максимальную из сумм подряд идущих элементов (а выводить всё — это уже моцартом навеяно)?
В таком случае всё гораздо проще и делается за один пробег по списку.
Перекуём баги на фичи!
Re: Haskell. Вопросик новичка
От: reductor  
Дата: 04.12.05 03:14
Оценка: 24 (1)
Здравствуйте, Mamut, Вы писали:

Лень было думать, написал что написалось :

M>Значит, друг задал задачу. С клавиатуры вводится некоторая последовательность чисел, которые загоняются в массив. Потом все числа в этом массиве складываются сначала попарно, потом по три, потом по четыре и так далее.


M>То есть получается что-то вроде

M>
M>[x(i) + x(i+1) : x(i) + x(i+1) + x(i+2) : x(i) + x(i+1) + x(i+2) + x(i+3) : ...]
M>i = 0..length
M>


M>После этого массив получившихся чисел сортируется по возрастанию и выводится на экран.


Если я ничего не путаю, то должен получиться список списков, нет?
Вот например (далеко не самый эффективный) код:
sumn [] _ = []
sumn xs n = sum head : sumn tail n
    where (head, tail) = splitAt n xs

main = let num = 15
           xs = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
       in mapM_ (print . sumn xs) [2..num]


Выводит:
[3,7,11,15,19,23,27,15]
[6,15,24,33,42]
[10,26,42,42]
[15,40,65]
[21,57,42]
[28,77,15]
[36,84]
[45,75]
[55,65]
[66,54]
[78,42]
[91,29]
[105,15]
[120]


Или, видимо (скорее всего), я как-то не так понял задачу.

Функция сортировки так и называется — sort (см. модуль Data.List)
прочитать что-то с терминала — например, getChar или getLine
представить это как число — read c :: Integer
Re[2]: Haskell. Вопросик новичка
От: Mamut Швеция http://dmitriid.com
Дата: 04.12.05 08:22
Оценка:
plus_elts :: (Num elt)
    => [elt] -- суммы с прошлого раза
    ->> [elt] -- данные из исходного массива
    ->> [elt] -- новые суммы

plus_elts [_] [] = 0 -- ниже дадим гарантию, что списки отличаются на 1 элемент
plus_elts (x:xs) (y:ys) = (x+y):(plus_elts xs ys)


В этом месте и GHC и Hugs ругаются следующим:

GHC
— Could not deduce (Num [elt]) from the context (Num elt) Main.hs ArraySort/src line 9 04 December 2005 10:18:06 13
— Probable fix: — add (Num [elt]) to the type signature(s) for `plus_elts' — or add an instance declaration for (Num [elt]) — In the definition of `plus_elts': plus_elts [_] [] = 0 Main.hs ArraySort/src line 9 04 December 2005 10:18:06 14

Hugs
ERROR "D:\Mamut\EclipseWorkspace\ArraySort\src\Main.hs":9 — Cannot justify constraints in explicitly typed binding
*** Expression : plus_elts
*** Type : Num a => [a] -> [a] -> [a]
*** Given context : Num a
*** Constraints : Num [a]



К>Далее тебе нужно отсортировать этот список. Поскольку его элементы — списки, то требуется лексикографическая сортировка.

К>Надо поискать в библиотеках — наверняка есть и лексикографическое сравнение, и сортировка.
К>Или самому руками написать.

Млин. Вернуть ны время вспять лет на десять, когда я жил и дышал математикой


dmitriid.comGitHubLinkedIn
Re: Пояснение по условию
От: Mamut Швеция http://dmitriid.com
Дата: 04.12.05 08:36
Оценка:
Как оказалось, условие я и сам неправильно понял. Оказалось, что надо не просто суммы смежных двоек, троек и т.д., а все гораздо хуже Необходимо суммы всех возможных групп чисел вообще. Т.е. а1 + а2, а1 + а3, а1 + а4, ...., а1 + а2 + а3, а1 + а3 + а4, ..., а2 + а3, ..., а2 + а4 + а5, ...

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


dmitriid.comGitHubLinkedIn
Re[3]: Haskell. Вопросик новичка
От: Mamut Швеция http://dmitriid.com
Дата: 04.12.05 08:38
Оценка:
Т>
Т>f = (map fromInt).sort.(map ((ssum 2).toInt).words 
Т>


Скобки не до конца закрыты


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

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


Ну он злодей! Очевидно, что каждая такая сумма идентифицируется булевым вектором длины n и веса не менее 2 (указывающим вхождение элементов входных данных).
И какова же мощность множества таких векторов?

ОТВЕТ: (2^n)-(n+1)
где 2^n — мощность всего пространства, n — количество векторов с весом=1, 1 — количество векторов с весом=0

Ленивые вычисления здесь не пройдут, потому что сортировка. Либо придумать генератор сортированной последовательности (боюсь, что тогда вместо экспоненты в памяти мы получим экспоненту во времени).

Тебе (и ему) оно надо?
Перекуём баги на фичи!
Re[3]: Пояснение по условию
От: Mamut Швеция http://dmitriid.com
Дата: 04.12.05 12:33
Оценка:
К>ОТВЕТ: (2^n)-(n+1)
К>где 2^n — мощность всего пространства, n — количество векторов с весом=1, 1 — количество векторов с весом=0

*задумчиво почесал в затылке*

К>Ленивые вычисления здесь не пройдут, потому что сортировка. Либо придумать генератор сортированной последовательности (боюсь, что тогда вместо экспоненты в памяти мы получим экспоненту во времени).


К>Тебе (и ему) оно надо?


он говорит, что ему надо. А вот надо ли мне

Итак. В Хаскеле эта задача трудновыполнимая из-за невозможности сохранить промежуточный результат, так получается (если не так, то примите во внимание, что Дима последние несколько дней немного тормоз )

Блин. А счастье было так возможно Придется качать CDT, писать на С++


dmitriid.comGitHubLinkedIn
Re[4]: Пояснение по условию
От: Кодт Россия  
Дата: 04.12.05 13:35
Оценка: 21 (1)
Здравствуйте, Mamut, Вы писали:

M>Итак. В Хаскеле эта задача трудновыполнимая из-за невозможности сохранить промежуточный результат, так получается (если не так, то примите во внимание, что Дима последние несколько дней немного тормоз )


Почему трудновыполнимая? Не труднее, чем где-либо ещё. Просто она ЭКСПОНЕНЦИАЛЬНАЯ по своей природе

Но давай, однако, подумаем — а нельзя ли решить её алгоритмически?

Отсортируем входные данные.

Очевидно, что если две перестановки из n по k — назовём их I, J, упорядочены, I<J, то и соответствующие им суммы находятся в том же порядке. Проще говоря, I={i1,i2,...,ik} < J={j1,j2,...,jk} => x[i1]+...+x[im] < x[j1]+...+x[jm]

Перестановки можно перечислить. (Создание перестановки по индексу — дело неблагодарное, а вот получить следующую из текущей — легко и просто).

Отсюда:
1) делаем генератор сумм перестановок из n по k (для большого k, наверное, есть смысл вычислять очередную сумму инкрементно, а для маленького — можно и пересчитывать каждый раз заново)
2) делаем генератор, выполняющий сортировку слиянием — у него на входе n-1 генераторов сумм, для k=2..n

Затраты памяти — O(N^2). Затраты времени — O(N) на каждую итерацию.
Если бы мы умудрились нарожать массив сумм сразу — то на сортировку потратили бы O(S*log(S)) = O(N^2*N), где S=O(2^N) — размер массива.
То есть примерно столько же

Теперь осталось закодировать это на С, С++ или Хаскелле.
Конечно, там без монад не обойтись — но возможно (почти 100% уверен), что это всего лишь list comprehensions.

Если хочешь освоить Хаскелл — то вперёд, а если нужно по-быстрому за оставшийся день — то С++ в руки
Перекуём баги на фичи!
Re[5]: Пояснение по условию
От: Mamut Швеция http://dmitriid.com
Дата: 04.12.05 13:55
Оценка:
M>>Итак. В Хаскеле эта задача трудновыполнимая из-за невозможности сохранить промежуточный результат, так получается (если не так, то примите во внимание, что Дима последние несколько дней немного тормоз )

К>Почему трудновыполнимая? Не труднее, чем где-либо ещё. Просто она ЭКСПОНЕНЦИАЛЬНАЯ по своей природе


К>Но давай, однако, подумаем — а нельзя ли решить её алгоритмически?


Ага, я так и думал, что где-то будет "the catch". Он состоит в том, что надо думать

К>Отсортируем входные данные.


[skip]

К>Теперь осталось закодировать это на С, С++ или Хаскелле.

К>Конечно, там без монад не обойтись — но возможно (почти 100% уверен), что это всего лишь list comprehensions.

К>Если хочешь освоить Хаскелл — то вперёд, а если нужно по-быстрому за оставшийся день — то С++ в руки


Ну что ж. Буду думать, благо алгоритм уже разжеван и разве что в рот не положен Тем более, что время есть


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

К>>Если хочешь освоить Хаскелл — то вперёд, а если нужно по-быстрому за оставшийся день — то С++ в руки


M>Ну что ж. Буду думать, благо алгоритм уже разжеван и разве что в рот не положен Тем более, что время есть


-- тип "комбинация"...
type Combination = [Int] -- это упорядоченный список индексов комбинации
                         -- в принципе, мог быть и массив - но его порождать тяжелее

-- генератор комбинаций
combinations :: Int -> Int -> Int -> [Combination]
combinations n0 n1 k -- перебор k чисел из диапазона [n0..n1]
  | k==0      = [ [] ]                                       -- вырожденный случай
  | k==1      = [ [x] | x <- [n0..n1] ]                      -- банальный случай
  | otherwise = [ (x:xs) | x <- [n0..n1-(k-1)],              -- первое число
                           xs <- combinations (x+1) n1 (k-1) -- и перебор всех остальных
                ]

-- сумма данной комбинации элементов массива
sum :: (Num a) => Array a -> Combination -> a
sum arr inds = foldr fn ids
  where
    {- по смыслу:
       index `fn` total = (arr!index) + total
    что равно
       fn i t = (+) ((!) arr i) t
       fn i   = (+) ((!) arr i)
              = (+)(((!) arr)i)
              = (+)$((!) arr)i
       fn     = (+)$((!) arr)
    -}
    fn = (+)$((!)arr)

-- генератор сумм (до посинения)
gensums :: (Num a) => Array a -> Int -> [a]
gensums arr k = [ sum' comb | comb <- combinations n0 n1 k ] -- внёс поправку: combinations, а не permutations'
  where
    sum' = sum arr -- говорят, биндинг дешевле пассинга
    (n0,n1) = bounds arr

-- список сумм
listsums :: (Num a) => Array a -> [[a]]
listsums arr = [ gensums' k | k <- [1..n] ]
  where
    gensums' = gensums arr
    (n0,n1) = bounds arr
    k = n1-n0+1

-- и вот теперь, над этим списком будем надругиваться...
mergesums :: (Num a) => [[a]] -> [a]
-- (фантазия временно иссякла)

-- финальная функция
allsums :: (Num a) => Array a -> [a]
allsums {-arr-} = mergesums.listsums {-arr-}

main = do
  lst <- read <<= getStrLn -- через запятую, в квадратных скобках
  let arr = arrayList (1,length lst) lst
  print (allsums arr) -- тоже через запятую и в квадратных скобках
  return ()
Перекуём баги на фичи!
Re[7]: Пояснение по условию
От: Кодт Россия  
Дата: 04.12.05 17:26
Оценка: 4 (1)
Меня вдруг посетила эврика, что задача-то уже почти решена.
Дано: список из n-1 упорядоченных списков (порождённое генератором — но это не имеет значения). Сами списки, правда, здоровенные (и порождаются генераторами).
Найти: их слияние.

Раз у нас список списков невелик, то рекурсивно применить попарное слияние — не страшно.
mergesums :: (Cmp a) => [[a]] -> [a]

mergesums {-lsums-} = foldr merge2 [] {-lsums-}
  where
    merge2 :: [a] -> [a] -> [a]
    xs `merge2` [] = xs
    [] `merge2` ys = ys
    (x:xs) `merge2` (y:ys) | x<y       = x : (   xs  `merge2` (y:ys))
                           | otherwise = y : ((x:xs) `merge2`    ys )

Мы получим такую вычислительную сеть
             +--- gensums(1)
output <--merge2    +--- gensums(2)
             +---merge2     +--- gensums(3)
                    +--- merge2
                            .........  +--- gensums(n)
                               +--- merge2
                                       +--- [] (стартовое значение, переданное в foldr)

И, поскольку язык ленивый, то каждый merge2 будет вызван только тогда, когда в нём появится потребность.
Разумеется, выборка head output приведёт к тому, что все они по разу вздрогнут и предоставят первые элементы списков.
Но дальше этого не провалятся, и мы не выжрем вагон памяти.
Перекуём баги на фичи!
Re[7]: Пояснение по условию
От: Кодт Россия  
Дата: 04.12.05 17:31
Оценка: 8 (1)
К>main = do
К>  lst <- read <<= getStrLn -- через запятую, в квадратных скобках
К>  let arr = arrayList (1,length lst) (sort lst)
                                    -- ~~~~~    ~
К>  print (allsums arr) -- тоже через запятую и в квадратных скобках
К>  return ()
Перекуём баги на фичи!
Re[2]: Пояснение по условию
От: reductor  
Дата: 04.12.05 18:04
Оценка: 8 (1)
Здравствуйте, Mamut, Вы писали:

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


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



Ой!
если ничего не напутал, то так вроде должно:

perm :: [Int] -> [Int]
perm zs = perm' zs (tails zs)
    where perm' [] _ = []
          perm' _ [] = []
          perm' (x:xs) (y:ys) = map ((+) x . sum) ys ++ perm' xs ys
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<#)
Re[6]: Пояснение по условию
От: Трурль  
Дата: 08.12.05 08:13
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:


LCR>Что то слишком многословно

LCR>
LCR>m=:1 7 4 5 2 0 6 6       NB. пример списка
LCR>x=:(2:+i.@-&2@#)+/\]     NB. магия
LCR>/:~@-.&0,x m
LCR>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
LCR>

Зато правильно
  sort[allsum[1 7 4 5 2 0 6 6]]
1 2 3 3 4 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9
 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 11 11 11 11 11 12 12 12 12 12 12 
 12 12 12 12 12 12 12 12 12 12 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 
 13 13 14 14 14 14 14 14 14 14 14 14 14 14 14 14 15 15 15 15 15 15 15 15 15 15 
 15 15 16 16 16 16 16 16 16 16 16 16 16 16 17 17 17 17 17 17 17 17 17 17 17 17 
 17 17 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 18 19 19 19 19 19 19 
 19 19 19 19 19 19 19 19 19 19 20 20 20 20 20 20 20 20 20 20 20 20 21 21 21 21 
 21 21 21 21 22 22 22 22 22 22 22 22 23 23 23 23 23 23 23 23 24 24 24 24 24 24 
 24 24 24 24 25 25 25 25 25 25 25 25 26 26 26 26 27 27 28 28 29 29 30 30 31 31
Re[7]: Пояснение по условию
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 08.12.05 10:16
Оценка:
Трурль,

Т>Зато правильно

Т>
Т>  sort[allsum[1 7 4 5 2 0 6 6]]
Т> <247 чиселок>
Т>


Да ладно уж, просто ты перебираешь все непустые и неединичные подмножества, а я — те, которые идут подряд, то есть решаю первую задачу Но это, как ты понимаешь, непринципиально:
   d=:[:#:[:i.2:^#
   x=:#~>&1@(+/"1)
   f=:/:~@(+/"1@#~[:x d)
   #f 1 7 4 5 2 0 6 6
247
   f 1 7 4 5 2 0 6 6 
1 2 3 3 4 5 5 5 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 10 10 10 10 10 10 10 10 11 11 11 11 11 11 11 11 11 11 11 11 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 12 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 13 14 14 14 14 14 1...

хъ:
1. что такое ; (точка с запятой) в К? (подозреваю что композиция)
2. где ты умудрился скачать К? Ссылкой не поделишься
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[6]: Пояснение по условию
От: mishaa Россия http://kmmbvnr.livejournal.com
Дата: 08.12.05 10:37
Оценка: +1
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>Что то слишком многословно

LCR>
LCR>m=:1 7 4 5 2 0 6 6       NB. пример списка
LCR>x=:(2:+i.@-&2@#)+/\]     NB. магия
LCR>/:~@-.&0,x m
LCR>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
LCR>


А сумма все чисел 31 в ответ входить разве не должна?
-- Главное про деструктор копирования не забыть --
Re[2]: Пояснение по условию
От: Глеб Алексеев  
Дата: 08.12.05 11:01
Оценка: 20 (2)
Здравствуйте, Mamut, Вы писали:

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


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


Я, видимо, все неправильно понял, и в ФП полный чайник, так что не судите строго. Просто задача очень похожа на упражнение из Харпера. Вот решение на ОКамле (извините, Хаскеля не знаю):

let rec powerset lst = match lst with
      [] -> [ []]
    | h::t ->          
          let pstail = powerset t in
          let diff = List.map (fun x -> h::x) pstail in
              pstail @ diff

let sum_list lst = List.fold_left (+) 0 lst

let all_sums lst =
    let ps = powerset lst in
    let sums = List.map sum_list ps in
        List.sort compare sums


# powerset [1;2;3;5];;
- : int list list =
[[]; [5]; [3]; [3; 5]; [2]; [2; 5]; [2; 3]; [2; 3; 5]; [1]; [1; 5]; [1; 3];
 [1; 3; 5]; [1; 2]; [1; 2; 5]; [1; 2; 3]; [1; 2; 3; 5]
# all_sums [1;2;3;4];;
- : int list = [0; 1; 2; 3; 3; 4; 4; 5; 5; 6; 6; 7; 7; 8; 9; 10]
#
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: Пояснение по условию
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 08.12.05 11:14
Оценка:
Миша,

LCR>>
LCR>>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
LCR>>


M>А сумма все чисел 31 в ответ входить разве не должна?


А фиг его знает. По постановке непонятно. Но если всё же если хочется, то пожалуйста:
   x=:(2:+i.@-&1@#)+/\]
   /:~@-.&0,x 1 7 4 5 2 0 6 6
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 31


Как грится, нот э биг дил
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[3]: Совсем мелочь
От: Глеб Алексеев  
Дата: 08.12.05 11:52
Оценка:
Здравствуйте, Глеб Алексеев, Вы писали:

ГА>let sum_list lst = List.fold_left (+) 0 lst


Чуть красивше можно:
let sum_list = List.fold_left (+) 0
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Пояснение по условию
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 09.12.05 05:04
Оценка:
Глеб Алексеев,

ГА>Я, видимо, все неправильно понял, и в ФП полный чайник, так что не судите строго. Просто задача очень похожа на упражнение из Харпера. Вот решение на ОКамле (извините, Хаскеля не знаю):


ГА>
ГА>let rec powerset lst = match lst with
ГА>      [] -> [ []]
ГА>    | h::t ->          
ГА>          let pstail = powerset t in
ГА>          let diff = List.map (fun x -> h::x) pstail in
ГА>              pstail @ diff

ГА>let sum_list lst = List.fold_left (+) 0 lst

ГА>let all_sums lst =
ГА>    let ps = powerset lst in
ГА>    let sums = List.map sum_list ps in
ГА>        List.sort compare sums
ГА>



Я бы ввёл ещё парочку функций
let rec size l = match l with
    | [] -> []
    | h::t -> 1 + size t;;

let rec seive l = match l with
    | [] -> []
    | h::t ->
        if (size h) > 1 then
            h::seive t
          else
              seive t;;

и переписал бы all_sums как
let all_sums lst =
    let ps = seive powerset lst in
    let sums = List.map sum_list ps in
        List.sort compare sums;;


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

LCR>1. что такое ; (точка с запятой) в К? (подозреваю что композиция)

Скорее, разделитель.

LCR>2. где ты умудрился скачать К? Ссылкой не поделишься

На kx.com. Только они его уже убрали.

Ну,и в качестве упражнения в фалометрии.
  f:{b@<b:+/'x@&:'a@&1<+/'a:+2_vs!_2^#x}
  #f 1 7 4 5 2 0 6 6
247
Re[4]: Пояснение по условию
От: Глеб Алексеев  
Дата: 09.12.05 09:12
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

Чувствую, что написал или лишнего, или некрасивого кода, и гуры надо мной издеваются, только в чем я неправ — не пойму.
По порядку.

LCR>Я бы ввёл ещё парочку функций

LCR>
(*  А разве нету готовой функции List.length? *)
LCR>let rec size l = match l with
LCR>    | [] -> [] (*  А здесь [] с ноликом не перепутали? *)
LCR>    | h::t -> 1 + size t;;
(*  А зачем такое решето, если 
        1) пустой список в результатах по определению только один 
        2) сумма пустого списка равна нулю
        3) в условии задачи никто не говорил выбрасывать пустое множество
        4) и если все-таки его писать, то чем не подошел List.filter, зачем вручную?*)
LCR>let rec seive l = match l with
LCR>    | [] -> [] (* а здесь пару лишних [] не забыли? *)
LCR>    | h::t ->
LCR>        if (size h) > 1 then
LCR>            h::seive t
LCR>          else
LCR>              seive t;;
LCR>

LCR>и переписал бы all_sums как
LCR>
LCR>let all_sums lst =
LCR>    let ps = seive powerset lst in
LCR>    let sums = List.map sum_list ps in
LCR>        List.sort compare sums;;
LCR>


LCR>

На всякий случай тоже улыбнусь .

з.ы. После пары месяцев активного пребывания на РСДНе я всегда компилирую и разок запускаю код, который сюда выкладываю
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: Пояснение по условию
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 09.12.05 10:17
Оценка: +1
Глеб Алексеев,

ГА>
ГА>(*  А разве нету готовой функции List.length? *)
ГА>


+1 есть, но я не смог вспомнить, как она называется

LCR>>let rec size l = match l with
LCR>>    | [] -> [] (*  А здесь [] с ноликом не перепутали? *)


+1 перепутал; со скобками даже не откомпилируется

ГА>(*  А зачем такое решето, если 
ГА>        1) пустой список в результатах по определению только один 
ГА>        2) сумма пустого списка равна нулю
ГА>        3) в условии задачи никто не говорил выбрасывать пустое множество
ГА>        4) и если все-таки его писать, то чем не подошел List.filter, зачем вручную?*)


Да тут задача ведь складывать двойки, тройки и т.д., а у тебя пустое множество и все одноэлементные вошли. Вот и потребовалось "решето". Насчёт List.filter — , вместо того чтобы глянуть в доку и освежить память, я делаю велосипедик.

LCR>>let rec seive l = match l with
LCR>>    | [] -> [] (* а здесь пару лишних [] не забыли? *)


а здесь всё правильно, ибо функция seive должна выкидывать все элементы кроме не очень маленьких по длине. (элементы — списки, val seive : 'a list list -> 'a list list = <fun>), а из пустого списка выкинуть нечего. Если сделать []], то в результирующий список войдёт элемент [], что неправильно.

ГА>з.ы. После пары месяцев активного пребывания на РСДНе я всегда компилирую и разок запускаю код, который сюда выкладываю


Ты чертовски прав.

хъ: можно на ты, мы же братья по языку
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[9]: Пояснение по условию
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 09.12.05 10:28
Оценка:
Трурль,


LCR>>2. где ты умудрился скачать К? Ссылкой не поделишься

Т>На kx.com. Только они его уже убрали.

вот вот.

Т>
Т>  f:{b@<b:+/'x@&:'a@&1<+/'a:+2_vs!_2^#x}
Т>  #f 1 7 4 5 2 0 6 6
Т>247
Т>


Ничего личного, мне твоя программа тоже нравится Правда понятно только #x и :{...}, но вроде язык нормальный.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[6]: Пояснение по условию
От: Глеб Алексеев  
Дата: 09.12.05 11:07
Оценка:
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>Да тут задача ведь складывать двойки, тройки и т.д., а у тебя пустое множество и все одноэлементные вошли.

Кстати, не факт:
Mamut>Необходимо суммы всех возможных групп чисел вообще
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[7]: Пояснение по условию
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 09.12.05 11:59
Оценка:
Здравствуйте, Глеб Алексеев, Вы писали:

ГА>Здравствуйте, Lazy Cjow Rhrr, Вы писали:


LCR>>Да тут задача ведь складывать двойки, тройки и т.д., а у тебя пустое множество и все одноэлементные вошли.

ГА>Кстати, не факт:
Mamut>>Необходимо суммы всех возможных групп чисел вообще

Я ориентировался на
  #allsum[!22]
4194281

Как раз получается (2^22) — 23 == 4194281
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
Re[2]: Пояснение по условию
От: Аноним  
Дата: 15.12.05 13:45
Оценка: 9 (1)
Здравствуйте, Mamut, Вы писали:

M>Как оказалось, условие я и сам неправильно понял.


f = nub. sort . init . foldl1 (liftM2 (+)) . map (:[0])
Re[10]: Пояснение по условию
От: Трурль  
Дата: 19.12.05 07:30
Оценка: 17 (2)
Здравствуйте, Lazy Cjow Rhrr, Вы писали:

LCR>>>2. где ты умудрился скачать К? Ссылкой не поделишься

Т>>На kx.com. Только они его уже убрали.
LCR>вот вот.

Мир не без добрых людей
Re[11]: Пояснение по условию
От: Lazy Cjow Rhrr Россия lj://_lcr_
Дата: 19.12.05 08:29
Оценка:
Трурль, добрый человек.

Спасибо за ссылку.
quicksort =: (($:@(<#[),(=#[),$:@(>#[)) ({~ ?@#)) ^: (1<#)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.