Tuesday, August 23, 2011

Solução em Java 7 para a prova do Google Developer Day 2011

Semana passada me diverti um pouco com a prova para o Google Developer Day 2011. A prova não é obrigatória, na verdade faz parte do processo de inscrição e dever ser utilizada como filtro para identificar as pessoas que se adequema o público alvo do evento: Developers.

A prova era composta por 5 questões, todas em torno de 2 textos do idioma Googlon.


Regras do idioma

Letras e ordem do idioma: t w d c r z p s v h m k l n f x q j b g

Esse idioma estipula grupos de letras:
  - letras tipo foo: g, f, z, t e s
  - letras tipo bar: todas as outras.

As preposições são identificadas com a seguinte regra: palavras com 3 letras que terminam com uma letra do tipo bar, mas que não pode ser m.

A regra para identificar verbos: palavras de 7 ou mais letras que terminam com uma letra do tipo bar. Caso a palavra seja um verbo e começe com uma letra do tipo bar, deve ser considerado um verbo de primeira pessoa.

E os números? As palavras são números. Esses números são formados em base 20, onde cada letra é uma digito ordenado do menos para o mais significativo (contrário do binário). Dessa forma a primeira posição é 1, a segunda é 20, a terceira é 400 e assim por diante. Outro detalhe importante: cada letra tem um valor (posição) conforme a ordem do alfabeto, por exemplo t é 0, w é 1, d é 2, etc. Ainda para os números, existem uma classificação de números bonitos. Em Googlon um número bonito deve ser maior ou igual a 502344 e divisível por 4.


Questões

Todas as questões contavam com uma dica do Google, elas eram respondidas levando em consideração a o texto A, mas o participante deveria responder considerando o texto B.
  1. Qual a quantidade preposições no texto B?
  2. Quantos verbos existem no texto B?
  3. Quantos verbos em 1a pessoa existem no texto B?
  4. Imprimir o texto B colocando as palavras na ordem alfabética do Googlon.
  5. Quantos números bonitos existem no texto B?

A solução

Na semana passada estava focado em terminar demos e a apresentação que fiz no TDC2011 em Floripa, sobre Java 7. Aproveitei o embalo pra implementar a solução da prova do GDD usando Java, mas com um detalhe especial: primeiro programa utilizando Java 7. Coloquei as letras na ordem do Googlon em um List e fiz um split do texto (uma String). Dessa forma iteirei sob as palavras para encontrar as preposições, verbos (1a pessoa tb) e números, além de aplicar a ordenação Googlon.

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;

import static java.lang.System.out;

public class Googlon {

static List<Character> alf_ordem = 
    Arrays.asList( new Character[] {'t','w','d','c','r','z','p','s','v','h',
      'm','k','l', 'n','f','x','q','j','b','g'} );

  public static void main(String[] args) {
    String textoB = "prm pmqcf flqk mblz fzrr ..."; //um pedaco do texto B

    int preposicoes = 0, verbos = 0, verbos1Pessoa = 0, numerosBonitos = 0;
    //determina as letras do tipo foo
    List<Character> foo = 
      Arrays.asList( new Character[]{'g','f','z','t','s'} );

    //treeset com comparator resolvendo a ordem as palavras (questao 3)
    TreeSet<String> listaEmOrdem = new TreeSet<>(new Comparator<String>(){
      @Override
      public int compare(String s1, String s2) {
        int len1 = s1.length(), len2 = s2.length();
        int lim = Math.min(len1, len2);
        char chars1[] = s1.toCharArray(), chars2[] = s2.toCharArray();

        int i = 0;
        while (i < lim) {
          char c1 = chars1[i];
          char c2 = chars2[i];
          if (c1 != c2) {
            return alf_ordem.indexOf(c1) - alf_ordem.indexOf(c2);
          }
          i++;
        }
        return len1 - len2;
      }
    });

    //aqui percorro todas palavras, para ordernar e validar
    for (String s: textoB.split(" ")) {
      listaEmOrdem.add(s);

      if (isNumeroBonito(converteParaNumero(s))) {
        numerosBonitos++;
      }

      if (s.length() == 3) {
        if (!foo.contains(s.charAt(s.length()-1)) && s.indexOf('m') == -1) {
          preposicoes++;
        }
        continue;
      }

      if (s.length() >= 7) {
        if (!foo.contains(s.charAt(s.length()-1))) {
          verbos++;
          if (!foo.contains(s.charAt(0))) {
            verbos1Pessoa++;
          }
        }
      }
    }

    StringBuilder textoOrdenadoTeste = new StringBuilder();
    for (String s: listaEmOrdem) {
      textoOrdenadoTeste.append(s).append(" ");
    }

    out.println("1a resposta, qtde de preposicoes: "+preposicoes);
    out.println("2a resposta, qtde de verbos: "+verbos);
    out.println("3a resposta, qtde de verbos 1a pessoa: "+verbos1Pessoa);
    out.println("4a resposta, o texto ordenado: "+ textoOrdenadoTeste);
    out.println("5a resposta, qtde de numeros bonitos? "+numerosBonitos);
  }


  private static long converteParaNumero(String palavra) {
    int n = 0;
    long total = 0;
    for (char c: palavra.toCharArray()) {
      int codigo = alf_ordem.indexOf(c);
      total += codigo * (long) Math.pow(20,n++);
    }
    return total;
  }

  private static boolean isNumeroBonito(long numero) {
    //literal int com separador _ e a literal 4 em binario
    return numero >= 502_344 && numero % 0b100 == 0;
  }

}
Para rodar essa classe em versões anteriores do Java é muito simples, na ordem:
  • defina a tipagem de String na instância do objeto TreeSet no lugar do operador diamond.
  • dentro do método isNumeroBonito, na linha 92, remova o "_" entre o número 502304 e utiliza 4 em decimal ao invés de binário (0b100).

@edermag
www.yaw.com.br

No comments: