• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Lisboeta_c95

Duvida em Perl

23 mensagens neste tópico

Estou a tirar a certificação de Adm. Sis. Unix/Linux e tenho um problema num objectivo em Perl.

O objectivo e pegar num baralho de cartas e tirar 5 cartas aleatórias sem usar o rand, apenas quer que se use o shift, pop, push, e ordenalas da mais pequena para a maior. Escrevi o seguinte codigo mas o instrutor nao aceita, nao sei o que mais fazer, sem rand parece me dificil fazer uma escolha aleatoria.

o ultimo codigo que escrevi foi:

#!/usr/bin/perl

@startingdeck = ("A H","2 H","3 H","4 H","5 H","6 H","7 H","8 H",
                                  "9 H","10 H","J H","Q H","K H",
                                  "A D","2 D","3 D","4 D","5 D","6 D","7 D","8 D",
                                  "9 D","10 D","J D","Q D","K D",
                                  "A C","2 C","3 C","4 C","5 C","6 C","7 C","8 C",
                                  "9 C","10 C","J C","Q C","K C",
                                  "A S","2 S","3 S","4 S","5 S","6 S","7 S","8 S",
                 "9 S","10 S","J S","Q S","K S");

for my $x(0..5){
         my@shuffle=(
                     pop(@startingdeck),
                     shift(@startingdeck),
                     pop(@startingdeck),
                     shift(@startingdeck),
                     pop(@startingdeck),
                     shift(@startingdeck),
                     pop(@startingdeck),
                     shift(@startingdeck),
                     pop(@startingdeck),
                     );
  push @startingdeck, @shuffle;
         print"Top five Cards:@startingdeck[0..4]\n";
     }

A resposta dele foi: "Hi Bruno,

You've got a good start but we only want the first hand printed out.  And the cards do not appear to be shuffled, only shifted. You might want to mix up your functions a little. Please let me know if you have any questions and have a terrific day.

Kelly

Any ideas? :hmm:

Obrigado

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Se calhar o problema é estares a fazer isso de uma forma demasiado regular. Talvez devesses tentar misturar mais os pushs com os pop e shifts.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Nao percebi. Como demasiado regular? podes me dar um exemplo?

Cheers mate

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Em relação à sugestão do Rui Carlos. Essas funções não existem numa distribuição standard de Perl (http://perldoc.perl.org/index-functions-by-cat.html#Functions-for-real-@ARRAYs'>http://perldoc.perl.org/index-functions-by-cat.html#Functions-for-real-@ARRAYs). Por isso é certo que isso também não é uma solução que o instrutor aceite.

Nota:

ok... Percebi agora que o Rui Carlos não estava a falar das funções pushs e shifts, mas a tentar fazer o plural de push e shift... Por tanto o paragrafo em cima não faz muito sentido...

Não estou a ver o que é que isto tem a ver com uma certificação em administração de sistemas.

É certo que Perl é uma ferramenta útil aos administradores de sistemas, mas este problema está bem fora do scope... É um problema útil para quem quer aprender a programar em Perl para ser programador, porque obriga a aprender detalhes sobre o Perl. Mas isso também é um bocado subjectivo.

Sou contra a prática de ajudar com problemas para este fim. Acho que o trabalho deve ser o fruto do esforço e mérito de cada um. Embora seja justo pedir, aceitar e dar ajuda. Essa ajuda devem ser apenas orientações.

Mas não resisti a fazer código que resolve o teu problema. Já o tenho, só estou na dúvida em publicar o código.

Já tenho na cabeça mais umas duas formas de fazer isto... Mas não as vou colocar em código, porque tenho mais que fazer.

As ajudas que posso dar para já são:

Utilizei apenas builtins do Perl que não o rand e srand (usei map, keys, reverse, push, pop, shift e undef) e conhecimento sobre alguns tipos de dados do Perl (neste caso: arrays e hashes).

Dos builtins que utilizei só precisava mesmo do map e do keys. Alias, nem precisa de nenhuma delas, mas iria ter que escrever funções que fizessem o mesmo, o que aumentava a quantidade de código e a complexidade dele para resolver um problema de treta.

Estes links têm informação que te podem ajudar:

http://perldoc.perl.org/perlintro.html#Perl-variable-types

http://perldoc.perl.org/index-functions-by-cat.html

E já agora nunca faças perl que não tenha logo na segunda e terceira linha:

use strict;

use warnings;

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Nao percebi. Como demasiado regular? podes me dar um exemplo?

O problema a que me estava a referir era tu apenas fazeres uma sequência de shifts e pops (sempre alternados), e só fazes um push no fim.

Podias fazer qualquer coisa como criar uma nova lista, e ires retirando dois elementos no fim e um no início, que adicionas à nova lista, até que a primeira fique vazia. E podias repetir este processo várias vezes (com a nova lista que acabaste de gerar), o que te permitiria obter uma lista um pouco melhor baralhada.

Um exemplo da aplicação da ideia que referi a uma sequência de inteiros:

0123456789

9807615423

3294581607

7036128594

Com 3 iterações a sequência já parece mais ou menos aleatória.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Boas noites!

Lisboeta_c95 quantas vezes corres-te o teu código?

É este o resultado que deu na última vez que correste o código :

Top five Cards:5 H 6 H 7 H 8 H 9 H

Top five Cards:9 H 10 H J H Q H K H

Top five Cards:K H A D 2 D 3 D 4 D

Top five Cards:4 D 5 D 6 D 7 D 8 D

Top five Cards:8 D 9 D 10 D J D Q D

Top five Cards:Q D K D A C 2 C 3 C

Corri duas vezes e como é obvio o resultado foi o mesmo, logo não podias passar no "exame" porque crias-te um script com um valor estático.

Sendo que estás a tirar uma certificação para linux, eu vejo esta actividade como uma forma de conheceres as ferramentas do sistema operativo.

Claro que, por experiência própria te digo que teres lido na diagonal o livro Learning Perl (Lama book) te tinha dado melhores hipoteces de concluires o exercicio.

Edit: O teu exercicio é bastante similar aos que se encontram na net... não deverá ser coincidencia...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

A certificação da oreilly é composta por 4 modulos: unix services, unix system, dns and networking, e Perl.Sendo que no ultimo modulo tem varios objectivos para fazer um deles é este. no enunciado nem fala que nao se pode usar rand, mas depois ele ao corrigir diz que nao quer que se use o rand.

o enuncado é o seguinte:

Here are your instructions:

The pop function "pops" off the last element of an array and returns it. It works like this:

$element = pop(@array);

The shift function works the same way, but removes an element from the front of an array.

Using pop, shift, push, and the starting code below, write a script that sufficiently "shuffles" a simulated deck of cards before printing the top five cards. Save this script in your home directory on the hottub as obj10.pl.

#!/usr/bin/perl

@startingdeck = ("A H","2 H","3 H","4 H","5 H","6 H","7 H","8 H",

                "9 H","10 H","J H","Q H","K H",

                "A D","2 D","3 D","4 D","5 D","6 D","7 D","8 D",

                "9 D","10 D","J D","Q D","K D",

                "A C","2 C","3 C","4 C","5 C","6 C","7 C","8 C",

                "9 C","10 C","J C","Q C","K C",

                "A S","2 S","3 S","4 S","5 S","6 S","7 S","8 S",

                "9 S","10 S","J S","Q S","K S");

## Your code goes here ##

O problema é que ele quer uma forma aleatória sem correr o rand, o resultado da sempre o mesmo mesmo quecrie uma lista como tinham sugerido.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Bem, isso foi o que eu pensei, e ainda tentei solucionar o problema até cair de sono ontem... mas a mim pareceu-me um pouco impossivel com os meus conhecimentos.

Este foi tirado a ferros, mas tem uma falha, pode repetir a carta na mesma mão, e não segue o pedido pois usa o rand.

#!/usr/bin/perl -w

use strict;

my ($cada, @baralho, $baralhar);
my $range = 51;

@baralho = qw /"AH 2H 3H 4H 5H 6H 7H 8H 9H 10H JH QH KH AD 2D 3D 4D 5D 6D 7D 8D 9D 10D JD QD KD AS 2S 3S 4S 5S 6S 7S 8S 9S 10S JS QS KS AC 2C 3C 4C 5C 6C 7C 8C 9C 10C JC QC KC
/;

for $baralhar(0..4){
my $random = int(rand($range));
print $baralho[$random];
print " ";
}
print "\n";

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Já agora, podes usar a funções relacionadas com a hora?

Hum... a tua ideia é boa, mas pensando eu nos segundos (60 segundos ou de 0 a 59) e sendo as cartas 52 (0 a 51 num array) ficam 8 numeros a mais.

E sendo que a hora é incremental... 1,2,3,4,5 ... segundos não iriam sair cartas aleatorias mas 5 cartas seguidas.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Hum... a tua ideia é boa, mas pensando eu nos segundos (60 segundos ou de 0 a 59) e sendo as cartas 52 (0 a 51 num array) ficam 8 numeros a mais.

E sendo que a hora é incremental... 1,2,3,4,5 ... segundos não iriam sair cartas aleatorias mas 5 cartas seguidas.

Bastava acederes à hora uma vez. A partir daí haviam várias alternativas possíveis. Por exemplo, tendo por base a ideia que apresentei anteriormente, podias usar o número obtido para controlar o número de iterações de transformação da lista. Ou até podias chegar ao ponto de criares um gerador de números aleatórios (a hora seria a tua semente, que garantiria que em cada execução a sequência aleatória seria diferente).

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Boas,

Estou farto de dar voltas à minha cabeça de como solucionar o problema, mas com shift, pop, push parece-me muito à frente esse pensamento.

Descobri o List::Util qw/shuffle/ nas minhas pesquisas e o resultado:

#!/usr/bin/perl -w

use strict;
use List::Util qw/shuffle/;

my @cartas = qw /AH 2H 3H 4H 5H 6H 7H 8H 9H 10H JH QH KH AD 2D 3D 4D 5D 6D 7D 8D 9D 10D JD QD KD AS 2S 3S 4S 5S 6S 7S 8S 9S 10S JS QS KS AC 2C 3C 4C 5C 6C 7C 8C 9C 10C JC QC KC/;

for my $baralhar(1){
my @shut = shuffle(@cartas);
print " @shut[0..4] \n";
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O problema é que ele quer uma forma aleatória sem correr o rand, o resultado da sempre o mesmo mesmo quecrie uma lista como tinham sugerido.

Isso não é um grande problema.

Com as dicas que eu indiquei chega a uma solução simples para isso.

Bem, isso foi o que eu pensei, e ainda tentei solucionar o problema até cair de sono ontem...

Lesses com atenção o que eu disse e a documentação que eu indiquei e chegavas lá.

mas a mim pareceu-me um pouco impossivel com os meus conhecimentos.

Não existe, nem, pouco, nem muito impossível. Ou é possível, ou é impossível.

Não cometam essas atrocidades linguísticas.

        my $random = int(rand($range));

Ele já tinha dito que não podia usar o rand.

Já agora, podes usar a funções relacionadas com a hora?

Não me parece útil, nem necessário existem no Perl outras soluções mais adequadas e menos complexas.

Descobri o List::Util qw/shuffle/ nas minhas pesquisas e o resultado:

Se ele não pode usar o rand, parece-me também que não haveria de poder usar módulos do CPAN. Acho que o objectivo aqui é aprender algumas propriedades de tipos de dados em Perl e não a usar o CPAN.

Já agora acho mal que resolvam o problema dele (apresentem código). Ele tá a tirar uma certificação ele é que tem que provar que consegue resolver problemas.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Isso não é um grande problema.

Com as dicas que eu indiquei chega a uma solução simples para isso.

1 - Lesses com atenção o que eu disse e a documentação que eu indiquei e chegavas lá.

2 - Ele já tinha dito que não podia usar o rand.

3- Se ele não pode usar o rand, parece-me também que não haveria de poder usar módulos do CPAN. Acho que o objectivo aqui é aprender algumas propriedades de tipos de dados em Perl e não a usar o CPAN.

4- Já agora acho mal que resolvam o problema dele (apresentem código). Ele tá a tirar uma certificação ele é que tem que provar que consegue resolver problemas.

1- Nisso tens razão, que não li muito bem a documentação que sugeriste!

2- Tenho noção que não pode usar o rand, mas isso não me impede de tentar :thumbsup:

3- Apenas quis relatar o que tinha encontrado, não sei se usa o cpan directamente, pois não tive de lá ir buscar nada...

4- Não resolvi, nem estou perto de o resolver neste momento, mas o objectivo também não era resolver o exercicio por ele e sim mais um desafio pessoal.

Como estamos a ver, não voltou aqui para dizer que tinha feito algum tipo de evolução. E se tu dizes que ao ler a documentação devidamente é possivel, não estou a perceber porque é que ele não disse nada.

Uma coisa é certa, não é o primeiro, nem deverá ser o último a fazer esta pergunta na web.

Cumprimentos

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

4- Não resolvi, nem estou perto de o resolver neste momento, mas o objectivo também não era resolver o exercicio por ele e sim mais um desafio pessoal.

A questão é que independentemente do teu propósito/intenção, esse foi um efeito possível...

Às vezes temos de pensar que podemos causar problemas/coisas incorrectas mesmo que não seja essa a nossa intenção.

A mim também me apetecia colocar aqui pelo menos umas 5 soluções diferentes para o problema utilizando apenas builtins do Perl que não o rand e srand...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Falco, no que dizes em respeito de fazer o programa concordo contigo, mas nao quero que o façam o programa, posso te por varios programas que fiz para este objectivo e nenhum deles foi aceite, como viste coloquei o ultimo que tinha feito e o instrutor nao aceitou.

Visto ser um curso atraves da web a unica maneira de contactar com o instrutor e por mail, e vendo a respostas dele nao foram muito produtivas.

Quanto ao resto do pessoal, agradeço desde ja o apoio por tentarem resolver este enigma. O problema e mesmo como disse ele nao quer nem rands, nem shuffles, apenas push, shift, e pop.

A questao e que no loop so com estas funçoes cada vez que executa  programa ele ha de sempre apresentar o mesmo resultado.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Hi,

>

> I still have problems with this objective, can i use shuffle, or Keys

> function?

> Or may i put a cycle for give cards and exit when for example i click "Enter"?

>

> because like i said is very diffcult doing a rand or shuffle without rand

> or srand.

>

> Regards

>

> Bruno

Ele respondeu:

Hi Bruno,

This project is about using pop, shift, push and loops to shuffle. We are not looking for a random shuffle or anything near it, we just want you to mix up the cards a bit.

Please let me know if you have any questions and have a terrific day.

Kelly

Portanto ele nao me aceita nada fora do que pede. alguem me da uma ideia do loop que ele quer para baralhar as cartas, com pop, shift, push?

thanks

Bruno

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Acho que um ciclo do género que indiquei atrás servia. Se ele diz que não quer um "random shuffle" pressuponho que não haja problema em dar sempre o mesmo resultado.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu fiz com shuffle, e ele não aceitou, quer mesmo só com aquelas funçoes. Já deves ter reparado no meu dilema. :wallbash:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Para implementar a sugestão que apresentei apenas precisas das 3 funções que podes usar.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Amigos, junto envio o codigo que foi aceite, agradeço a todos pelo tempo e pelas dicas.

Um grande abraço.

#!/usr/bin/perl

#use strict;
use warnings;

@startingdeck = ("A H","2 H","3 H","4 H","5 H","6 H","7 H","8 H",
                                  "9 H","10 H","J H","Q H","K H",
                                  "A D","2 D","3 D","4 D","5 D","6 D","7 D","8 D",
                                  "9 D","10 D","J D","Q D","K D",
                                  "A C","2 C","3 C","4 C","5 C","6 C","7 C","8 C",
                                  "9 C","10 C","J C","Q C","K C",
                                  "A S","2 S","3 S","4 S","5 S","6 S","7 S","8 S",
                 "9 S","10 S","J S","Q S","K S");
@half1 = @startingdeck[0..25];
@half2 = @startingdeck[26..51];
for my $x(0..25){
my@shuffle=(
                        shift(@half1),
                        pop(@half2)
                );
    push@temp1, @shuffle;
}
push@shuffleddeck, @temp1;
for my $x(0..12){
         my@shuffle=(
                             pop(@shuffleddeck),
                     pop(@shuffleddeck),
                     shift(@shuffleddeck),
                     pop(@shuffleddeck)
                     );

         push@temp2, @shuffle;
}
push@shuffleddeck, @temp2;
print"@shuffleddeck[0..4] \n";

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Fixe!

Bem, quando vi esta frase :

We are not looking for a random shuffle or anything near it, we just want you to mix up the cards a bit.

Vi logo que estivemos aqui a pensar no que não era... KISS [KEEP IT SIMPLE STUPID]

Ainda bem que passas-te! Já estava na hora de sair um resultado positivo

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Parabéns pelo teu sucesso!

Agora que já passaste, já me sinto confortável em colocar aqui o meu código.

Não o tenho comigo, por isso não o posso colocar agora, mas assim que tiver coloco. Ando bastante ocupado, por isso só o devo fazer lá para domingo, ou segunda...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora