Skip to content

Instantly share code, notes, and snippets.

@dnovais
Last active January 20, 2022 21:33
Show Gist options
  • Save dnovais/f636c67cc935783e1f7bdf9317f7a7af to your computer and use it in GitHub Desktop.
Save dnovais/f636c67cc935783e1f7bdf9317f7a7af to your computer and use it in GitHub Desktop.
Entendendo o código para o problema do diamante e areia.

O problema

Dado um conjunto de caracteres, você precisará extrair os "diamantes" ( <>) e as "areias" ( . ) da expressão e no final exibir a quantidade de diamantes extraídos

Expressão: <<.<<..>><>><.>.>.<<.>.<.>>>><>><>>

  • Extrair os diamantes e areias da expressão até que não haja mais o que ser extraído;
  • Exibir a quantidade de diamantes extraídos;;

A solução proposta pelo RDSM (@das_rm)

Aqui meu objetivo é explicar o código criado pelo RDSM:

# Contador para os diamantes encontrados.
diamond_counter=0

####### Criando os caracteres <, > e . para formar a expressão (string) passada no problema: `<<.<<..>><>><.>.>.<<.>.<.>>>><>><>>`
# %w(< > .) ---> Ele cria um array com os elementos <, > e .
# %w(< > .).map{|char| char*15} ----> Aqui ele cria um no array com a quantidade de elementos
# %w(< > .).map{|char| char*15}.flatten -----> Aqui ele cria novamente um novo array unidimensional
# %w(< > .).map{|char| char*15}.flatten.join ----> Transforma o array unidimensional em uma string
# %w(< > .).map{|char| char*15}.flatten.join.split('') ----> Agora ele quebra a string em um array
# %w(< > .).map{|char| char*15}.flatten.join.split('').shuffle ----> Aqui ele embaralha o array
# %w(< > .).map{|char| char*15}.flatten.join.split('').shuffle.join --> por ultimo ele transforma novamente em string

expression = %w(< > .).map{|char| char*15}.flatten.join.split('').shuffle.join

# expression.tr('.','') ----> Aqui ele cria uma nova string, trocando o . por string vazia, ou seja, removendo o .
# expression.tr('.','').tap{|random| ----> O tap aqui retorn a propria string sem o . anterior como objeto para o bloco, ou seja, o objeto fica disponível ali para ser usado dentro do bloco
# while(random.sub!(/<>/,'')) do; puts random; diamond_counter += 1; end ----> Dentro do bloco é iniciado a iteração no objeto usando um while, e caso seja encontrado o diamante '<>' ele mostra o próprio objeto com o diamante extraído e o contador para mostrar que foi encontrado é incrementado

expression.tr('.', '').tap { |expression_without_sand| while expression_without_sand.sub!(/<>/, ''); puts expression_without_sand; diamond_counter += 1; end }

puts "Was found #{diamond_counter} diamonds"

=> 9
@haroldofurtado
Copy link

haroldofurtado commented Jan 20, 2022

Uma pequena correção, não é ideal usar o random dentro do tap por conta de ter uma declaração externa com o mesmo nome, nesse caso alterei para uma variável qualquer (usei x no exemplo), também acredito que o do do while nesse caso seja desnecessário, a não ser que queira fazer sempre a primeira vez.

Segue o código:

random.tr('.', '').tap { |x| while x.sub!(/<>/, ''); puts x; counter += 1; end }

@dnovais
Copy link
Author

dnovais commented Jan 20, 2022

Sim @haroldofurtado, você tem razão. Irei adicionar essa correção ali e algumas melhorias na nomenclatura das variáveis para ficar mais didático. Obrigado.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment