Torção Iterada do Divisor

13

Definições

Let mE nSer inteiros positivos. Dizemos que mé uma torção divisora de nse existem números inteiros, 1 < a ≤ btais que n = a*be m = (a - 1)*(b + 1) + 1. Se mpode ser obtido naplicando zero ou mais torções divisórias a ele, então mé um descendente de n. Observe que todo número é seu próprio descendente.

Por exemplo, considere n = 16. Nós podemos escolher a = 2e b = 8, desde então 2*8 = 16. Então

(a - 1)*(b + 1) + 1 = 1*9 + 1 = 10

o que mostra que 10é uma torção divisória de 16. Com a = 2e b = 5, vemos então que 7é uma torção divisória de 10. Assim 7é um descendente de 16.

A tarefa

Dado um número inteiro positivo n, calcule os descendentes de n, listados em ordem crescente, sem duplicatas.

Regras

Você não tem permissão para usar operações internas que computam os divisores de um número.

Programas e funções completos são aceitos e o retorno de um tipo de dados de coleção (como um conjunto de algum tipo) é permitido, desde que seja classificado e sem duplicação. A contagem de bytes mais baixa vence e as brechas padrão não são permitidas.

Casos de teste

1 ->  [1]
2 ->  [2] (any prime number returns just itself)
4 ->  [4]
16 -> [7, 10, 16]
28 -> [7, 10, 16, 25, 28]
51 -> [37, 51]
60 -> [7, 10, 11, 13, 15, 16, 17, 18, 23, 25, 28, 29, 30, 32, 43, 46, 49, 53, 55, 56, 60]
Zgarb
fonte
@ Zgarb, se você permitir uma cadeia de torções de 0 divisores, como cada número não é descendente de nenhum outro número?
rorlork
3
@rcrmn Para mim, uma cadeia de zero operações significa a operação de identidade. Portanto, permitir torções zero do divisor implica apenas que todo número é descendente de si mesmo.
Zgarb
@ Zgarb ok, então a definição deve ser alterada para expressar que, porque se não, até onde eu sei, qualquer número é considerado um descendente de qualquer outro número. Não sei por que é necessária a reflexividade. Você gostaria de explicar?
rorlork
@rmcrmn mudei um pouco a redação, está mais claro agora?
Zgarb
@ Zgarb desculpe, mas não, não é uma operação, você está definindo uma relação entre números. Se você definir o relacionamento <para os números naturais, para cada n, cada número será menor que ele, mas não ele próprio. Eu acho que isso deve ser algo semelhante. Dessa forma, acho que apenas 4 seriam seus próprios descendentes (embora não tenham certeza disso).
rorlork

Respostas:

9

Python 2, 109 98 85 82 bytes

f=lambda n:sorted(set(sum(map(f,{n-x+n/x for x in range(2,n)if(n<x*x)>n%x}),[n])))

Desde (a-1)*(b+1)+1 == a*b-(b-a)e b >= a, os descendentes são sempre menores ou iguais ao número original. Assim, podemos começar com o número inicial e continuar gerando descendentes estritamente menores até que não haja mais nenhum.

A condição (n<x*x)>n%xverifica duas coisas em uma - que n<x*xe n%x == 0.

(Agradecemos a @xnor por remover 3 bytes do gabinete base)

Pitão, 32 bytes

LS{s+]]bmydm+-bk/bkf><b*TT%bTr2b

Tradução direta do exposto acima, exceto pelo fato de Pyth parecer engasgar ao tentar somar ( s) em uma lista vazia.

Isso define uma função yque pode ser chamada anexando y<number>no final, assim ( tente online ):

LS{s+]]bmydm+-bk/bkf><b*TT%bTr2by60

CJam, 47 45 bytes

{{:X_,2>{__*X>X@%>},{_X\/\-X+}%{F}%~}:F~]_&$}

Também usando o mesmo método, com algumas modificações. Eu queria experimentar o CJam para comparação, mas infelizmente sou muito pior no CJam do que no Pyth / Python, então provavelmente há muito espaço para melhorias.

O acima é um bloco (basicamente a versão do CJam de funções sem nome) que recebe um int e retorna uma lista. Você pode testá-lo assim ( tente on-line ):

{{:X_,2>{__*X>X@%>},{_X\/\-X+}%{F}%~}:F~]_&$}:G; 60 Gp
Sp3000
fonte
Não sou especialista em Python, mas há uma razão pela qual você precisa set()lá? Você não pode simplesmente retornar a lista classificada?
18715 Alex A.
@Alex set()é remover duplicados :)
SP3000
Ah, tudo bem. Arrumado. Bom trabalho!
Alex A.
Talvez você possa fazer [n]+sum(...,[])como sum(...,[n])?
xnor 23/02
@ xnor Ah sim, eu posso. Eu nunca usei nada, mas []como base para resumir listas, então esqueci completamente!
Sp3000 23/02
6

