← Flyweight lesson
Lab

Flyweight

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.

type SeatSpec = { row: string; number: number; zone: string };

// The arena's zones: what a ticket costs and the colour the map draws.
const zones: Record<string, { price: number; color: string }> = {
  floor: { price: 120, color: 'red' },
  lower: { price: 85, color: 'blue' },
  upper: { price: 40, color: 'green' },
};

// Everything the map draws for one seat's zone. Each seat makes its own.
type ZoneStyle = { zone: string; price: number; color: string; held: boolean };
type Seat = { row: string; number: number; style: ZoneStyle };

function zoneStyle(zone: string): ZoneStyle {
  if (!Object.hasOwn(zones, zone)) throw new Error(`unknown zone: ${zone}`);
  const { price, color } = zones[zone]!;
  return { zone, price, color, held: false };
}

function buildSeatMap(specs: SeatSpec[]): Seat[] {
  return specs.map((spec) => ({
    row: spec.row,
    number: spec.number,
    style: zoneStyle(spec.zone),
  }));
}

// Hold one seat for a customer at the box office.
function holdSeat(seats: Seat[], row: string, number: number): boolean {
  const seat = seats.find((s) => s.row === row && s.number === number);
  if (!seat || seat.style.held) return false;
  seat.style.held = true;
  return true;
}

function drawSeat(seat: Seat): string {
  const { zone, price, color } = seat.style;
  const held = seat.style.held ? ' held' : '';
  return `${seat.row}${seat.number} ${zone} $${price} ${color}${held}`;
}