-
Notifications
You must be signed in to change notification settings - Fork 69
Expand file tree
/
Copy pathEven_More_Pizza.java
More file actions
226 lines (198 loc) · 5.72 KB
/
Copy pathEven_More_Pizza.java
File metadata and controls
226 lines (198 loc) · 5.72 KB
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
import java.io.*;
import java.util.*;
class Solution_Second
{
//Object representations of the pizzas which have been prepared.
static ArrayList<Pizza> pizzas = new ArrayList<Pizza>();
//Object representations of the deliveries which are to be made.
static ArrayList<Delivery> deliveries = new ArrayList<Delivery>();
//List of files to be processed.
static String in_files[] = {"a_example", "b_little_bit_of_everything", "c_many_ingredients", "d_many_pizzas", "e_many_teams"};
//Total number of pizzas.
static int total;
//Stores the number of teams 0->4 and 2->2.
static int teams[] = new int[3];
//Starting point of execution.
public static void main(String args[]) throws Exception
{
for(int i = 0; i < in_files.length; i++)
{
System.out.println("Running for file " + in_files[i]);
prepareData(in_files[i]);
initializeDeliveries();
computeScores();
produceOutputs(in_files[i]);
//Re-initializing variables.
pizzas = new ArrayList<Pizza>();
deliveries = new ArrayList<Delivery>();
}
}
//Write the outputs to a file.
public static void produceOutputs(String fileName) throws Exception
{
FileWriter fw = new FileWriter(fileName + ".out");
fw.write(deliveries.size() + "\n");
for(int i = 0; i < deliveries.size(); i++)
{
Delivery current = deliveries.get(i);
fw.write(current.orders + current.order_list + "\n");
}
fw.close();
}
//Compute the scores and make deliveries.
public static void computeScores()
{
//Blocks to be computed at a time.
int block = 2;
//Loop variable.
//False, if no delivery object has been modified.
boolean d_modified = true;
while(d_modified)
{
d_modified = false;
for(int i = 0; i < deliveries.size(); i++)
{
Delivery d = deliveries.get(i);
d.cache = new double[pizzas.size()];
if(d.c_orders < d.orders && !d_modified)
{d_modified = true;}
//Step: Number of pizzas to be added to the delivery at this point.
//Related to block.
int step = (block <= d.orders - d.c_orders)?block:d.orders - d.c_orders;
for(int j = 0; j < step; j++)
{
d.p_id = -1;
d.h_score = -1;
for(int k = 0; k < pizzas.size(); k++)
{
//Create relative scores for each pizza.
//Update if better.
double temp = d.pizzaScore(pizzas.get(k), k);
if(temp > d.h_score)
{
d.p_id = k;
d.h_score = temp;
}
}
//Process the selected pizza.
//And deliver it. (Add it to the delivery).
Pizza to_be_sent = pizzas.get(d.p_id);
//Ingredients to be added/sent.
String tbs_ings[] = to_be_sent.ingredients.split(" ");
d.order_list = d.order_list + " " + to_be_sent.index;
for(String ing : tbs_ings)
{
if(d.ingredients.indexOf(ing) == -1)
{
d.ingredients = d.ingredients + " " + ing;
d.count++;
}
}
//Remove added pizza from list.
pizzas.remove(to_be_sent);
d.c_orders++;
}
d.cache = null;
}
}
}
//Select the teams and initialize the delivery objects.
private static void initializeDeliveries()
{
int t_orders = 4;
while(true)
{
//Change the team size and continue, or exit.
if(total - t_orders < 0 || teams[4 - t_orders] - 1 < 0)
{
t_orders--;
if(t_orders < 2){return;}
continue;
}
Delivery c_delivery = new Delivery(t_orders);
deliveries.add(c_delivery);
total -= t_orders;
teams[4 - t_orders]--;
}
}
//Read data from the file and prepare it.
private static void prepareData(String fileName) throws Exception
{
BufferedReader Rb = new BufferedReader(new FileReader(fileName));
String str = Rb.readLine();
String temp[] = str.split(" ");
total = Integer.valueOf(temp[0]);
teams[2] = Integer.valueOf(temp[1]);
teams[1] = Integer.valueOf(temp[2]);
teams[0] = Integer.valueOf(temp[3]);
int index_counter = 0;
while((str = Rb.readLine()) != null)
{
temp[0] = str.substring(0, str.indexOf(" "));
str = str.substring(str.indexOf(" ") + 1);
temp[1] = str;
Pizza c_pizza = new Pizza();
c_pizza.count = Integer.valueOf(temp[0]);
c_pizza.ingredients = temp[1];
c_pizza.index = index_counter;
pizzas.add(c_pizza);
index_counter++;
}
Rb.close();
}
}
//One object for each pizza.
class Pizza
{
String ingredients;
//Number of ingredients.
int count;
int index = -1;
}
//One object for every delivery.
class Delivery
{
double cache[];
//Cache of previous values.
String ingredients = "";
//List of pizzas added.
String order_list = "";
//Number of ingredients.
int count;
//Current element count.
int c_orders;
//Total number of elements to be added.
int orders;
//Current high score.
double h_score;
//Current prospective addition.
int p_id;
Delivery(int t_orders)
{orders = t_orders;}
//Compute the score for a pizza.
//The greater the better.
double pizzaScore(Pizza p, int index)
{
if(cache[index] != 0)
{
if(cache[index] < h_score)
{return 0;}
}
//Ingredients found and not found.
int found = 0;
int n_found = 0;
String ings[] = p.ingredients.split(" ");
for(String ing : ings)
{
if(ingredients.indexOf(ing) != -1)
{found++;}
else
{n_found++;}
}
//Score to be returned.
double score = Math.pow(n_found, 1 - found / p.count / 2);
cache[index] = score;
//things to be added here.
return score;
}
}