Thread Perl Quiz-of-the-Week #21 (4 answers)
Opened by Crian at 2004-08-06 15:20

Crian
 2004-08-08 15:34
#85573 #85573
User since
2003-08-04
5872 Artikel
ModeratorIn
[Homepage]
user image
So, die ersten Spoiler laufen bei QOTW ein, ich habe meine Lösung auch gerade abgeschickt, dann kann ich sie hier ja auch angeben.

Der Quellcode ist doch etwas lang, weil ich mehr mache als nötig (ich hab vor, das eventuell noch zu erweitern...).

Download: qotw21.pl

Hier ist die Ausgabe von perldoc qotw21.pl:

Code: (dl )
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
227
228
229
230
231
232
233
234
235
236
NAME
qotw21.pl

SYNTAX
qotw21.pl task-file
cat task-file | qotw21.pl

TASK
You will write a program to perform scheduling. As we all
know, tasks sometimes take longer than expected. Sometimes
when this happens, the final deadline of the project is
affected; sometimes it isn't. For example, consider the four
tasks A, B, C, and D. B and C depend on A, which means that
they cannot be started until A is finished. D depends on B and
C, and cannot be started until both B and C are finished:

.-> B .
A :-> D
`-> C '

Suppose we expect the four tasks to take the following times:

A: 1 day
B: 2 days
C: 3 days
D: 1 day

Then we don't expect the project to be finished for at least 5
days: one day to complete A and start C; 3 days to complete C
and start D, and another day to finish D. Any delay in any of
the three tasks A, C, or D will cause the completion date to
slip. We say that A, C, and D are on the "critical path".
But B is not on the critical path, because B can go on while C
is going on, and can take up to one day longer than expected
without delaying the start of D.

You will write a program which will calculate critical paths. The
input to the program will be a file in the following format:

A 1
B 2 A
C 3 A
D 1 B C
FINAL 0 D

Each line represents one task. The first field in each line
is the name of the task. The second field is the expected
duration. If there are any other fields, they are the names
of other tasks which must be finished before this task can
start.

The program will find all the tasks on the critical path to
the task named FINAL and will print them out, one per line.

It may happen that the input specifies tasks that cannot possibly be
completed. For example:

A 1 B
B 1 A
FINAL 0 A B


Here A can't start until B is finished, but B can't start until A is
finished. In such cases, the program should diagnose an error.

TESTS
The following problems are tested by the program:

Is there a task called 'FINAL'?
If not, the program dies with the message
C<No task 'FINAL' exists>.

Are all given predecessor tasks known?
If not the program dies with
C<Task 'X' is not defined, but it is a
preliminary task of task 'Y'>.

Is a task a direct predecessor of itself?
If this is the case, the program dies with
C<Task 'X' is a preliminary task of itself>.

Is a task a indirect predecessor of itself?
If this is the case, the program dies with
C<preliminary circle with task 'X'>.

Are there any unused tasks for the task 'FINAL'?
If this is the case, the program gives the warning
C<unused tasks for 'FINAL' : 'X', 'Y', 'Z'>.

CALCULATIONS
The following things are calculated by the program:

The direct predecessors of all tasks.
(These are given in the input directly.)

All predecessors of all tasks.
Therefore we have to cycle through all the predecessors and
collect them by doing so. (This is done in the function
C<allpre>.)

The level (or column) of each task.
This means in which column the task can be printed. This is
the first step for plotting the tasks. Tasks with no
predecessors can be printed in column 0 (the left most column),
all other tasks can be printed one column after the highest
column of all its predecessors.

The direct successors of all tasks.
Therefore we have to look at all tasks, if the given task
'X' is a predeccessor of task 'Y', then 'Y' is a successor
of task 'X'.

All successors of all tasks.
Therefore we have to cycle through all the successors and
collect them by doing so. (This is done in the function
C<allsuc>.)

The pathes to the task 'FINAL'.
Therefore we have to cycle backwards through all the
predecessors and split the possible pathes for each
direct predeccessor we find.

DATA STRUCTURES
The program creates a HoH (hash of hashes), where the name
of the tasks are the keys and the values are a hash with
informations about this task. Here is an example for one
entry of this HoH:

'FINAL' => {
'duration' => '0',
'level' => 3,
'predecessor' => [
'D'
],
'predecessorall' => [
'A',
'B',
'C',
'D'
],
'successor' => [],
'successorall' => []
}

The name of this HoH is C<%task>.

The calculated pathes to the task 'FINAL' are stored in an
AoA (array of arrays) called C<@pathes>. This is the structur
of the AoA:

(
[
'A',
'B',
'D'
],
[
'A',
'C',
'D'
]
)

The critical tasks are stored in a simple array called
C<@maxtasks> and they are printed out one task by line.

EXAMPLES
The example given in the task description
crian@blitz:~/perl/qotw> cat qotw21_input1.txt
A 1
B 2 A
C 3 A
D 1 B C
FINAL 0 D
crian@blitz:~/perl/qotw> qotw21.pl qotw21_input1.txt
A
C
D

Circle predecessors / successors ('A'-'B'-'A')
crian@blitz:~/perl/qotw> cat qotw21_input2.txt
A 1 B
B 1 A
FINAL 0 A B
crian@blitz:~/perl/qotw> qotw21.pl qotw21_input2.txt
preliminary circle with task 'B' at
./qotw21.pl line 432, <> line 3.

Multiple definition of one task ('A')

crian@blitz:~/perl/qotw> cat qotw21_input3.txt
A 1 B
A 1 C
B 1 C
FINAL 0 C
crian@blitz:~/perl/qotw> qotw21.pl qotw21_input3.txt
Ambigous task definition 'A 1 C' in line 2: task 'A'
already defined! at ./qotw21.pl line 102, <> line 2.

Undefined tasks ('C')
crian@blitz:~/perl/qotw> cat qotw21_input4.txt
A 1 B
B 1 C
FINAL 0 A B
crian@blitz:~/perl/qotw> qotw21.pl qotw21_input4.txt
Task 'C' is not defined, but it is a preliminary task
of task 'B' at ./qotw21.pl line 145, <> line 3.

Longer circle predecessors / successors ('E'-'F'-'G'-'E')
crian@blitz:~/perl/qotw> cat qotw21_input5.txt
A 1
B 2 A
C 3 A
D 1 B C
E 1 G
F 1 E
G 1 F
FINAL 0 D G
crian@blitz:~/perl/qotw> qotw21.pl qotw21_input5.txt
preliminary circle with task 'E' at
./qotw21.pl line 432, <> line 8.

Unused tasks ('E')
crian@blitz:~/perl/qotw> cat qotw21_input6.txt
A 1
B 2 A
C 3 A
D 1 B C
E 12 C
FINAL 0 D
crian@blitz:~/perl/qotw> qotw21.pl qotw21_input6.txt
unused tasks for 'FINAL' : 'E' at
./qotw21.pl line 220, <> line 6.
A
C
D
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite

View full thread Perl Quiz-of-the-Week #21