Tìm giao điểm của 2 bộ trong ký hiệu khoảng thời gian liên kết


10

Tìm giao điểm của 2 bộ trong ký hiệu khoảng thời gian liên kết

Cho hai tập hợp số thực được mô tả là hợp của các khoảng, xuất ra một mô tả về giao điểm của hai tập hợp này dưới dạng một tập hợp của cùng một loại khoảng.

Các bộ đầu vào sẽ luôn bao gồm các hiệp của các khoảng sao cho mỗi khoảng bắt đầu và kết thúc ở một số nguyên khác nhau (nghĩa là không có khoảng nào có số đo bằng 0). Tuy nhiên, các khoảng khác nhau trong cùng một bộ có thể bắt đầu hoặc kết thúc tại cùng một số nguyên hoặc chồng lấp.

Tập đầu ra cũng phải là một tập hợp các khoảng bắt đầu và kết thúc tại các số nguyên, nhưng không có khoảng nào trong đầu ra có thể trùng với bất kỳ số nào khác ngay cả ở một số nguyên.

Đầu vào có thể có bất kỳ dạng nào phù hợp với ngôn ngữ bạn chọn, miễn là nó bao gồm hai danh sách các cặp số nguyên.

Ví dụ: bạn có thể biểu diễn tập hợp phương trìnhlà:

[-10,-4]u[1,5]u[19,20]

Hoặc như:

[[-10,-4],[1,5],[19,20]]

Hoặc như:

[-10,-4;1,5;19,20]

Đại diện đầu ra của bạn phải giống hệt với đại diện đầu vào của bạn (ngoại trừ việc nó chỉ là một danh sách các khoảng thay vì hai).

Ví dụ / Các trường hợp thử nghiệm:

Đầu vào:

[[[-90,-4],[4,90]],[[-50,50]]]

Đầu ra:

[[-50,-4],[4,50]]

Nói cách khác, chúng ta giao nhau với tập hợp chứa tất cả các số thực nằm trong khoảng từ -90 đến -4 và tất cả các số thực từ 4 đến 90 với tập hợp chứa tất cả các số thực nằm trong khoảng từ -50 đến 50. Giao điểm là tập hợp chứa tất cả số thực giữa -50 và -4 và tất cả các số thực từ 4 đến 50. Một lời giải thích trực quan hơn:

-90~~~~~-4  4~~~~~90   intersected with
    -50~~~~~~~~50        yields:
    -50~-4  4~~50

Đầu vào:

"[-2,0]u[2,4]u[6,8]
[-1,1]u[3,5]u[5,9]"

Đầu ra:

"[-1,0]u[3,4]u[6,8]"

Đầu vào:

[-9,-8;-8,0;-7,-6;-5,-4]
[-7,-5;-1,0;-8,-1]

Đầu ra:

[-8,0]

Đầu ra không hợp lệ (mặc dù nó đại diện cho cùng một bộ):

[-8,0;-7,-5;-5,0]

Ghi điểm:

Đây là để nguồn ngắn nhất tính bằng byte, như có khả năng được sửa đổi bởi phần thưởng sau.

Tặng kem:

-15% nếu bạn cũng hỗ trợ vô cực dương và âm dưới dạng giới hạn của các khoảng. Bạn có thể chọn mã thông báo đại diện cho những con số này. (Và vâng, vô cực là một số trong siêu thực; P)


Chúng ta có thể giả sử các tập hợp khác nhau trong mỗi triệu tập giao lộ được viết theo thứ tự tăng dần không? Nói cách khác (nhưng ngược lại), đầu vào sau có hợp lệ không? [[[4,90],[-90,-4]],[[-50,50]]]
msh210

2
@ msh210 ví dụ thứ ba sẽ trả lời câu hỏi này. (Không. Tự sắp xếp chúng.)
quintopia 7/12/2015

@nimi bạn nói đúng. đã sửa
quintopia

Câu trả lời:


3

Toán học, 41 byte - 15% = 34,85

Mathematica có một hàm tích hợp cho giao điểm.

List@@IntervalIntersection@@Interval@@@#&

Thí dụ:

In[1]:= List@@IntervalIntersection@@Interval@@@#&[{{{-90, -4}, {4, Infinity}}, {{-50,Infinity}}}]

Out[1]= {{-50, -4}, {4, Infinity}}

2
Wow ... Tôi chỉ đưa ra giải pháp chính xác mà không cần đọc nó. +1
LegionMammal978 7/12/2015

Phải yêu tự động kết hợp của Mathicala Interval.
mbomb007

