Campionati nazionali di conflitto di programmazione


25

xkcd: conflitto di pianificazione

(Intendevo pubblicare questo nel 1542: Scheduling Conflict era ancora l'attuale xkcd, ma avevo un conflitto di pianificazione.)

Ingresso

L'input sarà un elenco di 3nelementi, che rappresentano neventi. Il primo elemento in ciascun gruppo di 3 sarà il nome di un evento; il secondo e il terzo, rispettivamente l'ora di inizio e di fine. Per esempio:

foo 12 34 bar 56 78

rappresenta un evento fooche inizia al "tempo 12" (i tempi sono rappresentati semplicemente da numeri interi; puoi pensarli come minuti dopo la mezzanotte) e termina a 34, e un secondo evento barche inizia a 56 e termina a 78.

I nomi degli eventi saranno sempre composti solo da caratteri alfanumerici e i tempi saranno sempre numeri interi ≥ 0 e <1440. L'ora di fine sarà sempre almeno 1 maggiore dell'ora di inizio. Non è garantito che vengano ordinati in alcun modo.

Se lo desideri, puoi prenderlo come una singola stringa separata da spazio; altrimenti dovrebbe essere considerato come un array, un elenco, un vettore o l'equivalente della tua lingua.

Produzione

L'output dovrebbe essere un elenco separato da spazi di nomi di eventi. Le regole per le quali nomi di eventi da emettere sono le seguenti:

  • Nessuno degli eventi che hai prodotto potrebbe essere in conflitto tra loro. Ad esempio, con l'input a 0 10 b 5 15, non è possibile generare entrambi ae bperché i tempi sono in conflitto (ovvero si sovrappongono parzialmente). Se un evento termina esattamente quando ne inizia un altro, puoi includerli entrambi.

  • Non puoi generare l'evento chiamato NSCC("Concorso nazionale sui conflitti di programmazione"), di cui ci sarà sempre esattamente uno nell'input. È inoltre necessario generare almeno un evento in conflitto (parzialmente sovrapposto) con NSCC(e ci sarà sempre almeno uno di quelli).

  • È necessario generare il maggior numero possibile di eventi seguendo le due regole precedenti. (Questo è così che sembri il più impegnato possibile, in modo che la mancanza del NSCC sembri più credibile.)

Questo può anche essere emesso come una singola stringa separata da spazio o una matrice, un elenco, un vettore, ecc.

Possono esserci più di un output possibile.

Casi test

Si noti che le uscite elencate sono solo esempi. Il tuo codice potrebbe generare qualcosa di diverso, purché segua ancora le tre regole precedenti (in particolare, ciò significa che deve esserci la stessa quantità di eventi dell'esempio).

In: UnderwaterBasketWeavingConvention 50 800 NSCC 500 550
Out:UnderwaterBasketWeavingConvention

In: SconeEating 0 50 RegexSubbing 45 110 CodeGolfing 95 105 NSCC 100 200
Out:SconeEating CodeGolfing

In: VelociraptorHunting 0 300 NerdSniping 200 500 SEChatting 400 700 DoorknobTurning 650 750 NSCC 725 775
Out:NerdSniping DoorknobTurning

In: NSCC 110 115 A 100 120 B 120 140 C 105 135 D 100 105 E 135 500
Out:C D E

In: A 800 900 NSCC 700 1000 B 650 750 C 950 1050 D 655 660 E 660 665 F 1030 1040 G 1040 1060
Out:A D E F G

In: A 10 11 B 11 12 C 12 13 D 13 14 NSCC 15 1090 E 10 16
Out:E

Sentiti libero di aggiungere altri casi di test in una modifica se ci sono casi limite che mi sono perso.

Regole

  • Il codice deve essere completato entro 30 secondi per tutti i casi di test forniti (si tratta più di un controllo di integrità, poiché probabilmente dovrebbe essere completato molto più velocemente per tutti i casi di test combinati) su un ragionevole computer personale.

  • Questo è , quindi vince il codice più breve in byte.


È accettabile usare camelCase per eventi in input? ad esempio usando al underwaterBasketWeavingConvention 50 800 nscc 550posto del tuo esempio?
Fatalizza il

4
@Fatalize Non sei sicuro di cosa intendi; l'ingresso è dato esattamente come è mostrato. Dovresti essere in grado di supportare qualsiasi combinazione di caratteri alfanumerici.
Maniglia della porta

4
Dovrò lavorare su una soluzione a questo più tardi; Ho un conflitto di programmazione in questo momento.
Alex A.

Nel secondo esempio ci sono due spazi tra "CodeGolfing" e "95" - è un errore o dobbiamo tenere conto di un numero arbitrario di spazi nell'input? Per ora, assumerò il primo, dal momento che sembri un po 'indulgente sul formato dell'input.
Vijrox,

@VijayRamamurthy Sì, lo è. Fisso.
Maniglia della porta

Risposte:


9

Pyth, 45 byte

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

Questo è stato abbastanza difficile da golf. Trovate alcune soluzioni a 45 byte, questa è probabilmente la più esotica, poiché utilizza A(coppia-assegna) e .g(raggruppa).

Provalo online: cablaggio dimostrativo o di prova

Spiegazione

                            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

13

SWI-Prolog, 537 524 516 502 447 436 byte

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,[]),!.

Breve spiegazione di cosa fa ogni predicato:

  • z(A,B) verifica che un evento A non sia in conflitto con nessun evento di un elenco di eventi B
  • u(A,B)verifica che ogni evento di un elenco A non sia in conflitto con alcun evento di un elenco B (utilizzato per verificare che non vi siano conflitti nell'elenco A chiamando u(A,A))
  • y(A,B,C) divide un elenco in un elenco di terzine (per trasformare gli input in un elenco di eventi)
  • d(A) stampa i nomi degli eventi in un elenco A
  • l(A,R) valuta l'elenco degli eventi più lungo R contenuto nell'elenco degli elenchi A
  • v(A,NSCC,C,R) restituisce un elenco R contenente ogni elenco di eventi in A che non hanno conflitti interni e che sono in conflitto con l'evento NSCC
  • s(A,B) vero se B è un sottoinsieme di A
  • x(A) predicato principale, A è l'input.

Casi di prova : eseguire test.nell'interprete dopo aver caricato il codice sopra con il seguente aggiunto dopo:

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]).

