Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Daniel Ribeiro

[DESAFIO] Caixa Eletrônico

Recommended Posts

  Em 17/01/2011 at 11:58, Matias Rezende disse:

Mas o código do Bruno não funciona direito (ou eu fiz algo errado).

$ATM = new ATM( 6 );

$ATM -> getDistribution( TRUE );

 

Saída:

 

  Citar

Withdrawal Request: 6 in BRL

 

ATM has delivered 5 bills of 5 Reais

 

Sorry, but your withdrawal was not entirely perfect. We could not deliver 1 Real

 

Thank you for use our service!

 

Veja que é possível sacar 6 reais com as notas disponíveis ali. (2,5,10,20,50,100), retirando 3 notas de 2 reais. Pelo que a mensagem está dizendo, você retirou 5 notas de 5 reais para sacar 6 reais... é isto mesmo ou a mensagem está errada? Se for isto mesmo, eu to torcendo pra você fazer o sistema do caixa eletrônico do meu banco... :D

 

Até agora o único código que funcionou para qualquer combinação de notas foi o meu monstrinho!!!! O código do Evandro retorna bem certinho a quantidade de notas, mas depende do usuário. Se colocar um valor que não seja possível ele não sai do loop. Falta ver o do Daniel e o do João (que disse que já terminou, mas vai esperar um pouco pra postar pra não estragar a brincadeira... :P)

 

Carlos Eduardo

 

Realmente, não tinha testado para este caso.

 

O meu código está pronto, mas está em casa.

 

Saindo do trabalho colocarei o código aqui.

 

OBS: Como assim "o código do João vai estragar a brincadeira"? Não entendi... <_<

Compartilhar este post


Link para o post
Compartilhar em outros sites
  Em 17/01/2011 at 12:00, Daniel R. Gomes disse:

OBS: Como assim "o código do João vai estragar a brincadeira"? Não entendi... <_<

 

O "estragar a brincadeira" é frase minha, na tentativa de brincar com o fato que os códigos do João normalmente são abstratos, completos, complexos e grandes... Conhecendo o João do jeito que eu conheço e pelo que ele me falou que implementou (beeeeeemmmmmm mais que o desafio), tenho a impressão que vai colocar o meu monstrinho de volta na jaula dele :D. O seu, pelo que pude entender, deve implementar o que o desafio se propõe (nada a mais), estando preparado para realizar novas tarefas, mas ainda não implementadas.

 

Não era a minha intenção desmerecer ninguém, era só uma forma de fazer uma brincadeira.

 

Carlos Eduardo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Pensando justamente nessa interação da ATM com aqueles USB's teimosos, ajustei meu código para que caso a transação seja efetuada de forma imperfeita, talvez pelo valor requisitado ser menor do que o mínimo e também, caso algumas notas estejam faltando (não apenas as menores), quando a diferença na entrega pode ser maior que apenas um real, o próprio ATM instrua o usuário sobre o que fazer.

 

Sem contar um pequeno bug brutal na contagem distribuição de distribuição que ocorria com valores baixos.

 

 

  Mostrar conteúdo oculto

 

Compartilhar este post


Link para o post
Compartilhar em outros sites
  Em 17/01/2011 at 12:15, Matias Rezende disse:
  Em 17/01/2011 at 12:00, Daniel R. Gomes disse:

OBS: Como assim "o código do João vai estragar a brincadeira"? Não entendi... <_<

 

O "estragar a brincadeira" é frase minha, na tentativa de brincar com o fato que os códigos do João normalmente são abstratos, completos, complexos e grandes... Conhecendo o João do jeito que eu conheço e pelo que ele me falou que implementou (beeeeeemmmmmm mais que o desafio), tenho a impressão que vai colocar o meu monstrinho de volta na jaula dele :D. O seu, pelo que pude entender, deve implementar o que o desafio se propõe (nada a mais), estando preparado para realizar novas tarefas, mas ainda não implementadas.

 

Não era a minha intenção desmerecer ninguém, era só uma forma de fazer uma brincadeira.

 

Carlos Eduardo

 