3

Haskell, 145 byte

import Data.List
q(a,b)=[a,a+0.5..b]
p@(a,b)%(h:t)|h==b+0.5=(a,h)%t|1<2=p:(h,h)%t
p%_=[p]
a#b|h:t<-nub$sort$intersect(q=<<a)$q=<<b=(h,h)%t|1<2=[]

Ví dụ sử dụng: [(-2.0,0.0),(2.0,4.0),(5.0,6.0),(6.0,8.0)] # [(-1.0,1.0),(3.0,5.0),(5.0,9.0)]-> [(-1.0,0.0),(3.0,4.0),(5.0,8.0)].

Làm thế nào nó hoạt động:

                 q=<<a            -- turn each pair in the 1st input list into
                                  -- lists with halves in between (e.g. (1,4) ->
                                  -- [1,1.5,2,2.5,3,3.5,4]) and concatenate them
                                  -- to a single list
                      q=<<b       -- same for the second input list
    nub$sort$intersect            -- sort the intersection of those lists
                                  -- and remove duplicates
h:t<-                             -- call the first element h and the rest t
                       (h,h)%t    -- start rebuilding the intervals
                          |1<2=[] -- if there's no first element h, one of the
                                  -- input lists is empty, so the output is also
                                  -- empty


p@(a,b)%(h:t)                     -- an interval p = (a,b), build from a list (h:t)
             =(a,h)%t             -- becomes (a,h)
      |h==b+1                     --   if h equals b+0.5
                    p:(h,h)%t     -- or is put in the output list, followed by
                                  --       a new interval starting with (h,h)
      |1<2                        --   otherwise
p%_=[p]                           -- base case of the interval rebuilding function 

Tôi đặt "một nửa" -values x.5trong danh sách, bởi vì tôi cần phải phân biệt (1,2),(3,4)từ (1,4). Không có x.5, cả hai sẽ trở thành [1,2,3,4], nhưng với x.5cái thứ nhất trở thành [1,1.5,2,3,3.5,4](cái còn thiếu 2.5) và cái thứ hai [1,1.5,2,2.5,3,3.5,4].


Đầu ra phải giống hệt với đầu vào. ... vì vậy chỉ cần nói rằng đầu vào của bạn cần .0 sau mỗi số nguyên cũng được;)
quintopia 9/12/2015

@quintopia: vâng, cảm ơn.
nimi

2

Ruby, 90 byte

Ánh xạ mỗi bộ trong hai bộ thành một mảng phẳng, lấy giao điểm tập hợp của các mảng đó, sau đó cắt kết quả thành các khối liên tục và ánh xạ từng đoạn thành phần tử đầu tiên và cuối cùng. Dễ như ăn bánh.

->s{a,b=s.map{|y|y.flat_map{|f,l|[*f..l]}.sort}
(a&b).slice_when{|a,b|b-a>1}.map &:minmax}

Sử dụng:

f=->s{a,b=s.map{|y|y.flat_map{|f,l|[*f..l]}.sort}
(a&b).slice_when{|a,b|b-a>1}.map &:minmax}

s = [[[-90,-4],[4,90]], [[-50,50]]]
p f[s] # => [[-50, -4], [4, 50]]

s = [[[-2,0],[2,4],[6,8]], [[-1,1],[3,5],[5,9]]]
p f[s] # => [[-1, 0], [3, 4], [6, 8]]

s = [[[-9,-8],[-8,0],[-7,-6],[-5,-4]],[[-7,-5],[-1,0],[-8,-1]]]
p f[s] # => [[-8, 0]]

Chương trình của bạn đầu ra để làm s = [[[1,2],[3,4]], [[1,2],[3,4]]]gì? (Phiên bản ruby ​​của tôi không có slice_when, vì vậy tôi không thể tự kiểm tra)
nimi

@mimi nó cho [[1, 4]]. Các slice_whenphương pháp đã được bổ sung ở đâu đó xung quanh của Ruby 2.2 Tôi nghĩ.
daniero

... nhưng nó phải là [[1,2], [3,4]]
nimi

Các tập hợp trên các số thực, chỉ có các ranh giới khoảng là số nguyên, vì vậy 2.2không phải trong đầu vào s = [[[1,2],[3,4]], [[1,2],[3,4]]], mà là trong đầu ra của bạn [[1, 4]].
nimi

Hmm, bạn nói đúng. Điều đó có thể đã được làm rõ / nhấn mạnh một chút cho những thách thức toán học như bản thân tôi ..
daniero
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.