program simulator (input, output, data); type namestring = string[10]; qptr = ^qnode; qnode = record name: namestring; next: qptr; end; qstuff = record size: integer; served: integer; rear: qptr; end; qarray = array [1..3] of qstuff; var checkout: qarray; command: string[6]; newname: namestring; queue: integer; data: text; ok: boolean; procedure setup (var checkout: qarray); var j: integer; begin for j := 1 to 3 do begin checkout[j].size := 0; checkout[j].served := 0; checkout[j].rear := nil; end; end; procedure addq (var cashier: qarray; queue: integer; newname: namestring); var q: qptr; begin new(q); q^.name := newname; cashier[queue].size := cashier[queue].size + 1; if cashier[queue].rear = nil then q^.next := q else begin q^.next := cashier[queue].rear^.next; cashier[queue].rear^.next := q; end; cashier[queue].rear := q; end; procedure addqueue (var cashier: qarray; newname: namestring); var queue: integer; function least (var cashier: qarray): integer; var small, which, j: integer; begin small := cashier[1].size; which := 1; for j := 2 to 3 do if cashier[j].size < small then begin small := cashier[j].size; which := j; end; least := which; end; begin queue := least(cashier); addq (cashier, queue, newname); end; procedure deleteq (var cashier: qarray; var ok: boolean; qnum: integer); var q: qptr; begin ok := (qnum >= 1) and (qnum <= 3); if ok then ok := (cashier[qnum].rear <> nil); if ok then begin q := cashier[qnum].rear^.next; cashier[qnum].size := cashier[qnum].size - 1; cashier[qnum].rear^.next := q^.next; if q = q^.next then cashier[qnum].rear := nil; dispose (q); end; end; procedure checkq (var cashier: qarray; var ok: boolean; qnum: integer; var who: namestring); begin ok := (qnum >= 1) and (qnum <= 3); if ok then ok := (cashier[qnum].rear <> nil); if ok then who := cashier[qnum].rear^.next^.name; end; procedure report (var cashier: qarray); var hold: qarray; j: integer; ok: boolean; who: namestring; begin writeln (' Status Report'); writeln ('Station Served Waiting'); setup (hold); for j := 1 to 3 do begin write (j:4, cashier[j].served:10, ' '); while cashier[j].rear <> nil do begin checkq (cashier, ok, j, who); if ok then begin write (who:10, ' '); deleteq (cashier, ok, j); addq (hold, j, who); end; end; writeln; while hold[j].rear <> nil do begin checkq (hold, ok, j, who); deleteq (hold, ok, j); addq (cashier, j, who); end; end; end; procedure count (var cashier: qarray; qnum: integer); begin cashier[qnum].served := cashier[qnum].served + 1; end; begin setup (checkout); assign (data, 'b:\data.p5'); reset (data); repeat read (data, command); if command = 'NEW ' then begin readln (data, newname); addqueue (checkout, newname); end else if command = 'TAKE ' then begin readln (data, queue); deleteq (checkout, ok, queue); if ok then count (checkout, queue) else writeln ('Checkout #',queue:1, ' on break'); end else if command = 'REPORT' then begin readln (data); report (checkout); readln (command); end else writeln (command, ' is invalid'); until eof(data); end.