DEV Community

Lucas Nabesima
Lucas Nabesima

Posted on

11

Desafio de Código 01 - Explorando Serviços de Telefonia

Uma das coisas que eu acho bem bacana nos bootcamps da DIO é que durante a trilha tem alguns exercícios de código para serem realizados, com um editor ali do lado e algumas condições; uma pegada meio HackerRank assim. É bem bacana que ajuda a sedimentar os conhecimentos adquiridos durante as partes teóricas e não é uma pegada mais complexa como o desafio de projeto: é algo mais simplificado, para testar seu raciocínio lógico e seu conhecimento na linguagem. Assim como no HackerRank, eles te dão alguns trechos já prontos e você desenvolve sua lógica em cima disso.

Essa semana foi uma doideira, então a única coisa que eu consegui fazer foi a resolução dos dois desafios propostos no módulo "Explorando Serviços de Telefonia". Como o patrocinador desse bootcamp é a Claro, muitos dos temas vão ter esse pique de telecom.

Verificação de Serviço Contratado

Enunciado:

Uma concessionária de telecomunicações oferece quatro tipos de serviços: telefonia móvel, telefonia fixa, banda larga e TV por assinatura. Para facilitar o atendimento ao cliente, é necessário implementar um programa que verifique se um cliente específico contratou um determinado serviço. Por exemplo, quando um cliente liga para a central de atendimento e menciona um serviço, o atendente deve ser capaz de rapidamente verificar se esse serviço está contratado pelo cliente.

Entrada:

Duas strings: Uma com o serviço que a aplicação vai verificar (por exemplo, movel, fixa, banda larga, tv). A segunda deve conter o nome do cliente e quais produtos ele tem, separados por vírgula (Alice,movel,fixa)

Saída esperada:

Se o cliente contratou o serviço descrito na primeira entrada, a aplicação deve exibir Sim. Caso contrário, deve exibir Nao.

Exemplos:

Entrada Saída
movel
Alice,movel,fixa
Sim
fixa
Bob,movel,tv
Nao
tv
Carol,movel,fixa,tv
Sim

Código inicial:



import java.util.Scanner;

public class VerificacaoServico {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // Entrada do serviço a ser verificado
        String servico = scanner.nextLine().trim();

        // Entrada do nome do cliente e os serviços contratados
        String entradaCliente = scanner.nextLine().trim();

        // Separando o nome do cliente e os serviços contratados
        String[] partes = entradaCliente.split(",");
        String nomeCliente = partes[0];
        boolean contratado = false;

        // TODO: Verifique se o serviço está na lista de serviços contratados

        scanner.close();
    }
}


Enter fullscreen mode Exit fullscreen mode

Resolução:

Esse é um desafio relativamente simples. A aplicação recebe uma string delimitada por vírgulas que é transformada em array e precisamos descobrir se dentro dela existe uma string que coincide com outra entrada do usuário, que é o serviço que queremos checar se o cliente possui. Fácil, né?

Pra mim, que tem um histórico de JavaScript e C#, é só usar um método verificador (como o Array.includes() ou o List.Contains()). Certo? Errado.

Homem de camisa vermelha falando

Não existe, em Java, um método como esse na classe Array. Isso pode ser devido à implementação ser muito mais próxima da que acontece em linguagens de baixo nível (como C), que estabelece que elas devem ser estruturas de dados simples e eficientes. Aparentemente esse tipo de consulta não faz parte das funções essenciais dessa estrutura.

Descobrir essa informação foi um choque. O que o Java espera que eu faça? Que eu escreva um loop for e cheque manualmente se cada elemento bate com o item que eu estou procurando? Irmão, eu trabalho em tempo integral, tenho uma filha de menos de dois anos e ainda estou estudando Java. Tenho tempo pra isso não, bicho.

Mas eu descobri que desde o Java 8 é possível converter a array em uma list e, esta sim, tem o método .contains(). Então, para a resolução desse problema, é só converter a array partes em uma lista, e então verificar se dentro dessa lista existe a string passada em servico.
Se existir imprimimos Sim e em caso contrário, imprimimos Não.



import java.util.Arrays;
import java.util.Scanner;

public class VerificacaoServico {
    public static void main(String[] args) {
        //...
        // TODO: Verifique se o serviço está na lista de serviços contratados
        contratado = Arrays.asList(partes).contains(servico);

        System.out.println(contratado ? "Sim" : "Nao");

        scanner.close();
    }
}


Enter fullscreen mode Exit fullscreen mode

Com isso o exercício está concluído, mas durante a pesquisa que fiz descobri que desde o Java 8 existe uma abstração que ajuda a trabalhar com coleções de dados de uma maneira mais simples e de uma abordagem mais funcional, parecida com o que existe em JavaScript: as streams.

Assim como com listas, podemos converter o vetor em uma stream e checar se algum dos elementos presentes nela corresponde ao que foi passado em servico:



import java.util.Arrays;
import java.util.Scanner;

public class VerificacaoServico {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // Entrada do serviço a ser verificado
        String servico = scanner.nextLine().trim();

        // Entrada do nome do cliente e os serviços contratados
        String entradaCliente = scanner.nextLine().trim();

        // Separando o nome do cliente e os serviços contratados
        String[] partes = entradaCliente.split(",");
        String nomeCliente = partes[0];
        boolean contratado = false;

        contratado = Arrays.stream(partes).anyMatch(servico::equals);

        System.out.println(contratado ? "Sim" : "Nao");

        scanner.close();
    }
}


Enter fullscreen mode Exit fullscreen mode

Podíamos ter feito a verificação passando um callback para o método .anyMatch(p -> p == servico), mas isso checa se p e servico não apenas tem o mesmo valor mas também se apontam para o mesmo endereço de memória (ou seja, se são de fato o mesmo objeto). Normalmente, quando lidamos com strings, essa comparação vai retornar false mesmo se o valor for igual -- ou seja, um falso negativo. Por isso, a comparação usando servico::equals é mais adequada, porque compara apenas o valores entre os dois elementos, mais ou menos como o comparador de igualdade do JavaScript (==).

Com essa alteração, podemos julgar que o exercício está concluído. O que falta é rodar os testes e ver se eles passam:
Tela de sucesso na suite de testes.

Bom demais.
Esse exercício me deu outro motivo para reclamar de Java, que é a sintaxe da lambda. O uso da seta simples (->) ao invés da dupla (=>) me incomoda muito.


Verificação de Contratação de Combo Completo

Enunciado:

Implemente um sistema que verifique se um cliente de uma empresa de telecomunicações contratou um combo completo de serviços. Um combo completo inclui os três serviços principais oferecidos pela empresa: telefonia móvel, banda larga e TV por assinatura. O sistema deve ler uma lista de serviços contratados pelo cliente e determinar se todos os serviços necessários estão incluídos. Caso todos os três serviços estejam presentes, o sistema deve retornar "Combo Completo". Se faltar qualquer um dos serviços, o sistema deve retornar "Combo Incompleto".

Entrada:

Uma string contendo os serviços contratados pelo cliente, separados por vírgula. Os valores possíveis são movel, banda larga e tv.

Saída esperada:

Uma string contendo Combo Completo se o cliente tiver todos os serviços contratados, Combo Incompleto do contrário.

Exemplos:

Entrada Saída
movel,banda larga,tv Combo Completo
movel,tv Combo Incompleto
banda larga,tv,movel Combo Completo

Código inicial:



import java.util.Scanner;

public class VerificacaoComboCompleto {

    // Função para verificar se o cliente contratou um combo completo
    public static String verificarComboCompleto(String[] servicosContratados) {
        // Variáveis booleanas para verificar a contratação de cada serviço
        boolean movelContratado = false;
        boolean bandaLargaContratada = false;
        boolean tvContratada = false;

        // TODO: Itere sobre os serviços contratados
        for (String servico : servicosContratados) {
        }

        // TODO: Verifique se todos os serviços foram contratados
        if () {
            return "Combo Completo";
        } else {
            return "Combo Incompleto";
        }
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // Solicitando ao usuário a lista de serviços contratados
        String input = scanner.nextLine();

        // Convertendo a entrada em uma lista de strings
        String[] servicosContratados = input.split(",");

        // Verificando se o cliente contratou um combo completo
        String resultado = verificarComboCompleto(servicosContratados);

        // Exibindo o resultado
        System.out.println(resultado);

        // Fechando o scanner
        scanner.close();
    }
}


