Союз Интервалов

15

Задав список интервалов, выполните их объединение и уменьшите наложения. Это означает, что перекрывающиеся части уменьшаются. ( [a, b] U [c, d] = [a, d]если b > c) Предполагая все a <b во всех интервалах [a, b]. Реализовать как функцию списка интервалов ввода -> список интервалов вывода. Самый короткий код выигрывает. Вы не можете использовать любые существующие библиотеки.

Разъяснения:

  • Открытые и закрытые интервалы не различаются.
  • Интервалы для действительных чисел, а не целых чисел. ( [2, 3], [4, 5] -> [2, 3], [4, 5])
  • Нет необходимости сортировать выходные интервалы
  • Порядок, если вход не имеет значения
  • Недопустимые входные данные есть только [a, b]там b >= a, где они не имеют ничего общего с порядком входных интервалов и количеством входных интервалов.
  • Вам не нужно показывать сообщение об ошибке при неопределенном поведении

Примеры (с номерами строк)

 [2, 4], [7, 9] --> [2, 4], [7, 9]
   234
        789
-> 234  789

 [1, 5], [2, 10] --> [1, 10] (overlapping [2, 5] reduced)

   12345
    234567890
-> 1234567890
 [2, 4], [3, 6], [8, 9] -> [2, 6], [8, 9]
   234
    3456
         89
-> 23456 89

 [4, 2], [2, 2] -> (undefined behavior: against the assumption)
Мин-Tang
источник
3
Будут ли интервалы всегда сортироваться, как в ваших примерах?
Питер Олсон
1
Почему [2, 3], [4, 5] не перекрываются или [2, 4], [4, 5] тоже? Они оба дают
2345.
2
Интервалы только на множестве целых чисел?
Lowjacker
2
Нам нужны некоторые пояснения: 1) Является ли [4,5], [1,2] легальным вкладом? 2) Должен ли выход [2,3], [4,5] быть [2,5] или [2,3], [4,5]? 3) Должен ли выход [2,3], [3,4] быть [2,4] или [2,3], [3,4]?
MtnViewMark
1
Спасибо за разъяснения, но "Нет необходимости сортировать" означает что? Что вывод не нужно сортировать? Или что вход уже отсортирован?
MtnViewMark

Ответы:

2

GolfScript, 32

[{1$1$*-2%~2->{*$[(\)\;]}{}if}*]
  • Добавьте 2 символа, если вы предпочитаете блок, 4, если вы предпочитаете именованный блок.
  • Вход и выход представляют собой массив пар, например [[2 4] [3 5]]
  • Предполагается, что вход упорядочен по первому элементу.
  • Сжатие «смежных» диапазонов ([2 4] [5 6] -> [2 6])
  • Первое усилие по GolfScript. Совет и гнилые фрукты приветствуются.

Полная тестовая программа:

[~](;2/[{1$1$*-2%~2->{*$[(\)\;]}{}if}*]`

Пример вызова:

ruby golfscript.rb intervals.gs <<EOF
3
2 4
3 6
8 9
EOF
# Expected output: [[2 6] [8 9]]
Джесси Милликен
источник
4

Хаскелл (103)

Я думаю, это слишком многословно для Хаскелла. Спасибо Hoa Long Tam за его функцию сортировки.

m%(x:y)|x>m=m:x:y|2>1=x:m%y;m%_=[m]
(x:y)?l|x`elem`l=y?l|0<1=x:y?(x:l);a?_=a
a∪b=foldr(%)[](a++b)?[]

В Хаскеле интервал от aк bобозначается как [a..b]. Моя запись очень похожа на математическую запись. Используйте это так:

[a..b] ∪ [c..d] ∪ ... ∪ [y..z]
FUZxxl
источник
3

Хорошо, вот мои 250 символов трещины в этом.

void n(int a[]){if(!a[2])return;if(a[2]<=a[1]){if(a[1]<a[3])a[1]=a[3];
int *b=a+2;while(*b=*(b+2))++b;n(a);}n(a+2);}
void m(int a[]){if(!a[2])return;if(a[0]>a[2]){int s=a[0],t=a[1];
a[0]=a[2];a[2]=s;a[1]=a[3];a[3]=t;m(a+2);m(a);n(a);}m(a+2);n(a+2);}

Функция принимает массив int и работает с ним in-situ. Массив заканчивается 0, и интервалы могут быть заданы в любом порядке.

Пример вывода:

input list: (7,9) (5,6) (1,4) (15,18) (13,16) (2,3) (8,11) 
output list: (1,4) (5,6) (7,11) (13,18) 

Пример программы:

#include <stdio.h>

void n(int a[]){if(!a[2])return;if(a[2]<=a[1]){if(a[1]<a[3])a[1]=a[3];
int *b=a+2;while(*b=*(b+2))++b;n(a);}n(a+2);}
void m(int a[]){if(!a[2])return;if(a[0]>a[2]){int s=a[0],t=a[1];
a[0]=a[2];a[2]=s;a[1]=a[3];a[3]=t;m(a+2);m(a);n(a);}m(a+2);n(a+2);}


/*
void n(int a[])
{
    if(!a[2])return;
    if(a[2]<=a[1]) {
        if(a[1]<a[3])
            a[1]=a[3];
        int *b=a+2;
        while(*b=*(b+2))++b;
        n(a);
    }
    n(a+2);
}

void m(int a[])
{
    if(!a[2])return;
    if(a[0]>a[2]) {
        int s=a[0],t=a[1];
        a[0]=a[2];a[2]=s;
        a[1]=a[3];a[3]=t;
        m(a+2);m(a);n(a);
    }
    m(a+2);n(a+2);
}
*/

void p(int a[]) 
{
    if(!*a) {
        printf("\n");
        return;
    }
    printf("(%d,%d) ",a[0],a[1]);
    p(a+2);
}

int main (int argc, const char * argv[]) 
{
    // Code golf entry
    // Interval Merging

    int a[] = {7,9,5,6,1,4,15,18,13,16,2,3,8,11,0};
    printf( "input list: " ); p(a);
    m(a);
    printf( "output list: " ); p(a);

    return 0;
}
Джонатан Ватмоф
источник
perform the union of themдолжно привести к (1,11) (13,18), не так ли?
пользователь неизвестен
@ пользователь неизвестен: я бы подумал о том же, но я думаю, что инструкции говорят только объединить, если они перекрываются. Таким образом, (1, 4) (5, 6) не объединяются в соответствии с правилом ([a, b] U [c, d] = [a, d] if b > c). И в этом отношении, даже (1, 5) (5, 6) не будут объединены.
mellamokb
«Задав список интервалов, выполните их объединение и уменьшите перекрытия» andУменьшите перекрытия - нет if they overlap. ОК - следующие that means ...пункты снова в обратном направлении.
пользователь неизвестен
@ пользователь неизвестен: я согласен. Вот почему я прокомментировал это по этому вопросу. Надеемся, что ОП ответит :)
mellamokb
2

Питон, 100 символов

def f(L):R=sorted(set(p for p in sum(L,[])if 1-any(x<p<y for x,y in L)));return zip(R[::2],R[1::2])
print f([[2, 4], [7, 9]])
print f([[1, 5], [2, 10]])
print f([[3, 6], [2, 4], [8, 9]])
print f([[1, 5], [3, 5], [4, 5]])

генерирует

[(2, 4), (7, 9)]
[(1, 10)]
[(2, 6), (8, 9)]
[(1, 5)]

Занимает все конечные точки интервалов, удаляет любые, которые находятся строго в другом интервале, унифицирует и сортирует их, и объединяет их в пару.

Кит Рэндалл
источник
98 байт
movatica
2

Haskell, 55 символов

v(q@(a,b):p@(c,d):r)|c>b=q:v(p:r)|1<3=v((a,d):r);v x=x

Если ввод не отсортирован, то 88 символов:

p@(a,b)§(q@(c,d):r)|b<c=p:q§r|a>d=q:p§r|1<3=(min a c,max b d)§r;p§_=[p]
u i=foldr(§)[]i

Тестовые прогоны:

ghci> testAll v
pass: [(2,4),(7,9)] --> [(2,4),(7,9)]
pass: [(1,5),(2,10)] --> [(1,10)]
pass: [(2,4),(3,6),(8,9)] --> [(2,6),(8,9)]
ghci> testAll u
pass: [(2,4),(7,9)] --> [(2,4),(7,9)]
pass: [(1,5),(2,10)] --> [(1,10)]
pass: [(2,4),(3,6),(8,9)] --> [(2,6),(8,9)]

Я предполагаю, что «не может использовать никакие существующие библиотеки» исключает импорт Listи вызов sort. Если бы это было законно, то в несортированной версии было бы всего 71 символ.

MtnViewMark
источник
ИМХО будет достаточно импортировать Listиз пакета Haskell98.
FUZxxl
2

Скала, 272 персонажа

type p=List[(Int,Int)];def f(l:p):p={var(a,s,c,o)=(new Array[Int]((l map(x=>x._2)max)+1),0,0,List[Int]());l map(x=>(a(x._1)+=1,a(x._2)-=1));while(c<a.size){s+=a(c);if(a(c)==1&&s==1)o=o:+c;if(a(c)== -1&&s==0)o=o:+c;c+=1};return(o.grouped(2).map(x=>(x.head,x.last)).toList)}

Использование:

object Intervals2 extends Application
{
    type p=List[(Int,Int)];def f(l:p):p={var(a,s,c,o)=(new Array[Int]((l map(x=>x._2)max)+1),0,0,List[Int]());l map(x=>(a(x._1)+=1,a(x._2)-=1));while(c<a.size){s+=a(c);if(a(c)==1&&s==1)o=o:+c;if(a(c)== -1&&s==0)o=o:+c;c+=1};return(o.grouped(2).map(x=>(x.head,x.last)).toList)}

    print(f(List((1,2),(3,7),(4,10))))
}

Создает массив и вставляет 1 для каждого начала интервала и -1 для каждого конца интервала. Затем пошагово проходит по массиву, добавляя значения в счетчик, выводя начало каждый раз, когда счетчик переходит от 0 до 1, и конец, когда он переходит от 1 до 0. Возможно, излишне сложно.

Выход:

List((1,2), (3,10))
Gareth
источник
1

Perl (146) (92) (90)

игра в гольф до 90 символов, творчески с использованием двигателя регулярных выражений

sub u {map $ h [$ _] = 1, @ $ _ [0] .. @ $ _ [1] для @_; $ w. = $ _ + 0 для @ h; push @ r, $ - [0 ], $ + [0] -1while $ ш = ~ / 1 + / г; @r}

пример использования:

my @ out1 = u ([1, 5], [2, 10]); # (1,10)
my @ out2 = u ([2, 4], [3, 6], [8, 9]); № (2, 6, 8, 9)

давайте немного объясним этот код.

эта подпрограмма получает массив arrayrefs, каждый из которых указывает на массив, содержащий два элемента, начало и конец интервала: ([2, 4], [3, 6], [8, 9])

для каждого арефа мы генерируем массив элементов от первого до последнего ($_->[0] .. $_->[1]). затем мы используем map для установки элементов таких индексов в @h в 1.

за (@_) {
    map {$ h [$ _] = 1} ($ _-> [0] .. $ _-> [1]);
}

после этого, @hбудет содержать единицы (для интервалов) или undefs, изображенные ниже как дефисы для ясности.

индекс: 0 1 2 3 4 5 6 7 8 9
@h: - - 1 1 1 1 1 - 1 1

затем мы строим строку из @h, добавляя 0, чтобы заменить undefs чем-то более полезным (undef + 0 = 0).

$w .= $_+0 for @h;

$ w содержит 011111011сейчас.

пришло время немного злоупотребить движком регулярных выражений.

push @r, ($-[0], $+[0]-1) while $w=~/1+/g;

после успешных совпадений массивы @ - и @ + содержат соответственно позицию начала и конца каждого совпадения; 0-й элемент используется для всего совпадения: сначала за 1 доллар, затем за 2 доллара и т. Д.

$+[0] фактически содержит позицию первого несоответствующего символа, поэтому мы должны вычесть один.

@rсодержит (2, 6, 8, 9)сейчас.

@r

сделать суб возврат @r.

китайский Perl гот
источник
Не работает для [2,3],[4,5]доходности реальных чисел2 5
Xcali
1

Scala 305 279 символов без вызова:

type I=(Int,Int)
def l(p:I,q:I)=if(p._1<q._1)true else if(p._1>q._1)false else p._2<q._2
def r(l:List[I]):List[I]=l match{case x::y::z=>{if(y._1<=x._2&&y._2>x._2)(x._1,y._2)::r(z)else
if(y._1<=x._2&&y._2<=x._2)x::r(z)else  
x::r(y::z)}case _=>l}
def c(v:List[I])=r(v.sortWith(l))

вызов:

val i=List((7,9),(5,6),(1,4),(15,18),(13,16),(2,3),(8,11))
c(i)
res0: List[(Int, Int)] = List((1,4), (5,6), (7,11), (13,18))
Пользователь неизвестен
источник
1

Брахилог , 12 байт

⟦₂ᵐcod~c~⟦₂ᵐ

Попробуйте онлайн!

Восхитительно декларативное решение, принимающее ввод как список списков через входную переменную и выводящее список списков через выходную переменную.

        ~⟦₂ᵐ    The output is a list of intervals, where each interval is a range in
      ~c        the smallest partition of
  ᵐ             each element of the input
⟦₂              converted to an inclusive range,
   c            concatenated,
    o           sorted,
     d          and deduplicated
        ~⟦₂ᵐ    for which each element of the partition is a range.
Несвязанная строка
источник
1

Clojure, 138 байт

#(let[S(set(apply mapcat range(apply map list %)))Q(sort S)](map list(for[s Q :when(not(S(dec s)))]s)(for[s(map inc Q):when(not(S s))]s)))

Это сокращает до 119 байт, если ввод более гибкий, а именно список начальных точек интервалов И список конечных точек интервалов:

#(let[S(set(mapcat range % %2))Q(sort S)](map list(for[s Q :when(not(S(dec s)))]s)(for[s(map inc Q):when(not(S s))]s)))

Там должен быть лучший способ.

NikoNyrh
источник
1

Japt , 18 байт

Это слишком долго. I / O как отсортировано, 2D массив интервалов.

c_ròÃòÈaY Éîg[TJ]

Попытайся

мохнатый
источник