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


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)

3
Чи завжди будуть відсортовані інтервали, як вони є у ваших прикладах?
Пітер Олсон

1
Чому [2, 3], [4, 5] також не перекриваються або [2, 4], [4, 5]? Вони обоє приносять 2345.
mellamokb

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)

Я думаю, це занадто багатослівно для Haskell. Завдяки Хоа Лонг Там за його функцію сортування.

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)?[]

У Haskell Intervall від aдоb позначається через [a..b]. Моє позначення дуже схоже на математичне позначення. Використовуйте його так:

[a..b] ∪ [c..d] ∪ ... ∪ [y..z]

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), чи не так?
користувач невідомий

@user невідомо: Я б подумав те саме, але, мабуть, інструкції кажуть, що вони поєднуються, лише якщо вони перетинаються. Отже (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 ...пункти знову в зворотному напрямку.
користувач невідомий

@user невідомо: я згоден. Ось чому я прокоментував це питання. Сподіваємось, ОП відповість :)
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)]

Бере всі кінцеві точки інтервалів, видаляє будь-які, які знаходяться строго в іншому інтервалі, уніфікує та сортує їх та з’єднує їх.



2

Хаскелл, 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 символ.


імпорт Listіз пакету Haskell98був би достатнім IMHO.
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))

1

Perl (146) (92) (90)

гольф знизився до 90 символів, творчо використовуючи двигун регулярного випромінювання

sub u {map $ h [$ _] = 1, @ $ _ [0] .. @ $ _ [1] для @_; $ w. = $ _ + 0 для @ h; push @ r, $ - [0 ], $ + [0] -1 тим часом $ w = ~ / 1 + / g; @r}

приклад використання:

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

давайте трохи пояснимо цей код.

ця підпрограма отримує масив масивів, кожен aref вказує на масив, що містить два елементи, початок та кінець інтервалу: ([2, 4], [3, 6], [8, 9])

для кожного aref ми створюємо масив елементів від першого до останнього ($_->[0] .. $_->[1]). тоді ми використовуємо map для встановлення елементів таких індексів у @h до 1.

для (@_) {
    карта {$ h [$ _] = 1} ($ _-> [0] .. $ _-> [1]);
}

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

індекс: 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.


Не працює для реальних [2,3],[4,5]врожаїв2 5
Xcali

1

Скала 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)))

Має бути кращий спосіб.



Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.