Java, 148 146 104 bytes

Versão Golfed:

import java.util.*;Set s=new TreeSet();void f(int n){s.add(n);for(int a=1;++a*a<n;)if(n%a<1)f(n+a-n/a);}

Versão longa:

import java.util.*;
Set s = new TreeSet();
void f(int n) {
    s.add(n);
    for (int a = 1; ++a*a < n;)
        if (n%a < 1)
            f(n + a - n/a);
}

Então, eu estou fazendo minha estréia no PPCG com este programa, que usa a TreeSet(que classifica automaticamente os números, felizmente) e recursão semelhante ao programa do Geobits, mas de uma maneira diferente, verificando múltiplos de n e depois usá-los no próxima função. Eu diria que essa é uma pontuação bastante justa para quem está iniciando (especialmente com Java, que não parece ser a linguagem ideal para esse tipo de coisa, e a ajuda do Geobits).

TNT
fonte
Bem-vindo ao PPCG! Você pode salvar um casal, alterando a*ba nna linha 9.
Geobits
Obrigado pela recepção e pela sugestão! Sim, vai demorar um pouco para eu descobrir essas pequenas coisas. Cada byte conta! Obrigado novamente!
TNT
Você também pode economizar mais dois colocando c=n+a-bdentro add(). Como alternativa, você pode se livrar ccompletamente e usar n+a-bnos dois lugares os mesmos dois bytes.
Geobits
Falando nisso, acho que não preciso usar addduas vezes. Espere um momento ...
TNT
Mas o segundo ciclo não é necessário no geral. Se você tem um aque você sabe que divide de maneira nlimpa, não deve procurar para encontrar b, é só n/a. Nesse ponto, ele começa a se aproximar cada vez mais do meu;)
Geobits
4

Java, 157 121

Aqui está uma função recursiva que obtém descendentes de cada descendente de n. Retorna a TreeSet, que é classificado por padrão.

import java.util.*;Set t(int n){Set o=new TreeSet();for(int i=1;++i*i<n;)o.addAll(n%i<1?t(n+i-n/i):o);o.add(n);return o;}

Com algumas quebras de linha:

import java.util.*;
Set t(int n){
    Set o=new TreeSet();
    for(int i=1;++i*i<n;)
        o.addAll(n%i<1?t(n+i-n/i):o);
    o.add(n);
    return o;
}
Geobits
fonte
2

Oitava, 107 96

function r=d(n)r=[n];a=find(!mod(n,2:sqrt(n-1)))+1;for(m=(a+n-n./a))r=unique([d(m) r]);end;end

Pretty-print:

function r=d(n)
  r=[n];                          # include N in our list
  a=find(!mod(n,2:sqrt(n-1)))+1;  # gets a list of factors of a, up to (not including) sqrt(N)
  for(m=(a+n-n./a))               # each element of m is a twist
    r=unique([d(m) r]);           # recurse, sort, and find unique values
  end;
end
dcsohl
fonte
1
Entendo que o Octave possa terminar blocos com apenas endum pouco do que endfore endfunction. Isso economizaria 11 bytes.
18715 Alex A.
Ei, você está certo! Não é como eu aprendi o idioma e nunca percebi que isso poderia ser feito. Por que você é o primeiro a apontar isso depois que eu joguei vários golfe com ele?
21815 dcsohl
Eu só sabia disso porque pesquisei recentemente depois de ver no golfe de outra pessoa outra questão. Eu nunca usei o Octave e já faz anos desde que usei o Matlab. Meu palpite é que não existem tantos usuários ativos do Octave no PPCG, mas eu posso estar errado.
Alex A.
Bem, obrigado por apontar.
21815 dcsohl
O prazer é meu, feliz por poder ajudar. Ótima solução.
19415 Alex A.
1

Haskell, 102 100 bytes

import Data.List
d[]=[]
d(h:t)=h:d(t++[a*b-b+a|b<-[2..h],a<-[2..b],a*b==h])
p n=sort$nub$take n$d[n]

Uso: p 16quais saídas[7,10,16]

A função dcalcula recursivamente todos os descendentes, mas não verifica se há duplicatas; muitas aparecem mais de uma vez; por exemplo, d [4]retorna uma lista infinita de 4s. As funções pobtêm os primeiros nelementos dessa lista, remove duplicatas e classificam a lista. Voilà.

nimi
fonte
1

CJam - 36

ri_a\{_{:N,2>{NNImd!\I-z*-}fI}%|}*$p

Experimente online

Ou, método diferente:

ri_a\{_{_,2f#_2$4*f-&:mq:if-~}%|}*$p

Escrevi-os há quase 2 dias, fiquei preso aos 36 anos, fiquei frustrado e fui dormir sem postar.

aditsu sair porque SE é MAU
fonte