Ruby
1# encoding: utf-8
2
3data = (1..30).to_a
4name = ('A'..'O').to_a
5hash = {}
6
7# シフトのサンプルを作成
8
9siken = []
10
11=begin
1215.times do |n|
13 t = data.sample(rand(1..30)).sort
14 hash[:"#{name[n]}"] = t
15 siken << t
16end
17=end
18
19sample = [
20 ['A', []],
21 ['B', [1]],
22 ['C', [1, 2, 13]],
23 ['D', [3, 2, 6]],
24 ['E', [2, 14, 23, 24, 29, 5]],
25 ['F', [4, 8, 7]],
26 ['G', [23, 27]],
27 ['H', [4]],
28 ['I', [15, 12, 11]],
29 ['J', [3, 6, 9, 12, 13]],
30 ['K', [7, 8]],
31 ['L', [4, 8, 3]],
32 ['M', [12, 15, 19]],
33 ['N', [21, 22]],
34 ['O', [30]]
35]
36
37sample.each do |key, value|
38 hash[key.to_sym] = value
39 siken << value
40end
41
42# シフトのサンプルから一日ごとに一か月の間に各人が入れる日の配列作成
43list = []
4430.times do |x|
45 tmp_list = []
46 hash.each do |key, value|
47 if value.include?(x + 1)
48 tmp_list << key.to_s
49 end
50 end
51 list << tmp_list
52end
53
54# 各人の入れる回数を数えて入れる日が少ない順に並べる
55check_list = list.flatten
56name.map!{|e| [check_list.count(e), e]}.shuffle! # ここを変更(shuffle or sort)
57
58# シフトの情報作成
59sift = []
60name.each do |c|
61 test = hash[c[1].to_sym]
62 tmp = []
63 test.each do |e|
64 if data.include?(e)
65 tmp << e
66 end
67 end
68 day = tmp.sample(2)
69 sift << [c[1], day]
70 data -= day
71end
72
73# 残った日の割り当て
74sift.sort!
75name.map!{|e| e[1]}.sort!
76check = (1..30).to_a - sift.map{|e| e[1]}.flatten
77
78unless check.size.zero?
79 name_list = []
80 check.each do |d|
81 key = list[d - 1].sample
82 next if key.nil?
83 sift[name.index(key)][1].push(d)
84 end
85end
86
87# 出力
88a = []
89sift.each do |n, v|
90 a << v
91 puts "#{n}:#{v.sort.join(',')}"
92end
93
94# 確認用
95puts '-' * 20
96a.each_with_index do |e, i|
97 flags = false
98 e.each do |ee|
99 unless siken[i].include?(ee)
100 flags = true
101 end
102 end
103 p flags
104end
105
106a.flatten!
107p a.size
108p a.uniq.size
実行結果例
A:
B:1
C:2,13
D:3,6
E:5,14,24,29
F:
G:23,27
H:4
I:11,15
J:9
K:7,8
L:
M:12,19
N:21,22
O:30
データベースは分かりませんが考えてみました。
入れる日が少ない人から順に2つずつ日を選べるようにしました。
1日しか入れない人は1日だけ表示されます。
#補足
私のコードだとsampleのLのようにシフトが割り当てられない場合があります。
2017/05/10追記
shuffleをつけてみました。この変更で場合によってLにもシフトが割り当てられるようになりました。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。