Recherche d'écarts dans les plages de dates

15

Étant donné une liste de plages de dates ren entrée, en sortie ou renvoyant toutes les plages non trouvées dans r.

Pour cet exemple, l'entrée sera au YYYY-MM-DDformat.

Disons que vous avez trois plages de dates:

[2019-01-01, 2019-02-01]
[2019-02-02, 2019-04-05]
[2019-06-01, 2019-07-01]

Vous pouvez voir qu'il y a un écart entre 2019-04-05 et 2019-06-01.

Le résultat sera cet écart: [2019-04-06, 2019-05-31]

Règles

  • L'entrée et la sortie peuvent être dans n'importe quel format de date ou de collection raisonnable, tant qu'elles sont cohérentes.
  • Supposons que l'entrée n'est pas ordonnée.
  • Votre plage de dates ne doit pas nécessairement être [latest, earliest] , mais elle doit suivre la règle 2.
  • Supposons qu'il n'y a pas de dates qui se chevauchent dans l'entrée

Cas de test:

Contribution: [[2019-01-01, 2019-02-01],[2019-02-02, 2019-04-05],[2019-06-01, 2019-07-01]]

Production: [[2019-04-06, 2019-05-31]]


Contribution: [[2019-01-01, 2019-02-01],[2018-02-02, 2018-04-05],[2019-06-01, 2019-07-01]]

Production: [[2018-04-06, 2018-12-31], [2019-02-02, 2019-05-31]]


Contribution: [[2019-01-01, 2019-02-01],[2019-02-02, 2019-03-02],[2019-03-03, 2019-07-01]]

Production: []


Contribution: [[2019-01-01, 2019-02-01], [2019-11-02, 2019-11-20]]

Production: [[2019-02-02, 2019-11-01]]


Contribution: [[2019-01-01, 2019-02-01],[2019-02-03, 2019-04-05]]

Sortie: [[2019-02-02, 2019-02-02]]ou[[2019-02-02]]

Oliver
la source
5
Je suggère de retravailler toutes les dates d'exemple au format ISO, YYYY-MM-DDcar le format actuel est à la fois étranger à de nombreuses personnes et rendu encore plus difficile à analyser en raison de l'utilisation de petits jours de mois≤12.
Adám
@ Adám Bonne idée, mise à jour.
Oliver
Pouvons-nous prendre les entrées en tant que dates d'automatisation .NET OLE?
Adám
@ Adám Oui. Tout format de date raisonnable est acceptable.
Oliver
1
Les dates seront-elles commandées? De plus, dans une paire de dates, la dernière sera-t-elle la dernière?
Incarnation de l'ignorance

Réponses:

4

APL (Dyalog Extended) , 28 25 24 octets

Fonction de préfixe tacite anonyme. L'argument et le résultat sont des matrices à 2 colonnes de nombres de jours depuis une époque, chaque ligne représentant une plage.

1 ¯1+⍤1∘{⍵⌿⍨1<-⍨/⍵}1⌽⍢,∧

Essayez-le en ligne! La fonction de Inpré-processeur convertit d'une liste de paires de listes à 3 éléments (dates dans l'ordre ISO) en une matrice à 2 colonnes d'IDN, International Day Numbers (jours depuis 1899-12-31). La Outfonction post-processeur convertit une matrice d'IDN en une matrice de listes à 3 éléments.

 trier les lignes en ordre croissant

1⌽ faire pivoter les dates de façon cyclique un pas à gauche
⍢, tout en défilant (aplati) - après, remodeler à nouveau la forme d'origine

1 ¯1+ ajouter un et un négatif en
⍤1 utilisant cette liste pour chaque ligne
 du résultat de
{} le lambda suivant:
 l'argument
