RPCFN #2: Average Arrival Time For A Flight

In: ruby

27 out 2009

O Ruby Learning começou uma série de desafios para Rubistas iniciantes, na qual um profissional Ruby elabora um problema e os interessados em participar enviam as soluções desenvolvidas em Ruby para serem avaliadas. O autor do desafio escolhe a melhor implementação e sorteia uma entre as outras soluções funcionais. Os premios são screencasts da PeepCode e BDDCasts.

Por que não participar?

O problema proposto pelo Chris Strom foi o seguinte:

Você deve um grande favor e concordou em pegar um amigo no aeroporto toda Sexta-feira a noite. A linha área que seu amigo voa é barata, mas terrível quando se trata em reportar atrasos e horários de saída e chegada. Você rapidamente descobriu que o voos agendados para as 10pm nunca chegam no horário e usualmente atrasam mais de uma hora. Se o avião chegar as 11:15pm, 12:03am, 11:30pm, 11:23pm e 11:48pm, qual é o horário médio da chegada?

A solução funciona se seu amigo mudar o horário de chegada para 6 horas depois? E se for 12 horas depois?

A saída esperada do programa é a seguinte:

>> average_time_of_day(["6:41am", "6:51am", "7:01am"])
=> "06:51am"
 
>> average_time_of_day(["11:51pm", "11:56pm", "12:01am", "12:06am", "12:11am"])
=> "12:01am"

E qual foi a minha solução?

Eu identifiquei os seguintes passos a serem seguidos:

  • Transformar as posições do array de String para Time, para poder calcular qual é o médio.
  • O problema deixa claro que todos os tempos são no futuro, então é preciso corrigir o parser de tempo das horas que são do dia seguinte. No exemplo: Se no momento da consulta são 28/10/2009 19:00, o parser do Ruby irá converter 12:01am, 12:06am e 12:11am para 00:01, 00:06 e 00:11 do dia 28/10/2009, quando o correto seria do dia 29/10/2009).
  • Ordenar o array por tempo ascendente.
  • Pegar a posição do meio do array.

O código para essa implementação foi o seguinte:

require 'time'
def average_time_of_day(times)
    clean = Array.new
    times.each do |t|
        parsed = Time.parse(t)
        parsed += (60*60*24) if parsed < Time.now
        clean.push(parsed)
    end
    clean[ (clean.count / 2.0).ceil - 1 ].strftime("%I:%M%p")
end

Executando os testes propostos, tenho o resultado esperado. Woooo!

>> average_time_of_day(["6:41am", "6:51am", "7:01am"])
=> "06:51AM"
 
>> average_time_of_day(["11:51pm", "11:56pm", "12:01am", "12:06am", "12:11am"])
=> "12:01AM"

As soluções vencedoras foram:

UPDATE: o Chris Storm publicou um feedback sobre as soluções do teste. Leitura obrigatória.

Comment Form

Sobre

Ricardo Duarte, 26 anos, trabalha na Nuntec, atua como desenvolvedor web a mais de 12 anos, já tendo passado por diversas tecnologias. Este blog irá comentar um pouco destas experiências.

rduarte's tweets

  • Venicios Ribeiro: É uma excelente forma de ativar o cache. Existem tbm outras tecnicas muito simples, como o Gzip. à [...]
  • Andre Ferraro: Muito bom!! Estou fazendo o meu e vou postar no meu blog. Vlw!! [...]
  • paulo henrique: Bom dia! existe algum app para usar o twitter no e71, que seja free [...]
  • Ricardo: Bruno, Aplicativo para IM com vídeo eu não conheço, mas para áudio você pode usar o Nimbuzz [...]
  • Bruno: Olá boa tarde. Gostaria de saber qual software IM pro E71 suporta conversação com áudio e video. [...]