Em julho de 2011, fiz uma entrevista em uma empresa na qual foi-me solicitado a resolução de um teste, para ser feito em casa e enviado via e-mail, resolvi em 3 dias, após meu horário de trabalho e usando a análise combinatória na solução, fui aprovado, porém infelizmente cancelaram a contratação.
Na época existia apenas uma solução pronta do teste na internet para exemplo e usando binários na sua resolução.
Achei o teste interessante e com um bom nível de complexidade, pois não basta saber apenas PHP, mas também um pouco de estatística e análise combinatória, por isso estou compartilhando a minha solução.
Enunciado do teste
Escrever um algoritmo, em PHP, que tenha como entrada uma string composta por palavras separadas por pipe (|) e a saída seja uma sequência com todos os wildcards possíveis.
Exemplo 1:
Entrada: “sao-paulo”
Saída: *
Exemplo 2:
Entrada: “sao-paulo|restaurante”
Saída:
sao-paulo|*
*|restaurante
Exemplo 3:
Entrada: “a|b|c”
Saída:
*|b|c
a|*|c
a|b|*
a|*|*
*|b|*
*|*|c
Solução
<?php /** * @author Daniel Satiro da Rocha * Teste - 15/07/2011 */ /** * retorna combinacoes sem repeticao * @param array $elementos * @param int $s * @return Ambigous <multitype:, string> */ function combinacoes($elementos = array(), $s) { $combinArr = array (); $combin = ( int ) sprintf ( "1%0{$s}d", 0 ) - 1; for($cur = 0; $cur <= $combin; $cur ++) { $number = sprintf ( "%0{$s}d", $cur ); $equal_digits = array (); for($digit = 0; $digit < $s; $digit ++) { if (in_array ( $number {$digit}, $elementos ) && ! in_array ( $number {$digit}, $equal_digits )) { $equal_digits [] = $number {$digit}; } } if (count ( $equal_digits ) == $s) { $numArr = array(); for ($i = 0; $i < strlen($number); $i++) { $numArr[] = $number[$i]; } sort($numArr); $combinArr [] = implode($numArr); } } $combinArr = array_unique($combinArr); $elemComb = array(); foreach ($combinArr as $value) { $numArr = array(); for ($i = 0; $i < strlen($value); $i++) { $numArr[] = $value[$i]; } $elemComb[] = $numArr; } return $elemComb; } /** * calcula fatorial * @param int $valor * @return number|Ambigous <unknown, number> */ function fatorial($valor) { if ($valor == 0) { return 1; } $result = $valor; for ($index = $valor-1; $index > 1; $index--) { $result *= $index; } return $result; } /** * Calcula quantidade de combinacoes possiveis sem repeticao * Onde $n é o total de elementos e $s o número de elementos escolhidos. * @param int $n * @param int $s * @return number */ function combinatoria($n, $s){ $c = fatorial($n)/(fatorial($s)*fatorial($n-$s)); return $c; } /** * Calcula arranjo simples * Onde $n é o total de elementos e $s o número de elementos escolhidos. * @param int $n * @param int $s * @return number */ function arranjos($n, $s) { $a = fatorial($n)/fatorial($n-$s); return $a; } /** * Executa calculos conforme entrada e retorna as combinacoes * @param string $entrada * @return string|string */ function processaSaida($entrada) { $entArray = explode ( '|', $entrada ); $n = count ( $entArray ); if ($n == 1) { return '*'; } else { $linhas = array (); $html = ""; for($s = 1; $s < $n; $s ++) { $combin = combinatoria ( $n, $s ); $combArr = combinacoes ( range ( 0, $n - 1 ), $s ); for($c = 0; $c < $combin; $c ++) { $aux = array (); $d = 0; for($index = 0; $index < $n; $index ++) { if ($combArr [$c] [$d] == $index) { $aux [$index] = "*"; $d ++; } else { $aux [$index] = $entArray [$index]; } } $linhas [] = $aux; } } $html = ""; foreach ( $linhas as $key => $value ) { $html .= implode ( '|', $value ) . "<br />"; } return $html; } } $saida = "Nenhuma saida processada!"; if($_POST){ $entrada = trim($_POST['entrada']); $saida = processaSaida($entrada); } ?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <title>Teste Wildcard challenge</title> </head> <body> <center> <form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post"> <table border="0"> <tr valign="top"> <td>Entrada:</td> <td><input type="text" name="entrada" value="<?php echo $_POST['entrada'];?>" /></td> <td><input type="submit" value="Enviar" /></td> </tr> <tr> <td>Saída:</td> <td colspan="2"><?php echo $saida;?></td> </tr> </table> </form> </center> </body> </html>
É isso aí, não sei se a empresa ainda usa esse teste para avaliar seus candidatos, mas se ainda utilizar acho que ficará mais difícil para os próximos candidatos encontrar outra solução.