전국 일정 분쟁 챔피언십


25

xkcd : 스케줄링 충돌

(나는 1542 동안 이것을 게시하려고했습니다 : 스케줄링 충돌 은 여전히 ​​현재 xkcd 였지만 스케줄링 충돌이있었습니다.)

입력

입력은 이벤트 3n를 나타내는 요소 목록입니다 n. 3의 각 그룹에서 첫 번째 요소는 이벤트의 이름입니다. 두 번째와 세 번째는 각각 시작 및 종료 시간입니다. 예를 들면 다음과 같습니다.

foo 12 34 bar 56 78

foo"시간 12"에서 시작 하는 이벤트 를 나타냅니다 (시간은 단순히 정수로 표시됩니다. 자정이 지난 분으로 생각할 수 있음). 34에서 끝나고 두 번째 이벤트 bar는 56에서 시작하여 78에서 끝납니다.

이벤트 이름은 항상 영숫자 문자만으로 구성되며 시간은 항상 ≥ 0 및 <1440의 정수입니다. 종료 시간은 항상 시작 시간보다 1 이상 큽니다. 어떤 식 으로든 정렬 될 수는 없습니다.

원하는 경우 공백으로 구분 된 단일 문자열로 사용할 수 있습니다. 그렇지 않으면 배열, 목록, 벡터 또는 해당 언어로 간주해야합니다.

산출

출력은 공백으로 구분 된 이벤트 이름 목록이어야합니다. 출력 할 이벤트 이름의 규칙은 다음과 같습니다.

  • 출력 한 이벤트 중 어느 것도 서로 충돌 할 수 없습니다. 예를 들어, 입력이있는 a 0 10 b 5 15경우를 모두 출력하지 않을 수 ab때문에 충돌 시간 (이며 부분적으로 중첩). 다른 이벤트가 시작될 때 이벤트가 정확하게 종료되면 둘 다 포함 할 수 있습니다.

  • 입력에 항상 정확히 하나만 있는 이벤트 NSCC( "National Scheduling Conflict Competition")를 출력 할 수 없습니다 . 또한 충돌하는 (부분적으로 겹치는) 이벤트를 하나 이상 출력 해야합니다 (그리고 항상 그 중 하나도 있어야 함).NSCC

  • 위의 두 규칙을 따르는 동안 가능한 많은 이벤트를 출력해야합니다. (이것은 가능한 한 바쁘게 보이기 때문에 NSCC를 놓치는 것이 더 신뢰할만한 것처럼 보입니다.)

단일 공백으로 구분 된 문자열 또는 배열, 목록, 벡터 등으로 출력 될 수도 있습니다.

가능한 출력이 둘 이상있을 수 있습니다.

테스트 사례

나열된 출력은 단지 예일뿐입니다. 위의 세 가지 규칙을 따르는 한 코드에서 다른 결과를 출력 할 수 있습니다 (특히, 예 와 동일한 의 이벤트 가 있어야 함을 의미 함 ).

에서 : 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

내가 놓친 엣지 케이스가 있으면 편집에 더 많은 테스트 사례를 추가하십시오.

규칙

  • 제공되는 모든 테스트 사례에 대해 코드를 30 초 이내에 완료해야합니다 (모든 테스트 사례에 대해 훨씬 더 빨리 완료해야하므로 적절한 상태 검사).

  • 이것은 이므로 바이트 단위의 가장 짧은 코드가 이깁니다.


입력의 이벤트에 camelCase를 사용할 수 있습니까? underwaterBasketWeavingConvention 50 800 nscc 550예를 들어 예제 대신 사용 합니까?
치명적인

4
@Fatalize 무슨 뜻인지 잘 모르겠습니다. 입력은 표시된 그대로 제공됩니다. 영숫자 문자 조합을 지원할 수 있어야합니다.
Doorknob

4
나중에 이것에 대한 해결책을 연구해야 할 것입니다. 지금 예약 충돌이 있습니다.
Alex A.

두 번째 예에서는 "CodeGolfing"과 "95"사이에 두 개의 공백이 있습니다. 이것은 실수입니까, 아니면 입력에서 임의의 수의 공백을 고려해야합니까? 지금은 입력 형식에 약간 관대 해 보이기 때문에 전자를 가정하겠습니다.
vijrox 2016 년

@VijayRamamurthy 그렇습니다. 결정된.
Doorknob

답변:


9

Pyth, 45 바이트

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

이것은 골프하기가 매우 힘들었습니다. 꽤 많은 45 바이트 솔루션을 찾았습니다. 이것은 A(pair-assign) 및 .g(group-by)를 사용하기 때문에 아마도 가장 이국적인 것 입니다.

온라인으로 사용해보십시오 : 데모 또는 테스트 장치

설명

                            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-도입부 537 524 516 502 447 436 바이트

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

