powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Реверт очереди за линейное время
43 сообщений из 43, показаны все 2 страниц
Реверт очереди за линейное время
    #36892896
umniaxa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Подскажите, как обернуть очередь за линейное время?

Более подробно: на вход подается список, [1,2,3,4] например. На выходе должно получится [4,3,2,1] Использовать можно только! операции чтения с конца в начало и операцию дописывания элемента в начало списка. Программа должна отработать за линейное время
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36892983
Фотография Яростный Меч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Рекурсия.
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36892998
umniaxa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Извиняюсь, забыл написать. Свои функции, кроме 2-х оговоренных писать и использовать можно, но они не должны никак использовать рекурсию и основываться на чем-либо кроме 2-х оговоренных функций и лямбда выражений
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36893025
junior  idiot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Любые лямбда-выражения? Каков язык реализации? Python? Можно прикольнуться и сделать через комбинатор неподвижной точки %))
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36893036
umniaxa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Выполнять собираюсь на F#. Но приемлим любой функциональный язык, Haskel, например
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36893118
junior  idiot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Эфшарпа нет, есть питон.
Код: plaintext
1.
2.
3.
>>> Y = lambda g: (lambda f: g(lambda arg: f(f)(arg))) (lambda f: g(lambda arg: f(f)(arg)))
>>> reverse = lambda f: lambda l: ([] if l == [] else f(l[ 1 :]) + [l[ 0 ]])
>>> Y(reverse)([ 1 , 2 , 3 , 4 ])
[ 4 ,  3 ,  2 ,  1 ]
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36893128
umniaxa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо. Постараюсь разобраться и оттранслировать в том или ином виде на шарпы
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36893217
junior  idiot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ещё есть Scheme.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
(require unstable/queue)

(define (reverse-q queue)
  (((lambda (f)
     ((lambda (x)
        (f (lambda (y) ((x x) y))))
      (lambda (x)
        (f (lambda (y) ((x x) y))))))
   (lambda (rev) 
     (lambda (q) 
       (if (queue-empty? q) q
           (let ((x (dequeue! q)))
             (rev q)
             (enqueue! q x))))))
   queue))

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
> (define q (make-queue))
(enqueue! q  1 )
(enqueue! q  2 )
(enqueue! q  3 )
(enqueue! q  4 )
> (reverse-q q)
> (dequeue! q)
 4 
> (dequeue! q)
 3 
> (dequeue! q)
 2 
> (dequeue! q)
 1 
> 

Я, впрочем, сильно сомневаюсь, что хотели именно этого. Просто забавный обход ограничения на использование рекурсии.
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36893223
umniaxa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Большое спасибо) Вечером подниму питон поминимуму, разберусь в ваших примерах, надеюсь, что без потери всех условий и роста сложности удастся без проблем портировать.
Еще раз большое спасибо
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36893273
clihlt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
junior idiotЭфшарпа нет, есть питон.
Код: plaintext
1.
2.
3.
>>> Y = lambda g: (lambda f: g(lambda arg: f(f)(arg))) (lambda f: g(lambda arg: f(f)(arg)))
>>> reverse = lambda f: lambda l: ([] if l == [] else f(l[ 1 :]) + [l[ 0 ]])
>>> Y(reverse)([ 1 , 2 , 3 , 4 ])
[ 4 ,  3 ,  2 ,  1 ]


Ох и накрутил )

Не соответствует условию:

umniaxa
Использовать можно только! операции чтения с конца в начало и операцию дописывания элемента в начало списка.


Тут я понимаю на оборот.
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36893287
junior  idiot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ну да, кручу-верчу, что считать "началом", а что "концом" -- в общем, не принципиально.
Можно и наоборот:
Код: plaintext
>>> reverse = lambda f: lambda l: ([] if l == [] else [l[- 1 ]] + f(l[:- 1 ]))
Результат закономерно тот же.
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36893304
clihlt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Формаль ность но всеже :)
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36893671
Фотография k0rvin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
umniaxaСвои функции, кроме 2-х оговоренных писать и использовать можно, но они не должны никак использовать рекурсию
странное ограничение... а что тогда, цикл?
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36893674
Фотография k0rvin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
junior idiotПросто забавный обход ограничения на использование рекурсии.

