ナショナルスケジューリングコンフリクトチャンピオンシップ


25

xkcd:競合のスケジューリング

1542:Scheduling Conflict が現在のxkcdである間にこれを投稿するつもりでしたが、スケジューリングの競合がありました。)

入力

入力は3nnイベントを表す要素のリストになります。3の各グループの最初の要素はイベントの名前になります。2番目と3番目、それぞれ開始時刻と終了時刻。例えば:

foo 12 34 bar 56 78

foo「時刻12」で始まるイベント(時刻は単純に整数で表されます。時刻は真夜中過ぎの分と考えることができます)と34で終了しbar、56で始まり78で終了する2番目のイベントを表します。

イベントの名前は常に英数字のみで構成され、時刻は常に0以上1440未満の整数になります。終了時刻は常に開始時刻より少なくとも1大きくなります。それらは、いかなる方法でもソートされることを保証されません。

必要に応じて、スペースで区切られた単一の文字列としてこれを使用できます。それ以外の場合は、配列、リスト、ベクトル、または言語の同等物として取得する必要があります。

出力

出力は、スペースで区切られたイベント名のリストである必要があります。出力するイベント名のルールは次のとおりです。

  • 出力するイベントが互いに競合することはありません。たとえば、input a 0 10 b 5 15では、時間が競合するため(つまり、部分的に重複するため)、両方aを出力することはできませんb。イベントが別のイベントの開始と同時に終了する場合、両方を含めることができます。

  • NSCC「National Scheduling Conflict Competition」と呼ばれるイベントを出力することはできません。このイベントでは、常に入力に1つが含まれます。また、競合する(少なくとも部分的に重複する)イベントを少なくとも1つ出力する必要がありますNSCC(常に少なくとも1つが存在します)。

  • 上記の2つのルールに従って、できるだけ多くのイベントを出力する必要があります。(これは、できるだけ忙しいように見えるようにするためです。そのため、NSCCの欠落はより信頼できるように見えます。)

これは、単一のスペースで区切られた文字列または配列、リスト、ベクトルなどとして出力される場合もあります。

複数の出力が存在する可能性があります。

テストケース

リストされている出力は例にすぎないことに注意してください。上記の3つのルールに従っている限り、コードは異なるものを出力する可能性があります(特に、これは例と同じのイベントが存在する必要があることを意味します)。

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

私が見逃したエッジケースがある場合は、編集でさらにテストケースを追加してください。

ルール

  • 提供されたすべてのテストケースについて、コードは30秒以内に完了する必要があります(これはおそらく、すべてのテストケースを組み合わせた場合にはるかに高速に完了するため、健全性チェックになります)。

  • これはであるため、バイト単位の最短コードが優先されます。


入力のイベントにcamelCaseを使用することは許容されますか?underwaterBasketWeavingConvention 50 800 nscc 550たとえば、あなたの例の代わりに使用していますか?
15年

4
@Fatalizeどういう意味かわかりません。入力は表示されているとおりに与えられます。英数字の任意の組み合わせをサポートできるはずです。
ドアノブ

4
後でこれに対する解決策を検討する必要があります。現在、スケジュールの競合があります。
アレックスA.

2番目の例では、「CodeGolfing」と「95」の間に2つのスペースがあります。これは間違いですか、それとも入力のスペースの任意の数を考慮する必要がありますか?とりあえず、前者を想定します。これは、入力の形式について少し寛容に思えるからです。
vijrox

@VijayRamamurthyはい、そうです。一定。
ドアノブ

回答:


9

Pyth、45バイト

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

これはゴルフにはかなり難しかった。かなりの数の45バイトのソリューションが見つかりましたが、これはおそらくA(ペア割り当て)と.g(グループ化)を使用するため、最もエキゾチックなソリューションです。

オンラインで試す:デモンストレーションまたはテストハーネス

説明

                            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) 内部の競合がなく、イベント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バイト節約します。

編集2:述語「t / 3」は役に立たなかったことを指摘してくれた@Oliphauntに再び感謝します。55バイト節約

Edit3:述語yとの確定句文法を使用して11バイトを得ましたd


プロローグの答えが大好き!良いですね。
-18:

私もプロローグ愛好家です。提案:1.トリプレットの代わりに、たとえば10バイトを節約できると思います。2.の代わりに使用できますか?3.なぜ最終カットが必要なのか説明してもらえますか?A/B/C[A,B,C]\+notx(A)
オリファント-モニカを復元2015年

明日、私のラップトップから戻ってきます。今はベッドに横たわっているので、不器用なタイピングができて、とにかく寝るべきでしょう。:-)
オリファント-モニカの復元15年

1
これは、14バイトを節約するバージョンです。:代わりに/、前者の右結合性の恩恵を受けるために使用しました。つまりA:_、短縮形として書くことができますA:_:_(ただしA+B/C、同様に機能します:を使用できますA+_)。ちなみに、オリジナルでも、の[A|_]代わりに使用できます[A,_,_]。最後に、私のバージョンのSWI-Prologにはないのでnth0/4select/3代わりに使用したことに注意してください。
Oliphaunt -モニカ復活

1
私は以前にその必要性について疑問に思っていましたt(S,T)が、その後忘れていました。テスト済み:完全にドロップしてから直接呼び出してs(E,L)、さらに55バイト節約できますsetof/3
オリファント-モニカを復元15年

6

JavaScript(ES6)、228

もう一度試して、これがうまくいくことを願っています。

私のターゲットは、タイミングの競合があるイベントの最も長いシーケンスですが、イベントNSCCが削除されると、タイミングの競合はありません。NSCCが削除されたこの変更されたシーケンスは、要求された出力です。

Breadth First Searchを使用して、候補ソリューションのキューを調べ、最長のものから開始します(最初は最初のリストです)。n個のイベントの候補ソリューションから、さらにn個の候補ソリューションを構築してキューに入れ、イベントの1つを削除し、他のイベントを保持します。

タイミングの競合が「現状のまま」存在する場合、候補ソリューションは有効ですが、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
関数を呼び出さないとプログラムが何もしない場合、スタックスニペットのポイントを尋ねることができますか?
ベータ崩壊

1
@BetaDecay:edc65は通常、スニペットで実行されるテストケースを追加します。彼はすぐにこの答えに戻ってくるように聞こえますが、その時点で彼は実行可能なものを追加すると思います。:)
アレックスA.

1
@BetaDecayは急いでいた。そして(さらに悪いことに)テストの1つに失敗します。
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"};}

すべての変数を1か所で宣言すると、バイトを節約できます。
Spikatrix

する必要はありませんelse return
リトシアスト

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
E
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.