Berechnen Sie die Obermenge

18

Ihre Aufgabe hier ist einfach:

Suchen Sie anhand einer Liste von Ganzzahlensätzen die Mengenvereinigung. Mit anderen Worten, finden Sie die kürzeste Liste von Ganzzahlensätzen, die alle Elemente in der ursprünglichen Liste von Sätzen enthalten (aber keine anderen Elemente). Beispielsweise:

[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

Mengen werden unter Verwendung der Bereichsnotation notiert: [1,4]bedeutet die ganzen Zahlen 1,2,3,4. Mengen können auch unbegrenzt sein: [3,]bedeutet alle ganzen Zahlen >= 3und [,-1]bedeutet alle ganzen Zahlen <= -1. Es ist garantiert, dass das erste Element des Bereichs nicht größer als das zweite ist.

Sie können festlegen, dass Mengen in Zeichenfolgennotation verwendet werden sollen, oder Sie können Tupel mit zwei Elementen verwenden, wobei als "unendlicher" Wert eine nicht ganzzahlige Konstante verwendet wird. Sie können zwei unterschiedliche Konstanten verwenden, um die unendliche Obergrenze und die unendliche Untergrenze darzustellen. In Javascript können Sie beispielsweise [3,{}]alle Ganzzahlen notieren >= 3, sofern Sie diese {}in allen Testfällen konsistent verwendet haben.

Testfälle:

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

Das ist , also machen Sie Ihre Antwort so kurz wie möglich!

Nathan Merrill
quelle
Related
Nathan Merrill
1
Kann ich Infinitystattdessen verwenden {}?
Luis Felipe De Jesus Munoz
Können wir zB Eingaben als Float-Werte [1.0, 3.0]statt nehmen [1, 3]?
AdmBorkBork
Solange Sie sie als ganze Zahlen behandeln, ja. Mit anderen Worten [1.0, 3.0], [4.0, 5.0]sollte noch werden[1.0, 5.0]
Nathan Merrill
Wenn Ihre Sprache nicht Infinityund -Infinityals Eingabe akzeptieren kann, darf sie stattdessen -999999und 999999(oder sogar größer / kleiner)?
Kevin Cruijssen

Antworten:

7

R + intervals, 90 87 81 Bytes

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

Probieren Sie es online!

Die Eingabe ist eine Liste von Intervallen. -Infund Infsind R eingebaut für minus / plus unendlich. Die Ausgabe ist eine Matrix von Intervallspalten.

Normalerweise kein Fan von Nicht-Standard-Bibliotheken, aber dieses hat Spaß gemacht. TIO ist nicht intervalsinstalliert. Sie können es auf Ihrer eigenen Installation oder unter https://rdrr.io/snippets/ ausprobieren.

Das intervalsPaket unterstützt Real- und Integer ( type = "Z") -Intervalle und die reduceFunktion ist für die jeweiligen Anforderungen integriert, die Ausgabe scheint jedoch standardmäßig Intervalle zu öffnen. Sie wird also benötigt, um das gewünschte Ergebnis zu erzielen.close_intervals +c(1,-1)

Die alte Version enthielt Beispiele in einer Liste von Listen, die nützlich sein könnten. Ich habe den Link hier gelassen.

ngm
quelle
Ich denke , man kann ein paar Bytes speichern: function(...)close_intervals(reduce(Intervals(rbind(...),type="Z"))). Oder noch besser, Sie können mit op prüfen, ob sie eine Matrix als Eingabe zulassen.
JayCe
1
Ich lag letzte Nacht buchstäblich wach im Bett und dachte: "Es muss einen besseren Weg gegeben haben, aus den Eingabevektoren eine Matrix zu machen." Ich denke, die Herausforderung ist es, den Input so zu belassen, wie er ist. Aber es hat Spaß gemacht, reduceund Reducedort zu haben .
ngm
Ich liebe das "Double Reduce" -Ding! Golfy einfach nicht genug;) Was die offenen Intervalle wie folgt ändern: f=function(...)t(reduce(Intervals(rbind(...),type="Z")))+c(1,-1)?
JayCe
6

JavaScript (ES6), 103 Byte

1 Byte dank @Shaggy
gespeichert 1 Byte dank @KevinCruijssen gespeichert

Erwartet +/-Infinityunendliche Werte.

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)

Probieren Sie es online!

Wie?

Wir sortieren zuerst die Intervalle nach ihrer Untergrenze, von der niedrigsten zur höchsten. Obergrenzen werden ignoriert.

[pn,qn]mMp1q1

[pn,qn]

  • pnM+1Mmax(M,qn)
  • [m,M]mMpnqn

[m,M]

Kommentiert

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
Arnauld
quelle
p<=M+1kann sein p<M+2?
Kevin Cruijssen
@ KevinCruijssen Ich habe das komplett verpasst ... Danke!
Arnauld
4

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

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

Dank Mr.Xcoder ein Byte gespart, dank Jonathan Frech ein Byte und dank Dead Possum drei Byte.
Probieren Sie es online!