Com relação ao meu código, exatamente. Ele resolve o problema proposto e está pronto para se expandir de acordo com a demanda.

 

Acho que o tópico propõe soluções rápidas, simples e objetivas, saca?

 

Sobre o código do João, conversei com ele. Acho que se ele tem uma solução melhor, ele deveria postar logo pra compartilhar o conhecimento e dar a oportunidade àqueles que tiveram dificuldades tirarem suas dúvidas sobre o processo. Mas ele prefere postar o código depois do término do desafio, então temos que respeitar a vontade dele.

Compartilhar este post


Link para o post
Compartilhar em outros sites

O problema da contagem da nota foi corrigido, mas o problema do saque continua.

$ATM = new ATM( 6 );

$ATM -> getDistribution( TRUE );

Saída

 

  Citar

Withdrawal Request: 6 in BRL

 

ATM has delivered 1 bills of 5 Reais

 

Sorry, but your withdrawal was not entirely perfect.

We could not deliver 1 Real because this bill is not available in this ATM.

 

Thank you for use our service!

 

Na verdade o caixa deveria sacar 3 notas de 2 reais, já que o objetivo do desafio é exibir o menor número de notas necessárias para efetuar o saque com as notas disponíveis.

 

Continua só o meu monstrinho atendendo o desafio... :P

 

Carlos Eduardo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cacetada, esse fórum tá doido.

 

Quando eu respondi com meu update que além de maximizar essa interação ATM-Usuário corrigia esse bug brutal que o Matias apontou não haviam as mensagens #20, #21 e #22, estando apenas a #19 em que o Daniel analisa a situação e a minha.

 

O bug está corrigido e funciona para qualquer distribuição. Mas essa do fórum foi bizarra. :lol:

 

Quanto a comparação do código do Matias com o meu, bem, só posso dizer que eu não soube mesmo ^_^

 

Na bem da verdade, nem sei se um ATM de verdade faz esse tipo de distinção, para sempre retornar o menor de notas e tal...

Compartilhar este post


Link para o post
Compartilhar em outros sites
  Em 17/01/2011 at 12:36, Bruno Augusto disse:

Cacetada, esse fórum tá doido.

 

Quando eu respondi com meu update que além de maximizar essa interação ATM-Usuário corrigia esse bug brutal que o Matias apontou não haviam as mensagens #20, #21 e #22, estando apenas a #19 em que o Daniel analisa a situação e a minha.

 

O bug está corrigido e funciona para qualquer distribuição. Mas essa do fórum foi bizarra. :lol:

 

Quanto a comparação do código do Matias com o meu, bem, só posso dizer que eu não soube mesmo ^_^

 

Na bem da verdade, nem sei se um ATM de verdade faz esse tipo de distinção, para sempre retornar o menor de notas e tal...

 

Sim, o processo é adotado como padrão, até para economia de cédulas.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bruno, qual é o código correto então? Porque o último que você postou continua aparecendo o erro na distribuição das notas. A contagem está certa (1 nota de 5 reais), mas continua dizendo que não dá pra sacar R$ 6,00, sobrando R$ 1,00.

 

Posta o código certo, como executar e a saída (para R$ 6,00), pra não dar problema.

 

Carlos Eduardo

Compartilhar este post


Link para o post
Compartilhar em outros sites

É esse o código. Essa mensagem é definida apenas na exibição mais descritiva e quando NÃO EXISTE a nota de um real.

 

Melhorando o que eu falei, eu não assim tão ninja :lol:

 

[EDIT]

 

Agora que fui testar o "seu monstrinho". Peuei alguns valores gerados aleatóriamente pelo seu para comparar com o meu e, a principio, funciona como o meu.

 

O meu faz até um pouco a mais. O meu ATM até entrega o máximo de notas possível.

 

Um exemplo foi no seu 913 reais com notas de 10, 50 e 100. O seu abortou, o meu entregou nove de 100 e uma de 10, pedindo desculpa por não ter entregado 3.

Compartilhar este post


Link para o post
Compartilhar em outros sites
  Em 17/01/2011 at 12:57, Bruno Augusto disse:

É esse o código. Essa mensagem é definida apenas na exibição mais descritiva e quando NÃO EXISTE a nota de um real.

 

Melhorando o que eu falei, eu não assim tão ninja :lol:

 

Justamente Bruno.

 

O problema é que, e aí irás entender o meu comentário anterior, você não pode dizer para o usuário que é impossível conceder o valor de 6 reais.

 

A quantidade mínima de notas seria uma de 5 e uma de 1. Se com essa combinação o valor não pode ser concedido, pule para a próxima combinação possível, evidentemente com mais notas: 3 notas de 2.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu ainda acho que na relação performance-resultado, não entregar um valor baixo é melhor do que tentar novamente.

 

Claro, num ATM d verdade isso é ínfimo, mas com PHP já vale se considerar.

 

Eu tentei, mas acho que por não ter entendido direito a proposta, ficou simples assim. Estou na curiosidade sobre a solução final. De repente eu até sei fazer, mas não sei que sei. ^_^

Compartilhar este post


Link para o post
Compartilhar em outros sites
  Em 18/01/2011 at 10:59, Bruno Augusto disse:

Eu ainda acho que na relação performance-resultado, não entregar um valor baixo é melhor do que tentar novamente.

 

Claro, num ATM d verdade isso é ínfimo, mas com PHP já vale se considerar.

 

Eu tentei, mas acho que por não ter entendido direito a proposta, ficou simples assim. Estou na curiosidade sobre a solução final. De repente eu até sei fazer, mas não sei que sei. ^_^

 

Bruno,

 

eu sugiro que você tente implementar a lógica de chain a que me referi no post anterior.

 

O caso de um valor de 6 é perfeito para demonstrar essa lógica:

 

6 = 5 + 1

6 = 2 + 2 + 2

6 = 1 + 1 + 1 + 1 + 1 + 1

A partir disso você consegue detectar e manipular quaisquer outras situações reais.

 

OBS: O pattern chain of responsibility simula exatamente o processo de um ATM.

 

chainofresponsibilityex.png

 

É possível de se implementar uma estrutura interessante para simular a operação de um ATM utilizando o pattern chain of responsibility.

 

Apesar da minha solução estar focada no problema, no desafio, e ser bastante simples e objetiva, vou postar, mais tarde, essa implementação mais real e abstrata a qual me refiro.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Infelizmente, não manjo muito de padrões de projeto.

 

Sempre que me entusiasmo com o assunto o suficiente para aprender, ou o assunto acaba ou esfria e sou obrigado a buscar informações estrangeiras que nem sempre são lá muito explicativas, não se baseiam na aplicação dos mesmos com PHP e/ou usam de casos tão malucos e inúteis que a explicação focada fica difícil para alguém que não entende aplicar na vida real, em aplicações reais.

Compartilhar este post


Link para o post
Compartilhar em outros sites
  Em 18/01/2011 at 21:33, Bruno Augusto disse:

Infelizmente, não manjo muito de padrões de projeto.

 

Sempre que me entusiasmo com o assunto o suficiente para aprender, ou o assunto acaba ou esfria e sou obrigado a buscar informações estrangeiras que nem sempre são lá muito explicativas, não se baseiam na aplicação dos mesmos com PHP e/ou usam de casos tão malucos e inúteis que a explicação focada fica difícil para alguém que não entende aplicar na vida real, em aplicações reais.

 

Tudo bem... o tópico abriu a brecha para falarmos do pattern chain, mas não somos obrigados a utilizá-lo a partir de agora.

 

Faça o seguinte: implemente a resolução do último problema que seu código apresentou e vamos em frente com o desafio.

Compartilhar este post


Link para o post
Compartilhar em outros sites
  Em 18/01/2011 at 11:17, Daniel R. Gomes disse:

O pattern chain of responsibility simula exatamente o processo de um ATM.

 

Eu não usaria Chain of Responsibility nesse caso, usaria Command e o motivo é bem simples :seta: Uma transação pode não ser bem sucedida.

 

Caso um determinado comando (ou uma lista de comandos) não seja bem sucedido, a transação precisa retornar ao seu estado anterior, nesse caso um rollback precisa ser feito para cancelar todo o processo.

 

Outro ponto é o conhecimento das notas que podem existir em um caixa eletrônico, não existe nota de R$ 1.5 ou nota de R$ 57, a base de Chain of Responsibility é o desconhecimento do objeto que tratará uma requisição enquanto um Command é enviado para um objeto específico.

 

Um outro padrão para ser utilizado é Visitor:

 

Um caixa eletrônico possui vários cofres, um para cada nota. O Visitor visitaria cada um desses cofres e executaria um comando "contar notas", o sucesso desse comando mudaria o estado do Visitor ou, caso não haja notas suficientes naquele cofre específico, o Visitor pode ter seu estado revertido para uma situação anterior.

Compartilhar este post


Link para o post
Compartilhar em outros sites
  Em 19/01/2011 at 09:54, João Batista Neto disse:
Eu não usaria Chain of Responsibility nesse caso, usaria Command e o motivo é bem simples :seta: Uma transação pode não ser bem sucedida.

 

Na realidade, João, meu pensamento estava sob a hipótese do Chain of Responsibility utilizar o Command para representar as requisições como objetos "palpáveis".

 

A base do Chain of Responsibility, a nível conceitual, também pode ser pensada de forma que cada objeto da corrente irá contribuir da sua maneira para responder à requisição em um todo, o que é exatamente a realidade de um ATM.

 

Em um nível abstrato, existe sim um Transaction que irá manipular operações como Withdrawal e Deposit, e para este caso o Command seria bastante pertinente.

 

No nível interno da operação, porém, pode-se pensar que cada nota mantém a referência para a próxima nota na corrente, assim a separação do dinheiro em espécie será sempre bem sucedida, enquanto o Transaction, outra operação totalmente diferente, pode não ser.

 

Em CoR, a implementação conhece a "cabeça" da corrente, ou a entrada. Vejo necessária a utilização deste padrão específico para o processo porque, à medida que cada nota da corrente mantém referência para a próxima, pode-se ter uma flexibilidade para essa cabeça, podendo sempre ser alterada de acordo com a demanda. Para exemplificar, quando a nota de 100 não estivesse mais disponível, a nota mais alta depois dela se tornaria a cabeça da corrente, neste caso a nota de 50.

 

Veja que quem executa o rollback é o Transaction, repetindo todo o processo de separação de dinheiro.

 

OBS: Agora não tem jeito, posta sua solução aí! Hehehehe...^_^

Compartilhar este post


Link para o post
Compartilhar em outros sites
  Em 19/01/2011 at 10:38, Daniel R. Gomes disse:

OBS: Agora não tem jeito, posta sua solução aí! Hehehehe...^_^

 

Posta a sua solução também Daniel. To esperando pra ver.

 

Carlos Eduardo

Compartilhar este post


Link para o post
Compartilhar em outros sites
  Em 19/01/2011 at 10:47, Matias Rezende disse:
Posta a sua solução também Daniel. To esperando pra ver.

 

Carlos Eduardo

Com certeza, Matias.

 

Como havíamos comentado anteriormente, a minha solução é simples e objetiva, focada apenas no problema.

 

Essa implementação abstrada sobre a qual estamos discutindo ainda será feita e postada, porém mais à frente.

 

Só estou esperando para ver a resolução dos problemas nos códigos do Bruno.

 

O seu já está 100%, certo?

Compartilhar este post


Link para o post
Compartilhar em outros sites
  Em 19/01/2011 at 10:50, Daniel R. Gomes disse:

O seu já está 100%, certo?

O meu está 100% funcionando e 0% elegante ... :P Mas não vou mexer mais nele.

 

Carlos Eduardo

Compartilhar este post


Link para o post
Compartilhar em outros sites

O meu apesar de não lidar com essa questão de voltar atrás e tentar de novo, também é final, não vou mexer mais nele, afinal ele segue o conceito que eu tenho de um Caixa Eletrônico, não tenta fazer coisas mirabolantes sem ao menos poder.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.