Giải vô địch xung đột lịch trình quốc gia


25

xkcd: Xung đột lịch trình

(Tôi định đăng bài này trong khi 1542: Xung đột lập lịch vẫn là xkcd hiện tại, nhưng tôi đã có xung đột lịch trình.)

Đầu vào

Đầu vào sẽ là một danh sách các 3nyếu tố, đại diện cho ncác sự kiện. Phần tử đầu tiên trong mỗi nhóm 3 sẽ là tên của một sự kiện; lần thứ hai và thứ ba, thời gian bắt đầu và kết thúc tương ứng. Ví dụ:

foo 12 34 bar 56 78

đại diện cho một sự kiện foobắt đầu từ "thời gian 12" (thời gian được biểu thị đơn giản bằng số nguyên; bạn có thể nghĩ chúng là phút sau nửa đêm) và kết thúc lúc 34, và sự kiện thứ hai barbắt đầu từ 56 và kết thúc ở 78.

Tên của các sự kiện sẽ luôn chỉ bao gồm các ký tự chữ và số và thời gian sẽ luôn là các số nguyên ≥ 0 và <1440. Thời gian kết thúc sẽ luôn lớn hơn ít nhất 1 lần so với thời gian bắt đầu. Họ không được đảm bảo để được sắp xếp theo bất kỳ cách nào.

Nếu bạn muốn, bạn có thể coi đây là một chuỗi được phân tách bằng dấu cách; mặt khác, nó nên được sử dụng như một mảng, danh sách, vectơ hoặc ngôn ngữ của bạn.

Đầu ra

Đầu ra phải là một danh sách các tên sự kiện được phân tách bằng dấu cách. Các quy tắc cho tên sự kiện đầu ra như sau:

  • Không có sự kiện nào mà bạn xuất có thể xung đột với nhau. Ví dụ: với đầu vào a 0 10 b 5 15, bạn không thể xuất cả hai abvì xung đột thời gian (nghĩa là chồng chéo một phần). Nếu một sự kiện kết thúc chính xác khi một sự kiện khác bắt đầu, bạn có thể bao gồm cả hai.

  • Bạn không được xuất sự kiện có tên NSCC("Cạnh tranh xung đột theo lịch trình quốc gia"), trong đó sẽ luôn có một trong những sự kiện đầu vào. Bạn cũng phải xuất ít nhất một sự kiện xung đột (chồng chéo một phần) với NSCC(và sẽ luôn có ít nhất một trong số các sự kiện đó).

  • Bạn phải xuất ra càng nhiều sự kiện càng tốt trong khi tuân theo hai quy tắc trên. (Điều này là để bạn trông bận rộn nhất có thể, do đó, việc thiếu NSCC có vẻ đáng tin cậy hơn.)

Đây cũng có thể là đầu ra dưới dạng một chuỗi được phân tách bằng dấu cách hoặc một mảng, danh sách, vectơ, v.v.

Có thể có nhiều hơn một đầu ra có thể.

Các trường hợp thử nghiệm

Lưu ý rằng các đầu ra được liệt kê chỉ là ví dụ. Mã của bạn có thể xuất ra một cái gì đó khác nhau, miễn là nó vẫn tuân theo ba quy tắc ở trên (đáng chú ý, điều này có nghĩa là phải có cùng số lượng sự kiện như ví dụ).

Trong: UnderwaterBasketWeavingConvention 50 800 NSCC 500 550
Ra:UnderwaterBasketWeavingConvention

Trong: SconeEating 0 50 RegexSubbing 45 110 CodeGolfing 95 105 NSCC 100 200
Ra:SconeEating CodeGolfing

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

Trong: NSCC 110 115 A 100 120 B 120 140 C 105 135 D 100 105 E 135 500
Ra:C D E

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

Trong: A 10 11 B 11 12 C 12 13 D 13 14 NSCC 15 1090 E 10 16
Ra:E

Vui lòng thêm nhiều trường hợp thử nghiệm trong một chỉnh sửa nếu có các trường hợp cạnh mà tôi bỏ lỡ.

Quy tắc

  • Mã của bạn phải hoàn thành trong vòng 30 giây cho tất cả các trường hợp thử nghiệm được cung cấp (đây là phần kiểm tra độ tỉnh táo hơn, vì có lẽ nó sẽ hoàn thành nhanh hơn nhiều cho tất cả các trường hợp thử nghiệm được kết hợp) trên một máy cá nhân hợp lý.

  • Đây là , vì vậy mã ngắn nhất tính bằng byte sẽ thắng.


Có thể chấp nhận sử dụng camelCase cho các sự kiện trong đầu vào không? ví dụ sử dụng underwaterBasketWeavingConvention 50 800 nscc 550thay vì ví dụ của bạn?
Gây tử vong vào

4
@Firthize Không chắc ý của bạn là gì; đầu vào được đưa ra chính xác như nó được hiển thị. Bạn sẽ có thể hỗ trợ bất kỳ sự kết hợp của các ký tự chữ và số.
Doorknob

4
Tôi sẽ phải làm việc với một giải pháp cho vấn đề này sau; Tôi có một cuộc xung đột lịch trình ngay bây giờ.
Alex A.

Trong ví dụ thứ hai, có hai khoảng trắng giữa "CodeGolfing" và "95" - đây có phải là một lỗi hay chúng ta cần tính đến số lượng khoảng trắng tùy ý trong đầu vào? Ngay bây giờ, tôi sẽ giả sử trước đây, vì bạn có vẻ hơi khoan dung về định dạng của đầu vào.
vijrox

@VijayRamamurthy Vâng, đúng vậy. Đã sửa.
Doorknob

Câu trả lời:


9

Bình thường, 45 byte

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

Điều này là khá khó khăn để chơi golf. Tìm thấy khá nhiều giải pháp 45 byte, đây có thể là giải pháp kỳ lạ nhất, vì nó sử dụng A(gán cặp) và .g(theo nhóm).

Dùng thử trực tuyến: Trình diễn hoặc thử nghiệm khai thác

Giải trình

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

Giải thích ngắn gọn về những gì mỗi vị ngữ làm:

  • z(A,B) kiểm tra xem một sự kiện A không xung đột với bất kỳ sự kiện nào trong danh sách các sự kiện B
  • u(A,B)kiểm tra xem mọi sự kiện của danh sách A không xung đột với bất kỳ sự kiện nào của danh sách B (được sử dụng để kiểm tra rằng không có xung đột trong danh sách A bằng cách gọi u(A,A))
  • y(A,B,C) chia một Danh sách thành một danh sách các bộ ba (để chuyển đổi đầu vào thành một danh sách các sự kiện)
  • d(A) in tên các sự kiện trong danh sách A
  • l(A,R) đánh giá danh sách dài nhất các sự kiện R có trong danh sách danh sách A
  • v(A,NSCC,C,R) trả về danh sách R chứa mọi danh sách các sự kiện trong A không có xung đột nội bộ và xung đột với sự kiện NSCC
  • s(A,B) đúng nếu B là tập con của A
  • x(A) vị ngữ chính, A là đầu vào.

Các trường hợp kiểm tra : thực thi test.trong trình thông dịch sau khi tải mã ở trên với phần sau được thêm vào sau nó:

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

Điều này khiến tôi mất nhiều thời gian hơn tôi nghĩ. Điều này có thể có thể được chơi golf nhiều hơn đáng kể. Ngoài ra, bạn có thể có thể sử dụng các thư viện lập trình ràng buộc khác nhau tồn tại để có được các giải pháp ngắn hơn.

Chỉnh sửa: Cảm ơn @Oliphistic vì ý tưởng sử dụng A:B:Cthay vì [A,B,C]cho bộ ba. Lưu 14 byte.

Edit2: Một lần nữa xin cảm ơn @Oliphistic vì đã chỉ ra rằng vị từ `` t / 3` sẽ vô dụng. Lưu 55 byte

Edit3: Đạt được 11 byte bằng cách sử dụng ngữ pháp mệnh đề dứt khoát trên các vị ngữ yd.


Câu trả lời tình yêu trong Prolog! Đẹp một.
thúc

Tôi cũng là người yêu Prolog. Gợi ý: 1. Tôi nghĩ bạn có thể sử dụng ví dụ A/B/Cthay vì [A,B,C]cho bộ ba, tiết kiệm 10 byte; 2. Bạn có thể sử dụng \+thay vì not? 3. Bạn có thể giải thích lý do tại sao bạn cần cắt giảm cuối cùng x(A)?
Oliphistic - phục hồi Monica

Tôi sẽ quay lại với bạn vào ngày mai, từ máy tính xách tay của tôi. Ngay bây giờ trên giường với máy tính bảng khiến việc đánh máy vụng về và dù sao tôi cũng nên ngủ. :-)
Oliphistic - phục hồi Monica

1
Đây là một phiên bản tiết kiệm 14 byte. Tôi đã sử dụng :thay vì /để hưởng lợi từ tính kết hợp đúng của trình định dạng, do đó tôi có thể viết A:_như một cách viết tắt cho A:_:_(nhưng cũng A+B/Choạt động tốt: sau đó bạn có thể sử dụng A+_). Nhân tiện, trong bản gốc của bạn, bạn có thể đã sử dụng [A|_]thay vì [A,_,_]. Cuối cùng lưu ý rằng phiên bản SWI-Prolog của tôi không có nth0/4, vì vậy tôi đã sử dụng select/3thay thế.
Oliphistic - phục hồi Monica

1
Tôi tự hỏi trước đây về sự cần thiết t(S,T)nhưng rồi quên mất. Hiện đã được kiểm tra: bạn có thể lưu thêm 55 byte bằng cách loại bỏ hoàn toàn và gọi trực tiếp s(E,L)từ đó setof/3.
Oliphistic - phục hồi Monica

6

JavaScript ( ES6 ), 228

Lần thử thứ hai, tôi hy vọng cái này hoạt động.

Mục tiêu của tôi là chuỗi sự kiện dài nhất có xung đột thời gian, nhưng không có xung đột thời gian khi sự kiện NSCC bị xóa. Trình tự sửa đổi với NSCC bị loại bỏ là đầu ra được yêu cầu.

Tôi sử dụng Tìm kiếm đầu tiên Breadth kiểm tra hàng đợi các giải pháp ứng cử viên, bắt đầu với thời gian dài nhất (đầu tiên là danh sách ban đầu). Từ một giải pháp ứng cử viên của n sự kiện tôi xây dựng và liệt kê thêm n giải pháp ứng cử viên, loại bỏ một trong những sự kiện và giữ lại những sự kiện khác.

Một giải pháp ứng cử viên là hợp lệ nếu có xung đột thời gian 'như hiện tại', nhưng khi sự kiện NSCC được lọc ra thì không có xung đột. Tôi sử dụng một chức năng con K để kiểm tra xung đột.

Có lẽ có thể chơi gôn nhiều hơn một chút ...

Kiểm tra chạy đoạn mã bên dưới (chỉ là EcmaScript 6, chỉ 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
Tôi có thể hỏi điểm của Stack Snippet nếu chương trình không làm gì nếu bạn không gọi hàm?
Beta Decay

1
@BetaDecay: edc65 thường thêm các trường hợp thử nghiệm chạy trong đoạn mã. Có vẻ như anh ấy sẽ sớm trở lại câu trả lời này, lúc đó tôi cho rằng anh ấy sẽ thêm những thứ có thể chạy được. :)
Alex A.

1
@BetaDecay đã vội vàng. Và (tệ hơn nữa) nó thất bại một trong những bài kiểm tra.
edc65

1

Java, 828 byte

Có lẽ có một triển khai Java ngắn gọn hơn ngoài kia, nhưng đây là cú đâm của tôi:

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

Khai báo tất cả các biến ở một nơi sẽ tiết kiệm byte.
Spikatrix

Bạn không cần else return.
lirtosiast

0

Con trăn, 373 ký tự

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]

Tạo tất cả các kết hợp có thể và kiểm tra từng cái.

Kiểm tra

Đầu vào: ["NSCC",110,115,"A",100,120,"B",120,140,"C",105,135,"D",100,105,"E",135,500]

Đầu ra:

D
C
E
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.