Calcola il superset


18

Il tuo compito qui è semplice:

Dato un elenco di set di numeri interi, trova l'unione set. In altre parole, trova l'elenco più breve di set di numeri interi che contengono tutti gli elementi nell'elenco originale di set (ma non altri elementi). Per esempio:

[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

Gli insiemi vengono notati utilizzando la notazione dell'intervallo: [1,4]indica gli interi 1,2,3,4. Gli insiemi possono anche essere illimitati: [3,]significa tutti gli interi >= 3e [,-1]tutti gli interi <= -1. È garantito che il primo elemento dell'intervallo non sarà maggiore del secondo.

Puoi scegliere di prendere insiemi in notazione di stringa, oppure puoi usare tuple a 2 elementi, usando un costante non intero come valore "infinito". È possibile utilizzare due costanti distinte per rappresentare il limite superiore infinito e il limite inferiore infinito. Ad esempio, in Javascript, è possibile utilizzare [3,{}]per annotare tutti i numeri interi >= 3, purché si utilizzi {}in modo coerente in tutti i casi di test.

Casi test:

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

Questo è , quindi fai la tua risposta il più breve possibile!



1
Posso usare Infinityinvece {}?
Luis felipe De jesus Munoz,

Possiamo prendere input come valori float, ad es. [1.0, 3.0]Anziché [1, 3]?
AdmBorkBork,

Finché li tratti come numeri interi, sì. In altre parole [1.0, 3.0], [4.0, 5.0]dovrebbe ancora diventare[1.0, 5.0]
Nathan Merrill il

Se il linguaggio non può prendere Infinitye -Infinitycome input, è permesso di prendere -999999e 999999(o anche più grandi / piccoli), invece?
Kevin Cruijssen,

Risposte:


7

R + intervals, 90 87 81 byte

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

Provalo online!

L'input è un elenco di intervalli. -Infe Infsono R integrati per meno / più infinito. L'output è una matrice di colonne di intervalli.

Di solito non è un fan dell'utilizzo di librerie non standard ma questa è stata divertente. TIO non è intervalsinstallato. Puoi provarlo sulla tua installazione o su https://rdrr.io/snippets/

Il intervalspacchetto supporta type = "Z"intervalli reali e interi ( ) e la reducefunzione è integrata per ciò che la sfida vuole, ma l'output sembra predefinito per aprire gli intervalli, quindi è necessario per ottenere il risultato desiderato.close_intervals +c(1,-1)

La vecchia versione aveva degli esempi in un elenco di elenchi che potrebbero essere utili, quindi ho lasciato il link qui.


Penso che si possa salvare un paio di byte: function(...)close_intervals(reduce(Intervals(rbind(...),type="Z"))). O ancora meglio è possibile verificare con op se consentono una matrice come input.
JayCe,

1
Sono stato letteralmente a letto sveglio la scorsa notte pensando "doveva esserci stato un modo migliore per creare una matrice dai vettori di input". Penso che la sfida sia meglio lasciare l'input così com'è. Ma è stato divertente avere reducee Reducelì dentro.
ngm,

Adoro la cosa del "doppio riduci"! semplicemente non abbastanza golfy;) Che ne dici di modificare gli intervalli aperti in questo modo f=function(...)t(reduce(Intervals(rbind(...),type="Z")))+c(1,-1):?
JayCe,

6

JavaScript (ES6), 103 byte

Salvato 1 byte grazie a @Shaggy
Salvato 1 byte grazie a @KevinCruijssen

Si aspetta +/-Infinityvalori infiniti.

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)

Provalo online!

Come?

Prima ordiniamo gli intervalli in base al limite inferiore, dal più basso al più alto. I limiti superiori vengono ignorati.

Quindi ripetiamo gli intervalli ordinati [pn,qn] , tenendo traccia dei limiti inferiore e superiore attuali m e M , inizializzati rispettivamente su p1 e q1 .

Per ogni intervallo [pn,qn] :

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

[m,M]

Commentate

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+1può essere p<M+2?
Kevin Cruijssen,

@KevinCruijssen L'ho perso del tutto ... Grazie!
Arnauld,

4

Python 2 , 118 113 112 111 111 105 105 104 101 byte

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

Risparmio di un byte grazie a Mr.Xcoder, uno grazie a Jonathan Frech e tre grazie a Dead Possum.
Provalo online!


(b,c),salva un byte.
Mr. Xcoder,

Huh, pensavo di averlo già provato.

Non gsignifica che la tua funzione fnon è riutilizzabile e quindi non è valida?
Neil,

@Neil Probabilmente, ma quello era solo un ostacolo a un tentativo precedente.

1
Puoi anche fare il returndiventaprint per un altro byte.
Jonathan Frech,

2

Rubino , 89 76 byte

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

Provalo online!

Ordina l'array, quindi appiattisci aggiungendo tutti gli intervalli al primo: se un intervallo si sovrappone a quello precedente, scarta 2 elementi dagli ultimi 3 (mantenendo solo il massimo).

Tutto appiattito alla fine.


1

Pascal (FPC) , 367 362 357 byte

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;

Provalo online!

Una procedura che accetta una matrice dinamica di record costituita da 2 limiti di intervallo, modifica la matrice in atto e quindi la scrive sull'output standard, un intervallo per riga. ( 1/0Ci scusiamo per quella frase contorta.) Utilizza per ubounding up e -1/0per illimitato down.

Versione leggibile

Sarebbe bello tornare appena la matrice con il numero corretto di elementi, ma la matrice dinamica passato alla funzione / procedura non è array dinamico più ... In primo luogo ho trovato questo , allora c'è questo eccellente, da capogiro spiegazione .

Questa è la migliore struttura di dati che ho trovato per abbreviare il codice. Se hai opzioni migliori, sentiti libero di dare un suggerimento.


1

Wolfram Language (Mathematica) , 57 byte

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

Provalo online!

Prende l'input come un elenco di elenchi che {a,b}rappresentano l'intervallo [a,b], dove apuò essere -Infinitye bpuò essere Infinity.

Utilizza il built-in IntervalUnion, ma ovviamente dobbiamo prima massaggiare gli intervalli. Per far finta che gli intervalli siano numeri interi, aggiungiamo 1 al limite superiore (assicurandoci che l'unione di [1,3]e [4,9]sia [1,9]). Alla fine, annulliamo questa operazione e trasformiamo il risultato in un elenco di elenchi.

C'è anche un approccio completamente diverso, che arriva a 73 byte :

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

Qui, dopo aver ordinato gli intervalli, sostituiamo solo due intervalli consecutivi con la loro unione ogni volta che si tratterebbe di un singolo intervallo, e ripetiamo fino a quando non vi è più alcuna operazione da fare.


1

05AB1E (legacy) , 88 79 78 byte

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

L'infinito viene inserito come l'alfabeto minuscolo ( 'abcdefghijklmnopqrstuvwxyz').

Provalo online o verifica tutti i casi di test .

Nota importante: se ci fosse un reale Infinitye -Infinity, sarebbe invece 43 43 byte . Quindi poco più del 50% circa il 30% è una soluzione per la mancanza di Infinity..

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

Provalo online (con Infinitysostituito con 9999999999e -Infinitysostituito con -9999999999).

Può sicuramente essere giocato a golf in modo sostanziale. Alla fine si è rivelato molto, molto brutto pieno di soluzioni alternative. Ma per ora sono solo felice che funzioni.

Spiegazione:

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 byte

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

Provalo online!


Penso che tu faccia affidamento sul ivalore globale.
Jonathan Frech,

Quello che @JonathanFrech significa è che while(A)i++;dovrebbe essere for(i=0;A;)i++;impostato esplicitamente i=0prima di usarlo nel ciclo while, invece di usare il suo 0valore predefinito a livello globale. Non sono più sicuro del perché, ma è richiesto in base alle meta regole. Principalmente perché i metodi dovrebbero essere autonomi / riutilizzabili, senza dover ripristinare i valori globali tra le chiamate di metodo, IIRC.
Kevin Cruijssen,

Risolto il i
problema del



Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.