Championnats nationaux de conflits d'horaire

25

xkcd: conflit de planification

(Je voulais publier ceci pendant 1542: le conflit de planification était toujours le xkcd actuel, mais j'avais un conflit de planification.)

Contribution

L'entrée sera une liste d' 3néléments, qui représentent des névénements. Le premier élément de chaque groupe de 3 sera le nom d'un événement; les deuxième et troisième, respectivement l'heure de début et l'heure de fin. Par exemple:

foo 12 34 bar 56 78

représente un événement fooqui commence à «l'heure 12» (les heures sont simplement représentées par des nombres entiers; vous pouvez les considérer comme des minutes après minuit) et se termine à 34, et un deuxième événement barqui commence à 56 et se termine à 78.

Les noms des événements seront toujours composés uniquement de caractères alphanumériques, et les heures seront toujours des entiers ≥ 0 et <1440. L'heure de fin sera toujours au moins 1 supérieure à l'heure de début. Ils ne sont en aucun cas garantis pour être triés.

Si vous le souhaitez, vous pouvez prendre cela comme une chaîne unique séparée par des espaces; sinon, il doit être pris comme un tableau, une liste, un vecteur ou l'équivalent de votre langue.

Sortie

La sortie doit être une liste de noms d'événements séparés par des espaces. Les règles pour lesquelles les noms d'événements à afficher sont les suivantes:

  • Aucun des événements que vous générez ne peut entrer en conflit les uns avec les autres. Par exemple, avec l'entrée a 0 10 b 5 15, vous ne pouvez pas sortir les deux aet bparce que les heures sont en conflit (c'est-à-dire qu'elles se chevauchent partiellement). Si un événement se termine exactement au début d'un autre, vous pouvez inclure les deux.

  • Vous ne pouvez pas sortir l'événement appelé NSCC("National Scheduling Conflict Competition"), dont il y aura toujours exactement un dans l'entrée. Vous devez également générer au moins un événement qui entre en conflit (se chevauche partiellement) NSCC(et il y en aura toujours au moins un également).

  • Vous devez générer autant d'événements que possible tout en suivant les deux règles ci-dessus. (C'est pour que vous ayez l'air aussi occupé que possible, afin que manquer le NSCC semble plus crédible.)

Cela peut également être affiché sous la forme d'une chaîne séparée par des espaces ou d'un tableau, d'une liste, d'un vecteur, etc.

Il peut y avoir plusieurs sorties possibles.

Cas de test

Notez que les sorties répertoriées ne sont que des exemples. Votre code peut produire quelque chose de différent, tant qu'il suit toujours les trois règles ci-dessus (notamment, cela signifie qu'il doit y avoir le même nombre d'événements que l'exemple).

Entrée: UnderwaterBasketWeavingConvention 50 800 NSCC 500 550
Sortie:UnderwaterBasketWeavingConvention

Entrée: SconeEating 0 50 RegexSubbing 45 110 CodeGolfing 95 105 NSCC 100 200
Sortie:SconeEating CodeGolfing

Entrée: VelociraptorHunting 0 300 NerdSniping 200 500 SEChatting 400 700 DoorknobTurning 650 750 NSCC 725 775
Sortie:NerdSniping DoorknobTurning

Entrée: NSCC 110 115 A 100 120 B 120 140 C 105 135 D 100 105 E 135 500
Sortie:C D E

Entrée: A 800 900 NSCC 700 1000 B 650 750 C 950 1050 D 655 660 E 660 665 F 1030 1040 G 1040 1060
Sortie:A D E F G

Entrée: A 10 11 B 11 12 C 12 13 D 13 14 NSCC 15 1090 E 10 16
Sortie:E

N'hésitez pas à ajouter plus de cas de test dans une modification s'il y a des cas de bord que j'ai manqués.

