• Nenhum resultado encontrado

1ª Lista de Exercícios de Paradigmas de Linguagens Computacionais Professores: Fernando Castor, Paulo Borba e Márcio Cornélio Monitores: Ciência da computação: Agay Borges (abn), David Hulak (dbh), Glauco Santos (grps), Lívia Vilaça (lcjbv), Luís Gabriel

N/A
N/A
Protected

Academic year: 2019

Share "1ª Lista de Exercícios de Paradigmas de Linguagens Computacionais Professores: Fernando Castor, Paulo Borba e Márcio Cornélio Monitores: Ciência da computação: Agay Borges (abn), David Hulak (dbh), Glauco Santos (grps), Lívia Vilaça (lcjbv), Luís Gabriel "

Copied!
8
0
0

Texto

(1)

1ª Lista de Exercícios de Paradigmas de Linguagens Computacionais

Professores: Fernando Castor, Paulo Borba e Márcio Cornélio

Monitores:

Ciência da computação:

Agay Borges (abn), David Hulak (dbh), Glauco Santos (grps), Lívia Vilaça

(lcjbv), Luís Gabriel Lima (lgnfl), Pedro Melo (pam2), Thales Alex (tata), Vanessa Gomes de Lima

(vgl2), Walter Ferreira (wflf)

Engenharia da Computação:

Alan Gomes(aga)

Dennis Silveira (dwas), Eduardo Rocha (ejfrf),

Felipe

de Souza (fsa2),Gabriel Avelar (gafm),

Lucas Inojosa (licf), Victor Hugo (vhca), Wellington Oliveira

(woj)

CIn-UFPE – 2011.2

Disponível desde:

01/11/2011

Entrega:

16/11/2011

A lista deverá ser respondida

em dupla

. A falha em entregar a lista até a data estipulada implicará

na

perda de 0,25 ponto na

média

da disciplina para os membros da dupla. Considera-se que uma

lista na qual

menos que 6

das respostas estão corretas não foi entregue. A entrega da lista com

pelo menos 11

das questões corretamente respondidas implica em um

acréscimo de 0,125

ponto

na média da disciplina para os membros da dupla. Se

qualquer situação de cópia de respostas

for

identificada, os membros

de todas as duplas

envolvidas

perderão 0,5 ponto na média da disciplina.

O mesmo vale para respostas obtidas a partir da Internet. As respostas deverão ser entregues

exclusivamente em formato texto ASCII

(nada de .pdf, .doc, .docx ou .odt) e deverão ser enviadas

para o monitor responsável por sua dupla,

sem

cópia para o professor. Devem ser organizadas em

arquivos separados, um por questão, entregues em um único formato compactado, ou seja, um

único arquivo zipado contendo as respostas para todas as questões.

QUESTAO 1

Crie um contador em Haskell utilizando variáveis compartilhadas (

MVars

). No main você deverá criar um

número 2n de threads, n incrementando e n decrementando. Cada thread deverá realizar sua tarefa(++ ou --)

por 1000000/n vezes (10^6).

Você terá de analisar o tempo de execução e o custo de memória do programa e explicar o que acontece para

valores pequenos e grandes de n.

Use valores como 1, 10, 50, 100. Não é especificado.

Por exemplo, para n = 1:

thread 1: incrementador; até 1000000;

thread 2: decrementador; até 1000000.

Para n = 2:

thread 1: incrementador; até 500000;

thread 2: decrementador; até 500000;

thread 3: incrementador; até 500000;

thread 4: decrementador; até 500000.

QUESTAO 2

(2)

QUESTAO 3

Implemente um jogo de tiro ao alvo com as seguintes características:

O jogo tem 3 atiradores e 3 barracas

Cada barraca contem 15 alvos.

Os atiradores sempre acertam no alvo, mas a escolha do alvo no qual um atirador vai atirar em dado

momento, bem como a barraca onde ele vai escolher o alvo, são feitas aleatoriamente.

Cada atirador e barraca devem ser implementados em Threads separadas.

Cada atirador pode atirar em qualquer uma das barraca.

Cada vez que um atirador acerta um alvo, aquele alvo não pode mais ser acertado por outro atirador

até que ele seja reativado pela barraca.

Caso um atirador tente acertar um alvo que já foi acertado ele deve tentar acertar um outro alvo.

Cada alvo acertado conta 1 ponto para o atirador.

O tempo da competição é determinado pelo usuário.

