Tìm xem ai sẽ đến lượt mua bánh sừng bò, tính đến sự vắng mặt có thể


13

Một nhóm đã quyết định rằng mỗi buổi sáng ai đó nên mang bánh sừng bò cho mọi người. Không nên cùng một người mỗi lần, vì vậy cần có một hệ thống để xác định lượt tiếp theo của ai. Mục đích của câu hỏi này là để xác định một thuật toán để quyết định lượt của nó sẽ mang bánh sừng bò vào ngày mai.

Những ràng buộc, giả định và mục tiêu:

  • Ai sẽ mang bánh sừng bò vào buổi chiều hôm trước.
  • Vào bất kỳ ngày nào, một số người vắng mặt. Thuật toán phải chọn ai đó sẽ có mặt vào ngày hôm đó. Giả sử rằng tất cả sự vắng mặt được biết trước một ngày, vì vậy người mua bánh sừng bò có thể được xác định vào chiều hôm trước.
  • Nhìn chung, hầu hết mọi người có mặt vào hầu hết các ngày.
  • Vì lợi ích của sự công bằng, mọi người nên mua bánh sừng bò nhiều lần như những người khác. (Về cơ bản, giả sử rằng mọi thành viên trong nhóm đều có cùng số tiền để chi cho bánh sừng bò.)
  • Sẽ thật tốt nếu có một số yếu tố ngẫu nhiên, hoặc ít nhất là cảm nhận được sự ngẫu nhiên, để làm giảm bớt sự nhàm chán của một danh sách. Đây không phải là một hạn chế cứng: nó là một đánh giá thẩm mỹ nhiều hơn. Tuy nhiên, cùng một người không nên được chọn hai lần liên tiếp.
  • Người mang bánh sừng bò nên biết trước. Vì vậy, nếu người P mang bánh sừng bò vào ngày D, thì thực tế này nên được xác định vào một ngày trước đó, nơi người P có mặt. Ví dụ, nếu người bán bánh sừng bò luôn được xác định ngày hôm trước, thì đó phải là một trong những người có mặt ngày hôm trước.
  • Số lượng thành viên trong nhóm đủ nhỏ để tài nguyên lưu trữ và tính toán có hiệu quả không giới hạn. Ví dụ, thuật toán có thể dựa vào một lịch sử đầy đủ về người đã mang bánh sừng bò khi trong quá khứ. Lên đến vài phút tính toán trên PC nhanh mỗi ngày sẽ ổn.

Đây là mô hình của một vấn đề trong thế giới thực, vì vậy bạn có thể tự do thách thức hoặc tinh chỉnh các giả định nếu bạn nghĩ rằng họ mô hình hóa kịch bản tốt hơn.


Nguồn gốc 1: Tìm hiểu xem ai sẽ mua bánh sừng bò của Florian Margaine.
Nguồn gốc 2: Tìm hiểu ai sẽ mua bánh sừng bò của Gilles.
Câu hỏi này giống với phiên bản của Gilles và đã được đăng lại trên Lập trình viên dưới dạng thử nghiệm để xem các cộng đồng khác nhau giải quyết thách thức lập trình như thế nào.


2
Đã thêm thông báo bài đăng, tôi sẽ bảo vệ nếu cần nhưng tôi muốn giữ thông tin đó càng lâu càng tốt. Liên quan đến câu hỏi này theo bất kỳ cách nào khác nhau, nó là một thử nghiệm. Nó sẽ vẫn mở. Cho khoa học!
Kỹ sư thế giới

4
Phù hợp hơn cho Code Golf?
ozz

3
Ai quan tâm? Không có đội tự tôn sẽ có bánh sừng bò. Bây giờ, mặt khác, bánh rán , đó là một câu hỏi thú vị.
Ross Patterson

3
Điều này nghe có vẻ như là một trường hợp sử dụng hoàn hảo cho DA Form 6 (quái gì, nó đã làm việc cho Quân đội từ năm 1974!). Xem AR 220-45 để sử dụng. Nó nên tương đối đơn giản để dịch nó thành một thuật toán.
Adam Balsam

2
(để mở rộng trên @AdamBalsam dưới dạng armypub.army.mil/eforms/pdf/A6.PDF và sử dụng apd.army.mil/pdffiles/r220_45.pdf ... và vui lòng không đề xuất điều này với chủ cũ của tôi, họ có đủ chính sách và thủ tục như vậy)

Câu trả lời:


26

Tôi sẽ sử dụng thuật toán chấm điểm. Mỗi người bắt đầu với số điểm bằng không. Mỗi lần họ mang bánh sừng bò, tăng số điểm của họ lên 1. Điểm của tất cả các thành viên trong nhóm không mang bánh sừng bò bị giảm đi 1 / N. Do đó, điểm 0 có nghĩa là một thành viên trong nhóm không được mua hoặc mua.

Nếu không có sự ngẫu nhiên, hãy chọn người có điểm thấp nhất trong danh sách những người sẽ có mặt.

Để thêm tính ngẫu nhiên, hãy sắp xếp danh sách theo điểm số và chọn ngẫu nhiên trong danh sách tất cả các thành viên trong nhóm có điểm âm. Bằng cách hạn chế điểm số âm, bạn đảm bảo rằng không ai sẽ quá "may mắn" trong nhiều tuần.

Ưu điểm của thuật toán này là nó không phụ thuộc vào việc lưu giữ các hồ sơ lịch sử và nó dễ dàng cho phép bổ sung các thành viên nhóm mới bất cứ lúc nào.

Nó có thể được điều chỉnh để cho phép sự vắng mặt tương đối phổ biến bằng cách giảm điểm của chỉ những người có mặt để thưởng thức bánh sừng bò.


3
Tôi nghĩ rằng đoạn cuối cùng của bạn là rất cần thiết, nếu không, một người nào đó đi nghỉ trong một tháng (có thể là tuần trăng mật) sẽ trở lại với số điểm tiêu cực lớn và mua nhiều.
James

8
Cũng có thể điều chỉnh: -1 nếu bạn ăn bánh ngọt do người khác mang đến. (N-1) nếu bạn mua bánh ngọt. Theo cách đó, nếu ai đó gặp may mắn và chỉ mua cho 4 người thì ngày hôm sau người đó không may mắn và mua cho 7 người, hai lần mua đó không được đối xử như nhau. -1 vì một chiếc bánh ngọt bạn mua cho mình là trung tính.
James

@James, không sợ hãi; OP ở Mỹ và không ai ở Mỹ có được bất kỳ nơi nào gần kỳ nghỉ đó. :(
Kyralessa

@James Vâng, đó là một cải tiến tốt.
Gort Robot

7

Những gì tôi sẽ làm, nếu tôi phải chọn cái này, là lấy một cái mũ và đặt tên của mọi người vào chiếc mũ một lần trên những mảnh giấy nhỏ. Sau đó, mỗi ngày, tôi sẽ rút tên của ai đó một cách ngẫu nhiên và đó là người mang bánh sừng bò vào ngày hôm sau. Tờ giấy đó sau đó được xử lý trên một bảng, trong mục "MANG LẠI CROISSANTS TOMORWAY". Tờ giấy hiện đang ở trên bảng bị vứt đi.

Tôi cũng có một cái hộp. Nó bắt đầu trống rỗng. Mỗi ngày, trước khi vẽ tên, tôi sẽ bỏ nội dung của chiếc hộp vào chiếc mũ, sau đó đi qua các tờ giấy trong chiếc mũ và loại bỏ tất cả những người sẽ vắng mặt vào ngày mai. Tên của họ đi trong hộp.

Nếu đã đến lúc vẽ tên và chiếc mũ trống rỗng, tôi sẽ xé thêm một số giấy và thêm tên của mọi người một lần, sau đó di chuyển tên của tất cả những người sẽ vắng mặt vào ngày mai vào hộp.

Vì hai bước cuối cùng này, có thể cùng một tên sẽ ở trong mũ nhiều lần cùng một lúc. Nếu tên tôi tình cờ vẽ giống như tên trên bảng, tôi sẽ di chuyển tờ giấy đó vào hộp, rồi vẽ lại.

Không quá khó để dịch hệ thống này sang một thuật toán bằng ngôn ngữ bạn chọn.


Sắp xếp qua chiếc mũ cho tất cả những người sắp ra ngoài dường như là một nỗi đau thực sự.
Bobson

@Bobson: Câu hỏi đặc biệt nói rằng quy mô của đội tương đối nhỏ. Nếu tôi đang xử lý một tập dữ liệu lớn, tôi sẽ làm một cái gì đó tinh vi hơn.
Mason Wheeler

6

Thuật toán, thuật toán. Sử dụng DB.

create table team_members 
(
    id integer auto_increment,
    name varchar(255),
    purchase_count integer,
    last_purchase_date datetime,
    present integer,
    prefers_donuts integer default 0,
    primary key( id)
)

Ai mua?

select id from team_members where (present = 1) and (prefers_donuts = 0) order by purchase_count, last_purchase_date limit 1;

Sau khi họ mua:

update team_members set purchase_count = purchase_count + 1, last_purchase_date = now() where id = ?

Và sau đó thiết lập:

insert into team_members (name, prefers_donuts) values ('GrandmasterB', 1);

... bởi vì tôi là trường học cũ.

Không nên quá khó khăn để thêm một chút ngẫu nhiên bằng cách điều chỉnh truy vấn đầu tiên - có thể bằng cách thêm một ngẫu nhiên () thay vì sắp xếp theo ngày cuối cùng.


1
+1. Đối với tuyển dụng mới, bạn có khởi tạo purchase_countmức trung bình của mọi người khác không?
Dan Pichelman

6
Hmm, câu hỏi rất hay. Điều đó có thể sẽ làm việc. Hoặc bạn chỉ có thể làm cho anh chàng mới mang bánh sừng bò vào mỗi buổi sáng cho đến khi anh ta bắt kịp. Anh ấy là người mới.
GrandmasterB

4

Tôi thực sự đã phải giải quyết vấn đề này phần nào trong thế giới thực:

remember how many times people have gotten donuts
every day:
  var candidates = everyone
  toss out people who aren't here tomorrow
  toss out people who aren't here today 
  toss out the person who got them today (unless they're the only one left)
  toss out everyone where "times they got donuts"/"times everyone has got donuts"
    is more than 1/number of people (unless that would eliminate everyone)

  pick someone at random from the candidates

Điều gì xảy ra là những người đã mua bánh rán "quá nhiều" (do không may mắn, sẽ đi làm khi những người khác đang đi nghỉ, v.v.) bị loại khỏi hồ bơi cho đến khi đủ số lần mua lại để đưa họ trở lại dưới phần trăm "đúng" mua hàng.

Điều này sẽ cần được mở rộng để xử lý tốt hơn việc thuê người mới mặc dù ...

Dù sao, thiết kế này đã làm việc thực sự tốt để thay đổi các biến (ai vào, ai ra) và khi lịch trình cần phải là (thực tế) vô hạn. Là một phần thưởng bổ sung, thật dễ dàng để đưa ra quyết định bằng cách gieo RNG của bạn.


2

Không tốt như một số câu trả lời khác đã được trình bày, nhưng một cách khác để xem xét vấn đề:

  1. Lập danh sách tất cả nhân viên tham gia
  2. Sao chép danh sách rất nhiều lần (giả sử, 1.000)
  3. Xáo trộn danh sách

Mỗi buổi chiều, chọn croissant-bringer tiếp theo. Mỗi buổi sáng, croissant-bringer vượt qua tên của anh ấy / cô ấy ra khỏi đầu danh sách.

Xử lý hàng ngày là bút & giấy đơn giản.

Cựu sinh viên tuyển dụng và chấm dứt có lẽ sẽ được xử lý tốt nhất bằng cách lập một danh sách mới. Nếu chu kỳ CPU trở nên đắt đỏ trở lại (hoặc bạn có 100 triệu nhân viên và chỉ có Arduino thế hệ thứ nhất) thì có thể dễ dàng bỏ qua danh sách ban đầu với số lượng người giữ chỗ thích hợp.


Thêm thông tin (theo yêu cầu).

Sử dụng phương pháp này với một danh sách dài tùy ý, bạn sẽ có được lợi ích của tính minh bạch.

Bạn không chỉ biết ai sẽ mang bánh sừng bò vào ngày mai, mà bạn còn biết ai sẽ lên kế hoạch mang chúng vào ngày hôm sau, v.v. Tất nhiên, càng xa thời gian bạn trông càng kém chính xác thì bạn sẽ vắng mặt, v.v.

Những nhà phát triển lén lút tìm ra cách để cân những tờ giấy của họ trong một chiếc mũ sẽ không có nhiều cơ hội để tránh nhiệm vụ mang bánh sừng bò của họ.

Những người không phải là nhà phát triển yêu cầu xử lý bị gian lận có thể dễ dàng xem xét dữ liệu, đưa ra kết luận sai và dù sao cũng rên rỉ.


1
Chấm dứt ? Ghenghis Khan chấp thuận bài này.
Thợ săn hươu

1
@DeerHunter Tôi luôn không thích cách nói của HR về "chấm dứt con người". Nó mang đến cho tâm trí đội bắn. Có lẽ tôi nên nói "Hires & Al cựu sinh viên mới ...".
Dan Pichelman

1

Không ngẫu nhiên

Duy trì một danh sách theo thứ tự. Nếu một người vắng mặt vào ngày họ phải mua, hãy trao đổi họ với người có sẵn tiếp theo. Cuối cùng, người đó sẽ có mặt và do đó mua bánh sừng bò. Vì vậy, nội dung của danh sách vẫn giữ nguyên, nhưng mọi người có thể được di chuyển lên hoặc xuống tùy theo sự vắng mặt.

Những người mới được chèn vào danh sách sau vị trí hiện tại. Những người bỏ hoặc chấm dứt được xóa khỏi danh sách. Vị trí hiện tại tăng thêm 1 mỗi ngày, khi đến cuối, nó sẽ quay trở lại bắt đầu.

Điều này giả định có đủ người trong danh sách để tính thời gian vắng mặt trung bình để thúc đẩy sự công bằng.

Ngẫu nhiên

Chúng ta không thể chỉ chọn những người ngẫu nhiên mỗi ngày vì sẽ có sự thiên vị ngắn hạn, ví dụ lật một đồng xu 10 lần và bạn có thể đi lên đầu 8 và đuôi 2, vì vậy những cái đầu sẽ bị vặn trong thời gian ngắn. Vì vậy, chúng ta cần tạo ra những nhóm người để giữ cho nó công bằng.

Các thùng được xác định bởi số lần mọi người đã mua chéo trong quá khứ. Vì vậy, trong trường hợp này, chúng tôi sẽ lưu trữ một từ điển của mọi người và mua chéo. Vào ngày 1 mọi người đều ở trong số không. Khi mọi người mua croissiants, họ sẽ được chỉ định cho nhóm tiếp theo, tức là 1, 2, v.v ... Phần ngẫu nhiên là chọn từ nhóm người có sẵn trong thùng. Thùng có sẵn đầu tiên là thùng có số lượng mua ít nhất. Nếu có 10 người trong xô, sau đó chọn một số ngẫu nhiên từ 1 đến 10 và người đó mua bánh sừng bò. Những người mới được chỉ định nhóm thấp nhất hiện tại để cuối cùng họ không mua thêm vòng chéo (mặc dù họ sẽ ở trong nhóm mua ngay lập tức). Nếu không có ai trong thùng thấp nhất (tất cả đều vắng mặt), thì bạn đi đến thùng cao nhất tiếp theo. Ví dụ: hãy ' s nói có một danh sách 10 người. Vào ngày 8, 8 người ở trong thùng 1 và 2 ở trong thùng 0. Hai người trong xô 0 vắng mặt. Trong trường hợp này, xô 1 sẽ được sử dụng và một người sẽ kết thúc ở xô 2. Nhưng, mọi người sẽ luôn ở trong một vài lần mua chéo (xô) trong nhau, bởi vì người bây giờ trong xô 2 rất có thể sẽ không ở trong Các hồ bơi mua trong một thời gian.

Tinh chỉnh có thể được thêm vào để đảm bảo cùng một người không mua hai ngày liên tiếp và có một số trường hợp cạnh để xử lý, nhưng điều này sẽ thêm một yếu tố ngẫu nhiên cũng như giữ cho nó công bằng. Ngoài ra, người ta có thể muốn giữ cho các giao dịch mua croissant thực tế so với xô hiện tại được tách ra. Khi mọi người rời đi, sẽ bị xóa khỏi xô bằng cách đánh dấu họ vắng mặt vĩnh viễn hoặc xóa chúng hoàn toàn.


1
Đã thêm triển khai ngẫu nhiên.
Jon Raynor
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.