Questo mi ha richiesto molto più tempo di quanto pensassi. Questo può probabilmente essere giocato a golf molto di più. Inoltre potresti probabilmente usare le varie librerie di programmazione di vincoli esistenti per ottenere soluzioni più brevi.

Modifica: grazie a @Oliphaunt per l'idea di utilizzare A:B:Cinvece che [A,B,C]per le terzine. Salva 14 byte.

Edit2: Grazie ancora a @Oliphaunt per aver sottolineato che il predicato `` t / 3` era inutile. Salva 55 byte

Edit3: ottenuto 11 byte usando la grammatica della clausola definitiva su predicati ye d.


L'amore risponde in Prolog! Ben fatto.
apre il

Sono anche un amante di Prolog. Suggerimenti: 1. Penso che tu possa usare ad esempio A/B/Cinvece che [A,B,C]per le terzine, risparmiando 10 byte; 2. Puoi usare \+invece di not? 3. Potresti spiegare perché hai bisogno del taglio finale x(A)?
Oliphaunt: ripristina Monica il

Tornerò da te domani, dal mio laptop. In questo momento a letto con il tablet che rende la digitazione goffa e dovrei probabilmente dormire comunque. :-)
Oliphaunt - ripristina Monica il

1
Ecco una versione che salva 14 byte. Ho usato :invece di /beneficiare della giusta associatività della prima, cioè potrei scrivere A:_come scorciatoia per A:_:_(ma A+B/Cfunziona altrettanto bene: puoi quindi usare A+_). A proposito, anche nel tuo originale avresti potuto usare [A|_]invece di [A,_,_]. Nota infine che la mia versione di SWI-Prolog non aveva nth0/4, quindi ho usato select/3invece.
Oliphaunt: ripristina Monica il

1
Prima mi ero chiesto della necessità, t(S,T)ma poi ho dimenticato. Ora testato: puoi salvare altri 55 byte rilasciandolo completamente e chiamando direttamente s(E,L)da setof/3.
Oliphaunt: ripristina Monica il

6

JavaScript ( ES6 ), 228

Secondo tentativo, spero che questo funzioni.

Il mio obiettivo è la sequenza di eventi più lunga che presenta un conflitto di temporizzazione, ma nessun conflitto di temporizzazione quando l'evento NSCC viene rimosso. Questa sequenza modificata con NSCC rimosso è l'output richiesto.

Uso una Breadth First Search che esamina una coda di soluzioni candidate, a partire dalla più lunga (la prima è la lista iniziale). Da una soluzione candidata di n eventi, ho creato e accodato n più soluzioni candidate, rimuovendo uno degli eventi e mantenendo gli altri.

Una soluzione candidata è valida se si verifica un conflitto di temporizzazione "così com'è", ma quando l'evento NSCC viene filtrato non si verificano conflitti. Uso una sottofunzione K per verificare la presenza di conflitti.

Probabilmente potrebbe essere giocato a golf un po 'di più ...

Test che esegue lo snippet di seguito (essendo EcmaScript 6, solo FireFox)

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>


3
Posso chiedere il punto di uno snippet di stack se il programma non fa nulla se non si chiama la funzione?
Decadimento beta

1
@BetaDecay: edc65 di solito aggiunge casi di test eseguiti nello snippet. Sembra che tornerà presto a questa risposta, a quel punto presumo che aggiungerà le cose eseguibili. :)
Alex A.

1
@BetaDecay Era di fretta. E (peggio ancora) fallisce uno dei test.
edc65,

1

Java, 828 byte

C'è probabilmente un'implementazione Java più concisa là fuori, ma ecco la mia pugnalata:

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"};}

Dichiarare tutte le variabili in un unico posto salverà i byte.
Spikatrix,

Non è necessario else return.
lirtosiast,

0

Python, 373 caratteri

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]

Crea tutte le possibili combinazioni e controlla ognuna.

Test

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

Produzione:

D
C
E
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.