Guia do calouro para programação competitiva - Introdução a programação (Comparações e Operações Lógicas)

calouros Dez 02, 2020

Sei lá, deu vontade de voltar aqui para continuar o que começei.

Seja bem vindo à continuação dessa série de postagens, onde estou ensinando programação básica para ser utilizada na programação competitiva. Assim como a postagem anterior, vou continuar usando termos em português, porém vou começar a introduzir o uso de alguns termos em inglês. Bom, sem enrolar como na primeira postagem, vamos começar.

Comparações

Um dos comandos mais utilizados em programação competitiva são as comparações. Como o próprio nome já diz, esse comando irá realizar comparações entre valores. Quanto aos valores, são os valores que você irá fornecer no programa, podendo ser valores constantes ou variáveis. Quando você estiver fazendo uma comparação, na verdade você estará fazendo uma operação lógica, portanto você deverá informar os termos dessa operação lógica. Antes de avançarmos então com as comparações, vamos tratar sobre operações lógicas.

Operações Lógicas

Essas operações, que estão ligadas ao tipo booleano de variáveis (você verá o motivo desse nome em algum momento da faculdade, não me cabe explicar aqui), recebem valores e operadores, retornando como resultado apenas dois possíveis valores: 0 ou 1 (Verdadeiro ou Falso). Vamos então com calma, para explicar melhor as operações lógicas básicas:

  • x: Quando se passa apenas um valor "x" para a operação, retorna 0 caso "x" seja 0 e retorna 1 caso contrário;
  • NEGAÇÃO x: O operador "NEGAÇÃO" inverte o valor booleano de "x", retornando 1 caso "x" seja 0 e retornando 0 caso contrário;
  • x E y: O operador "E" testa a condição de "x" e "y" possuirem valor booleano 1 (considere aqui que "x" e "y" já são resultados de operações), retornando 1 caso "x" e "y" sejam iguais a 1 e retornando 0 caso "x" ou "y" possuam valor igual a 0;
  • x OU y: O operador "OU" testa a condição de "x" ou "y" possuirem valor booleano 1. Dessa forma, basta que "x" possua valor igual a 1 ou "y" possua valor igual a 1 para que essa operação retorne 1, da mesma forma que se "x" e "y" possuirem valor igual a 1 a operação também terá valor 1. Retornará 0 caso "x" e "y" possuam valor igual a 0;
  • x MAIOR QUE y: O operador "MAIOR QUE" testa a condição de "x" ser estritamente maior que "y", retornando 1 caso "x" seja maior que "y" e retornando 0 caso contrário;
  • x MENOR QUE y: O operador "MENOR QUE" testa a condição de "x" ser estritamente menor que "y", retornando 1 caso "x" seja menor que "y" e retornando 0 caso contrário;
  • x IGUAL A y: O operador "IGUAL A" testa a condição de "x" ser exatamente igual a "y", retornando 1... Ah você já entendeu como esses operadores funcionam, não é? Vou poupar o ctrl+c ctrl+v a partir daqui;
  • x DIFERENTE DE y: O operador "DIFERENTE DE" testa a condição de "x" ser diferente "y", agindo como um NEGAÇÃO x IGUAL A y;
  • x MAIOR OU IGUAL A y: O operador "MAIOR OU IGUAL A" testa a condição de "x" ser maior que "y", ou também de "x" ser igual a "y". É a mesma coisa que usar NEGAÇÃO x MENOR QUE y;
  • x MENOR OU IGUAL A y: semelhante ao operador acima, testa a condição de "x" ser menor que "y", ou também de "x" ser igual a "y". É a mesma coisa que usar NEGAÇÃO x MAIOR QUE y (sim, isso aqui foi feito com ctrl+c ctrl+v também).

Lembre-se que assim como operações matemáticas, as operações lógicas também podem ser combinadas. Mas por que eu sinto que esqueci de explicar algo sobre combinar operações matemáticas na postagem anterior? Ah, claro, esqueci de falar sobre a ordem das operações (chamamos isso de precedência de operadores). Bom, sobre as operações matemáticas, a ordem das operações funciona igualmente às operações matemáticas que fazemos no papel. Mas e como é a ordem das operações lógicas então? As operações lógicas seguem um padrão parecido, que vou demonstrar a seguir:

  1. x: os valores serão convertidos em valores booleanos
  2. (x): as operações dentro de parênteses serão resolvidas em seguida
  3. NEGAÇÂO: as operações de negação serão aplicadas
  4. E, OU, MAIOR QUE, MENOR QUE, IGUAL A, DIFERENTE DE, MAIOR OU IGUAL A, MENOR OU IGUAL A: essas operações serão resolvidas