각 술어의 기능에 대한 간단한 설명 :

  • z(A,B) 이벤트 A가 이벤트 목록 B의 이벤트와 충돌하지 않는지 확인
  • u(A,B)목록 A의 모든 이벤트가 목록 B의 이벤트와 충돌하지 않는지 확인합니다 (을 호출하여 목록 A에 충돌이 없는지 확인하는 데 사용 u(A,A))
  • y(A,B,C) 입력을 이벤트 목록으로 변환하기 위해 목록을 트리플렛 목록으로 분할합니다.
  • d(A) 목록 A에 이벤트 이름을 인쇄합니다.
  • l(A,R) 목록 A에 포함 된 가장 긴 이벤트 목록 R을 평가합니다.
  • v(A,NSCC,C,R) 내부 충돌이없고 NSCC 이벤트와 충돌하는 A의 모든 이벤트 목록을 포함하는 목록 R을 반환합니다.
  • s(A,B) B가 A의 부분 집합 인 경우 true
  • x(A) 기본 술어, A는 입력입니다.

테스트 사례 : test.위의 코드를로드 한 후 인터프리터에서 다음을 추가하여 실행 하십시오.

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

생각보다 시간이 많이 걸렸습니다. 이것은 아마도 훨씬 더 골프를 칠 수 있습니다. 또한 더 짧은 솔루션을 얻기 위해 존재하는 다양한 제약 조건 프로그래밍 라이브러리를 사용할 수 있습니다.

편집 : 트리플렛 A:B:C대신 사용하는 아이디어에 대한 @Oliphaunt에게 감사드립니다 [A,B,C]. 14 바이트를 저장합니다.

Edit2 : ``t / 3 ''가 쓸모가 없다는 점을 지적한 @Oliphaunt에게 다시 감사드립니다. 55 바이트 절약

EDIT3는 : 술어에 결정적인 절 문법을 사용하여 11 바이트 습득 한 yd.


프롤로그에서 사랑의 답변! 좋은데

나도 프롤로그 애호가입니다. 제안 : 1. 내가 생각하는 당신은 예를 들어, 사용할 수있는 A/B/C대신에 [A,B,C]10 바이트를 절약 세 쌍둥이를 위해; 2.\+ 대신 사용할 수 있습니까 not? 3. 왜 최종 컷이 필요한지 설명해 주 x(A)시겠습니까?
Oliphaunt-복원 Monica Monica

내 노트북에서 내일 다시 올게. 서투른 타이핑을하는 태블릿이있는 침대에서 지금은 어쨌든 잠을 자야합니다. :-)
Oliphaunt-복원 Monica Monica

1
다음 은 14 바이트를 절약하는 버전입니다. 나는 전자의 오른쪽 연관성으로부터 이익을 얻는 :대신에 사용 했다 /. 즉, 나는 A:_속기처럼 쓸 수 있었다 A:_:_(그러나 A+B/C잘 작동한다 : 당신은 사용할 수있다 A+_). 그건 그렇고, 원본에서도 [A|_]대신 사용할 수 [A,_,_]있습니다. 마지막으로 내 SWI-Prolog 버전에는이 없었으므로 대신 nth0/4사용 select/3했습니다.
Oliphaunt-모니카

1
나는 그 필요성에 대해 궁금해 t(S,T)했지만 잊었다. 테스트 완료 : 전체를 직접 삭제하고에서 직접 호출 s(E,L)하여 55 바이트를 더 절약 할 수 있습니다 setof/3.
Oliphaunt-복원 Monica Monica

6

자바 스크립트 ( ES6 ), 228

두 번째 시도, 나는 이것이 작동하기를 바랍니다.

내 목표는 타이밍 충돌이 있지만 NSCC 이벤트가 제거 될 때 타이밍 충돌이없는 가장 긴 이벤트 시퀀스입니다. NSCC가 제거 된이 수정 된 순서는 요청 된 출력입니다.

가장 먼저 시작하여 후보 솔루션 큐를 검사하는 너비 우선 검색을 사용합니다 (첫 번째는 첫 번째 목록 임). 의 후보 솔루션에서 N I 빌드 이벤트 대기열 N 개 후보 솔루션, 이벤트 중 하나를 제거하고 다른 사람을 유지.

'있는 그대로'타이밍 충돌이있는 경우 후보 솔루션이 유효하지만 NSCC 이벤트가 필터링 될 때 충돌이 없습니다. 하위 기능 K를 사용하여 충돌을 확인합니다.

아마 조금 더 골프를 칠 수 있습니다 ...

아래 스 니펫 실행 테스트 (EcmaScript 6, 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
함수를 호출하지 않으면 프로그램이 아무것도하지 않는 경우 스택 스 니펫을 요청할 수 있습니까?
Beta Decay

1
@BetaDecay : edc65는 일반적으로 스 니펫에서 실행되는 테스트 사례를 추가합니다. 그가 곧이 답변으로 돌아 오는 것처럼 들리며,이 시점에서 그는 실행 가능한 물건을 추가 할 것이라고 가정합니다. :)
Alex A.

1
@BetaDecay는 서두르고있었습니다. 그리고 (아직도) 테스트 중 하나가 실패합니다.
edc65

1

자바, 828 바이트

아마도 더 간결한 Java 구현이있을 수 있지만 여기에 내 찔림이 있습니다.

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

한 곳에서 모든 변수를 선언하면 바이트가 절약됩니다.
Spikatrix

필요하지 않습니다 else return.
lirtosiast

0

파이썬, 373 자

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]

가능한 모든 조합을 작성하고 각각을 점검하십시오.

테스트

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

산출:

디
기음
이자형
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.