Olá companheiros!
Saída: tone(123, 1000);
tone(432,100);
tone(222,1000);
O algoritmo acima funciona perfeitamente, porém sua função de complexidade é
: f(n)=2n
: f(n) = n
Agora já fizemos a implementação do projeto estamos disponibilizando o repositório dos códigos fonte tanto para o Arduino quanto para o bot do Telegram através do Bitbucket.
Até para comentar um pouco mais sobre a implementação considero válido passar uma experiência que tivemos com C. Durante o projeto tivemos a necessidade de tokenizar os dados que estão chegando no Arduino para que ele pudesse fazer o sequenciamento das notas que serão reproduzidas, o fato é que o Arduino não possui em sua biblioteca de manipulação de String uma função para isso e tivemos que implementar. Apenas para ficar mais claro o que acontece é o seguinte o dado chega pelo Raspberry como um texto que contém uma sequência de números seguido de uma vírgula, outra sequência de números e um espaço em branco, a primeira sequência de número é a frequência da noa que deve ser tocada e a segunda sequência é a duração em millisegundos, o desafio aqui era receber essa sequência de caracteres e dividir a mesma para que seja tocada uma nota por vez:
Entrada: "123,1000 432,100 222,1000"Saída: tone(123, 1000);
tone(432,100);
tone(222,1000);
Inicialmente fizemos a implementação usando malloc e realloc pois tinha como idéia criar uma variável char* e conforme percorrêssemos a sequência principal iríamos acumulando a mesma na variável até que uma vírgula ou espaço fosse encontrado dessa forma o pseudo-código havia ficado assim:
char* nota;
char* duracao;
nota = (char*)malloc(nota, sizeof(char));
strcpy(nota,"");
duracao = (char*)malloc(duracao, sizeof(char));
strcpy(duracao, "");
char[] principal = "123,1000 432,100 222,1000";
para i de 1 ate N repita
char cnota = principal[i];
...
int lnota = strlen(nota);
nota = realloc(nota, lnota+1);
strcat(nota,cnota);
...
fim para
Bom o que aconteceu é que o código funcionava muito bem para pequenas cadeias, porém para cadeias grandes de caracteres começávamos a pegar sujeira da memória e com isso não tínhamos como transformar a informação em int para poder passar para a função tone. Perdemos muitas horas tentando fazer esse código funcionar até que chegamos num ponto de desistir e começar do zero com outra abordagem que foi o código abaixo que está disponível no bitbucket:
void tocar(const char *notas){
int l = strlen(notas);
int i = 0;
int j;
int indexComma = 0;
int start = 0;
for (i = 0; i < l; i++){
char c = notas[i];
if (c == ' ' || c == '\n' || c == '\0'){
int lnota = indexComma - start;
char nota[lnota];
int k = 0;
for(j = start; j < indexComma; j++){
nota[k++] = notas[j];
}
nota[k] = '\0';
int lduracao = i - indexComma;
char duracao[lduracao];
k = 0;
for(j = indexComma+1; j < i; j++){
duracao[k++] = notas[j];
}
duracao[k] = '\0';
int inota = atoi(nota);
int iduracao = atoi(duracao);
tone(10,inota, iduracao);
int pausaEntreNotas = iduracao;// * 1.30;
delay(pausaEntreNotas);
noTone(10);
start = i+1;
}else if (c == ','){
indexComma = i;
}
}
}
O algoritmo acima funciona perfeitamente, porém sua função de complexidade é
: f(n)=2n
pois ele percorre a cadeia de caracteres uma vez procurando pelos marcadores ("," e " ") e quando acha ele percorre de um ponto inicial a um final copiando os dados para as variáveis a que se destinam. Enquanto que o primeiro algoritmos ("caso tivesse dado certo") teria feito a mesma coisa com função de complexidade
: f(n) = n
Pois ele já viria acumulando a cada passada por n nas variáveis a que se destinam.
O que aprendemos disso tudo foi existem mil maneiras de resolver um problema e quando uma não vai de jeito nenhum procure ver as alternativas a partir do zero.