Números Trimórficos

Secção dedicada à linguagem de programação favorita dos quarkianos: Python!

Números Trimórficos

Mensagempor Bruno Oliveira em Terça Dez 01, 2009 7:14 pm

OK, este problema poderá ser um pouco redundante, até porque o prof. já colocou aqui um sobre números automórficos, que foi, inclusivé, o meu primeiro problema, pitónico :P , e, depois de revisitar esse mesmo problema e com umas consultas na wikipedia, descobri os números trimórficos :lol: .

NOTA: Este problema é mesmo muito fácil, e tem como único objectivo, incentivar mais alguns quarkianos a descobrirem o Python e a animar um pouco, em termos de problemas, a secção Pitónica aqui do fórum.

Problema:

Um número n é dito trimórfico, se a representação decimal de n^3, terminar no número n. Exemplos triviais destes números são os números de um só digito, nomeadamente, 1, 4, 5, 6, 9, dado que:
1^3 = 1
4^3 = 64
5^3 = 125
6^3 = 216
9^3 = 729.

O objectivo é calcular a soma de todos os números trimórficos de 5 dígitos. :)

PS: À boa moda dos programadores, e para os newbies que ainda não saibam, aconselho a subdividirem o problema em alíneas, isto é, escrevam um pedaço de código para gerar os números trimórficos, depois um pedaço de código (ou melhoramento do anterior) que vos dá apenas os números trimórficos de 5 dígitos, e por fim, é só somá-los. :wink:
Para quem não sabe, esta técnica de programação é designada de scaffolding, e é muito útil :D
e^{ix}=cos x + i\,sin x
Avatar do utilizador
Bruno Oliveira
top-Quark!
top-Quark!
 
Mensagens: 1553
Registado: Quarta Nov 14, 2007 10:19 pm
Localização: Lisboa

Re: Números Trimórficos

Mensagempor jap em Terça Dez 01, 2009 10:48 pm

Boa! :hands:

Fico à espera dos vossos códigos! :wink:
José António Paixão
Departamento de Física da FCTUC
Avatar do utilizador
jap
Site Admin
Site Admin
 
Mensagens: 6790
Registado: Quinta Nov 09, 2006 9:34 pm
Localização: Univ. de Coimbra

Re: Números Trimórficos

Mensagempor Tharis em Quarta Dez 02, 2009 3:32 pm

Código: Seleccionar Todos
>>> sum( filter( lambda n: str(n**3).endswith(str(n)), range(10**4, 10**5)))
681248
>>> sum( [i for i in range(10**4, 10**5) if str(i**3).endswith(str(i))] )
681248


Serve? :)
Avatar do utilizador
Tharis
up-Quark!
up-Quark!
 
Mensagens: 387
Registado: Quinta Out 23, 2008 4:26 pm

Re: Números Trimórficos

Mensagempor Bruno Oliveira em Quarta Dez 02, 2009 3:39 pm

Eh eh,

Claro que sim! :D

Até porque tu sabes bem mais que eu, em termos de programação, e eu, para ser sincero, acho que serei sempre aquele programmer "old-school" que apenas recorre a if`s, funções, ciclos for, uso de files e claro faz uso das peculiaridades do Python, nomeadamente as ferramentas para tratamento de string`s que para mim são simplesmente AWESOME! :P

E, pelo que disse acima, e por não estar (ainda!) dentro da programação funcional, aqui vai o código que eu tinha feito para este simples problema:

Código: Seleccionar Todos
"""
Trimorphic Numbers:
Program that computes the sum of the trimorphic numbers with 5 digits.

@Bruno Oliveira 2009 Having a great time with Python :)

Always trying to improve and write truly Pythonic code :)

To be used by quarkonia.

"""


def trimorphic(n):
    if str(n**3).endswith(`n`):
        return n
    else:
        return 0


nmax=100000
L=[]
for k in range(1,nmax):
    if trimorphic(k)!=0 and len(str(k))==5:
        L.append(k)
print "Searching for trimorphic numbers with 5 digits..."
print "Found", len(L), "trimorphic numbers with 5 digits. They are:", L, "and their sum is:",sum(L)


Output:
Código: Seleccionar Todos
IDLE 2.6.4      ==== No Subprocess ====
>>>
Searching for trimorphic numbers with 5 digits...
Found 11 trimorphic numbers with 5 digits. They are: [18751, 31249, 40625, 49999, 50001, 59375, 68751, 81249, 90624, 90625, 99999] and their sum is: 681248
>>>


Não estará tão pitónico como o teu, Tharis, mas está bem melhor do que o meu código antigo para os automórficos! :lol:
e^{ix}=cos x + i\,sin x
Avatar do utilizador
Bruno Oliveira
top-Quark!
top-Quark!
 
Mensagens: 1553
Registado: Quarta Nov 14, 2007 10:19 pm
Localização: Lisboa

Re: Números Trimórficos

Mensagempor Tharis em Quarta Dez 02, 2009 4:51 pm

O teu código está normal para um programa estruturado seguindo o paradigma imperativo.

Continuando, aí só tens uma coisinha menos bem que é começares a pesquisa em 1. ;)

Vou explicar o meu código:

Código: Seleccionar Todos
lambda n: str(n**3).endswith(str(n))


Uma função lambda que me diz se o número é trimórfico... Basicamente é equivalente a:

Código: Seleccionar Todos
def is_trimorphic(n):
    if str(n**3).endswith( str(n) ):
        return True
    else:
        return False



Código: Seleccionar Todos
range(10**4, 10**5)

Todos os números de 5 dígitos.


Depois entra o funcional. A função filter recebe um dois argumentos: uma função (esta função deve retornar True ou False) e um objecto iterável (lista, tupla, wtv). A função filter vai aplicar a função passada no 1º argumento a cada elemento do 2º argumento e cria uma nova lista com todos os elementos do 2º argumento para qual a função passada retorne True. (Como o próprio nome indica a função filter filtra o conteúdo).

E depois a função sum que dá a soma de todos os elementos de um iterável.


Na segunda uso listas por compreensão. É a mesma coisa só que escrito de outra maneira.
última vez editado por Tharis s Quarta Dez 02, 2009 4:58 pm, editado 1 vez no total
Avatar do utilizador
Tharis
up-Quark!
up-Quark!
 
Mensagens: 387
Registado: Quinta Out 23, 2008 4:26 pm

Re: Números Trimórficos

Mensagempor Bruno Oliveira em Quarta Dez 02, 2009 4:56 pm

Obrigado pela rápida resposta, Tharis.

Em relação ao facto de eu ter começado o ciclo for em 1, eu fi-lo de proposito, para poder incluir a função len(str(k))==5, embora dê mais trabalho ao computador... Por outro lado, se tivesse inicializado o ciclo em 10000 e terminado em 99999 ou neste caso 100000, não precisava sequer de incluir a função len... Foi piquinhice (omg, isto escreve-se assim?) minha! :P
e^{ix}=cos x + i\,sin x
Avatar do utilizador
Bruno Oliveira
top-Quark!
top-Quark!
 
Mensagens: 1553
Registado: Quarta Nov 14, 2007 10:19 pm
Localização: Lisboa

Re: Números Trimórficos

Mensagempor Bruno Oliveira em Quarta Dez 02, 2009 8:55 pm

Já agora, posso também deixar aqui uma explicação detalhada do meu código para que os newbies não se assustem e, aliás, se divirtam a pegar no Python! :lol: Just like I did back in the day! :wink:

Código: Seleccionar Todos
"""
Trimorphic Numbers:
Program that computes the sum of the trimorphic numbers with 5 digits.

@Bruno Oliveira 2009 Having a great time with Python :)

Always trying to improve and write truly Pythonic code :)

To be used by quarkonia.

"""


Esta primeira parte do código, chama-se uma doc string. É aconselhável escrever uma doc string no ínicio de um programa (pitónico ou qualquer outro), já que esta serve como uma indicação do que irá fazer o programa. Uma espécie de resumo, se assim o quiserem entender. Como já disse o prof. jap, esta doc string é uma ferramenta de metaprogramação, que pode ser invocada a partir do próprio programa, que é algo, ao que consta, bastante útil, embora eu não saiba propriamente as implicações práticas disto... :roll:

Código: Seleccionar Todos
def trimorphic(n):
    if str(n**3).endswith(`n`):
        return n
    else:
        return 0


Este pedaço de código, é talvez o mais pitónico de todos! :lol:

Nele, está-se a definir uma função, (a sintaxe para criarmos uma função definida por nós é: def nome_da_funcao(args): ) onde def é a keyword para indicarmos que vamos definir uma função, nome_da_funcao é o nome da função, que neste caso se chama trimorphic, e (args) são os argumentos que a função recebe (podem ser um, vários ou até nenhum :shock: ).

A segunda linha deste bloco de código e simultaneamente a primeira linha da função propriamente dita, faz uso das potentes ferramentas para tratamento de strings do Python e creio que é bastante auto-explicativa. (Pode-se praticamente ler em português: Se o número n^3 terminar em n...) Esta função retorna o número n que nós estamos à procura se a condição se verificar, caso contrário, retorna o valor 0.

Código: Seleccionar Todos
nmax=100000
L=[]
for k in range(1,nmax):
    if trimorphic(k)!=0 and len(str(k))==5:
        L.append(k)
print "Searching for trimorphic numbers with 5 digits..."
print "Found", len(L), "trimorphic numbers with 5 digits. They are:", L, "and their sum is:",sum(L)


Este código, tem como principal finalidade somar os números automórficos de 5 dígitos, usando para o efeito um ciclo for.
O ciclo for, em Python, tem a sintaxe apresentada na terceira linha deste bloco de código e tem a finalidade de repetir uma dada tarefa nmax-1 vezes. Neste caso, vai avaliar o retorno da função trimorphic, e caso este seja diferente de 0 (!=0) e o número tenha 5 dígitos (len(str(k))==5) vai acrescentá-lo á lista L. (L.append(k)).

Notem que a instrução antes do ciclo for (L=[]) cria uma lista vazia, chamada L, à qual vamos adicionando elementos se as condições que impusemos se verifiquem :) .

Por fim, os print, não têm nada de transcendente, servem apenas para enviar mensagens como output. Basta apenas saberem que: len(L) nos dá o numero de elementos na lista, no final do ciclo for e que sum(L), tal como pretendido, soma todos os elementos da lista. :D

Espero que tenha ficado claro, e assim têm 2 abordagens distintas (imperativa, a minha e funcional, a do Tharis).
última vez editado por Bruno Oliveira s Quarta Dez 02, 2009 9:52 pm, editado 2 vezes no total
e^{ix}=cos x + i\,sin x
Avatar do utilizador
Bruno Oliveira
top-Quark!
top-Quark!
 
Mensagens: 1553
Registado: Quarta Nov 14, 2007 10:19 pm
Localização: Lisboa

Re: Números Trimórficos

Mensagempor Ivo_Timóteo em Quarta Dez 02, 2009 8:58 pm

A eficiência é sempre algo a ter em conta quando estás a programar...

Principalmente quando as coisas começam a "crescer" de tamanho :)
Avatar do utilizador
Ivo_Timóteo
charm-Quark!
charm-Quark!
 
Mensagens: 579
Registado: Quarta Nov 15, 2006 7:25 pm
Localização: V. N. Gaia

Re: Números Trimórficos

Mensagempor jap em Quarta Dez 02, 2009 11:05 pm

A propósito os one-liners (como os programas do Tharis) não são considerados pelo BDFL lá como muito pitónicos, uma vez que uma das máximas do ZEN do Python é "Explicit is better than implicit".

One-liners são mais LISPónicos do que Pitónicos, mas são sempre um desafio interessante... Como escrever um programa numa só linha +- críptica, mas sem "side effects"? :P
José António Paixão
Departamento de Física da FCTUC
Avatar do utilizador
jap
Site Admin
Site Admin
 
Mensagens: 6790
Registado: Quinta Nov 09, 2006 9:34 pm
Localização: Univ. de Coimbra

Re: Números Trimórficos

Mensagempor Bruno Oliveira em Quarta Dez 02, 2009 11:29 pm

Se a pessoa começar a perder a sanidade mental, ou neste caso, o objectivo dos códigos pitónicos(que começo a apreender), bastam 2 simples palavrinhas no IDLE, para recuperar a orientação:

Código: Seleccionar Todos
>>> import this


:P
e^{ix}=cos x + i\,sin x
Avatar do utilizador
Bruno Oliveira
top-Quark!
top-Quark!
 
Mensagens: 1553
Registado: Quarta Nov 14, 2007 10:19 pm
Localização: Lisboa


Voltar para Pitónica

Quem está ligado

Utilizadores a navegar neste fórum: Nenhum utilizador registado e 2 visitantes

cron