Autor Tema: Múltiplos de 7 con recursión en Python

0 Usuarios y 1 Visitante están viendo este tema.

21 Junio, 2020, 05:05 pm
Leído 4058 veces

gorkam

  • $$\Large \color{#5372a0}\pi\,\pi$$
  • Mensajes: 50
  • País: es
  • Karma: +0/-0
  • Sexo: Masculino
Buenas tardes, tengo el siguiente enunciado:
Un número natural n de varios dígitos es múltiplo de
7 si y solo si al restar al número sin el dígito de las unidades el doble de dicho dígito se obtiene un múltiplo
de 7. Por ejemplo, n = 1946 es múltiplo de 7 porque 194−12 es igual a 182, que a su vez es múltiplo de
7 porque 18−4= 14. Sin embargo, n= 5219 no es múltiplo de 7 porque 521−18 es igual a 503, que no es
múltiplo de 7 porque 50−6= 44.
El código iterativo me funciona bien pero no se como sacar el código recursivo. He pensado algo asi, pero no me funciona:
Código: [Seleccionar]
def div7rec(n):
    if n==0:
        return True
    else:
        return div7rec((n//10) - ((n%10*2))

Si alguien pudiera echarme una mano, lo agradecería. Si tenéis algún truco o algo para dominar y entender mejor recursividad también lo agradecería. Muchas gracias.

21 Junio, 2020, 10:00 pm
Respuesta #1

feriva

  • $$\Large \color{#a53f54}\pi\,\pi\,\pi\,\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 11,319
  • País: es
  • Karma: +1/-0
  • Sexo: Masculino
No sé, yo creo que lo que necesitas es algo así metido en bucle

Código: [Seleccionar]
s=str (n) # S es n convertido a cadena

Ucifra = int (s[-1:] ) # cifra del final convertida a entero.

dobleU = 2 * (Ucifra)  # El doble de la cifra del final.

Dcifras = int (s[:-1]) # Primeras cifras convertidas a entero.

R = Dcifras - dobleU  # Diferencia


Y a partir de ahí que R haga de nuevo número y se repita. Si es múltiplo de siete, llegará a 0 ó a 7 ó -7 y -14 (funcionará con números que tengan al menos dos cifras).

Saludos.


21 Junio, 2020, 10:15 pm
Respuesta #2

gorkam

  • $$\Large \color{#5372a0}\pi\,\pi$$
  • Mensajes: 50
  • País: es
  • Karma: +0/-0
  • Sexo: Masculino
Es que no me dejan meter bucles, nos han dicho que en recursividad usemos condicionales....

21 Junio, 2020, 10:56 pm
Respuesta #3

Gustavo

  • Moderador Global
  • Mensajes: 1,870
  • País: co
  • Karma: +0/-0
Hola. La estructura de la recursión está bien, lo que hay que arreglar son los casos base. Nota que tu programa no tiene ningún retorno para números que no son múltiplos de 7 (en ningún lado hay un False), ni tiene buen retorno para algunos múltiplos de 7, como por ejemplo el 49 que retorna 4-9*2=-14. Mi sugerencia es que apliques el algoritmo (a mano) a múltiplos de 7 de dos cifras y notes que todos llegan a 0,-7 o -14. El resto de números llegan a un negativo distinto a los tres ya mencionados.

PD. Por favor no uses sólo mayúsculas en los títulos. Lo he cambiado.

21 Junio, 2020, 11:08 pm
Respuesta #4

feriva

  • $$\Large \color{#a53f54}\pi\,\pi\,\pi\,\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 11,319
  • País: es
  • Karma: +1/-0
  • Sexo: Masculino
Es que no me dejan meter bucles, nos han dicho que en recursividad usemos condicionales....

Bueno, quien dice un bucle dice una llamada dentro de la función; pero tendrás que usar el if algunos or para los distintos casos.

Saludos.

22 Junio, 2020, 10:56 am
Respuesta #5

feriva

  • $$\Large \color{#a53f54}\pi\,\pi\,\pi\,\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 11,319
  • País: es
  • Karma: +1/-0
  • Sexo: Masculino
Prueba éste, gorkam, a ver qué tal te va.

Código: [Seleccionar]
try:
def f(n):
if n == 0 or n == 7 or n == -7 or n == -14:
print ("n SI es multiplo de 7")
else:
s=str (n)
Ucifra = int (s[-1:] )
dobleU = 2 * (Ucifra) 
Dcifras = int (s[:-1])
n = Dcifras - dobleU
return f(n)
n = int (input ("introduce un entero positivo n de entrada: "))
f(n)
except:
print ("n NO es multiplo de 7 y/o no es positivo")

Editado

Saludos.

22 Junio, 2020, 06:06 pm
Respuesta #6

ingmarov

  • Moderador Global
  • Mensajes: 5,423
  • País: hn
  • Karma: +0/-0
  • Sexo: Masculino
Hola có digo corregido

Interesante solución feriva, aprovechando el error en la función int() para detener el ciclo.

Pongo otra forma, hice un poco de trampa porque estoy utilizando al final la función módulo. La utilizo cuando se ve fácil que es múltiplo de siete.

Código: [Seleccionar]
def prueba(n):
   a=n%10
    r=int((n-a)/10)
    resta=r-2*a
    if resta%100!=resta:
        print(resta)
        prueba(resta)
    else:
        print(resta)
        if resta%7==0:
            print("El número es múltiplo de siete porque {} lo es.".format(resta))
            return
        else:
            print("El número no es múltiplo de siete porque {} no lo es.".format(resta))
            return

prueba(int(input("ingresé un número entero mayor que 100: ")))
       


Saludos

No te confíes, revisa lo que escribo. Yo también me equivoco.
Odio el autocorrector de Android...

22 Junio, 2020, 09:15 pm
Respuesta #7

feriva

  • $$\Large \color{#a53f54}\pi\,\pi\,\pi\,\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 11,319
  • País: es
  • Karma: +1/-0
  • Sexo: Masculino
Hola, Ingmarov.

Hola código corregido
Pongo otra forma

Me da problemas con algunos números; si abajo invoco la función con, por ejemplo, prueba(38) produce un error en bucle; y con otros números, con 24, 35... con varios que he probado (no sé si soy yo o mi ordenador).

Saludos.

22 Junio, 2020, 09:40 pm
Respuesta #8

ingmarov

  • Moderador Global
  • Mensajes: 5,423
  • País: hn
  • Karma: +0/-0
  • Sexo: Masculino
Hola, Ingmarov.

Hola código corregido
Pongo otra forma

Me da problemas con algunos números; si abajo invoco la función con, por ejemplo, prueba(38) produce un error en bucle; y con otros números, con 24, 35... con varios que he probado (no sé si soy yo o mi ordenador).

Saludos.
Es verdad, debe dar error, porque para 38 se tiene
resta=-13

Y.  -13%10=7 por lo que para el primer bloque if la condición propuesta es verdadera. Cuando deseamos que sea falsa.

Creo que gorkam ya tiene una solución, espero intenté corregir mi error y así beneficie más a su formación.

Saludos
No te confíes, revisa lo que escribo. Yo también me equivoco.
Odio el autocorrector de Android...

23 Junio, 2020, 12:54 am
Respuesta #9

feriva

  • $$\Large \color{#a53f54}\pi\,\pi\,\pi\,\pi\,\pi\,\pi\,\pi$$
  • Mensajes: 11,319
  • País: es
  • Karma: +1/-0
  • Sexo: Masculino

Es verdad, debe dar error, porque para 38 se tiene
resta=-13

Y.  -13%10=7 por lo que para el primer bloque if la condición propuesta es verdadera. Cuando deseamos que sea falsa.

Gracias, Ingmarov; todavía tengo que pensar del todo cómo funciona la línea del if resta%100!=resta, pero lo dejo para mañana, que ahora estoy un poco dormido (y, si no, ya me lo explicas un poco).

En mi código, sí, el error que manda está relacionado con el int y no sé qué más de la base 10, según informa. Pero éste error se produce por una razón entendible: el valor “n” en el bucle interno de la función va siendo cada vez menor hasta que llega a un primer número que ya tiene una sola cifra (un carácter en la cadena); si ese número no es 0,7 ó -7, el bucle no se para, sigue y al llegar aquí ( s[:-1]) no extrae el carácter de la izquierda, porque no existe, no está definido; de ahí que produzca el fallo al intentar convertirlo en int. El que está definido, en caso de un sólo carácter en la cadena, es el de la derecha s[-1:]. En caso de que el número fuera negativo, la cadena tiene dos caracteres, con lo cual intenta convertir a entero el signo “-” y entonces da error también; concretamente indica el signo menos al final:

ValueError: invalid literal for int() with base 10: '-'

Saludos.