Para explicar melhor, vou utilizar o seguinte exemplo, ilustrando o passo-a-passo:

10 E (NEGAÇÃO (NEGAÇÃO 0 E 0))

  • 1 E (NEGAÇÃO (NEGAÇÃO 0 E 0)): convertemos os valores 10, 0 e 0 para 1, 0 e 0 (Qualquer valor decimal diferente de 0 é mapeado para 1)
  • NEGAÇÃO 0 E 0: extraímos o parênteses que está dentro de parênteses para resolver essa expressão
  • 1 E 0: resolvemos a operação de NEGAÇÃO
  • 0: resolvemos a operação E
  • 1 E (NEGAÇÃO 0): transferimos o resultado obtido da expressão de volta à expressão original para continuar a resolução
  • NEGAÇÃO 0: mesma operação do passo 2
  • 1: resolvemos a operação de NEGAÇÃO
  • 1 E 1: mesma operação do passo 5
  • 1: resolvemos a operação E e obtemos o resultado da operação 10 E (NEGAÇÃO (NEGAÇÃO 0 E 0))

Bom, agora que já tratamos de operações lógicas (espero que você não tenha se perdido nessa explicação, costumo me perder tentando passar a teoria por trás de algo, principalmente tentando explicar pra mim mesmo), vamos voltar a falar sobre comparações. O ponto em explicar operações lógicas, como disse anteriormente, é porque agora, em comparações, vamos utilizar justamente as operações lógicas. Assim como na postagem anterior, vou explicar como funcionam as comparações utilizando primeiro pseudocódigo, e em seguida como escrever em Python. O princípio das comparações, utilizando pseudocódigo, é o seguinte:

SE (CONDIÇÃO) FAÇA
    bloco de código
FIMSE

Nesse caso, o "bloco de código", que já vou explicar o que é, irá ser executado caso a CONDIÇÃO, dada por uma expressão lógica, tiver valor igual a 1. Podemos também utilizar a comparação da seguinte forma:

SE (CONDIÇÃO) FAÇA
    bloco de código 1
SENÃO FAÇA
    bloco de código 2
FIMSE

Nesse caso, o "bloco de código 1" será executado caso a CONDIÇÃO possuir valor 1, enquanto o "bloco de código 2" será executado caso CONDIÇÃO tiver valor 0. Ainda existe outra forma de escrever a comparação, encadeando diversas comparações:

SE (CONDIÇÃO 1) FAÇA
    bloco de código 1
SENÃO SE (CONDIÇÃO 2) FAÇA
    bloco de código 2
    ...
SENÃO SE (CONDIÇÃO N-1) FAÇA
    bloco de código n-1
SENÃO FAÇA
    bloco de código n
FIMSE

Nesse caso, "bloco de código 1" será executado se CONDIÇÃO 1 for igual a 1, mas caso CONDIÇÃO 1 tiver valor 0 será testado a CONDIÇÃO 2, sendo executado o "bloco de código 2" caso CONDIÇÃO 2 for igual a 1, e assim por diante, até chegar ao último SENÃO, que por não ter comparação alguma, terá seu código executado. Ah, e não se preocupe com o senão, ele não é obrigatório, como foi mostrado no primeiro exemplo de comparação. Quanto ao "bloco de código", basicamente é quase a mesma coisa que eu expliquei na postagem anterior sobre o funcionamento do python. Sendo assim, "bloco de código" é basicamente:

instrução 1
instrução 2
...
instrução n

Pronto, agora que já expliquei utilizando pseudocódigo, vou explicar utilizando nossa linguagem de programação. Em python, o comando para realizar uma comparação é o comando if ("se" em inglês), e a sintaxe é um pouco diferente da que eu apresentei em pseudocódigo. No pseudocódigo, eu definia o começo e fim dos blocos de código escritos nas comparações com FAÇA e (SENÃO ou FIMSE). Para substituir o FAÇA em python, utilizamos ':' após definirmos a (CONDIÇÃO), porém não existe exatamente uma definição da onde termina o bloco de código, portanto, para sermos capazes de definir um bloco de código, é necessário definir isso utilizando espaçamento do código. Pode ter alguém me perguntando: "tá, e o que significa esse negócio de espaçamento?". Para tentar explicar melhor o que seria o espaçamento, vou fazer um exemplo aqui:

sem espaçamento (0)
 1 espaço de espaçamento (1)
  2 espaços de espaçamento (2)
   3 espaços de espaçamento (3)
    4 espaços de espaçamento (4)
	1 tabulação de espaçamento (1)
	 1 tabulação e 1 espaço de espaçamento (2)

