Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

[Projeto] Exercício: Sistema de sorteio com avaliação de participantes

import { createInterface } from "readline";

const rl = createInterface({
  input: process.stdin,
  output: process.stdout,
});

const perguntar = (pergunta) => {
  return new Promise((resolve) => {
    rl.question(pergunta, resolve);
  });
};

const validarNome = (input) => {
  const nome = input.trim();

  if (nome.length > 1 && /^[a-zA-ZÀ-ÿ\s'-]+$/.test(nome)) return nome;
  return null;
};

const validarNum = (input) => {
  const num = Number(input);

  if (Number.isNaN(num) || !Number.isInteger(num) || num < 0) return null;
  return num;
};

const tratarInvalido = (dado) => {
  if (dado === null) {
    rl.close();
    throw new Error("Entrada inválida");
  }
  return dado;
};

const sortearParticipante = (listaNomes) => {
  const nomeSorteado = Math.floor(Math.random() * listaNomes.length);

  if (listaNomes.length === 0) throw new Error("Lista vazia");

  return listaNomes[nomeSorteado];
};

const avaliarPontuacao = (nomeSorteado, listaNomes, listaPontos) => {
  const faixas = [
    { limite: 49, avaliacao: "Infelizmente, não foi dessa vez." },
    {
      limite: 80,
      avaliacao: "Você quase conseguiu! Fique de olho nos próximos sorteios.",
    },
    { limite: Infinity, avaliacao: "Parabéns, você foi premiado!" },
  ];

  const pontos = listaPontos[listaNomes.indexOf(nomeSorteado)];

  return faixas.find((faixa) => pontos < faixa.limite).avaliacao;
};

const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const manterSuspense = async (
  sortearParticipante,
  avaliarPontuacao,
  listaNomes,
  listaPontos,
) => {
  console.log("A pessoa sorteada foi...");
  const sorteado = sortearParticipante(listaNomes);

  await delay(4000);

  const resultado = avaliarPontuacao(sorteado, listaNomes, listaPontos);
  console.log(sorteado + "!");
  return resultado;
};

const organizarSorteio = async () => {
  try {
    console.log("Monte a lista de participantes.\n['fim' encerra inserções]");

    const listaNomes = [];
    const listaPontos = [];

    while (true) {
      const nome = tratarInvalido(validarNome(await perguntar("Nome: ")));

      if (nome.trim() === "fim") break;
      listaNomes.push(nome);

      const pontuacao = tratarInvalido(validarNum(await perguntar(`Pontos: `)));
      listaPontos.push(pontuacao);
    }

    console.log(
      await manterSuspense(
        sortearParticipante,
        avaliarPontuacao,
        listaNomes,
        listaPontos,
      ),
    );
  } catch (err) {
    console.log(err.message);
  } finally {
    rl.close();
  }
};

organizarSorteio();
1 resposta
solução!

Oii Vitor Hugo, tudo bem?

Obrigado por compartilhar sua solução no fórum! Você foi bem além do proposto — adicionou validação de entradas, tratamento de erros, leitura interativa via readline e até o efeito de suspense com Promise + setTimeout. É uma implementação bem robusta.

Tenho apenas uma observação pontual: na função validarNome, você rejeita entradas com length <= 1, mas a palavra "fim" tem 3 caracteres e passa pela regex, então o fluxo de encerramento funciona corretamente. Só vale notar que, caso o usuário digite algo como "fi", a validação vai retornar null e encerrar o programa em vez de pedir nova tentativa. Se quiser deixar o sistema mais tolerante a falhas, uma alternativa é substituir o tratarInvalido (que fecha tudo) por um loop que repete a pergunta até receber uma entrada válida.

Conte com a Alura para evoluir seus estudos. Em caso de dúvidas, fico à disposição.

Bons estudos!

Sucesso

Imagem da comunidade