quelle
(b,c),Speichert ein Byte.
Mr. Xcoder
Huh, dachte, ich hätte das schon versucht.
Bedeutet das nicht, gdass Ihre Funktion fnicht wiederverwendbar und daher ungültig ist?
Neil
@ Neil Wahrscheinlich, aber das war nur ein Überbleibsel von einem früheren Versuch.
1
Sie können das returnwird auchprint für ein anderes Byte ausführen.
Jonathan Frech
2

Ruby , 89 76 Bytes

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

Probieren Sie es online!

Sortieren Sie das Array und glätten Sie es, indem Sie alle Bereiche an den ersten anhängen: Wenn sich ein Bereich mit dem vorherigen überschneidet, verwerfen Sie 2 der letzten 3 Elemente (wobei Sie nur das Maximum beibehalten).

Machen Sie am Ende alles glatt.

GB
quelle
1

Pascal (FPC) , 367 362 357 Bytes

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;

Probieren Sie es online!

Eine Prozedur, die ein dynamisches Array benötigt von Datensätzen verwendet, das aus zwei Bereichsgrenzen besteht, das Array an der richtigen Stelle ändert und es dann in die Standardausgabe schreibt, einen Bereich pro Zeile. (Entschuldigen Sie diesen verdrehten Satz.) Verwendet 1/0für unbegrenzt und -1/0unbegrenzt.

Lesbare Version

Es wäre schön, nur das Array zurück mit korrigierten Anzahl von Elementen, aber die dynamische Array - Funktion übergeben / Prozedur ist nicht dynamisch Array mehr ... Zuerst fand ich diese , dann gibt es diese hervorragende, irrsinnig Erklärung .

Dies ist die beste Datenstruktur, die ich zum Kürzen des Codes finden konnte. Wenn Sie bessere Möglichkeiten haben, können Sie uns gerne einen Vorschlag unterbreiten.

AlexRacer
quelle
1

Wolfram Language (Mathematica) , 57 Byte

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

Probieren Sie es online!

Nimmt die Eingabe als eine Liste von Listen {a,b}das Intervall darstellt [a,b], in dem asein kann , -Infinityund bsein kann Infinity.

Verwendet die eingebaute IntervalUnion, aber natürlich müssen wir zuerst die Intervalle in Form massieren. Um vorzutäuschen, dass die Intervalle ganze Zahlen sind, addieren wir 1 zur oberen Grenze (stellen Sie sicher, dass die Vereinigung von [1,3]und [4,9]ist [1,9]). Am Ende machen wir diese Operation rückgängig und wandeln das Ergebnis wieder in eine Liste von Listen um.

Es gibt auch einen ganz anderen Ansatz, der mit 73 Bytes einrastet :

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

Hier ersetzen wir nach dem Sortieren der Intervalle einfach zwei aufeinanderfolgende Intervalle durch ihre Vereinigung, wann immer dies ein einzelnes Intervall wäre, und wiederholen dies, bis keine solche Operation mehr auszuführen ist.

Mischa Lawrow
quelle
1

05AB1E (Legacy) , 88 79 78 Byte

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

Unendlich wird als Kleinbuchstabe ( 'abcdefghijklmnopqrstuvwxyz') eingegeben .

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Wichtiger Hinweis: Wenn es ein tatsächliches Infinityund gegeben hätte -Infinity, wären es stattdessen 43 bis 42 Bytes gewesen . So etwas über 50% um 30% ist als Abhilfe für den Mangel an Infinity..

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

Probieren Sie es online aus (mit Infinityersetzt durch 9999999999und -Infinityersetzt durch -9999999999).

Kann definitiv erheblich golfen werden. Am Ende war es sehr, sehr hässlich und voller Workarounds. Aber jetzt bin ich nur froh, dass es funktioniert.

Erläuterung:

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]]
Kevin Cruijssen
quelle
1

C (clang) , 346 342 Bytes

Compiler - Flags -DP=printf("(%d,%d)\n", -DB=a[i+1]und-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);}

Probieren Sie es online!

Logern
quelle
Ich denke, Sie verlassen sich auf iden globalen Wert von.
Jonathan Frech
Was @ JonathanFrech bedeutet, while(A)i++;sollte for(i=0;A;)i++;explizit gesetzt werdeni=0 bevor es in der while-Schleife verwendet wird, anstatt seinen Standardwert 0auf globaler Ebene zu verwenden. Ich weiß nicht mehr warum, aber es ist gemäß den Metaregeln erforderlich. Hauptsächlich, weil Methoden in sich geschlossen / wiederverwendbar sein sollten, ohne dass globale Werte zwischen Methodenaufrufen zurückgesetzt werden müssen, IIRC.
Kevin Cruijssen
Feste Abhängigkeit vom globalen iWert
Logern
1
@KevinCruijssen Siehe Müssen Funktionsübermittlungen wiederverwendbar sein? .
Jonathan Frech
246 Bytes
Ceilingcat