Règles

  • Votre code doit se terminer dans les 30 secondes pour tous les cas de test fournis (il s'agit davantage d'un contrôle d'intégrité, car il devrait probablement se terminer beaucoup plus rapidement pour tous les cas de test combinés) sur une machine personnelle raisonnable.

  • Il s'agit de , donc le code le plus court en octets l'emporte.

Poignée de porte
la source
Est-il acceptable d'utiliser camelCase pour les événements dans les entrées? par exemple en utilisant underwaterBasketWeavingConvention 50 800 nscc 550au lieu de votre exemple?
Fatalize
4
@Fatalize Je ne sais pas ce que tu veux dire; l'entrée est donnée exactement comme elle est montrée. Vous devriez pouvoir prendre en charge n'importe quelle combinaison de caractères alphanumériques.
Poignée de porte
4
Je devrai trouver une solution à cela plus tard; J'ai un conflit d'horaire en ce moment.
Alex A.
Dans le deuxième exemple, il y a deux espaces entre "CodeGolfing" et "95" - est-ce une erreur, ou devons-nous tenir compte des nombres arbitraires d'espaces dans l'entrée? Pour l'instant, je vais supposer le premier, car vous semblez un peu indulgent sur le format de l'entrée.
vijrox
@VijayRamamurthy Oui, ça l'est. Fixé.
Poignée de porte

Réponses:

9

Pyth, 45 octets

AGH.gqhk"NSCC"m,hdrFtdcQ3hMef&.{KseMT@KehHtyG

Celui-ci était assez difficile à jouer au golf. J'ai trouvé pas mal de solutions de 45 octets, celle-ci est probablement la plus exotique, car elle utilise A(pair-assign) et .g(group-by).

Essayez-le en ligne: démonstration ou test de harnais

Explication

                            implicit: Q = input list
                      cQ3   split Q into triples
              m             map each triple d to:
               ,              the pair containing
                hd              - d[0] (name)
                  rFtd          - range from start-time to end-time
   .g                       group these tuples k by:
     qhk"NSCC"                k[0] == "NSCC"
AGH                         pair assign to G,H. This assigns all
                            tuples != NSCC to G, and the NSCC one to H

                  yG        generate all subsets of G
                 t          remove the first one (the empty subset)
   f                        filter for subsets T, which satisfy:
         eMT                  get the last item (the range) for all tuples in T
        s                     and combine them (sum)
       K                      assign to K
     .{                       check for uniqueness of K (no overlapping times)
    &                         and
            @KehH             check the intersection of K and H[0][1]
  e                         take the last element (most events)
hM                          get the first item (name) for each event
                            and implicitly print this list
Jakube
la source
13

SWI-Prolog, 537 524 516 502 447 436 octets

z(A:B:C,[D:E:F|G]):-(A=D;B>=F;E>=C),(G=[];z(A:B:C,G)).
u([A|B],C):-z(A,C),(B=[];u(B,C)).
y([A,B,C|D])-->[A:B:C],(y(D);{_=_}).
d-->[A:_],{write(A),tab(1)},d;{_=_}.
l([H|T],R):-T=[],R=H;length(H,N),l(T,X),length(X,M),(N>M,R=H;R=X).
v([],_,R,R).
v([A|T],Z,B,R):-u(A,A),\+z(Z,A),v(T,Z,[A|B],R);v(T,Z,B,R).
s([E|T],[F|N]):-E=F,(N=[];s(T,N));s(T,[F|N]).
x(A):-y(A,D,[]),K="NSCC":_,select(K,D,E),setof(L,s(E,L),B),v(B,K,[],R),l(R,S),d(S,[]),!.

Brève explication de ce que fait chaque prédicat:

  • z(A,B) vérifie qu'un événement A n'est pas en conflit avec un événement d'une liste d'événements B
  • u(A,B)vérifie que chaque événement d'une liste A n'est pas en conflit avec un événement d'une liste B (utilisé pour vérifier qu'il n'y a pas de conflits dans la liste A en appelant u(A,A))
  • y(A,B,C) divise une liste en une liste de triplets (pour transformer les entrées en une liste d'événements)
  • d(A) imprime les noms des événements dans une liste A
  • l(A,R) évalue la plus longue liste d'événements R contenue dans la liste des listes A
  • v(A,NSCC,C,R) renvoie une liste R contenant toutes les listes d'événements dans A qui n'ont pas de conflit interne et qui sont en conflit avec l'événement NSCC
  • s(A,B) vrai si B est un sous-ensemble de A
  • x(A) prédicat principal, A est l'entrée.

Cas de test : exécutez test.dans l'interpréteur après avoir chargé le code ci-dessus avec ce qui suit ajouté après:

test:-
    x(["UnderwaterBasketWeavingConvention",50,800,"NSCC",500,550]),
    nl,
    x(["SconeEating",0,50,"RegexSubbing",45,110,"CodeGolfing",95,105,"NSCC",100,200]),
    nl,
    x(["VelociraptorHunting",0,300,"NerdSniping",200,500,"SEChatting",400,700,"DoorknobTurning",650,750,"NSCC",725,775]),
    nl,
    x(["NSCC",110,115,"A",100,120,"B",120,140,"C",105,135,"D",100,105,"E",135,500]),
    nl,
    x(["A",800,900,"NSCC",700,1000,"B",650,750,"C",950,1050,"D",655,660,"E",660,665,"F",1030,1040,"G",1040,1060]),
    nl,
    x(["A",10,11,"B",11,12,"C",12,13,"D",13,14,"NSCC",15,1090,"E",10,16]).

Cela m'a pris beaucoup plus de temps que je ne le pensais. Cela peut probablement être joué beaucoup plus. Vous pourriez aussi probablement utiliser les diverses bibliothèques de programmation de contraintes qui existent pour obtenir des solutions plus courtes.

Edit: Merci à @Oliphaunt pour l'idée d'utiliser à la A:B:Cplace des [A,B,C]triplés. Enregistre 14 octets.

Edit2: Merci encore à @Oliphaunt d'avoir souligné que le prédicat `` t / 3` était inutile. Enregistre 55 octets

Edit3: 11 octets gagnés en utilisant la grammaire de la clause définitive sur les prédicats yet d.

Fatalize
la source
L'amour répond dans Prolog! Joli.
plocks
Je suis aussi un amoureux de Prolog. Suggestions: 1. Je pense que vous pouvez utiliser par exemple A/B/Cau lieu de [A,B,C]pour les triplets, en économisant 10 octets; 2. Pouvez-vous utiliser à la \+place de not? 3. Pourriez-vous expliquer pourquoi vous avez besoin de la dernière intervention x(A)?
Oliphaunt - réintègre Monica le
Je te reviendrai demain, depuis mon ordinateur portable. En ce moment au lit avec la tablette qui rend la frappe maladroite et je devrais probablement dormir de toute façon. :-)
Oliphaunt - réintègre Monica le
1
Voici une version qui enregistre 14 octets. J'ai utilisé :au lieu de /bénéficier de l'associativité de droite de l'ancien, c'est-à-dire pour que je puisse écrire A:_en raccourci A:_:_(mais A+B/Cça marche aussi bien: vous pouvez alors l'utiliser A+_). Soit dit en passant, également dans votre original, vous auriez pu utiliser à la [A|_]place de [A,_,_]. Notez enfin que ma version de SWI-Prolog n'en avait pas nth0/4, donc j'ai utiliséselect/3 place.
Oliphaunt - réintègre Monica le
1
Je me suis interrogé avant sur la nécessité t(S,T)mais j'ai oublié. Maintenant testé: vous pouvez économiser 55 octets supplémentaires en le supprimant entièrement et en appelant directement s(E,L)depuis setof/3.
Oliphaunt - réintègre Monica le
6

JavaScript ( ES6 ), 228

Deuxième essai, j'espère que celui-ci fonctionne.

Mon objectif est la séquence d'événements la plus longue qui a un conflit de synchronisation, mais pas de conflit de synchronisation lorsque l'événement NSCC est supprimé. Cette séquence modifiée avec NSCC supprimé est la sortie demandée.

J'utilise une recherche en largeur examinant une file d'attente de solutions candidates, en commençant par la plus longue (la première est la liste initiale). A partir d' une solution candidate de n événements que je construis et enqueue n plus des solutions candidats, la suppression d' un des événements et garder les autres.

Une solution candidate est valide s'il y a un conflit de synchronisation «tel quel», mais lorsque l'événement NSCC est filtré, il n'y a pas de conflit. J'utilise une sous-fonction K pour vérifier les conflits.

On pourrait probablement jouer au golf un peu plus ...

Testez l'exécution de l'extrait ci-dessous (en EcmaScript 6, FireFox uniquement)

F=l=>(K=>{
  l.map(v=>l.push(l.splice(0,3)));// I'm particularly proud of this trick for grouping in triplets (in pith it's "cQ3")
  for(S=[l.sort((a,b)=>a[1]-b[1])];!K(l=S.shift())|K(m=l.filter(x=>x[0]!='NSCC'));)
    l.map((v,i)=>(S.push(n=[...l]),n.splice(i,1)));
})(l=>l.some(x=>[p>+x[1],p=+x[2]][0],p=0))||m.map(x=>x[0])

// Less golfed and ES5

function Find(l) {
  var n,m;
  var Check = function(l) {
    // check timing conflict comparing start time and end time of previous event (events must be sorted)
    var p = 0 // previous event end time, init to 0
    return l.some( function(x) {
      var err = p > +x[1]; // unary plus convert string to number
      p = +x[2]; // update end time
      return err;
    });  
  };  
  // group initial array in triplets
  // forEach repeats for the initial number of elements in l, even if l becomes shorter
  // so it loops more times than necesary, but it works anymay
  l.forEach(function() { 
    l.push(l.splice(0,3)); // remove first 3 elements and add to back as a triple
  }) 
  l.sort(function(a,b) { return a[1]-b[1]} ); // sort by start time
  var S=[l]; // S is the main queue, start with complete list 
  
  while (l = S.shift(), // current list
         m = l.filter( function(x) { return x[0]!='NSCC'} ), // current list with NSCC removed
         !Check(l)|Check(m)) // loop while list ha no errors or filtered list do have errors
  {
    // build new candidate to check
    l.forEach ( function(v,i) {
      n = l.slice(); // make a copy of l
      n.splice(i,1); // remove ith element
      S.push(n); // put in S
    });  
  }
  // when exiting while, m has the list with NSCC removed
  return m.map( function(x) { return x[0]; }); // keep the event name only
}

// Test

out=(...x)=>O.innerHTML += x + '\n';

test=[
  ['UnderwaterBasketWeavingConvention 50 800 NSCC 500 550','UnderwaterBasketWeavingConvention']
, ['SconeEating 0 50 RegexSubbing 45 110 CodeGolfing  95 105 NSCC 100 200','SconeEating CodeGolfing']
, ['VelociraptorHunting 0 300 NerdSniping 200 500 SEChatting 400 700 DoorknobTurning 650 750 NSCC 725 775'
  ,'NerdSniping DoorknobTurning']
, ['NSCC 110 115 A 100 120 B 120 140 C 105 135 D 100 105 E 135 500','C D E']
, ['A 800 900 NSCC 700 1000 B 650 750 C 950 1050 D 655 660 E 660 665 F 1030 1040 G 1040 1060','A D E F G']
, ['A 10 11 B 11 12 C 12 13 D 13 14 NSCC 15 1090 E 10 16','E']
]


test.forEach(x=>{
  var l=x[0].split(/\s+/), r=F(l).sort().join(' '), e=x[1].split(/\s+/).sort().join(' ');
  out('Test ' + (r==e ? 'OK':'FAIL')+'\nInput:    '+x[0]+'\nResult:   '+r+'\nExpected: '+e)
} )
<pre id=O></pre>

edc65
la source
3
Puis-je demander l'intérêt d'un extrait de pile si le programme ne fait rien si vous n'appelez pas la fonction?
Beta Decay
1
@BetaDecay: edc65 ajoute généralement des cas de test qui s'exécutent dans l'extrait de code. On dirait qu'il reviendra bientôt à cette réponse, moment auquel je suppose qu'il ajoutera les éléments exécutables. :)
Alex A.
1
@BetaDecay était pressé. Et (pire encore), il échoue à l'un des tests.
edc65
1

Java, 828 octets

Il existe probablement une implémentation Java plus concise, mais voici mon coup de poignard:

String s(String e){String[] a=e.split(" ");String m="";String[] c=g(a.length/3);int l=0;for(int i=0;i<a.length;i+=3)if(a[i].equals("NSCC"))l=i/3;for(String p:c)if(p.indexOf(l+"")==-1&&!h(p,a)&&h(p+l,a)&&p.length()>m.length())m=p;String r="";for(int i=0;i<m.length();i++)r+=a[3*(m.charAt(i)-48)]+((i==m.length()-1)?"":" ");return r;}boolean h(String c, String[] e){for(int i=0;i<c.length()-1;i++){int p=c.charAt(i)-48;for(int j=i+1;j<c.length();j++){int q=c.charAt(j)-48;if((Integer.parseInt(e[3*p+1])-Integer.parseInt(e[3*q+2]))*((Integer.parseInt(e[3*p+2])-Integer.parseInt(e[3*q+1])))<0)return true;}}return false;}String[] g(int n){if(n>1){String[] result=new String[(int)Math.pow(2,n)];String[] l=g(n-1);for(int i=0;i<l.length;i++){result[2*i]=l[i];result[2*i+1]=l[i]+(n-1);}return result;}else return new String[]{"","0"};}
vijrox
la source
La déclaration de toutes les variables au même endroit permettra d'économiser des octets.
Spikatrix
Vous n'en avez pas besoin else return.
lirtosiast
0

Python, 373 caractères

import itertools as j
a=zip(*[iter(input())]*3)
f,g,r=[],0,"NSCC"
p=f
for q in a:
 p=(p,q)[q[0]==r]
for h in range(1,len(a)+1):
 for i in j.combinations(a,h):
  s,i,l,m=0,sorted(i,key=lambda k:int(k[1])),-1,len(i)
  for n in i:
   s=(s,1)[p[1]<n[2]or p[2]<n[1]]
   if r==n[0]or n[1]<l:
    m=-1
    break
   else:
    l=n[2]
  if s*m>g:
   g,f=m,i
for o in f:
 print o[0]

Crée toutes les combinaisons possibles et vérifie chacune.

Tester

Contribution: ["NSCC",110,115,"A",100,120,"B",120,140,"C",105,135,"D",100,105,"E",135,500]

Sortie:

ré
C
E
sudo rm -rf slash
la source