Pull to refresh

Comments 15

Я бы немного упростил:

set @start := X;
set @end := Y;
select * from tab
where greatest(start, @start) <= least(end, @end)
      or ((end > @start or @end > start) and sign(start - end) <> sign(@start - @end))
      or (end < start and @end < @start);
Так действительно ясней выглядит — не как каша из условий. Благодарю.
Вот смотрю я на ваши циферблаты, и кажется мне, что у этой задачи должно быть простое тригонометрическое решение.
Тригонометрическое решение проще, но не намного:
set @start := X;
set @end := Y;
select * from tab
where sin((start - @start)/4) * sin((start - @end)/4) * sin((end - @start)/4) * sin((end - @end)/4) <= 0
Делитель 4 здесь для того, чтобы максимальный элемент множества не был бы больше два пи. В принципе, вместо четверки можно взять и 100 с запасом. Это решение лучше в том смысле, что оно получено не перечислением вариантов, а выведено из условия пересечения хорд.
Приношу извинения — вариант оказался ошибочным! Поторопился. Простой вариант 0 — 20 и 1 — 15 к пересечению хорд не приводит и так не диагностируется.
WHERE NOT ( `start` >= @end OR `end` <= @start )

Теперь раскрываем скобки отрицанию — после чего всё становится куда менее понятно :)

WHERE `start` < @end AND `end` > @start)

Поверить в то, что это условие в самом деле ищет любое пересечение, очень непросто.
Поверить в то, что это условие в самом деле ищет любое пересечение, очень непросто.

Всю жизнь использовал именно такое условие для поиска пересечений и оно мне казалось очевидным. Сила привычки?
В моём — несомненно сила привычки. Я несколько раз выводил это выражение сам, и сейчас оно мне уже кажется верным. Хотя всё ещё не очевидное.

В вашем случае — не знаю. Может, Вы просто очень умный :).
Сам удивляюсь (тому, как сам не догадался), но это так. Проверил сейчас… сначала на логической матрице, потом на практике. Еще одно упрощение в копилку, спасибо.
А как по-простому вычислить максимальное число пересечений на заданном незамкнутом отрезке времени?
А можно еще усложнить, start: 23, end: 0 — это не только 1 час работы, но и 25 часов (допустим, сутки/трое).
  AND  NOT (`prime_end`<= @start AND  XOR  @end <=`prime_start` )

Тут ведь опечатка? Или я это что-то, что я не понимаю? AND XOR?
Виноват, исправил. Вообще, ошибки возможно еще есть. Простите, я очень торопился — проект все время отнимает…
Вот еще вариант:
set @start := X;
set @end := Y;
select * from tab
where (@start - start) * (start - @end) * (@start - @end) <= 0 
      or (@start - start) * (@start - end) * (start - end) >= 0;
Sign up to leave a comment.

Articles