Re[27]: LINQ только для РСУБД!
От: Gaperton http://gaperton.livejournal.com
Дата: 21.11.09 20:54
Оценка:
Здравствуйте, Lloyd, Вы писали:

G>>Ну, по мелочи — двоеточие пропустил. Вот здесь.


G>>for i, val := range x {


L>И это еще не конец. Эх, Gaperton, вроде и язык простой и задача простая, а столько ошибок на пустом месте.

L>Как же так?

Компилятора нет, пишу на бумажке. Кроме того, это одна из моих первых программ на Go, и я постоянно сверяюсь с мануалом.

Удовлетворен? Или будут еще не относящиеся к делу вопросы?
Re[26]: LINQ только для РСУБД!
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 21.11.09 20:56
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Тяжело, когда под рукой нет компилятора. Впрочем, наши коллеги линкеры также свой код не тестили. Иначе бы заметили, что их результаты с твоими примерами не совпадают.


Можно гипотетически прикинуть. Уменя получилось что-то вроде такого (предположим для простоты, что канал бесконечен):

func (c chan int, o chan int) {
  var va int <- c
  var vb int := 0
  for {
    vb <- c
    if vb - a = 1 {
      o <- vb
      va <- c
    }
    else va := vb
  }
}
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[28]: LINQ только для РСУБД!
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 21.11.09 20:58
Оценка: :)
Здравствуйте, Lloyd, Вы писали:

L>Кушать подано:


Твою двадцать...
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[27]: Теперь у меня опечатка
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 21.11.09 21:01
Оценка:
func (c chan int, o chan int) {
  var va int <- c
  var vb int := 0
  for {
    vb <- c
    if vb - va = 1 {
      o <- vb
      va <- c
    }
    else va := vb
  }
}
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[26]: LINQ только для РСУБД!
От: Gaperton http://gaperton.livejournal.com
Дата: 21.11.09 21:03
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Там два условия:

L>1) елемент на единицу больше предыдущего.
L>2)
L>

L>при этом извлечённый элемент не должен принимать участия в последующем сравнении

L>Ты же заменил 2-е условие на другое:
L>

L>при этом предшествующий элемент не должен удовлетворять первому условию

L>А такая замена некорректна.

?! Такая "замена" абсолютно корректна, ибо никакой "замены" по сути нет. Алгоритм удовлетворяет условию. Это можно строго доказать при желании. Утверждение "извлеченный элемент не принимает участия в последующем сравнении" относится к критерию фильтра, а не к алгоритму, который является решением задачи.
Re[27]: LINQ только для РСУБД!
От: Lloyd Россия  
Дата: 21.11.09 21:08
Оценка: 1 (1) +2
Здравствуйте, Gaperton, Вы писали:

L>>2)

L>>

L>>при этом извлечённый элемент не должен принимать участия в последующем сравнении

L>>Ты же заменил 2-е условие на другое:
L>>

L>>при этом предшествующий элемент не должен удовлетворять первому условию

L>>А такая замена некорректна.

G> ?! Такая "замена" абсолютно корректна, ибо никакой "замены" по сути нет. Алгоритм удовлетворяет условию.


Нет, он не удовлетворяет условию. Возьми последовательность {1, 2, 3, 4} и убедись.

G> Это можно строго доказать при желании.


Ты че такой упертый? Сам же видишь, что не прав, но продолжаешь упираться. Твой алгоритм даже на тестовом примере, что был изначально приведен, даст ответ, отличный от ожидаемого. О чем тут спорить?
Re[26]: LINQ только для РСУБД!
От: Gaperton http://gaperton.livejournal.com
Дата: 21.11.09 21:16
Оценка:
Здравствуйте, Lloyd, Вы писали:

G>>От чего твоему коду сильно легчает, и становится заметно, что это простейшая императивная реализация.


G>>Вот тебе еще один пример с циклом, который проще чем твой вариант с линком.


L>Ну вот, превратил занятную головоломку для последующих supporter-ов в какое-то банальное унылое г**но.


Виноват, привычка, доведенная до автоматизма годами практики. Видишь-ли, я на саппорте 6 лет отработал.
Re[27]: LINQ только для РСУБД!
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 21.11.09 21:19
Оценка:
Здравствуйте, Gaperton, Вы писали:

L>>Ты же заменил 2-е условие на другое:

L>>

L>>при этом предшествующий элемент не должен удовлетворять первому условию

L>>А такая замена некорректна.

G> ?! Такая "замена" абсолютно корректна, ибо никакой "замены" по сути нет. Алгоритм удовлетворяет условию. Это можно строго доказать при желании. Утверждение "извлеченный элемент не принимает участия в последующем сравнении" относится к критерию фильтра, а не к алгоритму, который является решением задачи.


Не. Lloyd прав — твой алгоритм на монотонно возрастающей последовательности {1, 2, 3, 4, 5} выдаст {2}, а не {2, 4}.

Вот экивалент на шарпе:

static bool p(int[] x, int i)
{
  return i > 0 && x[i - 1] == (x[i] - 1);
}

static List<int> gena_1(int[] x){
  var res = new List<int>();
  for(int i = 0; i < x.Length; ++i)
  {
    if (p(x, i) && !p(x, i - 1))
      res.Add(x[i]);
  }
  return res;
}
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[28]: Теперь у меня опечатка
От: Gaperton http://gaperton.livejournal.com
Дата: 21.11.09 21:42
Оценка: 14 (1) :)
Здравствуйте, Геннадий Васильев, Вы писали:

Можно чутка попроще.

func loop( c, o chan int ) // два раза типы писать не надо.
{ 
     prev := <- c          // := позволяет не писать мусора при объявлении+инициализации

     for val := range с    //читать из потока идиоматично в нашем случае так.
     { 
         if val != prev + 1       // это у нас типо фильтр входных значений, мы его четко отделили
         {     
            prev = val
            continue
         }
         
         o <- val                 //а здесь обработка результата
         prev = <- c              //и как положено, пропускаем один шаг.
                                  //Да, операция чтения - унарная, и надо писать "равно".
     }
}


Вообще красота получилась. Не ожидал. Возьму на заметку.
Re[28]: LINQ только для РСУБД!
От: Gaperton http://gaperton.livejournal.com
Дата: 21.11.09 21:49
Оценка:
Здравствуйте, Lloyd, Вы писали:

G>> ?! Такая "замена" абсолютно корректна, ибо никакой "замены" по сути нет. Алгоритм удовлетворяет условию.


L>Нет, он не удовлетворяет условию. Возьми последовательность {1, 2, 3, 4} и убедись.


Ага, теперь вижу. Блин, и правда бага . Непорядок. Ща схожу за сигаретами, и что-нибудь придумаю.

G>> Это можно строго доказать при желании.


L>Ты че такой упертый? Сам же видишь, что не прав, но продолжаешь упираться.


Не видел, пока ты не привел теста, на котором оно ломается. Че, не знаешь как баги репортить штоли?
Re[29]: Теперь у меня опечатка
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 21.11.09 22:58
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Вообще красота получилась. Не ожидал. Возьму на заметку.


Это CSP.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[28]: LINQ только для РСУБД!
От: Gaperton http://gaperton.livejournal.com
Дата: 21.11.09 23:52
Оценка: 15 (2)
Здравствуйте, Геннадий Васильев, Вы писали:

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


L>>>Ты же заменил 2-е условие на другое:

L>>>

L>>>при этом предшествующий элемент не должен удовлетворять первому условию

L>>>А такая замена некорректна.

G>> ?! Такая "замена" абсолютно корректна, ибо никакой "замены" по сути нет. Алгоритм удовлетворяет условию. Это можно строго доказать при желании. Утверждение "извлеченный элемент не принимает участия в последующем сравнении" относится к критерию фильтра, а не к алгоритму, который является решением задачи.


ГВ>Не. Lloyd прав — твой алгоритм на монотонно возрастающей последовательности {1, 2, 3, 4, 5} выдаст {2}, а не {2, 4}.


Так. По-ходу, как фиксить багу я кажется понял. Удивительно, но похоже эту задачку все-таки можно решить через компрехеншнс (в чем и была моя изначальная идея — решить в компрехеншнс, и перевести в цикл). Получается, правда, уже не так красиво, как я написал... Но все-таки, похоже задача решается без протягивания состояния с итерации на итерацию. Что далеко не очевидно.

Предлагается примерно следующая схема:
собираем индексы начал монотонного возрастания с единицей
starts = [ i | i <- 0..N, x.p(i), !x.p(i-1) ]
и индексы концов.
ends = [ i | i <- 0..N, !x.p(i), x.p(i-1) ]

p — предикат из моего решения, надо его профиксить чтобы он работал при превышении границы массива (выдавал false).
Элементов в обоих списках должно получиться равное количество, если правильно подобрать границы.

Потом, мы пробегаемся по обоим одновременно, и для каждой пары s и e генерируем последовательность индексов с шагом 2, делая выборку индекса уже из нее. Так в компрехеншнсах можно.

res = [ x[n] | ( s <- start & e <- ends ), n <- seq( s, e, 2 ) ]
где
seq — это функция, генерирующая последовательность чисел начиная с s, с шагом в третьем аргументе, и не более чем e.
& для генераторов обозначает параллельную выборку.

Как-то так. Решение вполне реляционно, и должно получиться примерно 4-5 строк кода на языках с компрехеншнсами (если я опять чего-нибудь не пропустил). Естественно, это достаточно компактно (если сравнивать с компрехеншнсами) переводится в циклы. Сейчас уже делать не буду, да и смысла особого нет — обычный вариант с циклом и форсированием пропуска следующей итерации очевидно проще.

Но вообще — жесть. Повезло, что удалось зацепиться за особенности задачи. Небольшая вариация условия — и все, досвидос.

Геннадий, спасибо за задачку . Это был фан .
Re[29]: LINQ только для РСУБД!
От: Lloyd Россия  
Дата: 22.11.09 00:31
Оценка: 1 (1)
Здравствуйте, Gaperton, Вы писали:

ГВ>>Не. Lloyd прав — твой алгоритм на монотонно возрастающей последовательности {1, 2, 3, 4, 5} выдаст {2}, а не {2, 4}.


G>Так. По-ходу, как фиксить багу я кажется понял. Удивительно, но похоже эту задачку все-таки можно решить через компрехеншнс (в чем и была моя изначальная идея — решить в компрехеншнс, и перевести в цикл). Получается, правда, уже не так красиво, как я написал... Но все-таки, похоже задача решается без протягивания состояния с итерации на итерацию. Что далеко не очевидно.


Она решается без протягивания состояния исключительно потому, что в твоем решении сосотояние глобально.
В случае, когда у тебя будет только курсор, который можно прокрутить только вперед (IEnumerable) без состояния уже не обойтись, как минимум придется сохранять значение предиката на предыдущем элементе.
Re[19]: Я всё ж таки вот, о чём думаю
От: Lloyd Россия  
Дата: 22.11.09 00:40
Оценка:
Здравствуйте, Геннадий Васильев, Вы писали:

ГВ>Вообще, знаешь, ты прав, пожалуй. Можно ввести требование, например, "отбирать запись, отстоящую от заданной не более, чем на -30 минут", или вообще — связанную с какой-то отдельной меткой события.


А можно уточнить, какие сложности при этом возникают. Не втыкаю как-то.
Re[29]: LINQ только для РСУБД!
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 22.11.09 00:41
Оценка:
Здравствуйте, Gaperton, Вы писали:

G>Как-то так. Решение вполне реляционно, и должно получиться примерно 4-5 строк кода на языках с компрехеншнсами (если я опять чего-нибудь не пропустил). Естественно, это достаточно компактно (если сравнивать с компрехеншнсами) переводится в циклы. Сейчас уже делать не буду, да и смысла особого нет — обычный вариант с циклом и форсированием пропуска следующей итерации очевидно проще.


Ещё можно поиграть с возвратом замыканий. Тоже, кажется, должно компактно получиться.

G>Но вообще — жесть. Повезло, что удалось зацепиться за особенности задачи. Небольшая вариация условия — и все, досвидос.

G>Геннадий, спасибо за задачку . Это был фан .

Всегда пожалуйста.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[20]: Я всё ж таки вот, о чём думаю
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 22.11.09 01:04
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Здравствуйте, Геннадий Васильев, Вы писали:


ГВ>>Вообще, знаешь, ты прав, пожалуй. Можно ввести требование, например, "отбирать запись, отстоящую от заданной не более, чем на -30 минут", или вообще — связанную с какой-то отдельной меткой события.


L>А можно уточнить, какие сложности при этом возникают. Не втыкаю как-то.


Не так просто привязаться к позиции. Например, у нас идут вот такие записи:

struct R {
  DateTime time;
  int value;
  bool mark;
  ...
};


...в порядке возрастания time. Некоторые содержат true в mark. Когда на вход поступает очередная запись с mark=true (обозначим её r0), нужно выдать на выход "самую старую" запись, пришедшую не ранее, чем за 30 минут. Задача усложняется тем, что совершенно не обязательно, что time будет выравнен по границе минуты, т.е. к индексу уже не привяжешься.

Вот такой пример, скажем:

time    mark
------------
0:14:00    f
0:15:28    f
0:18:20    f
0:27:37    f < ...а вернуть надо вот эту
0:29:59    f
0:32:28    f
0:55:32    t < mark = true, теперь см. выше...


Или, например, так. Та же структура, только на входе два потока — один "чаще", второй "реже". Теперь нужно выдавать на выход те записи первого потока, временнАя метка которых лежит в пределах [время-в-записи-второго-потока...+2 часа].

Ну то есть:

Stream 2, "редкий"
time     mark
-------------
3:00:00    f
4:15:00    t <- опорное время

Stream 1, "частый"
time    mark
------------
4:14:00    f
4:15:28    f <- начать нужно отсюда...
4:18:20    f
4:27:37    f 
4:35:32    f 
...
5:14:30    f <- ...а закончить здесь
5:15:32    f


Для Stream 1 тоже может быть добавлено какое-то условие, скажем, вычленять записи, находящиеся в диапазоне [-10 минут ... +2 часа].

Ну и дополнительную прелесть задаче придаёт то, что такие серии могут быть в десятки мегабайт размером.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[21]: Поспешил
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 22.11.09 01:07
Оценка:
Несколько опечаток:

ГВ>Или, например, так. Та же структура, только на входе два потока — один "чаще", второй "реже". Теперь нужно выдавать на выход те записи первого потока, временнАя метка которых лежит в пределах [время-в-записи-второго-потока...+1 час].


ГВ>Для Stream 1 тоже может быть добавлено какое-то условие, скажем, вычленять записи, находящиеся в диапазоне [-10 минут ... +1 час].
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[30]: LINQ только для РСУБД!
От: Gaperton http://gaperton.livejournal.com
Дата: 22.11.09 01:20
Оценка:
Здравствуйте, Lloyd, Вы писали:

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


ГВ>>>Не. Lloyd прав — твой алгоритм на монотонно возрастающей последовательности {1, 2, 3, 4, 5} выдаст {2}, а не {2, 4}.


G>>Так. По-ходу, как фиксить багу я кажется понял. Удивительно, но похоже эту задачку все-таки можно решить через компрехеншнс (в чем и была моя изначальная идея — решить в компрехеншнс, и перевести в цикл). Получается, правда, уже не так красиво, как я написал... Но все-таки, похоже задача решается без протягивания состояния с итерации на итерацию. Что далеко не очевидно.


L>Она решается без протягивания состояния исключительно потому, что в твоем решении сосотояние глобально.


В этом решении нет состояния вообще, потому, что в нем нет мутабельных операций. Все абсолютно чисто. Я нигде не изменяю состояния создаваемых объектов, и ничего помнить между итерациями не требуется.

L>В случае, когда у тебя будет только курсор, который можно прокрутить только вперед (IEnumerable) без состояния уже не обойтись, как минимум придется сохранять значение предиката на предыдущем элементе.


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

Интерес, правда, в этом скорее академический. Уж больно через жопу как-то получается. Но надо на всякий случай запомнить, может пригодится когда-нибудь.
Re[30]: LINQ только для РСУБД!
От: Gaperton http://gaperton.livejournal.com
Дата: 22.11.09 01:27
Оценка:
Здравствуйте, Геннадий Васильев, Вы писали:

G>>Как-то так. Решение вполне реляционно, и должно получиться примерно 4-5 строк кода на языках с компрехеншнсами (если я опять чего-нибудь не пропустил). Естественно, это достаточно компактно (если сравнивать с компрехеншнсами) переводится в циклы. Сейчас уже делать не буду, да и смысла особого нет — обычный вариант с циклом и форсированием пропуска следующей итерации очевидно проще.


ГВ>Ещё можно поиграть с возвратом замыканий. Тоже, кажется, должно компактно получиться.


Возврат замыкания принципиально не отличается от алгоритмов, выраженных через foldl, с явным состоянием, и от "объектного" стиля, где состояние завернуто в объект, и от простых циклов. Во всех этих случаях так или иначе состояние протягивается с одной итерации на другую, только разными способами. Работая с Go, я бы предпочел, вероятно, завернуть состояние в объект, ибо объекты там очень легко делаются. Может быть, ты что-то другое имеешь в виду, правда.
Re[31]: LINQ только для РСУБД!
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 22.11.09 01:32
Оценка:
Здравствуйте, Gaperton, Вы писали:

ГВ>>Ещё можно поиграть с возвратом замыканий. Тоже, кажется, должно компактно получиться.


G>Возврат замыкания принципиально не отличается от алгоритмов, выраженных через foldl, с явным состоянием, и от "объектного" стиля, где состояние завернуто в объект, и от простых циклов. Во всех этих случаях так или иначе состояние протягивается с одной итерации на другую, только разными способами. Работая с Go, я бы предпочел, вероятно, завернуть состояние в объект, ибо объекты там очень легко делаются. Может быть, ты что-то другое имеешь в виду, правда.


Да нет, я как раз именно протягивание состояния имею в виду. А в случае Go, кстати, состояние неплохо заворачивается в горутину. Что ты думаешь, я тут крыльями машу?
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.