全国排程冲突锦标赛


25

xkcd:计划冲突

(我打算在1542年发布此消息:调度冲突 仍然是当前的xkcd,但是我遇到了调度冲突。)

输入项

输入将是3n代表n事件的元素列表。每3个组中的第一个元素将是事件的名称;第二和第三,分别是开始时间和结束时间。例如:

foo 12 34 bar 56 78

表示一个事件foo始于“时间12”(时间仅用整数表示;您可以将它们视为午夜之后的分钟),结束于34,第二个事件bar始于56,结束于78。

事件的名称将始终仅由字母数字字符组成,并且时间将始终为≥0且<1440的整数。结束时间将始终比开始时间至少大1。不保证它们会以任何方式进行排序。

如果愿意,可以将其作为单个以空格分隔的字符串;否则,应将其视为数组,列表,向量或您的语言的等效形式。

输出量

输出应为事件名称的空格分隔列表。输出事件名称的规则如下:

  • 您输出的所有事件都不会相互冲突。例如,对于input a 0 10 b 5 15,您可能不会同时输出两者ab因为时间冲突(即部分重叠)。如果一个事件恰好在另一个事件开始时结束,则可以同时包含这两个事件。

  • 您可能不会输出称为NSCC“国家日程安排冲突竞赛” 的事件,该事件中始终始终只有一个是输入。您还必须输出至少一个与之发生冲突(部分重叠)的事件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不确定您的意思;输入的输入与显示的完全相同。您应该能够支持字母数字字符的任何组合。
门把手

4
稍后,我将致力于解决这个问题。我现在有安排冲突。
Alex A.

在第二个示例中,“ CodeGolfing”和“ 95”之间有两个空格-这是一个错误,还是我们需要考虑输入中任意数量的空格?现在,我将采用前者,因为您似乎对输入格式有些宽容。
vijrox

@VijayRamamurthy是的,是的。固定。
门把手

Answers:


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-Prolog的,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) 将List拆分为三联列表(将输入转换为事件列表)
  • d(A) 打印列表A中的事件名称
  • l(A,R) 计算包含在列表A中的最长事件R的列表
  • v(A,NSCC,C,R) 返回一个列表R,其中包含A中没有内部冲突且与事件NSCC冲突的所有事件列表
  • 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]).

这花了我很多时间,超出了我的预期。这可能打得更多。同样,您可能可以使用现有的各种约束编程库来获得更短的解决方案。

编辑:感谢@Oliphaunt为使用A:B:C而不是[A,B,C]三胞胎的想法。节省14个字节。

Edit2:再次感谢@Oliphaunt指出谓词``t / 3`是无用的。节省55个字节

Edit3:在谓词y和上使用确定性子句语法获得11个字节d


喜欢Prolog中的答案!好东西。
2015年

我也是Prolog爱好者。意见建议:1.认为您可以使用例如A/B/C代替[A,B,C]三联体,节省10个字节;2.可以\+代替使用not吗?3.您能否解释为什么需要最终切入x(A)
Oliphaunt-恢复莫妮卡2015年

明天我会从笔记本电脑上找您。现在躺在床上,平板电脑很笨拙,我可能还是应该睡觉。:-)
Oliphaunt-恢复莫妮卡

1
是一个节省14个字节的版本。我以前:不是/从前者的右联想中受益,也就是说,我可以写A:_为速记A:_:_(但A+B/C效果也不错:您可以使用A+_)。顺便说一句,您也可以使用原本的来[A|_]代替[A,_,_]。最后请注意,我的SWI-Prolog版本没有nth0/4,所以我select/3改用了。
Oliphaunt-恢复莫妮卡2015年

1
我以前想知道是否需要,t(S,T)但后来忘记了。现在经过测试:您可以将其完全删除并直接s(E,L)从调用,以节省55个字节setof/3
Oliphaunt-恢复莫妮卡

6

JavaScript(ES6),228

第二次尝试,希望这一工作。

我的目标是具有时间冲突的最长事件序列,但是删除事件NSCC时没有时间冲突。删除了NSCC的此修改后的序列是请求的输出。

我使用广度优先搜索来检查候选解决方案的队列,从最长的开始(第一个是初始列表)开始。从n个事件的候选解决方案中,我构建并排队了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 2015年

1
@BetaDecay:edc65通常会添加在代码段中运行的测试用例。听起来他将很快返回到此答案,这时我认为他将添加可运行的内容。:)
Alex A.

1
@BetaDecay着急。并且(更糟糕的是)它没有通过一项测试。
edc65

1

Java,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

Python,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]

输出:

d
C
Ë
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.