O tempo para reativar os alvos é determinado pelo usuário.

Ao final do tempo, deve ser impresso a pontuação de cada um dos atiradores bem como um número

identificador para ele. Utilize

Mvars

para resolver o problema.

QUESTAO 4

Implemente uma solução para a questão anterior, desta vez usando

STM

.

Faça testes com diversos valores tanto para o tempo de execução do programa quanto para a quantidade de

tempo que a barraca leva para reativar os alvos e faça uma comparação com as duas soluções.

QUESTAO 5

Crie um programa em haskell, utilizando

MVars

, que rode um número N de threads, definidas no

início da execução. Metade delas devem executar o cálculo da função f(x) = (N∕2)*x+1 e a outra metade deve

executar a inversa dessa função. Considere que as threads deverão executar um total de:

a) 1000000 vezes.

b) 1000*(N2-55N+750) vezes.

c) 1000000/ΣN vezes.

Análise, para cada simulação, os resultados para diversos valores N (devem ser pares) e explique o

comportamento do programa quando o valor de N tende a aumentar.

Obs: ΣN é o somatório dos valores de 0 a N.

QUESTAO 6

Orcs são criaturas estúpidas que só conseguem fazer duas coisas: morder ou gritar. Para um Orc

conseguir comer sua presa, ele deve primeiro gritar até atordoar sua vítima, para depois então tentar morder.

Certo dia, dois Orcs resolveram caçar juntos no pântano e eles fizeram um acordo: quando eles avistarem uma

presa, primeiro eles tentarão gritar, quem conseguir gritar depois poderá tentar morder, se o outro não estiver

mordendo, ele conseguirá morder com certeza. Mas claro, Orcs não são criaturas confiáveis, então mesmo que

o primeiro Orc consiga gritar o outro ainda assim terá uma chance de 50% de tentar morder e roubar a presa.

Implemente este problema dos Orcs usando

memória transacional

em haskell. Considere que a cada segundo

aparece uma presa nova. O programa deve parar quando um número N de presas, definido no início da

execução, forem atacadas. Cada Orc deve ser implementado como uma thread distinta.

QUESTAO 7

(3)

problema, quando os filósofos sentem fome deverão pegar dois garfos para comer: primeiro, o

filósofo pega o garfo da esquerda e, depois, o da direita. Como só há cinco garfos, os filósofos que

estiverem ao lado e também sentirem fome não conseguirão comer até que o que está comendo

largue os dois garfos e volte a pensar. Outro problema mais complicado é se todos os filósofos

ficarem com fome ao mesmo tempo e pegarem um dos garfos, fazendo com que nenhum consiga

pegar os dois necessários para comer causando um impasse permanente. Implemente uma solução

para esse problema usando

memória transacional

.

QUESTAO 8

Implemente uma solução para o problema do papai noel usando

memória transacional

.

QUESTAO 9

Duas cidades são separadas por uma ponte de madeira e em cada cidade há 'n' comerciantes. Os

comerciantes querem aumentar sua renda passando para a cidade vizinha, mas, porque a ponte é frágil, só

podem atravessar dois comerciantes ao mesmo tempo e isso só é possível se eles estiverem na mesma

direção. Crie uma thread para cada comerciante, o programa termina quando todos comerciantes tiverem

visitado a cidade vizinha e voltado para sua cidade. Para o desenvolvimento crie 'n' threads para representar

os comerciantes, suponha que cada comerciante passe no mínimo 500 milisegundos na cidade vizinha e 40

milisegundos na passagem pela ponte. Obs.: Use

MVars

para o desenvolvimento da questão.

QUESTAO 10

Um GuitarHero multiplayer foi desenvolvido com uma única música, nesse jogo a música possui 10

rodadas que por sua vez possuem 50 notas. Cada jogador demora 'q' milisegundos (um número entre 10-50)

para acertar 'k' notas(um número aleatório ente 1 e 50), em cada rodada. Se o jogador demorar mais de 45

milisegundos para tocar as 'k' notas da rodada é desclassificado. Para o desenvolvimento crie 'n' threads

representando os jogadores e ao fim das rodadas imprima em ordem decrescente (de notas acertadas no total)

os jogadores classificados. Obs.: Use

TVars

para o desenvolvimento da questão.

QUESTAO 11

Imagine o seguinte jogo.

O jogo possui:

Um mapa, contendo varias regiões, cada qual cada uma começa defesa igual a zero.

Varios jogadores, que são colocados, no início do jogo, em áreas aleatórias.

Cada jogador contem uma função que recebe três inteiros e retorna um valor. (Int -> Int -> Int -> Int).

A cada momento o jogador deverá se mover para uma nova região e tentar conquistá-la. Para isso ele jogará

três dados de seis faces e os resultados dos dados será calculados na função do jogador e o resultado será

comparado à defesa da região. (Esse movimento será exemplificado abaixo)

Se ataque do jogador for maior que a defesa da região, ele conquista ela( o terreno fica marcado como

território daquele jogador) e a região passa a ter como defesa o resultado do ataque do jogador.

Se o valor for menor, ele perde 1 ponto de vida e retorna para a região anterior, onde descansará por 200

milisegundos até poder se mover.

Após conquistar o território, o jogador deverá descansar por 200 milisegundos, permanecendo

parado naquele território.

Enquanto um jogador está disputando um território, nenhum outro pode entrar naquele território.

No entanto, enquanto o jogador está descansando em um território, outros jogadores podem entrar e atacar

aquele território.

A região para qual o jogador irá se mover, deverá ser escolhida aleatoriamente entre as regiões

adjacentes a que ele está.

Caso o jogador se mova pra uma região que já seja dele, ele deverá se mover novamente.

Caso o jogador escolha uma região que já esteja sendo disputada, ele deverá escolher outra.

Se o jogador perder todos os seus pontos de vida, ele será eliminado.

O jogo termina quando restar apena um jogador

(4)

Use uma thread para cada jogador.

Use

MVars

Imprima na tela, sempre que um jogador for derrotado, seu nome e as áreas que ele possui.

No final da partida, imprima na tela o nome do vencedor e as áreas que ele possui.

Exemplo do cálculo do ataque do jogador:

data Player = Player String (Int -> Int -> Int -> Int)

ataque :: Player -> Int -> Int -> Int -> Int

ataque (Player nome f) a b c = f a b c

let player = Player "Jogador 1" (\a b c => a*2 + b*3 + c*4)

ataque player 1 2 3 = 20

QUESTAO 12

Em uma fazenda, toda manha, uma familia de 5 pessoas acorda bem cedo para ordenhar as vacas da

fazenda.

Os fazendeiros trabalham em paralelo.

As vacas, muito exigentes, não deixam os fazendeiros ordenharem enquanto elas colocam o capim na

boca, no entanto permitem enquanto elas estão ruminando.

Cada vaca aguenta até dois fazendeiros ordenhando ela ao mesmo tempo. Mais que isso ela se torna

violenta e ataca os fazendeiros.

Enquanto a vaca está sendo ordenhada, ela da um mugido para avisar que vai começar a comer, e

nesse momento os fazendeiros devem parar de ordenhar a vaca, e se dirigir a outra, que não esteja comendo.

A cada 200 milisegundos cada vaca decide se quer comer, em uma probabilidade de 1/5, durante 'x'

milisegundos, sendo 'x' um número aleatório entre 100 e 400 milisegundos.

Os fazendeiros devem escolher uma vaca aleatória a cada instante em que eles vão trocar de vaca.

Essa troca leva 100 milisegundos.

A quantidade de leite retirada é proporcional ao tempo que o fazendeiro passou ordenhando

(considere 1 ml para cada 1 segundo).

Todas as vacas possuem a mesma quantidade de leite

Imprima sempre que uma vaca decidir comer, indicando o número da vaca que foi comer, e quais

fazendeiros estavam ordenhando ela naquele instante.

Quando todo o leite de todas as vacas for ordenhado, imprima o tempo que os fazendeiros gastaram.

Use

Tvars

QUESTAO 13

Com a morte de Steve Jobs, as pessoas no CIn ficaram tristes e começaram a chorar. Steve, sendo tão

adorado, causou muito choro, o que rapidamente inundou o local e causou uma enxurrada a qual se espalhou

pela Grande Recife inteira, e algumas pessoas continuavam a chorar pelo ídolo, continuando a inundar a

cidade.

Para reverter esta situação, os alunos do CIn deverão consertar o caos causado por eles próprios. Para isto,

irão se dividir em 2 grupos: Os que consolarão as pessoas a pararem de chorar e os que irão remover a água da

cidade e jogar no oceano. Como não encontraram baldes no CIn, cada um destes alunos deverá usar conjuntos

de copinhos de café (usados para tomar água na copa do CIn) para esvaziar a água da cidade.

Considere o cenário: k litros de inundação, x pessoas chorando, w alunos do CIn responsáveis por consertar

tudo, sendo y alunos para consolar as pessoas e z para jogar a água fora. Cada conjunto de copinhos de café

cabe meio litro. De um em um segundo cada aluno joga meio litro de água fora, enquanto de dois em dois

segundos cada aluno consegue fazer uma pessoa na cidade parar de chorar. Cada pessoa chora 100 mililitros a

cada segundo, ajudando a inundar ainda mais a cidade.

(5)

(inundação atual da cidade em litros). O programa imprimir no console “Inundação encerrada” quando toda a

água for esvaziada da cidade. No exato momento em que a água toda for esvaziada, todos devem parar suas

atividades, tanto os alunos quanto os chorões, e o programa deverá ser encerrado.

QUESTAO 14

Considerando a situação acima, reimplemente a questão utilizando

TVar

ao invés de MVar. Além

disso, Dado k = 1000, x = 500 e w = 50, qual uma boa combinação de valores de y e z, dado que w = y + z, de

forma que a cidade seja esvaziada mais rapidamente? Descubra isto empiricamente na execução.

QUESTAO 15

O problema da cobertura por vértices ponderada é um problema conhecido, e é um problema NP-completo. O

problema consiste em, dado um grafo G = (V,E), e uma função w: V → N+, obter V' c V, tal que para toda aresta

(v,w) pertencente a E, v pertence a V' ou w pertence a V', e o somatório dos w(vi) para todo vi pertencente

a V' é mínimo. Elabore, utilizando apenas

Memória Transacional

(exceto para verificar se as threads já

terminaram) uma estratégia não-determinística (e concorrente), que receba a quantidade de threads pela

entrada padrão (console), para resolver este problema. O nome do arquivo de entrada é “in.txt”, do arquivo

de saída é “out.txt”. Cada grafo da entrada será formado por uma linha contendo 2 inteiros n m (|V| e |

E| respectivamente); uma linha com os pesos dos vértices de 1 até n em ordem; m linhas com inteiros x

y, que indicam que a aresta (x,y) pertence ao grafo; uma linha em branco. A saída deve conter os vértices

pertencentes a V' na primeira linha em ordem crescente, o custo da solução encontrada e uma linha em

branco.

Exemplo:

in.txt:

5 4

1 1 1 1 1

1 2

2 3

1 3

3 4

7 6

1 1 1 1 1 1 1

1 2

2 3

1 4

4 5

1 6

6 7

out.txt:

2 4

2

2 4 6

3

QUESTAO 16

(6)

Código:

import Control.Concurrent

import Control.Concurrent.MVar

import System.Random

maxBalde = 5000

maxChuva = 2000000

caneca = 500

numBaldes = 10

delayChuva = 1000000

goteira :: MVar Int -> MVar Int -> MVar Int -> IO ()

goteira balde chuva fim =

do

total <- takeMVar chuva

if total < maxChuva then do {

volBalde <- takeMVar balde;

numGotas <- randomRIO (10,100) :: IO Int;

numGotas <- return (min (maxBalde - volBalde) (min numGotas (maxChuva - total)));

putMVar chuva (total + numGotas);

if volBalde == maxBalde then do {

putMVar balde volBalde;

} else do {

putMVar balde (volBalde + numGotas);

};

threadDelay delayChuva;

goteira balde chuva fim;

} else do {

putMVar chuva total;

putMVar fim 0;

return ()

}

childermass :: [MVar Int] -> Int -> Int -> Int -> MVar Int -> String -> IO ()

childermass baldes bal1 bal2 count fim nome = do

if (bal1 == bal2)

then do

conteudo <- takeMVar (baldes!!bal1)

if (conteudo < (caneca*2))

then do

putMVar (baldes!!bal1) conteudo

threadDelay 100

childermass baldes bal1 bal2 count fim nome

else do

parar <- takeMVar fim

if (parar /= 0)

then do

putMVar (baldes!!bal1) (conteudo - (caneca*2))

threadDelay (delayChuva*2)

novoBal1 <- randomRIO (0,numBaldes-1) :: IO Int

novoBal2 <- randomRIO (0,numBaldes-1) :: IO Int

childermass baldes novoBal1 novoBal2 (count+1) fim nome

else do

(7)

else do

conteudo1 <- takeMVar (baldes!!bal1)

conteudo2 <- takeMVar (baldes!!bal2)

if ((conteudo1 < caneca) || (conteudo2 < caneca))

then do

putMVar (baldes!!bal1) conteudo1

putMVar (baldes!!bal2) conteudo2

threadDelay 100

childermass baldes bal1 bal2 count fim nome

else do

parar <- takeMVar fim

if (parar /= 0)

then do

putMVar (baldes!!bal1) (conteudo1 - caneca)

putMVar (baldes!!bal2) (conteudo2 - caneca)

threadDelay (delayChuva*2)

novoBal1 <- randomRIO (0,numBaldes-1) :: IO Int

novoBal2 <- randomRIO (0,numBaldes-1) :: IO Int

childermass baldes novoBal1 novoBal2 (count+1) fim nome

else do

putMVar (baldes!!bal1) conteudo1

putMVar (baldes!!bal2) conteudo2

putMVar fim 0

main :: IO ()

main =

do

balde1 <- newMVar 0

balde2 <- newMVar 0

balde3 <- newMVar 0

balde4 <- newMVar 0

balde5 <- newMVar 0

balde6 <- newMVar 0

balde7 <- newMVar 0

balde8 <- newMVar 0

balde9 <- newMVar 0

balde10 <- newMVar 0

chuva <- newMVar 0

fim <- newEmptyMVar

bal1 <- randomRIO (0,numBaldes-1) :: IO Int

bal2 <- randomRIO (0,numBaldes-1) :: IO Int

bal3 <- randomRIO (0,numBaldes-1) :: IO Int

bal4 <- randomRIO (0,numBaldes-1) :: IO Int

forkIO (goteira balde1 chuva fim)

forkIO (goteira balde2 chuva fim)

forkIO (goteira balde3 chuva fim)

forkIO (goteira balde4 chuva fim)

forkIO (goteira balde5 chuva fim)

forkIO (goteira balde6 chuva fim)

forkIO (goteira balde7 chuva fim)

forkIO (goteira balde8 chuva fim)

forkIO (goteira balde9 chuva fim)

forkIO (goteira balde10 chuva fim)

forkIO (childermass [balde1, balde2, balde3, balde4, balde5, balde6, balde7, balde8, balde9, balde10] bal1

bal2 0 fim "Childermass")

(8)

f <- takeMVar fim

f <- takeMVar fim

f <- takeMVar fim

f <- takeMVar fim

f <- takeMVar fim

f <- takeMVar fim

f <- takeMVar fim

f <- takeMVar fim

f <- takeMVar fim

f <- takeMVar fim

b1 <- takeMVar balde1

b2 <- takeMVar balde2

b3 <- takeMVar balde3

b4 <- takeMVar balde4

b5 <- takeMVar balde5

b6 <- takeMVar balde6

b7 <- takeMVar balde7

b8 <- takeMVar balde8

b9 <- takeMVar balde9

b10 <- takeMVar balde10

ch <- takeMVar chuva

Referências

Documentos relacionados

Para definir qual será o monitor responsável por corrigir a sua lista, vá até o endereço http://sites.google.com/a/cin.ufpe.br/monitoria-plc/ e inclua (a página é editável) os

Este tipo pode ser Secante (para uma reta que passa em dois pontos da circunferência), Tangente (para uma reta que passa por um ponto da circunferência) ou

 Sua  implementação   deve  usar  apenas  memória  transacional  e  variáveis

Toda esta proeza com o arco é devido ao seu excelente nível de Agilidade, mas ainda possui níveis de Força e Inteligência um pouco abaixo (este último é menor ainda, pois não

20) Nem tudo são flores! Crie funções para realizar acessos às posições de uma Matrix através de índices. Você deve criar duas dessas funções, set e get, uma para “mudar” o

compõe as respectivas funções de forma que o resultado seja igual a aplicação sucedidas dessas funções da esquerda para a direita.. O funcionamento de functions é tal que

A brincadeira termina quando alguém estver com seu tonel cheio, após isso imprima a quantdade de litros (ou mililitros) que cada pessoa conseguiu encher, de forma ordenada.

14) Seu Zé possui uma fábrica de chocolates muito boa, só que infelizmente, a demanda da fábrica é muito grande e ele não consegue supri-la. Sabendo disso, Seu Zé,