Tá, talvez não tenha ficado tão bem explicado, mas basicamente o espaçamento será o número de espaços e tabs que será utilizado antes de começar a escrever na linha. Recomendo fortemente usar apenas "tab" para realizar o espaçamento (sempre utilizando largura de tabulação 4), para não deixar o código confuso, pois usar o espaçamento corretamente em python é muito importante.

Outra coisa importante a ser explicado também é a sintaxe dos operadores lógicos. Para isso, vou fazer uma lista colocando o termo em português à esquerda, com seu respectivo termo em Python à direita.

  • E / and
  • OU / or
  • NEGAÇÃO / not
  • MAIOR QUE / >
  • MENOR QUE / <
  • IGUAL A / ==
  • DIFERENTE DE / !=
  • MAIOR OU IGUAL A / >=
  • MENOR OU IGUAL A / <=

Agora que já expliquei a sintaxe (mais ou menos) das comparações em python, vamos para o código. Vamos começar utilizando duas variáveis, x e y, e apenas uma comparação (if). O código ficará assim:

x = 1
y = 1
if (x == y):
    print('Iguais')

Nesse exemplo, "Iguais" será imprimido como resultado, pois x e y possuem valor 1, portanto, são iguais. Vamos agora incrementar um pouco o programa.

x = 1
y = 2
if (x == y):
    print('Iguais')
else:
    print('Diferentes')

Como agora o valor de y foi modificado, e por causa do else (equivalente ao SENÃO), será escrito "Diferentes". Por fim, vamos criar um exemplo que use SENÃO SE, capaz de verificar se um número é maior, menor ou igual ao outro.

x = 1
y = 2
if (x > y):
    print('Maior')
elif (x < y):
    print('Menor')
else:
    print('Iguais')

Nesse código, que imprimirá "Menor", if equivale ao SE, elif equivale ao SENÃO SE e else equivale ao SENÃO. Falei que aquele era o último exemplo, mas vale ressaltar que dentro do bloco de código do if, podemos inserir mais ifs, assim como no exemplo a seguir:

x = 1
y = 1
if (x != y):
    print('Diferentes')
    if (x > y):
        print('Maior')
    else:
        print('Menor')
else:
    print('Iguais')

Nesse exemplo, como x e y não são diferentes, o código não irá executar o código que está no primeiro if, mas sim o código que está no else. Portanto, a execução desse problema será a impressão da palavra "Iguais".

Como dito anteriormente, é preciso ficar atento à identação do código, pois python utiliza dela para se achar durante a execução do programa, da mesma forma que a linguagem C utiliza ; para saber o que fazer durante a compilação.

E com isso, chegamos (quase) ao fim dessa postagem, então gostaria de agradecer quem conseguiu ler até aqui (sei que é maçante, mas não consigo explicar algo sem falar um pouco da teoria por trás).

Até a próxima postagem (novamente, se eu tiver vontade de continuar escrevendo)!

Exercícios propostos

Espera um pouco aí, não pense que você pode ler o assunto e achar que já aprendeu. Uma das coisas mais importantes para um programador competitivo (e atletas de qualquer esporte em geral) é o treinamento, e nada melhor para nós, programadores competitivos, treinarmos resolvendo alguns problemas. Vou deixar aqui uma lista de problemas para vocês resolverem no ambiente do URI Online Judge (espero que já tenham lido esse artigo):

Ah, e antes que eu me esqueça, existem alguns problemas nessa lista que contém conteúdos que não foram explicados ainda, então vou tentar dar umas dicas aqui para tentar resolver esses exercícios:

  1. Quando existir muitas entradas para uma mesma linha, leia a linha da seguinte forma: a1,a2,...,an = [int(x) for x in input.split()] (mais pra frente eu explico sobre essa entrada, mas por enquanto só aceita)
  2. Quando for ler números com ponto flutuante, lembre de trocar o comando int() utilizado na leitura para double().
  3. Quando for imprimir números com ponto flutuante, geralmente a plataforma irá exigir uma formatação específica. Para atender a essa formatação, imprima da seguinte forma: print('%.1f' % x), substituindo o número 1 pelo número exigido pelo problema, e sendo x uma variável onde você esteja armazenando o valor da resposta. Caso deseje imprimir diversos valores, a sintaxe será: print('%.1f' %a1, '%.2f' %a2, ..., '%.nf' %an);
  4. Por último, e não menos importante, sempre que surgir uma dúvida, lembre-se de usar nossos meios de comunicação para tirar essa dúvida, lembrando que pode ser pelo nosso email, telegram ou discord.

João Vitor Fröhlich

Membro | Participou de uma Summer School | Buscando ser roxo no codeforces | Prefere fazer exames finais a trabalhos durante o semestre