JavaScript (ES 6, feedback welcome!)
function Driver(route) {
this.id = Driver.drivers.length;
this.route = route;
this.stop = 0;
this.numGossips = 1;
this.gossips = {};
this.gossips[this.id] = 1;
this.getStopName = () => this.route[this.stop];
this.drive = () => this.stop = (this.stop + 1) % this.route.length;
this.heardItAll = () => this.numGossips === Driver.drivers.length;
this.receiveGossip = gossip => !this.gossips[gossip] ? this.gossips[gossip] = ++this.numGossips : null;
}
Driver.drivers = [];
function gossip(input) {
var addDriver = route => Driver.drivers.push(new Driver(route.split(' '))),
drive = () => Driver.drivers.forEach(driver => driver.drive()),
doneGossiping = () => Driver.drivers.every(driver => driver.heardItAll()),
gossip = function() {
var driversAtStop = {}, gossipsAtStop = {};
Driver.drivers.forEach(function(driver) {
var stop = driver.getStopName();
if (!gossipsAtStop[stop]) gossipsAtStop[stop] = {};
if (!driversAtStop[stop]) driversAtStop[stop] = [];
for (var gossip in driver.gossips) gossipsAtStop[stop][gossip] = true;
driversAtStop[stop].push(driver);
});
for (var stop in driversAtStop) {
var drivers = driversAtStop[stop], gossips = gossipsAtStop[stop];
if (drivers.length > 1) {
for (var gossip in gossips)
drivers.filter(driver => driver.id != gossip)
.forEach(driver => driver.receiveGossip(gossip));
}
};
};
input.split('\n').forEach(route => addDriver(route));
var minutes = 0;
while (!doneGossiping() && minutes++ <= 480) {
gossip();
drive();
}
console.log(doneGossiping() ? minutes : 'never');
}
$.get('input.txt', gossip, 'text');