-⍨/ soustrait la date de gauche de la date de droite, le
1< masque par ligne où les différences dépassent un (c'est-à-dire où les plages ne sont pas adjacentes)
⍵⌿⍨  filtre les rangées par ce masque

Adam
la source
3

C # (compilateur interactif Visual C #) , 108 octets

n=>{n.Sort();for(int i=0;;)Write(n[i].b.AddDays(1)==n[++i].a?"":n[i-1].b.AddDays(1)+""+n[i].a.AddDays(-1));}

Sorties par impression au format DD/MM/YYYY 12:00:00 AMDD/MM/YYYY 12:00:00 AM . Provoquera une exception IndexOutOfRange, ce qui est bien par méta consensus.

Essayez-le en ligne!

Si nous prenons des informations sous forme de jours depuis l'époque unix, nous pouvons obtenir ceci à ...

83 octets

n=>{n.Sort();for(int i=0;;)Print(n[i].b+1==n[++i].a?"":n[i-1].b+1+" "+(n[i].a-1));}

Essayez-le en ligne!

Nous pouvons jouer au golf encore plus loin avec le /u:System.Array drapeau, pour ...

78 octets

n=>{Sort(n);for(int i=0;;)Print(++n[i].b==n[++i].a--?"":n[i-1].b+" "+n[i].a);}

Essayez-le en ligne!

Incarnation de l'ignorance
la source
2

Perl 5, 130 octets

/-(\d+)-/,$_=strftime"%Y-%m-%d",0,0,0,$'+($|--||-1),$1-1,$`-1900 for@F=sort@F;$,lt$;&&say"$, $;"while($,,$;)=@F[++$i,$i+1],++$i<@F

TIO

Nahuel Fouilleul
la source
2

Bash, 125 octets

set `sort<<<$1`;shift;for a;{ s=$[x++%2?-1:1]day;c=`date -d$a\ $s +%Y-%m-%d`;[ $p ]&&{ [[ $p < $c ]]&&echo $p $c;p=;}||p=$c;}

TIO

Nahuel Fouilleul
la source
2

PHP, 208 197 190 177 octets

Hunky Chunky était assis sur un mur ... bien que la nouvelle approche ait un certain potentiel de golf.

function($a){sort($a);for($m=$x=$a[0][0];$f=$m<=$x;$f^$g&&print($g=$f)?"$m/":"$n
",$m=date("Y-m-d",strtotime($n=$m)+9e4))foreach($a as$d)$x=max($x,$d[1|$f&=$m<$d[0]|$m>$d[1]]);}

la fonction prend un tableau de plages [début, fin] au format ISO, imprime les intervalles d'intervalle. Essayez-le en ligne .


panne

function($a){
    sort($a);                           # sort ranges (for easy access to min date)
    for($m=$x=$a[0][0];$f=$m<=$x;       # loop from min date to max date, 1. set flag
        $f^$g&&print($g=$f)?"$m/":"$n\n",       # 4. flag changed: backup flag, print date
        $m=date("Y-m-d",strtotime($n=$m)+9e4)   # 5. backup and increment date
    )foreach($a as$d)
        $x=max($x,$d[1                          # 2. find max date
            |$f&=$m<$d[0]|$m>$d[1]              # 3. date found in ranges: clear flag
        ]);
}
Titus
la source
1

Gelée , 13 octets

FṢṖḊs2+Ø+>/Ðḟ

Jelly (actuellement) n'a pas de dates intégrées, donc cela utilise les jours depuis l'époque.
La liste d'entrée des plages (paires d'entiers) peut être dans un ordre et des directions mixtes.
Le résultat est une liste de plages ascendantes dans l'ordre croissant.

Essayez-le en ligne! (formats de pied de page afin d'afficher une liste vide comme[])

Comment?

Remarque: Cela repose sur l'assurance qu '«il n'y a pas de dates qui se chevauchent dans l'entrée» comme indiqué dans les règles.

FṢṖḊs2+Ø+>/Ðḟ - Link: list of pairs of integers
F             - flatten
 Ṣ            - sort
  Ṗ           - pop (remove tail)
   Ḋ          - dequeue (remove head)
    s2        - split into twos
       Ø+     - literal [1,-1]
      +       - add (vectorises)
           Ðḟ - filter discard those for which:
          /   -   reduce by:
         >    -     greater than?
Jonathan Allan
la source
Intéressant, je ne savais pas que Jelly n'avait pas de support de date. Est-ce l'approche habituelle? Utiliser les jours depuis l'époque?
dana
Quelques jours depuis l'époque est, je crois, utilisé par certains systèmes (Excel peut-être). Secondes depuis l'époque est plus courante (par exemple Unix). Je suis juste allé avec quelque chose qui semble couvrir les exigences, quoique assez laxiste.
Jonathan Allan
Boo, vous pouvez calculer les dates manuellement . ; P Days puisque epoch est en effet utilisé plus souvent pour les langues qui ne supportent pas les dates. J'ai l'impression que cela rend ce défi BEAUCOUP plus facile, cependant.
Kevin Cruijssen
@KevinCruijssen heh, d'accord.
Jonathan Allan
1

C # (Visual C # Interactive Compiler) , 103 octets

x=>{var(a,_)=x[0];foreach(var(b,c)in x.OrderBy(y=>y)){if(a<b)Print((a,b.AddDays(-1)));a=c.AddDays(1);}}

Essayez-le en ligne!

L'entrée est une liste de tuples de date de début / fin. Sort chaque plage manquante vers STDOUT.

// x: input list of start/end date tuples
x=>{
  // variable definitions...
  // a: 1 day after the end date of the previous range
  // b: start of the current range
  // c: end of the current range

  // start by deconstructing the start date of the first tuple
  // into a. a will then be a DateTime and will contain a value
  // at least a large as the smallest start date.
  var(a,_)=x[0];
  // iterate over sorted ranges
  foreach(var(b,c)in x.OrderBy(y=>y)){
    // if the day after the end of the previous range is less
    // than the start of the current range, then print the
    // missing days.
    if(a<b)
      Print((a,b.AddDays(-1)));
    // save the day after the current range to a for next iteration
    a=c.AddDays(1);
  }
}
dana
la source
128
ASCII uniquement
Hah - si vous imprimez comme Embodiment of Ignorance, vous pouvez devenir vraiment petit - Essayez-le en ligne!
dana
Agréable. Également avec leur méthode de saisie pour les deux derniers
ASCII uniquement
Eh bien en fait ... cela semble vraiment incorrect
ASCII uniquement
1
Ouais ça a l'air bien maintenant
ASCII uniquement
1

R , 88 octets

function(a,b=a[order(a$x),],d=c(b$x[-1]-b$y[-nrow(b)],0))data.frame(b$y+1,b$y+d-1)[d>1,]

Essayez-le en ligne!

Cela prend un bloc de données de plages de dates en entrée et génère un bloc de données avec les plages manquantes. Je suis assez sûr que cela pourrait être joué au golf plus, mais j'ai rencontré des problèmes avec c, cbindet d'autres, en supprimant la classe de date.

Nick Kennedy
la source