Kesatuan Interval

15

Diberikan daftar interval, lakukan penyatuannya, dan kurangi tumpang tindih. Itu berarti, bagian yang tumpang tindih berkurang. ( [a, b] U [c, d] = [a, d]jika b > c) Dengan asumsi semua a <b dalam semua interval [a, b]. Menerapkan sebagai fungsi dari daftar interval input -> daftar interval output. Kode terpendek menang. Anda tidak dapat menggunakan perpustakaan yang ada.

Klarifikasi:

  • Interval terbuka dan tertutup tidak dibedakan.
  • Interval untuk bilangan real, bukan bilangan bulat. ( [2, 3], [4, 5] -> [2, 3], [4, 5])
  • Tidak perlu mengurutkan interval output
  • Urutan jika input tidak masalah
  • Input ilegal hanya di [a, b]mana b >= a, tidak ada hubungannya dengan urutan interval input dan jumlah interval input.
  • Anda tidak perlu menampilkan pesan kesalahan pada perilaku yang tidak terdefinisi

Contoh (dengan garis angka)

 [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)
Ming-Tang
sumber
3
Apakah interval selalu diurutkan seperti yang ada dalam contoh Anda?
Peter Olson
1
Mengapa tidak [2, 3], [4, 5] tumpang tindih, atau [2, 4], [4, 5] juga? Keduanya menghasilkan 2345.
mellamokb
2
Apakah interval hanya pada himpunan bilangan bulat?
Lowjacker
2
Kami membutuhkan beberapa klarifikasi: 1) Apakah [4,5], [1,2] masukan hukum? 2) Apakah output dari [2,3], [4,5] menjadi [2,5] atau [2,3], [4,5]? 3) Apakah output dari [2,3], [3,4] menjadi [2,4] atau [2,3], [3,4]?
MtnViewMark
1
Terima kasih atas klarifikasi, tetapi "Tidak perlu disortir" artinya apa? Bahwa hasilnya tidak perlu disortir? Atau inputnya sudah diurutkan?
MtnViewMark

Jawaban:

2

GolfScript, 32

[{1$1$*-2%~2->{*$[(\)\;]}{}if}*]
  • Tambahkan 2 karakter jika Anda lebih suka satu blok, 4 jika Anda lebih suka satu blok bernama.
  • Input dan output adalah array berpasangan, misalnya [[2 4] [3 5]]
  • Mengasumsikan bahwa input diurutkan berdasarkan elemen pertama.
  • Kompak rentang "berdekatan" ([2 4] [5 6] -> [2 6])
  • Upaya GolfScript pertama. Nasihat & buah busuk dihargai.

Program uji penuh:

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

Doa contoh:

ruby golfscript.rb intervals.gs <<EOF
3
2 4
3 6
8 9
EOF
# Expected output: [[2 6] [8 9]]
Jesse Millikan
sumber
4

Haskell (103)

Saya pikir, itu terlalu bertele-tele untuk Haskell. Terima kasih kepada Hoa Long Tam untuk fungsinya menyortir.

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

Dalam Haskell, sebuah intervall dari ake bdilambangkan dengan [a..b]. Notasi saya sangat mirip dengan notasi matematika. Gunakan seperti ini:

[a..b] ∪ [c..d] ∪ ... ∪ [y..z]
FUZxxl
sumber
3

Ok, ini 250 karakter saya.

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);}

Fungsi ini mengambil array int, dan beroperasi di situ in-situ. Array diakhiri oleh 0, dan interval dapat diberikan dalam urutan apa pun.

Output sampel:

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) 

Program sampel:

#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;
}
Jonathan Watmough
sumber
perform the union of themharus mengarah ke (1,11) (13,18), bukan?
pengguna tidak diketahui
@ Pengguna tidak diketahui: Saya akan memikirkan hal yang sama, tapi saya kira instruksi mengatakan hanya menggabungkan jika mereka tumpang tindih. Jadi (1, 4) (5, 6) tidak digabungkan sesuai aturan ([a, b] U [c, d] = [a, d] if b > c). Dan dalam hal ini, bahkan (1, 5) (5, 6) tidak akan digabungkan.
mellamokb
"Diberikan daftar interval, lakukan penyatuannya, dan kurangi tumpang tindih" andkurangi tumpang tindih - bukan if they overlap. OK - that means ...titik - titik berikut lagi di arah yang berlawanan.
pengguna tidak diketahui
@ pengguna tidak diketahui: Saya setuju. Itu sebabnya saya berkomentar tentang itu pada pertanyaan. Semoga OP akan merespons :)
mellamokb
2

Python, 100 karakter

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

menghasilkan

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

Mengambil semua titik akhir interval, menghilangkan semua yang benar-benar di dalam interval lain, menyatukan & mengurutkannya, dan memasangkannya.

Keith Randall
sumber
98 byte
movatica
2

Haskell, 55 karakter

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

Jika input tidak disortir, maka 88 karakter:

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

Tes berjalan:

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

Saya berasumsi bahwa "tidak dapat menggunakan pustaka yang ada" menghalangi impor Listdan panggilan sort. Jika itu legal, versi yang tidak disortir hanya 71 karakter.

MtnViewMark
sumber
mengimpor Listdari paket Haskell98akan cukup IMHO.
FUZxxl
2

Scala, 272 karakter

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)}

Pemakaian:

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))))
}

Membuat array dan menyisipkan 1 untuk setiap interval dimulai dan -1 untuk setiap akhir interval. Kemudian langkah-langkah melalui array menambahkan nilai-nilai ke penghitung menghasilkan awal setiap kali penghitung langkah dari 0 ke 1 dan berakhir ketika langkah dari 1 ke 0. Mungkin rumit tidak perlu.

Keluaran:

List((1,2), (3,10))
Gareth
sumber
1

Perl (146) (92) (90)

bermain golf hingga 90 karakter, secara kreatif menggunakan mesin regex

sub u {peta $ h [$ _] = 1, @ $ _ [0] .. @ $ _ [1] untuk @_; $ w. = $ _ + 0 untuk @ h; push @ r, $ - [0 ], $ + [0] -1sementara $ w = ~ / 1 + / g; @r}

contoh penggunaan:

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

mari kita jelaskan kode ini sedikit.

subrutin ini menerima larik arrayref, masing-masing menunjuk ke larik yang mengandung dua elemen, mulai dan akhir interval: ([2, 4], [3, 6], [8, 9])

untuk setiap aref, kami menghasilkan array elemen dari pertama hingga terakhir ($_->[0] .. $_->[1]). maka kita menggunakan peta untuk mengatur elemen-elemen dari indeks tersebut di @ h ke 1.

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

setelah ini, @hakan berisi yang (untuk interval) atau undefs, digambarkan di bawah ini sebagai tanda hubung untuk kejelasan.

indeks: 0 1 2 3 4 5 6 7 8 9
@ h: - - 1 1 1 1 1 - 1 1

selanjutnya kita membangun string dari @h, menambahkan 0 untuk mengganti undefs dengan sesuatu yang lebih berguna (undef + 0 = 0).

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

$ w mengandung 011111011sekarang.

saatnya untuk sedikit menyalahgunakan mesin regex.

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

setelah pertandingan yang berhasil, array @ - dan @ + masing-masing berisi posisi awal dan akhir dari setiap pertandingan; Elemen 0 digunakan untuk seluruh pertandingan, pertama untuk $ 1, kedua untuk $ 2 dan seterusnya.

$+[0] sebenarnya berisi posisi char pertama yang tidak cocok, jadi kita harus mengurangi satu.

@rmengandung (2, 6, 8, 9)sekarang.

@r

untuk membuat pengembalian sub @r.

perl Cina goth
sumber
Tidak berfungsi untuk [2,3],[4,5]hasil bilangan real2 5
Xcali
1

Scala 305 279 karakter tanpa doa:

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))

doa:

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))
Pengguna tidak diketahui
sumber
1

Brachylog , 12 byte

⟦₂ᵐcod~c~⟦₂ᵐ

Cobalah online!

Solusi deklaratif yang menyenangkan, mengambil input sebagai daftar daftar melalui variabel input dan mengeluarkan daftar daftar melalui variabel output.

        ~⟦₂ᵐ    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.
String yang tidak terkait
sumber
1

Clojure, 138 byte

#(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)))

Ini lebih pendek menjadi 119 byte jika input lebih fleksibel, yaitu daftar titik awal interval DAN daftar titik akhir interval:

#(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)))

Harus ada cara yang lebih baik.

NikoNyrh
sumber
1

Japt , 18 byte

Ini terasa terlalu lama. I / O sebagai diurutkan, array interval 2D.

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

Cobalah

Shaggy
sumber
0

Perl 5 -MList::Util=max -n , 89 byte

@r=/\S+/g;map{/ /;$`<=$r[1]?$r[1]=max@r,$'*1:(say"@r")|(@r=($`,$'))}sort{$a-$b}<>;say"@r"

Cobalah online!

Xcali
sumber