• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

chuckytuh

[Desafio] Contador

20 mensagens neste tópico

Titulo do Desafio

Contador

Objectivo

Pois bem, como já toda a gente deve ter visto um conta kms num carro

sabe que a contagem da quilometragem é feita de uma maneira engraçada, isto é , vejamos o seguinte exemplo:

[ 0 , 0 , 0] ->0

[ 0 , 0 , 1] ->1

[ 0 , 0 , 2] ->2

[ 0 , 0 , 3] ->3

[ 0 , 0 , 4] ->4

[ 0 , 0 , 5] ->5

[ 0 , 0 , 6] ->6

[ 0 , 0 , 7] ->7

[ 0 , 0 , 8] ->8

[ 0 , 0 , 9] ->9

[ 0 , 1 , 0] ->10

e por ai alem..

Penso que me fiz entender :)

Ora o que aqui proponho é a criação de um algoritmo que permita fazer um contador deste género.

Exemplo de Input/Output:

Input poderá ser o limite da contagem para cada casa, isto é, por exemplo limite 1 e o seu output uma tabela por exemplo deste género:

[ 0 , 0 , 0]

[ 0 , 0 , 1]

[ 0 , 1 , 0]

[ 0 , 1 , 1]

[ 1 , 0 , 0]

[ 1 , 0 , 1]

[ 1 , 1 , 0]

[ 1 , 1 , 1]

Material de Apoio

Julgo não ser necessário visto que é um problema realmente muito simples porém so aqui o apresento de

forma a poder ver várias soluções para o mesmo problema, eu já tenho uma soluçao

para ele mas não neste PC, assim que tiver acesso ao meu desktop irei apresentar-la aqui!

Restrições

Nenhuma a relatar ;)

Quanto ao output, sejam criativos se assim o quiserem, se forem programadores de AS

não vos proíbo de ate criarem um ambiente gráfico em flash para recriar um contador

como os reais ^^. Podem também resolve-lo com pseudo-código que td a gente se entende ainda melhor :P

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

:)

Vê esta imagem e repara no conta quilometros...a contagem é feita de 0 a 9 na "casa" mais a direita, assim que chega a 9 incrementa a segunda casa a contar da direita, ficando com 10, e por ai adiante...fiz me entender agora? ;)

ContaQuilometros01.jpg

PS: o conta quilometros é o que esta no centro e nao o que tem a setinha a apontar para os numeros, isso é o velocimetro -.-'

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

a casa mais à direita muda de 1 em 1 quilometro

a seguinte de 2 em 2

a outra de 4 em 4

...por aí em diante

o algoritmo é bastante simples não?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

a casa mais à direita muda de 1 em 1 quilometro

a seguinte de 2 em 2

a outra de 4 em 4

...por aí em diante

o algoritmo é bastante simples não?

ora, nao tinha pensado por ai mas foi precisamente por isto que criei este tópico, para ver várias soluçoes a um mesmo problema ;)

Recorri ao conta quilometros por ser mais facil para vos mostrar o tipo de contador que é mas nao quer dizer precisamente que seja para contar quilometros :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

a casa mais à direita muda de 1 em 1 quilometro

a seguinte de 2 em 2

a outra de 4 em 4

...por aí em diante

Não estou a perceber. Então a segunda casa a contar da direita não deveria mudar para 1 ao fim de 10 kilometros?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Queres um "contador" em numeração de base-b, em que b pode tomar qualquer valor. Isso é trivial de se implementar.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

pode não ser bem assim... não sei qual era o modelo, mas havia um carro que o contador dava a volta aos 300 000 km's, ou seja, era base 10, excepto para o último dígito

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

em haskell legivel para o caso em que a base é igual para todas as posiçoes:

contador lista base = foldr f [] lista where
   f v [] = [(v+1) `mod` base]
   f v (0:t) = ((v+1) `mod` base) : 0 : t
   f v lst = v:lst

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ah, não tinha lido o enunciado todo :$ Sim, realmente é um problema de bases numéricas.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

em haskell legivel para o caso em que a base é igual para todas as posiçoes:

contador lista base = foldr f [] lista where
   f v [] = [(v+1) `mod` base]
   f v (0:t) = ((v+1) `mod` base) : 0 : t
   f v lst = v:lst

Pois é engraçado o quao pequeno o codigo fica em haskell, agora começo a entender as potencialidades de haskell!

Queres um "contador" em numeração de base-b, em que b pode tomar qualquer valor. Isso é trivial de se implementar.

Sim é trivial, nao disse o contrario, na verdade é muito simples mas estupidamente ou nao eu ainda demorei cerca de 2 horas para o implementar na altura em que pensei nisto, ok que eram 5 da manha, mas fiquei com o bichinho atras da orelha e foi mais a titulo de diversao e de ver quao variadas sao as soluçoes nas mais variadas linguagens de programaçao!

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Quão pequeno? Espera só até o Betovsky dar a solução dele. (Só não fica é legível  :))

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Isto?

>>> def contador(x, base):
    if x >= base:
        return contador(x/base, base)+[x%base]
    else:
        return [x]

>>> contador(16,16)
[1, 0]
>>> contador(15, 16)
[15]

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Penso que é isso sim.

contador[x_,base_]:=IntegerDigits[x,base]

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Versão mais curta

def contador(x, base):
    return {True: lambda: contador(x/base, base)+[x%base], False: lambda: [x]}[x>=base]()

Ou com lambda's (prefiro o def ao lambda neste caso por causa de forçar o nome da função...):

contador = lambda x, base: {True: lambda: contador(x/base, base)+[x%base], False: lambda: [x]}[x>=base]()

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Isto?

>>> def contador(x, base):
   if x >= base:
       return contador(x/base, base)+[x%base]
   else:
       return [x]

>>> contador(16,16)
[1, 0]
>>> contador(15, 16)
[15]

Colocando numa linha:

f = lambda x, b: f(x/b, b) + [x%b] if x >= b else [x]

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eia, já relembrei qualquer coisa hoje, não me lembrava que dava para pôr condições no lambda :P

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ai mãe :o eu olho para estes códigos até fico parvo :) eu no início pensei que isto fosse para fazer algo com If's ou assim, já ia usar VB.NET, mas sendo assim ...  :dontgetit:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ai mãe :o eu olho para estes códigos até fico parvo :P eu no início pensei que isto fosse para fazer algo com If's ou assim, já ia usar VB.NET, mas sendo assim ... :dontgetit:

Não é nada de mais:

f = lambda x, b: f(x/b, b) + [x%b] if x >= b else [x]

f =

>>> (definir a variável f (que há-de ser uma função))

lambda x, b 

>>> (função lambda que recebe dois argumentos, x, que é o número do contador e b que é a base (passar para a célula seguinte quando a célula actual atinge b) )

f(x/b,b) 

>>> (se dividirmos (divisão inteira) o x por b, então teremos o que valor que falta meter no contador para as próximas células)

+ [x%b] 

>>> o + [ ] não é para somar, mas sim para juntar listas ( [] é de uma lista ). O x%b é o dígito que deve ficar na célula actual do contador (resto da divisão inteira de x por b, conhecido como mod).

if x >= b 

>>> o código da explicação anterior só é executado de x for maior que b, já que se for menor, não são necessárias mais células

else [x] 

>>> se o x for efectivamente menor que b, é só retornar uma lista com um elemento, que é o valor de x.

Tiremos por exemplo o número 123 e base 10.

f(123,10) vai retornar f(123 / 10, 10) + [3] ### 123 / 10 = 12 (divisão inteira)

f(12, 10) vai retornar f(12/10, 10) + [2] ### 12/10 = 1

f(1,10) vai retornar [1] ### 1 < 10

Ou seja: [1] + [2] + [3] = [1,2,3] :D

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Bem aki vai um em pascal.

program kilometros;
uses crt;
var contador, maximo, limite : integer;
texto : string;
begin
clrscr;
writeln('Introduza o máximo de Kilómetros');
readln(limite);
for contador := 0 to limite do
begin
Str(contador,texto);(*armazena contador num string*)
maximo := Length(texto);(*conta o nº de caracteres*)
if maximo < 4 then
begin
if maximo < 3 then
begin
if maximo < 2 then
begin
if maximo < 1 then
begin
Insert('0',texto,1);(*insere o caracter zero na variável texto a partir da posição 1*)
end;
Insert('0',texto,1);
end;
Insert('0',texto,1);
end;
Insert('0',texto,1);
end;
writeln(texto);
end;
readln;
end.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora