const _ = require('lodash/fp');
const routes = [
[7, 11, 2, 2, 4, 8, 2, 2],
[3, 0, 11, 8],
[5, 11, 8, 10, 3, 11],
[5, 9, 2, 5, 0, 3],
[7, 4, 8, 2, 8, 1, 0, 5],
[3, 6, 8, 9],
[4, 2, 11, 3, 3],
];
const cyclicNth = _.curry((index, array) => array[index % array.length]);
const initialGossips = _.flow(
_.size,
_.range(0),
_.map(_.castArray)
)(routes);
const didSpread = _.every(array => array.length === routes.length);
_.reduce(({ timeTillCompleteSpread, gossipsPerRoute }, index) => {
if (!isFinite(timeTillCompleteSpread)) {
const currentStopPerRoute = _.map(cyclicNth(index), routes);
const groupGossipsByStop = _.flow(
_.zip(currentStopPerRoute),
_.groupBy(_.first),
_.mapValues(_.flatMap(_.last))
)
const gossipsPerStop = _.flow(
groupGossipsByStop,
_.mapValues(_.uniq)
)(gossipsPerRoute);
gossipsPerRoute = _.map(_.propertyOf(gossipsPerStop), currentStopPerRoute);
if (didSpread(gossipsPerRoute)) {
timeTillCompleteSpread = index;
}
}
return { timeTillCompleteSpread, gossipsPerRoute };
}, {
timeTillCompleteSpread: Infinity,
gossipsPerRoute: initialGossips
}, _.range(0, 480));