-
Notifications
You must be signed in to change notification settings - Fork 19
/
shift_picker.rb
157 lines (133 loc) · 11.8 KB
/
shift_picker.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# frozen_string_literal: true
#### Org Shift Picker
## Inputs
## Copy org preferences and shift information into this section.
# =============================================================================
# Use the org names from the seeds file so that the output can be used directly in seeds, should be in the order they submitted prefs
orgs = %w[aepi_org aphi_org aphio_org asa_org asig_org astro_org axo_org ddd_org dg_org
dtd_org fringe_org kapsig_org kat_org kgb_org kkg_org math_org mayur_org mcs_org phidelt_org sae_org sdc_org sigchi_org sigep_org spirit_org tsa_org]
# How many shifts get assigned to each org, it will assign shifts to orgs who submitted prefs earlier first
sizes = [6, 6, 6, 6, 5, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 6, 6, 3, 3, 6, 2, 6]
# Org prefs, make sure highest_pref matches your form's highest preference
$highest_pref = 5
$prefs = [
[3, 2, 1, 1, 1, 1, 2, 2, 4, 5, 5, 5, 4, 3, 1, 1, 1, 1, 2, 2, 4, 5, 5, 5, 5, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 2, 1, 1, 1, 1, 4, 5, 5, 5, 5, 5, 4, 2, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 2, 1, 1, 1, 2, 3, 3, 2, 1, 1],
[2, 2, 2, 2, 2, 2, 3, 5, 5, 5, 5, 5, 4, 4, 2, 2, 2, 2, 4, 5, 5, 5, 5, 5, 3, 3, 2, 2, 2, 2, 2, 3, 3, 4, 4, 4, 4, 3,
2, 2, 2, 2, 2, 3, 3, 4, 4, 4, 4, 3, 2, 2, 2, 2, 2, 3, 3, 4, 4, 4, 4, 3, 3, 2, 2, 2, 3, 4, 4, 4, 4, 4, 4, 3, 2, 2, 2, 2, 3, 4, 4, 4, 4, 3, 2, 2, 1, 1, 1, 2, 2, 5, 5, 5, 5, 4, 3, 3, 1, 1, 1, 3, 4, 4, 4, 3, 3],
[5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5],
[1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 5, 5, 3, 1, 1, 3, 3, 3, 3, 3, 5, 5, 5, 5, 3, 1, 1, 3, 3, 4, 4, 1, 2, 2, 2, 5, 3, 1, 1, 1, 1, 1, 1, 1],
[1, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 4, 3, 2, 2, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 2, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4],
[3, 2, 1, 1, 1, 1, 1, 5, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 5, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 5, 4, 3, 2, 1, 1, 1,
1, 1, 1, 1, 1, 5, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 5, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 5, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 5, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 5, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 5, 4, 3, 2],
[3, 3, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4,
2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 1, 1, 1, 3, 3, 3, 3, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 2, 2, 2, 1, 1, 1, 1, 1, 3, 3, 3, 3],
[1, 1, 1, 1, 1, 3, 5, 5, 5, 5, 5, 5, 5, 3, 1, 1, 1, 5, 5, 5, 5, 5, 5, 5, 3, 1, 1, 1, 1, 1, 2, 2, 3, 3, 5, 5, 5, 3,
1, 1, 1, 3, 3, 3, 4, 5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 3, 3, 3, 4, 4, 4, 2, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 5, 1, 1, 1, 1, 4, 4, 5, 5, 5, 5, 5, 3, 1, 1, 1, 1, 4, 4, 5, 5, 5, 5, 5, 3, 1, 1, 1, 1, 2, 2, 3, 3, 5, 5, 5, 5,
1, 1, 1, 1, 2, 2, 2, 3, 4, 5, 5, 5, 1, 1, 1, 1, 2, 2, 3, 4, 5, 5, 5, 5, 1, 1, 1, 1, 1, 2, 2, 3, 2, 2, 2, 2, 1, 1, 1, 1, 3, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 4],
[5, 5, 4, 4, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 2, 1, 1, 1, 1, 2, 2, 2, 4, 4, 4, 4,
1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 1, 1, 1, 4, 4, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1],
[3, 2, 2, 1, 1, 2, 3, 4, 5, 5, 5, 5, 4, 4, 2, 1, 1, 2, 3, 4, 5, 5, 5, 4, 4, 3, 2, 1, 1, 2, 2, 4, 5, 5, 5, 5, 4, 4,
2, 1, 1, 2, 3, 4, 4, 5, 5, 5, 4, 4, 2, 1, 1, 2, 3, 4, 5, 5, 5, 4, 4, 4, 2, 1, 1, 2, 3, 4, 5, 5, 5, 4, 4, 4, 2, 1, 1, 2, 3, 4, 5, 5, 5, 4, 4, 4, 2, 1, 1, 2, 3, 3, 4, 5, 5, 5, 4, 4, 2, 1, 1, 2, 3, 4, 5, 5, 5],
[3, 1, 1, 1, 1, 3, 5, 5, 5, 5, 5, 5, 3, 1, 1, 1, 1, 3, 5, 5, 5, 5, 5, 5, 3, 1, 1, 1, 1, 3, 5, 5, 5, 5, 5, 5, 3, 1,
1, 1, 1, 3, 5, 5, 5, 5, 5, 5, 3, 1, 1, 1, 1, 3, 5, 5, 5, 5, 5, 5, 3, 1, 1, 1, 1, 3, 5, 5, 5, 5, 5, 5, 3, 1, 1, 1, 1, 3, 5, 5, 5, 5, 5, 5, 3, 1, 1, 1, 1, 3, 5, 5, 5, 5, 5, 5, 3, 1, 1, 1, 1, 3, 5, 5, 5, 5, 5],
[5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5],
[1, 1, 1, 1, 1, 1, 3, 4, 5, 5, 5, 5, 5, 3, 2, 1, 1, 1, 3, 4, 5, 5, 5, 5, 5, 3, 1, 1, 1, 1, 3, 3, 3, 3, 3, 5, 5, 3,
1, 1, 1, 1, 3, 3, 3, 3, 3, 5, 5, 3, 1, 1, 1, 1, 3, 3, 3, 3, 3, 5, 5, 3, 1, 1, 1, 1, 3, 4, 5, 5, 5, 5, 5, 3, 2, 2, 2, 2, 3, 4, 4, 4, 4, 4, 4, 3, 2, 2, 2, 2, 3, 4, 5, 5, 5, 5, 5, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[5, 5, 1, 1, 1, 3, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 1, 3, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 1, 3, 5, 5, 5, 5, 5, 5, 5, 5,
1, 1, 1, 3, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 1, 3, 5, 5, 5, 5, 5, 5, 5, 5, 3, 1, 1, 1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 5],
[5, 5, 4, 2, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 2, 2, 2, 2, 3, 4, 5, 5, 5, 5, 4, 3, 2, 2, 3, 3, 4, 5, 5, 5, 5, 5, 5, 4,
3, 2, 2, 2, 4, 5, 5, 5, 5, 5, 5, 4, 3, 2, 2, 2, 3, 5, 5, 5, 5, 5, 5, 4, 3, 2, 2, 2, 4, 5, 5, 5, 5, 5, 4, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[2, 2, 1, 1, 2, 1, 1, 1, 2, 2, 2, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2],
[5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5],
[1, 1, 1, 1, 1, 1, 1, 3, 5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 1, 1,
1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 5],
[4, 2, 1, 1, 1, 1, 2, 3, 4, 4, 5, 4, 3, 2, 1, 1, 1, 1, 1, 2, 3, 4, 5, 4, 3, 2, 1, 1, 1, 3, 3, 2, 2, 4, 5, 5, 5, 5,
5, 1, 1, 3, 2, 2, 5, 5, 5, 5, 5, 5, 5, 1, 1, 2, 3, 2, 2, 4, 5, 5, 5, 5, 5, 1, 1, 3, 3, 2, 2, 2, 5, 5, 5, 5, 1, 1, 1, 1, 2, 3, 4, 5, 5, 5, 5, 4, 1, 1, 1, 1, 2, 3, 4, 5, 5, 5, 5, 4, 1, 1, 1, 1, 2, 3, 4, 4, 3],
[3, 3, 2, 2, 3, 4, 4, 4, 4, 4, 4, 3, 2, 2, 1, 1, 1, 3, 4, 4, 4, 4, 4, 3, 2, 1, 1, 1, 2, 4, 4, 2, 2, 3, 3, 2, 3, 3,
3, 1, 1, 2, 4, 2, 2, 4, 4, 4, 4, 4, 1, 1, 2, 4, 4, 2, 2, 4, 4, 4, 4, 4, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 3, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 4, 4, 4, 4, 4, 4],
[4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2],
[1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 5, 3, 1, 1, 1, 1, 1, 5, 5, 5, 5, 1, 3, 3, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4,
1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 5, 4, 1, 1, 1, 1, 1, 2, 2, 2, 4, 4, 4, 4, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 2, 2, 1, 1, 1, 1, 1, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3],
[5, 5, 2, 2, 2, 1, 1, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 1, 1, 5, 5, 5, 5, 5, 5, 5, 1, 1, 1, 2, 2, 5, 5, 5, 5, 5, 5, 5,
1, 1, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 1, 1, 1, 1, 5, 5, 5, 5, 5, 2, 2, 2, 1, 1, 1, 1, 5, 5, 5, 5, 5, 4, 4, 4, 5, 5, 5, 5, 5, 5],
[1, 1, 2, 2, 2, 2, 4, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 4, 5, 5, 5, 4, 3, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 2, 2,
1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 1, 1, 1, 1, 1, 1, 5, 5, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
]
# Whether or not orgs are okay with double shifts
$double = [true, true, true, true, true, false, true, false, true, true, false, true, true, false, true, false, true,
true, true, true, true, true, true, true, true]
# Number of shifts required at each timeslot
$required = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1]
# =============================================================================
num_orgs = orgs.length
num_shifts = $required.length
avg_prefs = $prefs.transpose.map { |prefs| prefs.reduce(:*)**(1.0 / num_orgs) }
$popularity = Array.new(num_shifts) { |i| i }
$popularity.sort! { |a, b| avg_prefs[a] <=> avg_prefs[b] }
$assigned = Array.new(num_shifts, 0)
$standards = Array.new(num_orgs, $highest_pref)
$shifts = Array.new(num_orgs) { [] }
$score = 0
$scores = Array.new(num_orgs) { [] }
# Return whether this assignment satisfies the org's double preference.
# This will return true for orgs who do not want double shifts when we have no other options.
def can_double?(org, shift)
limit = $double[org] ? 2 : 1
(($standards[org]).positive? and $shifts[org].count(shift) < limit)
end
def find_shift(org)
loop do
# Go through the shifts in ascending popularity order.
# Return if we find a shift for the org that isn't full, meets their standards, and satifies their double preference.
$popularity.each do |shift|
if ($assigned[shift] < $required[shift]) &&
($prefs[org][shift] >= $standards[org]) &&
can_double?(org, shift)
return shift
end
end
# If we don't find a shift, lower the org's standards and try again.
$standards[org] -= 1
end
end
def assign_shift(org, shift)
# Assign the shift to the org
$shifts[org].push(shift)
$assigned[shift] += 1
# Update the scores
$scores[org].push($prefs[org][shift])
$score += $standards[org]
end
# Iterate over the total number of shifts that need to be assigned, looping through the orgs and assignig shifts on at a time.
org = 0
(0..$required.reduce(:+) - 1).each do |_i|
# Skip orgs who have been assigned all their shifts
org = (org + 1) % num_orgs while $shifts[org].length >= sizes[org]
shift = find_shift(org)
assign_shift(org, shift)
org = (org + 1) % num_orgs
end
org = 0
(0..$shifts.length - 1).each do |i|
$shifts[i].each do |shift|
puts "Shift.create({ shift_type: watch_shift, organization: #{orgs[i]}, starts_at: move_on + 21.hours + #{2 * shift}.hours , ends_at: move_on + 21.hours + #{2 * (shift + 1)}.hours, required_number_of_participants: 2 })"
end
end
puts
puts 'Shift List:'
p $shifts
puts
puts 'Scores:'
p $scores
puts
puts format("Total Score: #{$score} / #{$highest_pref * $required.reduce(:+)}", $score)