Pesquisar este blog

Livros Recomendados

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

terça-feira, 18 de julho de 2023

URI (BEECROWD) - 3162 - Space Communication (Comunicação Espacial) - Iniciante - Haskell

Buenas!

Cá estou para apresentar mais um problema resolvido!

Foi resolvido agora o problema "Comunicação Espacial". Esse problema é relativamente novo na plataforma e não tem muitas soluções, pelo menos até agora. Eu, inclusive, ainda não o resolvi em outras linguagens, fiz ele só em Haskell por enquanto. Veja na sequência desse post como eu fiz para resolvê-lo!

Porém, como costumo indicar em alguns posts, recomendo que antes de resolver qualquer algoritmo do BEECROWD você siga os seguintes passos:

  1. Leia todo enunciado do problema.
  2. Leia os tópicos do fórum em caso de dúvidas. As vezes os outros usuários podem esclarecer questões interpretativas e fornecer casos de teste interessantes ou outras dicas valiosas.
  3. Prepare arquivos de entrada para teste, considerando as entradas de exemplo do Beecrowd, do udebug e outros valores limite;
  4. Prepare o ambiente de desenvolvimento e utilize os mesmos parâmetros dos compiladores do Beecrowd
  5. Prepare um código-fonte padrão, já contendo a chamada às bibliotecas padrão, pré-processadores, retorno de função e um comando de escrita com "\n", pois no Beecrowd a grande maioria dos problemas exige a quebra de linha final.


Plataforma
: BEECROWD

Problema3162

Enunciado:

O ano é 2337. Milhares de naves de tripulações humanas viajam pelo espaço de forma alucinada para lá e para cá. E o melhor: as naves conseguem se comunicar através de rádio, é possível até mesmo que tripulações entre naves distintas jogarem truco.

No entanto, infelizmente a qualidade do sinal esvanece com a distância. Enquanto naves próximas conseguem se comunicar bem, as naves que estão distantes possuem péssima intensidade de sinal para se comunicar. Por esse motivo, as naves comunicam-se preferencialmente com a nave mais próxima.

Considerando um trecho do espaço onde as naves podem ser consideradas pontos no espaço, portanto com coordenadas tridimensionais, com cada eixo podendo ter valor entre 0 e 100 u.m. Sabe-se que a intensidade do sinal de comunicação se dá pela distância entre as naves; de modo que naves que distam entre si até 20 u.m. possuem uma intensidade alta; acima de 20 u.m. e até 50 u.m. possuem uma intensidade média; enquanto a intensidade do sinal acima de 50 u.m. é tão baixa que não possibilita a comunicação entre as naves.

Dadas as informações passadas, ajude os tripulantes destas naves a conseguirem saber a intensidade do sinal entre cada uma delas e a nave mais próxima, para informá-los se eles vão conseguir ter uma boa comunicação entre si.

Linguagem: Haskell

Solução:

A ideia é ler as coordenadas e salvá-las em listas de inteiros, o que é feito com a função replicate monádica. Depois disso, cria-se uma lista contendo a distância de cada ponto com os demais (ok, tive preguiça e calculei distâncias duplicadas, com certeza não precisava disso). O cálculo da distância em R3 é o mesmo que já aprendemos na matemática no ensino médio, é necessário somar o quadrado da diferença de cada eixo e tirar a raiz disso.

Depois, o que fiz foi ordenar as listas de distâncias e pegar sempre a segunda distância, pois a primeira será zero (distância de um ponto até ele mesmo). Ao pegar o segundo elemento de cada lista de distâncias, basta verificar se ele se enquadra em intensidade alta, baixa ou média com base em cada condição e imprime A, B ou M  para cada caso.

Usei a função map monádica sem retorno (mapM_) para imprimir a resposta porque assim ela é fácil de usar e estou interessado somente no efeito que é produzido (escrita na tela), e não no resultado.

Eu mesmo cheguei a criar outras soluções para esse exercício, mas dessa vez vou deixar só essa aqui.

E aí, conseguiu entender?

Código em Haskell:

import Control.Monad (mapM_, replicateM)
import Data.List (sort)

getDistance :: [Double] -> [Double] -> Double
getDistance (x1:y1:z1:[]) (x2:y2:z2:[]) = sqrt ((x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2)

getAllDistances :: [[Double]] -> [Double] -> [Double]
getAllDistances [] _ = []
getAllDistances (l:ist) point = getDistance l point : getAllDistances ist point

getAns :: [Double] -> [Char]
getAns list
   | list!!1 < 20 = "A"
   | list!!1 <= 50 = "M"
   | otherwise = "B"

main :: IO ()
main = do
   n <- readLn
   coord <- replicateM n (do
      line <- getLine
      let xyz = map read (words line) :: [Double]
      return (xyz))
   let values = map (getAllDistances coord) coord
   let sorted = map sort values
   let ans = map getAns sorted
   mapM_ putStrLn ans

Ajude o blog a continuar postando respostas para ajudar a todos com exercícios de programação! A chave aleatória (PIX) para doações é 6d8bc7a8-5d74-493a-ab7a-3515baf35956.

Um abraço a todos!

sexta-feira, 9 de junho de 2023

URI (BEECROWD) - 1016 - Distance (Distância) - Iniciante - Haskell

Novo desafio resolvido em Haskell! O problema n. 1016 é o problema da distância (título Distance/Distância).
Esse exercício é muito fácil de se resolver e serve mais para quem quer se familiarizar com a linguagem ou está dando os primeiros passos em programação.

Vamos ver como resolvi esse exercício? As informações sobre ele estão abaixo, na sequência desse post.

Plataforma: URI (BEECROWD)
Problema1016

Enunciado:
Two cars (X and Y) leave in the same direction. The car X leaves with a constant speed of 60 km/h and the car Y leaves with a constant speed of 90 km / h.

In one hour (60 minutes) the car Y can get a distance of 30 kilometers from the X car, in other words, it can get away one kilometer for each 2 minutes.

Read the distance (in km) and calculate how long it takes (in minutes) for the car Y to take this distance in relation to the other car.

Linguagem: Haskell

Solução:

Basicamente precisamos apenas dobrar a distância e assim teremos os minutos necessários.

Nosso código precisa estar na função principal, que é chamada de main. A função main é do tipo IO (). Essa primeira linha é opcional, se não utilizarmos ela o compilador irá inferir o tipo da função.

Na segunda linha iniciamos a função main já colocando o seu código dentro de um bloco do, pois ele é uma sequência de duas ou mais instruções.

No nosso bloco do, temos primeiramente a leitura de um valor inteiro, que é a distância. Como este valor é lido pela entrada padrão, utilizamos o tipo IO Int. A linha seguinte já imprime a resposta. Para isso usamos putStrLn, que quebra a linha ao final do texto, e como parâmetro informamos a mensagem no formato "distancia*2 minutos". Para obter o valor certo de distancia*2 (o dobro da distância), precisamos converter o resultado da expressão para String, o que fazemos com a função show().

Obviamente esta resposta não é a única possível; poderíamos ter usado tipo Integer ou mesmo ter resolvido sem multiplicação (distance+distance era uma possibilidade).

E aí? O que achou desta solução?

Veja o código abaixo e até a próxima!

main :: IO ()
main = do 
   distance <- readLn :: IO Int
   putStrLn (show(distance * 2) ++ " minutos")

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