это не обход, а рекурсия.
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36893705
junior  idiot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
k0rvinэто не обход, а рекурсия.
Формально -- нет.
Комбинатор неподвижной точки как раз и нужен для того, чтобы рекурсивное определение преобразовать в не рекурсивное.
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36893708
junior  idiot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Немного поясню.
Дело в том, что это можно "собрать" в одну строчку:
Код: plaintext
1.
>>> (lambda g: (lambda f: g(lambda arg: f(f)(arg))) (lambda f: g(lambda arg: f(f)(arg))))(lambda f: lambda l: ([] if l == [] else [l[- 1 ]] + f(l[:- 1 ])))([ 1 , 2 , 3 , 4 ])
[ 4 ,  3 ,  2 ,  1 ]
То есть, без определения функций вообще. А "рекурсивность" -- это именно свойство определения функции. Нет определения, нет смысла даже говорить о "рекурсии".
В Scheme то же самое.
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36893729
clihlt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
junior idiot,

Я не очень шарю в лябда выражениях... но для меня этот пример выглядит, как способ вызова из функции самой себя при условии, что "свое" имя она не знает.
Да и выражение типа "lambda g: ............. " - разве ж это не определение функции ?
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36893731
clihlt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
clihlt,

О первая ссылка ,что попалась
Тынц

автор
Комбинаторы неподвижной точки позволяют определять анонимные рекурсивные функции.
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36893851
junior  idiot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
clihltдля меня этот пример выглядит, как способ вызова из функции самой себя при условии, что "свое" имя она не знает.
Как она тогда себя вызывает?

clihltДа и выражение типа "lambda g: ............. " - разве ж это не определение функции ?
Скорее запись функции. Чтобы она стала определением , функцию надо поименовать, то есть, строго говоря, "определяется" не сама функция, а её имя, связываясь с конкретным лямбда-выражением.
http://en.wikipedia.org/wiki/Definition]A definition is a passage that explains the meaning of a term (a word, phrase or other set of symbols), or a type of thing. The term to be defined is the definiendum (plural definienda).
Впрочем, это не более чем игра слов. Потому я и сказал, что, видимо, от ТС ждут другого решения.
Хотя ни одного определения рекурсии, в котором не использовалось бы слово "definition", то есть относящегося также и к анонимным функциям, я не нашёл.
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36894436
umniaxa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Поясните пожалуйста еще один момент, я правильно понимаю, что в операции
Код: plaintext
l[:- 1 ]
пусть и неявно используется операция удаления с конца списка? точнее на вход список - а на выход - список без последнего эл-та?
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36894448
junior  idiot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
umniaxa , именно так.
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36894483
umniaxa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мдя) Тогда к сожалению это и есть то условие - которое делает ваше предложенное решение неприемлимым... сложность задачи как раз и состоит в том, что с любыми списками можно сделать ровно 2 операции: прочитать эл-ты с конца к началу (причем именно прочитать, а не прочитать и удалить) и дописать в существующий список (ну или в некий новый) 1 эл-т в начало
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36894486
umniaxa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Причем все это за линейное время....
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36894528
junior  idiot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
umniaxaпрочитать эл-ты с конца к началу (причем именно прочитать, а не прочитать и удалить)
Предположу, что вы таки неверно поняли этот момент условия задачи, так получается совсем нелепица. Очередь -- это вполне чёткая абстракция, на ней определена операция ( dequeue , или иногда pop , хотя это несовсем корректно) " извлечения элемента, который был добавлен раньше всех оставшихся" (называть это "началом" или "концом" -- не принципиально, хотя правильнее, конечно, называть "началом").
Иначе вот какая бессмыслица получается: если элементы не удаляются, а только читаются, то
1) либо очередь сама "помнит" сколько раз был считан крайний элемент и сдвигает счётчик, чтобы в следующий раз выдать следующий элемент; тогда это ничем внешне не отличается от извлечения (удаления элементов);
2) либо можно считывать произвольный элемент очереди в любой момент времени; тогда это не очередь вообще, а список.

