Campeonatos nacionales de conflictos de programación

25

xkcd: conflicto de programación

(Tenía la intención de publicar esto mientras 1542: El conflicto de programación todavía era el xkcd actual, pero tuve un conflicto de programación).

Entrada

La entrada será una lista de 3nelementos, que representan neventos. El primer elemento en cada grupo de 3 será el nombre de un evento; el segundo y el tercero, la hora de inicio y finalización respectivamente. Por ejemplo:

foo 12 34 bar 56 78

representa un evento fooque comienza en el "tiempo 12" (los tiempos están representados simplemente por números enteros; puede pensar en ellos como minutos después de la medianoche) y termina en 34, y un segundo evento barque comienza en 56 y termina en 78.

Los nombres de los eventos siempre consistirán solo en caracteres alfanuméricos, y los tiempos siempre serán enteros ≥ 0 y <1440. La hora de finalización siempre será al menos 1 mayor que la hora de inicio. No se garantiza que se clasifiquen de ninguna manera.

Si lo desea, puede tomar esto como una sola cadena separada por espacios; de lo contrario, debe tomarse como una matriz, lista, vector o el equivalente de su idioma.

Salida

La salida debe ser una lista de nombres de eventos separados por espacios. Las reglas para los nombres de eventos que se deben generar son las siguientes:

  • Ninguno de los eventos que genera puede entrar en conflicto entre sí. Por ejemplo, con la entrada a 0 10 b 5 15, es posible que no genere ambas ay bporque los tiempos entran en conflicto (es decir, se superponen parcialmente). Si un evento termina exactamente como comienza otro, puede incluir ambos.

  • No puede generar el evento llamado NSCC("Competencia de conflicto de programación nacional"), del cual siempre habrá exactamente uno en la entrada. También debe generar al menos un evento que entre en conflicto (se superpone parcialmente) con NSCC(y siempre habrá al menos uno de esos también).

  • Debe generar tantos eventos como sea posible mientras sigue las dos reglas anteriores. (Esto es para que parezca lo más ocupado posible, para que perder el NSCC parezca más creíble).

Esto también se puede generar como una sola cadena separada por espacios o como una matriz, lista, vector, etc.

Puede haber más de una salida posible.

Casos de prueba

Tenga en cuenta que las salidas enumeradas son solo ejemplos. Su código puede generar algo diferente, siempre y cuando siga las tres reglas anteriores (en particular, esto significa que debe haber la misma cantidad de eventos que el ejemplo).

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

Siéntase libre de agregar más casos de prueba en una edición si hay casos límite que me perdí.

Reglas

  • Su código debe completarse dentro de los 30 segundos para todos los casos de prueba proporcionados (esto es más un control de cordura, ya que probablemente debería completarse mucho más rápido para todos los casos de prueba combinados) en una máquina personal razonable.

  • Este es el , por lo que gana el código más corto en bytes.

Pomo de la puerta
fuente
¿Es aceptable usar camelCase para eventos en entradas? por ejemplo usando en underwaterBasketWeavingConvention 50 800 nscc 550lugar de su ejemplo?
Fatalize
44
@Fatalize No estoy seguro de lo que quieres decir; la entrada se da exactamente como se muestra. Debería poder admitir cualquier combinación de caracteres alfanuméricos.
Pomo de la puerta
44
Tendré que trabajar en una solución para esto más tarde; Tengo un conflicto de programación en este momento.
Alex A.
En el segundo ejemplo, hay dos espacios entre "CodeGolfing" y "95". ¿Es esto un error o tenemos que tener en cuenta números arbitrarios de espacios en la entrada? Por ahora, voy a asumir lo primero, ya que pareces un poco indulgente con el formato de la entrada.
vijrox
@VijayRamamurthy Sí, lo es. Fijo.
Pomo de la puerta

Respuestas:

9

Pyth, 45 bytes

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

Este fue bastante duro para el golf. Encontramos bastantes soluciones de 45 bytes, esta es probablemente la más exótica, ya que utiliza A(asignación de pares) y .g(agrupar por).

Pruébelo en línea: demostración o prueba de arnés

Explicación

                            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
fuente
13

SWI-Prolog, 537 524 516 502 447 436 bytes

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 explicación de lo que hace cada predicado:

  • z(A,B) comprueba que un evento A no entre en conflicto con ningún evento de una lista de eventos B
  • u(A,B)comprueba que cada evento de una lista A no entre en conflicto con ningún evento de una lista B (se usa para verificar que no haya conflictos en la lista A llamando u(A,A))
  • y(A,B,C) divide una Lista en una lista de tripletes (para transformar entradas en una lista de eventos)
  • d(A) imprime los nombres de eventos en una lista A
  • l(A,R) evalúa la lista más larga de eventos R contenida en la lista de listas A
  • v(A,NSCC,C,R) devuelve una lista R que contiene todas las listas de eventos en A que no tienen conflicto interno y que entran en conflicto con el evento NSCC
  • s(A,B) verdadero si B es un subconjunto de A
  • x(A) predicado principal, A es la entrada.

Casos de prueba : ejecutar test.en el intérprete después de cargar el código anterior con lo siguiente agregado despué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]).

Esto me llevó mucho más tiempo del que pensaba. Esto probablemente se puede jugar mucho más golf. Además, probablemente podría usar las diversas bibliotecas de programación de restricciones que existen para obtener soluciones más cortas.

Editar: Gracias a @Oliphaunt por la idea de usar en A:B:Clugar de [A,B,C]trillizos. Ahorra 14 bytes.

Edit2: Gracias nuevamente a @Oliphaunt por señalar que el predicado `` t / 3` 'fue inútil. Ahorra 55 bytes

Edit3: Ganó 11 bytes usando la gramática de cláusula definitiva en predicados yy d.

Fatalizar
fuente
¡El amor responde en Prolog! Buena esa.
bloquea el
Soy un amante de Prolog también. Sugerencias: 1. Yo creo que puede utilizar por ejemplo, A/B/Cen lugar de [A,B,C]los trillizos, el ahorro de 10 bytes; 2. ¿Se puede usar en \+lugar de not? 3. ¿Podría explicar por qué necesita el corte final x(A)?
Oliphaunt - reinstalar a Mónica el
Volveré a ti mañana, desde mi computadora portátil. Ahora mismo en la cama con la tableta, lo que hace que escribir sea torpe y probablemente debería dormir de todos modos. :-)
Oliphaunt - reinstalar a Mónica
1
Aquí hay una versión que ahorra 14 bytes. He utilizado :en lugar de /a beneficio de las antiguas de asociatividad por la derecha, es decir, por lo que podría escribir A:_como forma abreviada de A:_:_(pero A+B/Cfunciona igual de bien: a continuación, puede utilizar A+_). Por cierto, también en su original podría haber usado en [A|_]lugar de [A,_,_]. Tenga en cuenta finalmente que mi versión de SWI-Prolog no tenía nth0/4, así que usé en su select/3lugar.
Oliphaunt - reinstalar a Monica el
1
Me preguntaba antes sobre la necesidad t(S,T)pero luego lo olvidé. Ahora probado: puede guardar 55 bytes más al soltarlo por completo y llamar directamente s(E,L)desde setof/3.
Oliphaunt - reinstalar a Monica el
6

JavaScript ( ES6 ), 228

Segundo intento, espero que este funcione.

Mi objetivo es la secuencia más larga de eventos que tiene un conflicto de tiempo, pero no hay conflicto de tiempo cuando se elimina el evento NSCC. Esta secuencia modificada con NSCC eliminado es la salida solicitada.

Utilizo Breadth First Search para examinar una cola de soluciones candidatas, comenzando por la más larga (la primera es la lista inicial). A partir de una solución candidata de n eventos, construyo y pongo en cola n más soluciones candidatas, eliminando uno de los eventos y manteniendo los otros.

Una solución candidata es válida si hay un conflicto de tiempo 'tal cual', pero cuando el evento NSCC se filtra no hay conflicto. Uso una subfunción K para verificar conflictos.

Probablemente podría jugar al golf un poco más ...

Pruebe a ejecutar el fragmento a continuación (siendo 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>

edc65
fuente
3
¿Puedo preguntar el punto de un fragmento de pila si el programa no hace nada si no llama a la función?
Beta Decay
1
@BetaDecay: edc65 generalmente agrega casos de prueba que se ejecutan en el fragmento. Parece que pronto regresará a esta respuesta, en cuyo momento supongo que agregará las cosas ejecutables. :)
Alex A.
1
@BetaDecay tenía prisa. Y (peor aún) falla una de las pruebas.
edc65
1

Java, 828 bytes

Probablemente haya una implementación de Java más concisa, pero aquí está mi puñalada:

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
fuente
Declarar todas las variables en un lugar ahorrará bytes.
Spikatrix
No necesitas hacerlo else return.
lirtosiast 01 de
0

Python, 373 caracteres

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 todas las combinaciones posibles y comprueba cada una.

Prueba

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

Salida:

re
do
mi
sudo rm -rf slash
fuente