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;;
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
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: