← Bridge lesson
Lab

Bridge

Sign in to run your code

Read the brief and the starter here. With a free account you can edit it, run the sample, step through it and check your work, and your progress is kept.

// minutes: how long until the train leaves; below zero, it has already left.
type Departure = { destination: string; platform: number; minutes: number };

// Checker plumbing, you don't need to edit this: the cases build trains with it.
function train(destination: string, platform: number, minutes: number): Departure {
  return { destination, platform, minutes };
}

// Today: one function per display, each with its own copy of the rules.
function boardNextTrains(departures: Departure[]): string {
  const due = departures
    .filter((d) => d.minutes >= 0)
    .sort((a, b) => a.minutes - b.minutes)
    .slice(0, 3);
  const rows = due.map((d) => {
    const when = d.minutes === 0 ? 'DUE' : `${d.minutes} MIN`;
    return `${d.destination.toUpperCase()} P${d.platform} ${when}`;
  });
  return `NEXT TRAINS: ${rows.length ? rows.join(' | ') : '--'}`;
}

// Copied from the board's function for the announcer, then edited.
function announceNextTrains(departures: Departure[]): string {
  const due = [...departures].sort((a, b) => a.minutes - b.minutes).slice(0, 3);
  const rows = due.map((d) => {
    const when = d.minutes === 0 ? 'now' : `in ${d.minutes} minutes`;
    return `The ${d.destination} train leaves platform ${d.platform} ${when}`;
  });
  return rows.length ? `Next trains. ${rows.join('. ')}.` : 'Next trains. No trains are due.';
}

// What every display can show: one departure, and a screen around the rows.
interface Display {
  departure(destination: string, platform: number, minutes: number): string;
  screen(title: string, rows: string[]): string;
}

// The LED board: capitals, and DUE for a train leaving now.
class LedBoard implements Display {
  departure(destination: string, platform: number, minutes: number): string {
    return ''; // not written yet
  }
  screen(title: string, rows: string[]): string {
    return ''; // not written yet
  }
}

// The announcer: a sentence per train, read aloud.
class Announcer implements Display {
  departure(destination: string, platform: number, minutes: number): string {
    return ''; // not written yet
  }
  screen(title: string, rows: string[]): string {
    return ''; // not written yet
  }
}

// The split the station asked for, half done: NextTrains holds a display,
// but still calls the announcer's old function, whatever display it holds.
class NextTrains {
  private readonly display: Display;
  constructor(display: Display) {
    this.display = display;
  }
  show(departures: Departure[]): string {
    return announceNextTrains(departures);
  }
}