Enter fullscreen mode Exit fullscreen mode

Resolução:

De novo, esse é um desafio simples. Para chegar no resultado, apenas alguns passos precisam ser seguidos:

  1. Iterar sobre a array gerada pelo método main a partir da string inserida pelo usuário;
  2. Checar se os serviços disponibilizados (descritos nas variáveis booleanas logo acima) foram contratados;
    • Em caso positivo, a variável correspondente deve ter seu valor alterado para true.
  3. Verificar se todos os serviços estão com o valor true. Apesar de ter mais passos, é bem mais direto que o anterior. Podemos começar a resolver esse trem de um jeito bem tosco, com uma série de ifs encadeados: ```java

for (String servico : servicosContratados) {
if(servico.equals("movel")) movelContratado = true;
if(servico.equals("bandaLarga")) bandaLargaContratada = true;
if(servico.equals("tv")) tvContratada = true;
}

E preenchemos a condição do nosso `if`:
```java


if (movelContratado && bandaLargaContratada && tvContratada) {
    return "Combo Completo";
} else {
    return "Combo Incompleto";


Enter fullscreen mode Exit fullscreen mode

Assim como no primeiro, com essas adições o desafio pode ser considerado como completo, mas esses ifs, um seguido do outro me incomoda um pouco. Podemos alterar isso pra um switch pra ficar menos feio:



for (String servico : servicosContratados) {
    switch (servico) {
        case "movel":
            movelContratado = true;
            break;
        case "banda larga":
            bandaLargaContratada = true;
            break;
        case "tv":
            tvContratada = true;
            break;
        default:
            System.out.println("Serviço inválido.");
            break;
    }
}


Enter fullscreen mode Exit fullscreen mode

Há quem diga que os ifs são de mais fácil leitura e que o ganho que a otimização traria para um switch tão pequeno como esse é desprezível. Outros diriam que eu tenho pouca consistência interna, reclamando de checar manualmente strings em um exercício e fazendo sem um pio em outro.
Pra essas pessoas eu digo:
Homem em um palco apontando para alguém e dizendo

O código final ficaria então:



import java.util.Scanner;
public class VerificacaoComboCompleto {
    // Função para verificar se o cliente contratou um combo completo
    public static String verificarComboCompleto(String[] servicosContratados) {
        // Variáveis booleanas para verificar a contratação de cada serviço
        boolean movelContratado = false;
        boolean bandaLargaContratada = false;
        boolean tvContratada = false;

        for (String servico : servicosContratados) {
            switch (servico) {
                case "movel":
                    movelContratado = true;
                    break;
                case "banda larga":
                    bandaLargaContratada = true;
                    break;
                case "tv":
                    tvContratada = true;
                    break;
                default:
                    System.out.println("Serviço inválido.");
                    break;
            }
        }

        if (movelContratado && bandaLargaContratada && tvContratada) {
            return "Combo Completo";
        } else {  
            return "Combo Incompleto";
        }
    }
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // Solicitando ao usuário a lista de serviços contratados
        String input = scanner.nextLine();
        // Convertendo a entrada em uma lista de strings
        String[] servicosContratados = input.split(",");
        // Verificando se o cliente contratou um combo completo
        String resultado = verificarComboCompleto(servicosContratados);
        // Exibindo o resultado
        System.out.println(resultado);
        // Fechando o scanner
        scanner.close();
    }
}


Enter fullscreen mode Exit fullscreen mode

Que, ao rodar a suite de testes, nos mostra que deu tudo certo:
Tela de sucesso na suite de testes.
O código desses (e dos demais) desafios está aqui.
Então é isso, pessoal. Até a próxima!

Top comments (1)

Collapse
 
zeotoni profile image
Ezequiel Otoni

Sênior é outro nível né? Começou agora e já tá dominando a linguagem. Parabéns mano XD. E a seta simples também me incomoda demais kkk.

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay