```ts
export function hopOffsetGrid(
  start: number[],
  moves: string[],
): { cell: number[]; distance: number } {
  if (!Array.isArray(start) || start.length !== 2) {
    throw new Error("the start must be a two-element address");
  }
  for (const part of start) {
    if (typeof part !== "number" || !Number.isInteger(part)) {
      throw new Error("an address must hold whole numbers");
    }
  }
  if (!Array.isArray(moves)) {
    throw new Error("the moves must be a list");
  }
  let col = start[0];
  let row = start[1];
  for (const move of moves) {
    if (move === "e") {
      col += 1;
    } else if (move === "w") {
      col -= 1;
    } else if (move === "ne" || move === "NE") {
      row -= 1;
      if (row % 2 !== 0) {
        col += 1;
      }
    } else if (move === "nw" || move === "NW") {
      row -= 1;
      if (row % 2 === 0) {
        col -= 1;
      }
    } else if (move === "se" || move === "SE") {
      row += 1;
      if (row % 2 !== 0) {
        col += 1;
      }
    } else if (move === "sw" || move === "SW") {
      row += 1;
      if (row % 2 === 0) {
        col -= 1;
      }
    } else {
      throw new Error("invalid move name");
    }
  }
  const q = col - Math.floor(row / 2);
  const r = row;
  return {
    cell: [col, row],
    distance: (Math.abs(q - start[0]) + Math.abs(r - start[1]) + Math.abs(q - start[0] + r - start[1])) / 3,
  };
}
```