Pesquisar este blog

Livros Recomendados

Mostrando postagens com marcador String. Mostrar todas as postagens
Mostrando postagens com marcador String. Mostrar todas as postagens

quarta-feira, 20 de dezembro de 2023

URI (BEECROWD) - 1632 - Variations (Variações) - Strings - C, C++ e Haskell

Hoje vamos apresentar a solução do problema Variations (Variações), da categoria Strings no Beecrowd. Não foi um problema difícil de resolver e acho que não terão dificuldades em entender o código :) Confira na sequência como eu resolvi esse problema!

Chave PIX para ajudar o blog: 6d8bc7a8-5d74-493a-ab7a-3515baf35956. 


Plataforma: URI (BEECROWD)

Problema1632

Enunciado:

A internet já não é tão segura quanto ela já foi. Um dos sinais disso é o aumento de ataque de hackers a diversos sites. Para piorar, quando um hacker rouba a senha de um usuário em um determinado site, ele tem também acesso a todas as outras contas deste usuário em outros sites, pois a maioria dos usuários hoje em dia usa a mesma senha em todos os sites que acessa.

Uma das soluções propostas para resolver este problema é usar diferentes senhas para cada site, ou até mesmo diferentes variações da mesma senha. Por exemplo, para variar a senha “batata”, é possível usar a senha “bAtaTa”, “B4tat4”, “baTATA”, etc. Ou seja, para cada caractere do alfabeto, é possível formar uma variação colocando tal caractere em maiúsculo ou minúsculo. Inclusive, para aumentar o número total de variações, para os caracteres A, E, I, O e S é possível usar também os números 4, 3, 1, 0 e 5, respectivamente.

Seu amigo precisa aumentar o número de variações de sua senha, e pediu sua ajuda. Dada a senha que ele escolheu, diga o número de diferentes variações que é possível montar.

Linguagem: C, C++ e Haskell


Solução: 

Basicamente a solução passa por verificar qual é o caractere em questão e substituí-lo pelo número correspondente, assim fazendo a multiplicação entre eles para gerar a resposta.

Código em C:


#include <stdio.h>

size_t obtemTamanho(const char *s) {
    size_t t = 0;
    while (++t)
        if (!s[t])
            return t;
}

int main() {
    unsigned int n;
    char senha[17];
    char c;
    unsigned int resposta;
    unsigned int i;

    scanf("%u", &n);
    while (n--) {
        scanf("%s", senha);
        resposta = 1;
        for (i = 0; i < obtemTamanho(senha); i++) {
            c = senha[i];
            if (c == 'a' || c == 'A' || c == 'e' || c == 'E' || c == 'i' || c == 'I' || c == 'o' || c == 'O' || c == 's' || c == 'S')
                resposta *= 3;
            else
                resposta *= 2;
        }
        printf("%u\n", resposta);
    }
    return 0; 
}

Código em C++:

O código em C++ segue a mesma lógica do código em C.

#include <iostream> 
#include <string>

int main() {
    unsigned int n;
    std::string senha;
    std::cin >> n;
    while (n--) {
        std::cin >> senha;
        int resposta = 1;
        for (int i = 0; i < senha.size(); i++) {
            char c = senha[i];
            if (c == 'a' || c == 'A' || c == 'e' || c == 'E' || c == 'i' || c == 'I' || c == 'o' || c == 'O' || c == 's' || c == 'S')
                resposta *= 3;
            else
                resposta *= 2;
        }
        std::cout << resposta << std::endl;
    }
    return 0; 
}

Código em Haskell:

Aqui também aplicou-se a mesma lógica, porém de forma recursiva.

main :: IO ()
main = do
   n <- readLn
   reading n

obtemVariacoes :: [Char] -> Int
obtemVariacoes [] = 1
obtemVariacoes (x:xs)
   | x == 'A' || x == 'a' || x == 'e' || x == 'E' || x == 'i' = 3 * obtemVariacoes xs
   | x == 'I' || x == 'o' || x == 'O' || x == 's' || x == 'S' = 3 * obtemVariacoes xs
   | otherwise = 2 * obtemVariacoes xs

reading :: Int -> IO ()
reading n = do
   if n == 0
      then return ()
      else do
         senha <- getLine
         print (obtemVariacoes senha)
         reading (n-1)

URI (BEECROWD) - 1803 - Matring - Strings - C, C++ e Haskell

Olá! Novo post de Strings! E novamente resolvido em três linguagens, que são C, C++ e Haskell.  Porém, dessa vez para C++ e Haskell eu apresentei duas soluções.

O problema resolvido é o "Matring".

E fica o pedido para que ajudem o blog, a chave PIX é 6d8bc7a8-5d74-493a-ab7a-3515baf35956. 

Valeu e até a próxima!


Plataforma: URI (BEECROWD)

Problema1803

Enunciado:

Matring é uma mistura de Matriz e String. Ela foi desenvolvida pela UNILA (União dos Nerds para Integração da Lógica e da Aventura) para manter mensagens seguras de escutas.

A primeira e última coluna de uma matring guarda a chave para traduzi-la na mensagem original. As colunas restantes de uma matring representam uma string codificada em ASCII, uma coluna por caractere.

Para uma mensagem com N caracteres, a matring correspondente é uma matriz 4x(N+2) de dígitos. Cada coluna é lida como um número de 4 dígitos; uma sequência de dígitos de cima para baixo é o mesmo que uma sequência de dígitos da esquerda para a direita na horizontal.

Seja o primeiro número F, o último número L e os restantes uma sequência de números Mi, onde 1 ≤ i ≤ N. A primeira coluna de uma matring é indexada por zero.

Para decodificar uma matring para uma string, calculamos: Ci = (F * Mi + L) mod 257, onde Ci é o caractere em ASCII na posição i da mensagem original.

Sua tarefa é desenvolver um algoritmo para decodificar matrings.

Linguagem: C, C++ e Haskell


Solução: 

Aqui eu fiz de algumas formas diferentes, confira abaixo!

Código em C:


#include <stdio.h>
#define LINHAS 4
#define MAXTAM 85

size_t obtemTamanho(const char *s) {
    size_t t = 0;
    while (++t)
        if (!s[t])
            return t;
}

int main() {
    int i;
    int j;
    int f;
    int l;
    int ultimo;
    int tamanho;
    int multiplicador;
    int caractereDecodificado;
    int valores[MAXTAM];
    char m[LINHAS][MAXTAM];

    for (i = 0; i < LINHAS; i++)
        scanf("%s", m[i]);

    tamanho = obtemTamanho(m[0]);
    for (i = 0; i < tamanho; i++) {
        valores[i] = 0;
        for (j = 0, multiplicador = 1000; j < LINHAS; j++, multiplicador /= 10)
            valores[i] += (m[j][i] - 48) * multiplicador;
    }

    ultimo = tamanho - 1;
    f = valores[0];
    l = valores[ultimo];
    for (i = 1; i < ultimo; i++) {
        caractereDecodificado = (f * valores[i] + l) % 257;
        printf("%c", caractereDecodificado);
    }

    printf("\n");

    return 0;
}

Código em C++:

Solução 1:

#include <iostream>
#include <string>

int main() {
    const int LINHAS = 4;
    const int MAXTAM = 85;
    int i;
    int j;
    int f;
    int l;
    int ultimo;
    int tamanho;
    int multiplicador;
    int valores[MAXTAM];
    char caractereDecodificado;
    std::string m[LINHAS];

    for (i = 0; i < LINHAS; i++)
        std::cin >> m[i];

    tamanho = m[0].size();

    for (i = 0; i < tamanho; i++) {
        valores[i] = 0;
        for (j = 0, multiplicador = 1000; j < LINHAS; j++, multiplicador /= 10)
            valores[i] += (m[j][i] - 48) * multiplicador;
    }

    ultimo = tamanho - 1;
    f = valores[0];
    l = valores[ultimo];
    for (i = 1; i < ultimo; i++) {
        caractereDecodificado = (f * valores[i] + l) % 257;
        std::cout << caractereDecodificado;
    }

    std::cout << std::endl;
    return 0;
}

Solução 2:

#include <iostream>
#include <string>

int main() {
    const int LINHAS = 4;
    const int MAXTAM = 85;
    int i;
    int j;
    int f;
    int l;
    int ultimo;
    int tamanho;
    int multiplicador;
    int valores[MAXTAM] = {0};
    char caractereDecodificado;
    std::string m[LINHAS];

    for (i = 0, multiplicador = 1000; i < LINHAS; i++, multiplicador /= 10) {
        std::cin >> m[i];
        if (!i) 
            tamanho = m[0].size();
        for (j = 0; j < tamanho; j++)
            valores[j] += (m[i][j] - 48) * multiplicador;
    }

    ultimo = tamanho - 1;
    f = valores[0];
    l = valores[ultimo];
    for (i = 1; i < ultimo; i++) {
        caractereDecodificado = (f * valores[i] + l) % 257;
        std::cout << caractereDecodificado;
    }

    std::cout << std::endl;
    return 0;
}

Código em Haskell:

Solução 1:

import Control.Monad (replicateM)
import Data.Char

main :: IO ()
main = do
    let linhas = 4
    m <- replicateM linhas getLine
    let tamanho = length (head m)
        valores = map (\i -> sum [digitToInt (m !! j !! i) * 10^(linhas - j - 1) | j <- [0..linhas-1]]) [0..tamanho-1]
        f = head valores
        l = last valores
        resposta = [chr (mod (f * v + l) 257) | v <- tail (init valores)]
    putStrLn resposta

Solução 2:

import Control.Monad (replicateM)
import Data.Char (chr, digitToInt)
import Data.List (transpose)

somaElementos :: [[Int]] -> [Int]
somaElementos [] = []
somaElementos ([]:_) = []
somaElementos lists = sum (map head lists) : somaElementos (map tail lists)

calcula :: [[Char]] -> Int -> [[Int]]
calcula [] _ = []
calcula _ 0 = []
calcula (x:xs) n = (map (*n) (map digitToInt x)):(calcula xs (div n 10))

obtemResposta :: [Int] -> Int -> Int -> [Char]
obtemResposta [] _ _ = []
obtemResposta (x:xs) f l = (chr (mod (f * x + l) 257)) : obtemResposta xs f l

main :: IO ()
main = do
   let linhas = 4
   m <- replicateM linhas getLine
   let tamanho = length (head m)
       inicial = 1000
       parcial = calcula m inicial
       listaTransposta = transpose parcial
       valores = map sum listaTransposta
       f = head valores
       l = last valores
       respostaTotal = obtemResposta valores f l
       resposta = init (tail respostaTotal)
   putStrLn resposta

terça-feira, 19 de dezembro de 2023

URI (BEECROWD) - 2591 - HameKameKa - Strings - C, C++ e Haskell

Olá! Novo post de Strings! E novamente resolvido em três linguagens, que são C, C++ e Haskell.

E fica o pedido para que ajudem o blog, a chave PIX é 6d8bc7a8-5d74-493a-ab7a-3515baf35956. 

Valeu e até a próxima!


Plataforma: URI (BEECROWD)

Problema2591

Enunciado:
O Hamekameka foi inventado por Mestre Hame praticado por cinquenta anos antes de conhecer Kogu. Chamando sua energia latente nas palmas de suas mãos, Hame consegue lançar um raio explosivo de energia. Kogu aprende após ver Mestre Hame usando-o para apagar as chamas na casa de um Rei. Para a surpresa de Hame, Kogu consegue performar a técnica de primeira, embora seja apenas forte o suficiente para destruir o carro que Chamya deu para Mulba. Kogu descobriu que há um padrão na pronúncia correta deste ataque, de modo que, se não for pronunciado corretamente, o mesmo não acontece.

Escreva um programa que, dada a parte inicial de um Hamekameka, faça a finalização ideal para que o ataque seja realizado com sucesso.

Linguagem: C, C++ e Haskell


Solução: 

A solução é basicamente multiplicar a quantidade de "a" das duas partes da string que podem repetir esta letra. Portanto, basta contar os dois valores e multiplicá-los. Assim, sabe-se a quantidade de "a" que é necessário escrever na saída, fazendo isso com um laço de repetição.

Código em C:

#include <stdio.h>
size_t obtemTamanho(const char* s) {
	int i = 0;
	while (s[i] != '\0')
		i++;
	return i;
}

int main() {
	int n;
	char palavra[210];
	scanf("%d", &n);
	while (n--) {
		scanf("%s", palavra);
		int p1 = 1, p2 = 1, i = 2;
		while (palavra[i] == 'a') {
			i++;
			p1++;
		}
		i = obtemTamanho(palavra) - 4;
		while (palavra[i] == 'a') {
			i--;
			p2++;
		}
		printf("k");
		int resposta = p1 * p2;
		for (int i = 0; i < resposta; i++)
			printf("a");
		printf("\n");
	}
	return 0;
}


Código em C++:

#include <iostream>
#include <string>

int main() {
	int n;
	std::string palavra;
	std::cin >> n;
	while (n--) {
		std::cin >> palavra;
		int p1 = 1, p2 = 1, i = 2;
		while (palavra.at(i) == 'a') {
			i++;
			p1++;
		}
		i = palavra.size() - 4;
		while (palavra.at(i) == 'a') {
			i--;
			p2++;
		}
		std::cout << "k";
		int resposta = p1 * p2;
		for (int i = 0; i < resposta; i++)
			std:: cout << "a";
		std::cout << std::endl;
	}
	return 0;
}


Código em Haskell:

main :: IO ()
main = do
   n <- readLn
   reading n

obtemQuantidade :: [Char] -> Int -> Int
obtemQuantidade [] _ = 0
obtemQuantidade (x:xs) n
   | x == 'm' = n
   | otherwise = obtemQuantidade xs (n+1)

reading :: Int -> IO ()
reading n = do
   if n == 0
      then return ()
      else do
         palavra <- getLine
         let tamanho = length palavra
         let parte1 = obtemQuantidade palavra (-1)
         let quantidade = parte1 * (tamanho - parte1 - 6)
         putStrLn ("k" ++ replicate quantidade 'a')
         reading (n-1)

domingo, 17 de dezembro de 2023

URI (BEECROWD) - 3358 - Surname is not Easy (Sobrenome Não é Fácil) - Strings - C, C++ e Haskell

Olá! Vamos com mais um post da categoria Strings! Dessa vez, resolvido em três linguagens!

Veja abaixo, as minhas soluções para esse problema!

Mais uma vez, faço a vocês um pedido: ajudem o blog! A chave PIX (chave aleatória) é 6d8bc7a8-5d74-493a-ab7a-3515baf35956. Qualquer valor ajudará muito, obrigado mais uma vez!


Plataforma: URI (BEECROWD)

Problema3358

Enunciado:
A região sul do Brasil é caracterizada pela ascendência multicultural de seus habitantes, sendo principalmente europeus e sobretudo italianos, alemães e poloneses. Uma consequência interessante disso é a variação na dificuldade na pronúncia dos sobrenomes da população, o que as vezes dificulta a vida dos professores na realização da chamada de sua turma, gerando até situações constrangedoras. Dada a possibilidade de constrangimento em suas aulas, a professora Jiraiya decidiu pesquisar os sobrenomes em sua lista de chamadas. Na concepção de Jiraiya, um sobrenome é difícil se tiver três ou mais consoantes consecutivas.

Linguagem: C, C++ e Haskell


Solução: 

Para identificar se o sobrenome é difícil é só achar três consoantes consecutivas. Comparar o caractere com cada consoante é custoso, então a estratégia é comparar com as vogais, que são menos. O que fica mais trabalhoso é que essa comparação deve acontecer tanto com maiúsculas quanto com minúsculas, ou é necessário criar ou usar uma função pronta uma para passar todo caractere para minúsculo na comparação. Assim, apenas verifico se o caractere não é vogal por três caracteres consecutivos, o que resultará em sobrenome difícil.


Código em C:

Há várias soluções possíveis. Na minha, apenas leio o texto e o percorro verificando se o caractere atual é vogal. Se durante essa varredura ele já encontrar três consoantes seguidas, interrompe essa repetição e imprime o resultado. Caso contrário, vai até o fim do laço até saber se há ou não três consoantes consecutivas para responder se é ou não é fácil.

#include <stdio.h>

size_t obtemTamanho(const char* s) {
   int i = 0;
   while (s[i] != '\0')
      i++;
   return i;
}

int ehVogal(char c) {
   return c == 'a' || c == 'A' || c == 'e' || c == 'E' || c == 'i'
   || c == 'I' || c == 'o' || c == 'O' || c == 'u' || c == 'U';
}

int main() {
   int n;
   char sobrenome[45];
   scanf("%d", &n);

   while (n--) {
      scanf("%s", sobrenome);
      int tamanho = obtemTamanho(sobrenome);
      int consoantesConsecutivas = 0;

      int dificil = 0;
      for (int i = 0; i < tamanho; i++) {
         if (ehVogal(sobrenome[i]))
            consoantesConsecutivas = 0;
         else
            consoantesConsecutivas++;

         if (consoantesConsecutivas == 3) {
            dificil = 1;
            break;
         }
      }

      if (dificil)
         printf("%s nao eh facil\n", sobrenome);
      else
         printf("%s eh facil\n", sobrenome);
   }
   return 0;
}

Código em C++:

Outra solução que utiliza a mesma estratégia, mas em C++. Aqui aproveito o uso do tipo string e a existência da função size, mas a lógica segue exatamente a mesma do código em C.

#include <iostream>
#include <string>

using namespace std;

bool ehVogal(char c) {
   return c == 'a' || c == 'A' || c == 'e' || c == 'E' || c == 'i' || c == 'I' ||
   c == 'o' || c == 'O' || c == 'u' || c == 'U';
}

int main() {
   int n;
   string sobrenome;
   cin >> n;

   while (n--) {
      cin >> sobrenome;
      int tamanho = sobrenome.size();
      int consoantesConsecutivas = 0;
      int maiorSequencia = 0;
      bool dificil = false;
      for (int i = 0; i < tamanho; i++) {
         if (ehVogal(sobrenome[i]))
            consoantesConsecutivas = 0;
         else
            consoantesConsecutivas++;

         if (consoantesConsecutivas == 3) {
            dificil = true;
            break;
	}
      }

      if (dificil)
         cout << sobrenome << " nao eh facil" << endl;
      else
         cout << sobrenome << " eh facil" << endl;
   }
   return 0;
}

Código em Haskell:

Aqui em Haskell, usando lógica parecida também. Porém, declarei uma função ehDificil para já retornar um booleano (valor lógico) quando o sobrenome for difícil.

main :: IO ()
main = do
   n <- readLn
   reading n

ehVogal :: Char -> Bool
ehVogal c = c == 'a' || c == 'A' || c == 'e' || c == 'E' || c == 'i' || c == 'I' || c == 'o' || c == 'O' || c == 'u' || c == 'U'

ehDificil :: [Char] -> Int -> Bool
ehDificil [] 3 = True
ehDificil [] _ = False
ehDificil (x:xs) n = if n == 3 then True else if ehVogal x then ehDificil xs 0 else ehDificil xs (n+1)

reading :: Int -> IO ()
reading n = do
   if n == 0
      then return ()
      else do
         sobrenome <- getLine
         let resposta = ehDificil sobrenome 0
         if resposta
            then
               putStrLn (sobrenome ++ " nao eh facil")
            else
               putStrLn (sobrenome ++ " eh facil")
         reading (n - 1)

domingo, 21 de março de 2021

URI (BEECROWD) - 2866 - Criptotexto - Strings - C e C++

Um post sobre um problema da categoria Strings! No URI/BEECROWD uma das categorias de exercícios é "Strings", onde é necessário manipular cadeias de caracteres para obter a resposta. Esse é o problema "Criptotexto", que foi resolvido por mim em C e C++. Bora ver os códigos?

Plataforma: URI (BEECROWD)

Problema2866

Linguagens: C e C++


Solução:

A lógica aplicada aqui foi a mesma para os códigos em C e C++. Lê todo texto e  o percorre de trás pra frente, em busca de caracteres lowercase (letras minúsculas). Imprime quando encontrar e no fim imprime a quebra de linha. Esse eu achei divertido de fazer, e vocês?

Código em C:

#include <stdio.h>

int main() {
    
    int c, contador = 0;
    
    scanf("%i ",&c);
    
    while(contador < c) {
        
        char palavra[1001];
        int pos = 0;
        
        scanf("%s",palavra);
    
        while (palavra[pos] != '\0')
            pos++;

        pos--;
        
        while (pos >= 0) {
            if (palavra[pos] >= 'a' && palavra[pos] <= 'z') {
                printf("%c",palavra[pos]);
            }
            pos--;
        }
        
        printf("\n");
        
        contador++;
        
    }
    return 0;
}

Código em C++:

#include <iostream>

using namespace std;

int main() {
    
    int c, contador = 0;
    
    cin >> c;
    cin.ignore();
    
    while(contador < c) {
        
        string palavra;
        int pos = 0;
        
        cin >> palavra;
    
        while (palavra[pos++] != '\0');
        
        while (--pos >= 0) {
            if (palavra[pos] >= 'a' and palavra[pos] <= 'z') {
                cout << palavra[pos];
            }
        }
        
        cout << endl;
        contador++;
        
    }
    return 0;
}

Postagem em destaque

URI (BEECROWD) - 2158 - Helping Uncle Cláudio (Ajudando o Tio Cláudio) - Matemática - C, C++ e Haskell

Buenas! Estou aqui mais uma vez para resolver um problema de Matemática! Agora tenho resolvido alguns dessa categoria, pra que vocês possam ...

Postagens mais visitadas