Короче, приведите интерфейс этой "очереди"; если он "классический", то предложенное решение (особенно для Scheme -- там вообще один-в-один) вполне корректно с точки зрения используемых операций.
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36894691
umniaxa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Полностью условие звучит так: Используя только операцию foldr и лямбда выражения ревертнуть список не использую рекурсивных функций за линейное время

foldr f arg работает приблизительно так:
foldr (+) 0 [1,2,3,4] = ((((0+4)+3)+2)+1)
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36894710
umniaxa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В предыдущем посту опечатался: foldr имеет 3 параметра fun, res, args - fun - функция, которая применяется на каждом шаге, res - результат после очередного шага, args - список, которые на вход
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36894849
junior  idiot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ёлки зелёные, так при чём жеж тут "очередь"? Да и foldr -- это самая что ни на есть рекурсия.

Это классическая задачка для будущих кулхацкеллов.

Код: plaintext
reverse = ($ []) . (foldr (((\f x y -> f y x) (.)) . (:)) (\x -> x))
Код: plaintext
1.
2.
Hugs> let reverse = ($ []) . (foldr (((\f x y -> f y x) (.)) . (:)) (\x -> x)) in reverse [ 1 , 2 , 3 , 4 ]
[ 4 , 3 , 2 , 1 ]
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36895038
umniaxa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Значит я перемудрил с тем, чтобы попонятнее написать) очень прошу извинить
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36895057
umniaxa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Можно еще вопрос: что за язык реализации? И где источник, в котором можно черпать такие задачки?
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36895106
junior  idiot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Haskell, вестимо. Конкретнее -- WinHugs.
Источник именно такого рода задачек не подскажу, к сожалению; сам нахватываюсь по мелочи и по случаю, то тут то там, но вообще больше алгоритмическими задачами интересуюсь.
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36895153
umniaxa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
junior idiot,

Спасибо большое))
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36895945
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
umniaxaБолее подробно: на вход подается список, [1,2,3,4] например. На выходе должно получится [4,3,2,1]
Любой язык программирования к реализованной структурой данных типа "стек" или "дек".
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36896484
Mozok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
umniaxaПолностью условие звучит так: Используя только операцию foldr и лямбда выражения ревертнуть список не использую рекурсивных функций за линейное время

foldr f arg работает приблизительно так:
foldr (+) 0 [1,2,3,4] = ((((0+4)+3)+2)+1)
Ну раз уж пошла такая пьянка:

Немного CL
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
>(defun reverse-list (l)
    (declare (list l))
    (reduce #'(lambda (x y) (cons y x)) l :initial-value '())
    )

REVERSE-LIST

>(reverse-list '( 1   2   3   4 ))

( 4   3   2   1 )

>
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36896543
umniaxa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Извините за еще один тупой вопрос, но не могли бы вы пояснить еще один момент:
что значит эта часть вашего примера:
Код: plaintext
($ []) .
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36896766
junior  idiot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Mozokreduce
Есть мнение, что reduce -- это fold l , а не fold r .
Если допустить использование foldl, то задача становится совсем по-детски тривиальной:
Код: plaintext
1.
Hugs> foldl (\x y -> y:x) [] [ 1 , 2 , 3 , 4 ]
[ 4 , 3 , 2 , 1 ]

Частично предположение об аналогии с foldl подтверждается исходниками clisp 2.48.
clisp-2.48/src/sequence.d
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
/*
...
UPD           (lambda (seq pointer) ...) -> pointer
              returns a pointer to the adjacent neighbor at the right.
              SEQ-UPD can assume, that the right border of
              SEQ is not stepped over.
...
INIT-START    (lambda (seq index) ...) -> pointer
              returns a pointer which moves in SEQ from left to right
              from Position index. Must execute the Range-test by itself.
...
*/
...
LISPFUN(reduce,seclass_default, 2 , 0 ,norest,key, 5 ,
        (kw(from_end),kw(start),kw(end),kw(key),kw(initial_value)) )
{ /* (REDUCE function sequence [:from-end] [:start] [:end] [:key]
             [:initial-value]), CLTL p. 251, CLTL2 p. 397
  Stack layout: function, sequence, from-end, start, end, key, initial-value. */
...
    /* Stack layout: function, seq, from-end, start, end, key, initial-value,
                     typdescr, count, pointer, value. */
    do {
      /* Calculate next value: */
      pushSTACK(STACK_( 5 + 4 )); pushSTACK(STACK_( 1 + 1 ));
      funcall(seq_access(STACK_( 3 + 2 )), 2 ); /* (SEQ-ACCESS seq pointer) */
      funcall_key(STACK_( 1 + 4 ),value1); /* (FUNCALL key (SEQ-ACCESS seq pointer)) */
      pushSTACK(STACK_0); pushSTACK(value1);
      funcall(STACK_( 6 + 4 + 2 ), 2 ); /* (FUNCALL fun value (FUNCALL key (SEQ-ACCESS seq pointer))) */
      STACK_0 = value1; /* =: value */
      into_fromstart_loop:
      /* Advance pointer: */
      pointer_update(STACK_1,STACK_( 5 + 4 ),STACK_3);
      /* count := (1- count) : */
      decrement(STACK_2);
    } while (!eq(STACK_2,Fixnum_0)); /* count (an integer) = 0 ? */
    VALUES1(popSTACK()); /* return value */
    skipSTACK( 7 + 3 );
  }
}

"Частично" -- потому что тут цикл, а не рекурсия. В Prelude.hs же определение foldl явно рекурсивно:
Prelude.hs
Код: plaintext
1.
2.
foldl            :: (a -> b -> a) -> a -> [b] -> a
foldl f z []      = z
foldl f z (x:xs)  = foldl f (f z x) xs

хотя, конечно, будучи хвостовым, соптимизируется в цикл, но всё же.

umniaxa, операторы (двуместные функции) ($) и (.) определены в Prelude.hs:
Prelude.hs
Код: plaintext
1.
2.
3.
4.
5.
($)            :: (a -> b) -> a -> b
f $ x           = f x
...
(.)            :: (b -> c) -> (a -> b) -> (a -> c)
(f . g) x       = f (g x)

Это аппликация и композиция соответственно.
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36896802
umniaxa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36897348
Mozok
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
junior idiot
Есть мнение, что reduce -- это fold l , а не fold r .

Согласен, забыл про волшебный флажок :)
Еще немного CL
Код: plaintext
(reduce #'(lambda (x y) (nconc y (list x))) l :from-end t :initial-value '())
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #36898039
Фотография k0rvin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
junior idiot
Формально -- нет.
Комбинатор неподвижной точки как раз и нужен для того, чтобы рекурсивное определение преобразовать в не рекурсивное.
дело не в определении, а в вычислительном процессе, порождаемом функцией
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Реверт очереди за линейное время
    #37982843
erwert
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rev l = foldr (\f a b -> a (f:b)) id l []
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #37994757
Фотография AndreTM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
erwert,
ага... Я ещё тогда забыл напомнить по поводу
maytonЛюбой язык программирования к реализованной структурой данных типа "стек" или "дек".Например, на любом Forth в реализации 83 и выше:
Код: sql
1.
2.
3.
4.
5.
: REVERT DEPTH DUP 0> IF 0 DO . LOOP ELSE DROP THEN ;
>Ok
1 2 3 4 REVERSE
4 3 2 1
>Ok
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #37994758
Фотография AndreTM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
* Да уж... REVERSE - это только что определенный REVERT, и должен именно так и писАться., как revert ...
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #37994766
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С новым годом...
...
Рейтинг: 0 / 0
Реверт очереди за линейное время
    #37994783
Фотография AndreTM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonС новым годом...Да видел я, видел
...
Рейтинг: 0 / 0
43 сообщений из 43, показаны все 2 страниц
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Реверт очереди за линейное время
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]