Üst kümesi hesapla


18

Buradaki göreviniz basittir:

Bir tamsayı kümesinin bir listesi göz önüne alındığında küme birliğini bulun. Başka bir deyişle, orijinal kümeler listesindeki tüm öğeleri içeren (ancak diğer öğeleri içermeyen) tam sayı kümelerinin listesini bulun. Örneğin:

[1,5] and [3,9] becomes [1,9] as it contains all of the elements in both [1,5] and [3,9]
[1,3] and [5,9] stays as [1,3] and [5,9], because you don't want to include 4

Setler aralık notasyonu kullanılarak notlandırılır: [1,4]tamsayılar anlamına gelir 1,2,3,4. Kümeler sınırsız da olabilir: [3,]tüm tam sayılar >= 3ve [,-1]tüm tam sayılar anlamına gelir <= -1. Aralığın ilk elemanının ikinciden daha büyük olmayacağı garanti edilir.

Dizi gösteriminde set almayı seçebilir veya "sonsuz" değer olarak sabit tamsayı olmayan bir sabit kullanarak 2-eleman tuples kullanabilirsiniz. Sonsuz üst sınır ve sonsuz alt sınır temsil etmek için iki farklı sabit kullanabilirsiniz. Örneğin, Javascript'te, tüm sınama durumlarında tutarlı bir şekilde kullandığınız sürece [3,{}]tüm tamsayıları not etmek için kullanabilirsiniz .>= 3{}

Test durumları:

[1,3]                     => [1,3]
[1,]                      => [1,]
[,9]                      => [,9]
[,]                       => [,]
[1,3],[4,9]               => [1,9]
[1,5],[8,9]               => [1,5],[8,9]
[1,5],[1,5]               => [1,5]
[1,5],[3,7]               => [1,7]
[-10,7],[1,5]             => [-10,7]
[1,1],[2,2],[3,3]         => [1,3]
[3,7],[1,5]               => [1,7]
[1,4],[8,]                => [1,4],[8,]
[1,4],[-1,]               => [-1,]
[1,4],[,5]                => [,5]
[1,4],[,-10]              => [1,4],[,-10]
[1,4],[,]                 => [,]
[1,4],[3,7],[8,9],[11,20] => [1,9],[11,20]

Bu , bu yüzden cevabınızı mümkün olduğunca kısa olun!



1
Onun Infinityyerine kullanabilir miyim {}?
Luis felipe De jesus Munoz

Biz mesela şamandıra değerler olarak girdi alabilir [1.0, 3.0]yerine [1, 3]?
AdmBorkBork

Onlara tamsayı olarak davrandığın sürece, evet. Başka bir deyişle [1.0, 3.0], [4.0, 5.0], yine de olmalı[1.0, 5.0]
Nathan Merrill

Diliniz alınamıyorsa Infinityve -Infinitygirdi olarak alıyorsa , yerine -999999ve 999999(veya daha büyük / küçük) yerine izin verilir mi?
Kevin Cruijssen

Yanıtlar:


7

R + intervals, 90 87 81 bayt

function(...)t(reduce(Intervals(rbind(...),type="Z")))+c(1,-1)
library(intervals)

Çevrimiçi deneyin!

Giriş, aralıkların bir listesidir. -Infve Infeksi / artı sonsuzluk için R yerleşikleridir. Çıktı, aralıklı sütunların matrisidir.

Genellikle standart olmayan kütüphaneleri kullanmanın hayranı değil, bu eğlenceliydi. TIO intervalskurulmamış. Kendi kurulumunuzda veya https://rdrr.io/snippets/ adresinden deneyebilirsiniz.

intervalsPaket destekler gerçek ve tamsayı ( type = "Z") aralıkları ve reducefonksiyonudur yerleşik bir meydan okuma ister ama çıkış öylesine açık aralıklarla varsayılan olarak görünüyor ne için istenilen sonucu elde etmek için gereklidir.close_intervals +c(1,-1)

Eski sürümde, uygun olabilecek listelerde örnekler vardı, bu yüzden bağlantıyı burada bıraktım.


Ben bir kaç bayt kaydedebilirsiniz düşünüyorum: function(...)close_intervals(reduce(Intervals(rbind(...),type="Z"))). Ya da daha iyisi op olarak giriş olarak bir matrise izin verip vermediklerini kontrol edebilirsiniz.
JayCe 28:18

1
Kelimenin tam anlamıyla, dün gece "girdi vektörlerinden bir matris yapmak için daha iyi bir yol olmalı olmalı" diyerek uyanık yatıyordum. Sanırım zorluğu girdiyi olduğu gibi bırakmak daha iyi. Ama orada olması reduceve eğlenceliydi Reduce.
NGM

"Çift azaltma" olayını seviyorum! yeterli golfy değil;) Bunun gibi açık aralıkları değiştirmeyle ilgili: f=function(...)t(reduce(Intervals(rbind(...),type="Z")))+c(1,-1)?
JayCe 28:18

6

JavaScript (ES6), 103 bayt

@Shaggy sayesinde 1 bayt kaydedildi @KevinCruijssen
sayesinde 1 bayt kaydedildi

+/-InfinitySonsuz değerler bekler .

a=>(a.sort(([p],[P])=>p-P).map(m=M=([p,q])=>p<M+2?M=q>M?q:M:(b.push([m,M]),m=p,M=q),b=[]),b[0]=[m,M],b)

Çevrimiçi deneyin!

Nasıl?

İlk önce aralıkları en alttan en yükseğe doğru alt sınırlarına göre sıralarız. Üst sınırlar göz ardı edilir.

Daha sonra yineleme sıralanmış aralıkları boyunca [pn,qn] , mevcut alt ve üst sınırları takip ederken, m ve M , başlatıldı p1 ve q1 , sırasıyla.

Her aralık için [pn,qn] :

  • Eğer pnM+1 : Bu aralık öncekilerin ile birleştirilebilir. Güncellemesini böylece Ancak, üst sınırı yeni olabilir M için max(M,qn) .
  • Aksi takdirde: önceki aralıklar ile bunun arasında bir boşluk vardır. Yeni bir aralığı oluşturmak [m,M] ve güncelleme m ve M için pn ve qn , sırasıyla.

İşlemin sonunda, mevcut sınırlarla [m,M] son bir aralık yaratırız .

Yorumlananlar

a => (                  // a[] = input array
  a.sort(([p], [P]) =>  // sort the intervals by their lower bound; we do not care about
    p - P)              // the upper bounds for now
  .map(m = M =          // initialize m and M to non-numeric values
    ([p, q]) =>         // for each interval [p, q] in a[]:
    p < M + 2 ?         //   if M is a number and p is less than or equal to M + 1:
      M = q > M ? q : M //     update the maximum M to max(M, q)
    : (                 //   else (we've found a gap, or this is the 1st iteration):
      b.push([m, M]),   //     push the interval [m, M] in b[]
      m = p,            //     update the minimum m to p
      M = q             //     update the maximum M to q
    ),                  //
    b = []              //   start with b[] = empty array
  ),                    // end of map()
  b[0] = [m, M], b      // overwrite the 1st entry of b[] with the last interval [m, M]
)                       // and return the final result

p<=M+1olabilir p<M+2mi?
Kevin Cruijssen

@KevinCruijssen Bunu tamamen özledim ... Teşekkürler!
Arnauld,

4

Python 2 , 118 113 112 111 106 105 104 101 bayt

x=input()
x.sort();a=[];b,c=x[0]
for l,r in x:
 if l>c+1:a+=(b,c),;b,c=l,r
 c=max(c,r)
print[(b,c)]+a

Mr.Xcoder, bir tanesi Jonathan Frech ve bir tanesi Dead Possum sayesinde bir bayt kurtardı.
Çevrimiçi deneyin!


(b,c),bir bayt kaydeder.
Bay Xcoder

Huh, bunu çoktan denedim sandım.

Does not gsenin işlevi anlamına fdeğil yeniden ve bu nedenle geçersiz?
Neil

@Neil Muhtemelen, ama bu daha önceki bir girişimin sadece bir sahibiydi.

1
Başka bir bayt için returnolurprint da yapabilirsiniz .
Jonathan Frech

2

Ruby , 89 76 bayt

->a{[*a.sort.reduce{|s,y|s+=y;y[0]-s[-3]<2&&s[-3,3]=s.max;s}.each_slice(2)]}

Çevrimiçi deneyin!

Diziyi sıralayın, ardından tüm aralıkları birinciye ekleyerek düzleştirin: bir aralık bir öncekiyle çakışırsa, son 3 öğeden 2 öğeyi atın (yalnızca maks.

Sonunda her şeyi çözdü.


1

Pascal (FPC) , 367 362 357 bayt

uses math;type r=record a,b:real end;procedure d(a:array of r);var i,j:word;t:r;begin for i:=0to length(a)-1do for j:=0to i do if a[i].a<a[j].a then begin t:=a[i];a[i]:=a[j];a[j]:=t;end;j:=0;for i:=1to length(a)-1do if a[j].b>=a[i].a-1then begin a[j].a:=min(a[i].a,a[j].a);a[j].b:=max(a[i].b,a[j].b)end else j:=j+1;for i:=0to j do writeln(a[i].a,a[i].b)end;

Çevrimiçi deneyin!

2 aralık sınırından oluşan dinamik bir kayıt dizisini alan, diziyi değiştiren ve ardından satır başına bir aralık olan standart çıktıya yazan bir prosedür . (Bu çarpık cümle için özür dilerim.) 1/0Sessiz ve -1/0sınırlandırılmamış kullanımlar için kullanır .

Okunabilir sürüm

Sadece elemanların düzeltilmiş sayı ile dizi dönmek güzel olurdu, fakat işlev / prosedüre geçirilen dinamik dizisi artık dinamik dizi değil ... İlk buldum bu , o zaman bu var mükemmel, akıl almaz açıklama .

Bu, kodu kısaltmak için bulabileceğim en iyi veri yapısı. Daha iyi seçenekleriniz varsa, bir öneride bulunmaktan çekinmeyin.


1

Wolfram Dili (Mathematica) , 57 bayt

List@@(#-{0,1}&/@IntervalUnion@@(Interval[#+{0,1}]&/@#))&

Çevrimiçi deneyin!

Girdiyi , nerede olabileceği ve olabileceği {a,b}aralığı temsil eden listelerin listesi olarak alır .[a,b]a-InfinitybInfinity

Yerleşik kullanır IntervalUnion, ancak tabii ki önce aralıklara masaj yapmalıyız. Aralıkları tamsayı olduğunu iddia etmek için, biz üst bağlı 1 eklenir (birliği emin olarak [1,3]ve [4,9]olduğu [1,9]). Sonunda, bu işlemi geri alıyoruz ve sonucu tekrar bir liste listesine çeviriyoruz.

Saatler de tamamen farklı bir yaklaşım da var 73 bayt :

NumericalSort@#//.{x___,{a_,b_},{c_,d_},y___}/;b+1>=c:>{x,{a,b~Max~d},y}&

Burada, aralıkları sıraladıktan sonra, ardışık olarak iki ardışık aralığın yerini değiştiriyoruz, ne zaman tek bir aralık olacaksa ve böyle bir işlem yapılıncaya kadar tekrar edin.


1

05AB1E (eski) , 88 79 78 bayt

g≠i˜AKïDW<UZ>VIøεAXY‚Nè:}ïø{©˜¦2ôíÆ1›.œʒíεćsO_*}P}н€g®£εø©θàDYQiA}V®нßDXQiA}Y‚

Sonsuzluk küçük harf alfabe ( 'abcdefghijklmnopqrstuvwxyz') olarak girilir .

Çevrimiçi deneyin veya tüm test durumlarını doğrulayın .

Önemli not: orada gerçek olsaydı Infinityve -Infinitybu olurdu 43 42 bayt yerine. Yani % 30'dan% 30'dan fazlası, % 30'dan az olması için çalışma ortamıdır Infinity.

{©Dg≠i˜¦2ôíÆ1›.œʒíεćsO_*}P}н€g®£εø©θàV®нßY‚

Çevrimiçi olarak deneyin (ile Infinitydeğiştirildi 9999999999ve -Infinitydeğiştirildi -9999999999).

Kesinlikle büyük ölçüde golf olabilir. Sonunda çok çirkin geçici çözümlerle dolu çıktı. Ama şimdilik işe yarayacağına sevindim.

Açıklama:

Dgi          # If the length of the implicit input is NOT 1:
              #   i.e. [[1,3]] → length 1 → 0 (falsey)
              #   i.e. [[1,4],["a..z",-5],[3,7],[38,40],[8,9],[11,20],[25,"a..z"],[15,23]]
              #    → length 8 → 1 (truthy)
    ˜         #  Take the input implicit again, and flatten it
              #   i.e. [[1,4],["a..z",-5],[3,7],[38,40],[8,9],[11,20],[25,"a..z"],[15,23]]
              #    → [1,4,"a..z",-5,3,7,38,40,8,9,11,20,25,"a..z",15,23]
     AK       #  Remove the alphabet
              #   i.e. [1,4,"a..z",-5,3,7,38,40,8,9,11,20,25,"a..z",15,23]
              #    → ['1','4','-5','3','7','38','40','8','9','11','20','25','15','23']
       ï      #  Cast everything to an integer, because `K` turns them into strings..
              #   i.e. ['1','4','-5','3','7','38','40','8','9','11','20','25','15','23']
              #    → [1,4,-5,3,7,38,40,8,9,11,20,25,15,23]
        D     #  Duplicate it
         W<   #  Determine the min - 1
              #   i.e. [1,4,-5,3,7,38,40,8,9,11,20,25,15,23] → -5
           U  #  Pop and store it in variable `X`
         Z>   #  Determine the max + 1
              #   i.e. [1,4,-5,3,7,38,40,8,9,11,20,25,15,23] → 40
           V  #  Pop and store it in variable `Y`
Iø            #  Take the input again, and transpose/zip it (swapping rows and columns)
              #   i.e. [[1,4],["a..z",-5],[3,7],[38,40],[8,9],[11,20],[25,"a..z"],[15,23]]
              #    → [[1,'a..z',3,38,8,11,25,15],[4,-5,7,40,9,20,'a..z',23]]
  ε       }   #  Map both to:
   A          #   Push the lowercase alphabet
    XY       #   Push variables `X` and `Y`, and pair them into a list
       Nè     #   Index into this list, based on the index of the mapping
         :    #   Replace every alphabet with this min-1 or max+1
              #   i.e. [[1,'a..z',3,38,8,11,25,15],[4,-5,7,40,9,20,'a..z',23]]
              #    → [['1','-6','3','38','8','11','25','15'],['4','-5','7','40','9','20','41','23']]
ï             #  Cast everything to integers again, because `:` turns them into strings..
              #   i.e. [['1','-6','3','38','8','11','25','15'],['4','-5','7','40','9','20','41','23']]
              #    → [[1,-6,3,38,8,11,25,15],[4,-5,7,40,9,20,41,23]]
 ø            #  Now zip/transpose back again
              #   i.e. [[1,-6,3,38,8,11,25,15],[4,-5,7,40,9,20,41,23]]
              #    → [[1,4],[-6,-5],[3,7],[38,40],[8,9],[11,20],[25,41],[15,23]]
  {           #  Sort the pairs based on their lower range (the first number)
              #   i.e. [[1,4],[-6,-5],[3,7],[38,40],[8,9],[11,20],[25,41],[15,23]]
              #    → [[-6,-5],[1,4],[3,7],[8,9],[11,20],[15,23],[25,41],[38,40]]
   ©          #  Store it in the register (without popping)
˜             #  Flatten the list
              #   i.e. [[-6,-5],[1,4],[3,7],[8,9],[11,20],[15,23],[25,41],[38,40]]
              #    → [-6,-5,1,4,3,7,8,9,11,20,15,23,25,41,38,40]
 ¦            #  And remove the first item
              #   i.e. [-6,-5,1,4,3,7,8,9,11,20,15,23,25,41,38,40]
              #    → [-5,1,4,3,7,8,9,11,20,15,23,25,41,38,40]
  2ô          #  Then pair every two elements together
              #   i.e. [-5,1,4,3,7,8,9,11,20,15,23,25,41,38,40]
              #    → [[-5,1],[4,3],[7,8],[9,11],[20,15],[23,25],[41,38],[40]]
    í         #  Reverse each pair
              #   i.e. [[-5,1],[4,3],[7,8],[9,11],[20,15],[23,25],[41,38],[40]]
              #    → [[1,-5],[3,4],[8,7],[11,9],[15,20],[25,23],[38,41],[40]]
     Æ        #  Take the difference of each pair (by subtracting)
              #   i.e. [[1,-5],[3,4],[8,7],[11,9],[15,20],[25,23],[38,41],[40]]
              #    → [6,-1,1,2,-5,2,-3,40]
      1      #  Determine for each if they're larger than 1
              #   i.e. [6,-1,1,2,-5,2,-3,40] → [1,0,0,1,0,1,0,1]
            #  Create every possible partition of these values
              #   i.e. [1,0,0,1,0,1,0,1] → [[[1],[0],[0],[1],[0],[1],[0],[1]],
              #                             [[1],[0],[0],[1],[0],[1],[0,1]],
              #                             ...,
              #                             [[1,0,0,1,0,1,0],[1]],
              #                             [[1,0,0,1,0,1,0,1]]]
  ʒ         } #  Filter the partitions by:
   í          #   Reverse each inner partition
              #    i.e. [[1],[0,0,1],[0,1],[0,1]] → [[1],[1,0,0],[1,0],[1,0]]
    ε     }   #   Map each partition to:
     ć        #    Head extracted
              #     i.e. [1,0,0] → [0,0] and 1
              #     i.e. [1] → [] and 1
              #     i.e. [1,0,1] → [1,0] and 1
      s       #    Swap so the rest of the list is at the top of the stack again
       O      #    Take its sum
              #     i.e. [0,0] → 0
              #     i.e. [] → 0
              #     i.e. [1,0] → 1
        _     #    And check if it's exactly 0
              #     i.e. 0 → 1 (truthy)
              #     i.e. 1 → 0 (falsey)
         *    #    And multiply it with the extracted head
              #    (is only 1 when the partition has a single trailing 1 and everything else a 0)
              #     i.e. 1 and 1 → 1 (truthy)
              #     i.e. 1 and 0 → 0 (falsey)
           P  #   And check if all mapped partitions are 1
н             #  Take the head (there should only be one valid partition left)
              #   i.e. [[[1],[0,0,1],[0,1],[0,1]]] → [[1],[0,0,1],[0,1],[0,1]]
 g           #  Take the length of each inner list
              #   i.e. [[1],[0,0,1],[0,1],[0,1]] → [1,3,2,2]
   ®          #  Push the sorted pairs we've saved in the register earlier
    £         #  Split the pairs into sizes equal to the partition-lengths
              #   i.e. [1,3,2,2] and [[-6,-5],[1,4],[3,7],[8,9],[11,20],[15,23],[25,41],[38,40]]
              #    → [[[-6,-5]],[[1,4],[3,7],[8,9]],[[11,20],[15,23]],[[25,41],[38,40]]]
ε             #  Map each list of pairs to:
 ø            #   Zip/transpose (swapping rows and columns)
              #    i.e. [[1,4],[3,7],[8,9]] → [[1,3,8],[4,7,9]]
              #    i.e. [[25,41],[38,40]] → [[25,38],[41,40]]
  ©           #   Store it in the register
   θ          #   Take the last list (the ending ranges)
              #    i.e. [[25,38],[41,40]] → [41,40]
    à         #   And determine the max
              #    i.e. [41,40] → 41
     DYQi }   #   If this max is equal to variable `Y`
              #     i.e. 41 (`Y` = 41) → 1 (truthy)
         A    #    Replace it back to the lowercase alphabet
           V  #   Store this max in variable `Y`
  ®           #   Take the zipped list from the register again
   н          #   This time take the first list (the starting ranges)
              #    i.e. [[25,38],[41,40]] → [25,38]
    ß         #   And determine the min
              #    i.e. [25,38] → 25
     DXQi }   #   If this min is equal to variable `X`
              #     i.e. 25 (`X` = -6) → 0 (falsey)
         A    #    Replace it back to the lowercase alphabet
           Y #   And pair it up with variable `Y` (the max) to complete the mapping
              #    i.e. 25 and 'a..z' → [25,'a..z']
              #  Implicitly close the mapping (and output the result)
              #   i.e. [[[-6,-5]],[[1,4],[3,7],[8,9]],[[11,20],[15,23]],[[25,41],[38,40]]]
              #    → [['a..z',-5],[1,9],[11,23],[25,'a..z']]
              # Implicit else (only one pair in the input):
              #  Output the (implicit) input as is
              #   i.e. [[1,3]]

1

C (clang) , 346 342 bayt

Derleyici bayrakları -DP=printf("(%d,%d)\n", -DB=a[i+1]ve-DA=a[i]

typedef struct{int a,b;}t;s(t**x,t**y){if((*x)->a>(*y)->a)return 1;else if((*x)->a<(*y)->a)return -1;}i;f(t**a){for(i=0;A;)i++;qsort(a,i,sizeof(t*),s);for(i=0;B;i++){if(B->a<=A->b+1){A->b=B->b;if(B->a<A->a)A->a=B->a;else B->a=A->a;}}for(i=0;A;i++){if(!B)break;if(A->a!=B->a)P,A->a,A->b);}P,A->a,A->b);}

Çevrimiçi deneyin!


Bence iküresel değere güveniyorsun .
Jonathan Frech

@JonathanFrech'in anlamı, küresel düzeyde varsayılan değerini kullanmak yerine, bunu while döngüsünde kullanmadan önce açıkça ayarlanması while(A)i++;gerektiğidir . Artık neden olduğundan emin değilim, ancak meta kurallarına göre gereklidir. Temel olarak, yöntemlerin çağrıları arasında IIRC genel değerleri sıfırlamak zorunda kalmadan, kendi kendine yeten / yeniden kullanılabilir olması gerektiği için. for(i=0;A;)i++;i=00
Kevin Cruijssen 28:18

Küresel ideğere
bağlılık



Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.