Torsion du diviseur itéré


13

Définitions

Soit met nsoyez des entiers positifs. Nous disons que mc'est une torsion du diviseurn s'il existe des entiers 1 < a ≤ btels que n = a*bet m = (a - 1)*(b + 1) + 1. Si mpeut être obtenu à partir nde l'application de zéro ou plusieurs torsions de diviseur, alors mest un descendant de n. Notez que chaque numéro est son propre descendant.

Par exemple, réfléchissez n = 16. On peut choisir a = 2et b = 8, depuis 2*8 = 16. alors

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

ce qui montre que 10c'est une torsion de diviseur de 16. Avec a = 2et b = 5, on voit alors que 7c'est une torsion de diviseur de 10. Ainsi 7est un descendant de16 .

La tâche

Étant donné un entier positif n, calculer les descendants den , répertoriés dans l'ordre croissant, sans doublons.

Règles

Vous n'êtes pas autorisé à utiliser des opérations intégrées qui calculent les diviseurs d'un nombre.

Les programmes complets et les fonctions sont acceptés, et le retour d'un type de données de collection (comme un ensemble quelconque) est autorisé, tant qu'il est trié et sans doublon. Le nombre d'octets le plus bas l'emporte et les failles standard sont interdites.

Cas de test

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 si vous autorisez une chaîne de 0 torsions de diviseur, alors comment chaque nombre n'est-il pas un descendant d'un autre nombre?
rorlork

3
@rcrmn Pour moi, une chaîne d'opérations nulles signifie l'opération d'identité. Donc, autoriser les torsions de diviseur nul implique seulement que chaque nombre est un descendant de lui-même.
Zgarb

@Zgarb d'accord, donc la définition devrait être modifiée pour exprimer cela, car sinon, pour autant que je sache, tout nombre est considéré comme un descendant de tous les autres. Je ne sais pas pourquoi il a fallu de la réflexivité. Voulez-vous expliquer?
rorlork

@rcrmn J'ai légèrement changé la formulation, est-ce plus clair maintenant?
Zgarb

@Zgarb désolé mais non, ce n'est pas une opération, vous définissez une relation entre les nombres. Si vous définissez la relation <pour les nombres naturels, pour chaque n vous obtenez chaque nombre plus petit que lui mais pas lui-même. Je pense que cela devrait être quelque chose de similaire. De cette façon, je pense que seulement 4 serait son propre descendant (cependant, je n'en suis pas sûr).
rorlork

Réponses:


9

Python 2, 109 98 85 82 octets

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])))

Depuis (a-1)*(b+1)+1 == a*b-(b-a)etb >= a , les descendants sont toujours inférieurs ou égaux au nombre d'origine. Nous pouvons donc simplement commencer par le nombre initial et continuer à générer des descendants strictement plus petits jusqu'à ce qu'il n'en reste plus.

La condition (n<x*x)>n%xvérifie deux choses en une - cela n<x*xet n%x == 0.

(Merci à @xnor d'avoir retiré 3 octets du cas de base)

Pyth, 32 octets

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

Traduction directe de ce qui précède, à l'exception du fait que Pyth semble s'étouffer en essayant de sum ( s) sur une liste vide.

Cela définit une fonction yqui peut être appelée en ajoutant y<number>à la fin, comme ceci ( essayez-le en ligne ):

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

CJam, 47 45 octets

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

En utilisant également la même méthode, avec quelques modifications. Je voulais essayer CJam à titre de comparaison, mais malheureusement, je suis bien pire à CJam qu'à Pyth / Python, donc il y a probablement beaucoup de place pour l'amélioration.

Ce qui précède est un bloc (essentiellement la version de CJam des fonctions sans nom) qui prend un int et renvoie une liste. Vous pouvez le tester comme ça ( essayez-le en ligne ):

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

Je ne suis pas un expert en Python, mais y a-t-il une raison pour laquelle vous set()en avez besoin ? Vous ne pouvez pas simplement renvoyer la liste triée?
Alex A.

@Alex set()consiste à supprimer les doublons :)
Sp3000

Ah d'accord. Soigné. Bon travail!
Alex A.

Pouvez-vous peut-être faire [n]+sum(...,[])comme ça sum(...,[n])?
xnor

@xnor Ah oui, je peux. Je n'ai jamais rien utilisé d'autre que []comme cas de base pour additionner des listes, alors j'ai complètement oublié!
Sp3000

6

Java, 148 146 104 octets

Version golfée:

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);}

Version longue:

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);
}

Je fais donc mes débuts sur PPCG avec ce programme, qui utilise un TreeSet(qui trie automatiquement les nombres, heureusement) et une récursivité similaire au programme de Geobits, mais d'une manière différente, en vérifiant les multiples de n puis en les utilisant dans le fonction suivante. Je dirais que c'est un score assez juste pour un débutant (en particulier avec Java, qui ne semble pas être le langage le plus idéal pour ce genre de chose, et l'aide de Geobits).


Bienvenue chez PPCG! Vous pouvez enregistrer un couple en passant a*bà la nligne 9.
Geobits

Merci pour l'accueil et la suggestion! Ouais, il me faudra du temps pour repérer ces petites choses. Chaque octet compte! Merci encore!
TNT

Vous pouvez également en enregistrer deux de plus en les mettant à l' c=n+a-bintérieur add(). Alternativement, vous pouvez vous débarrasser ccomplètement et simplement utiliser n+a-baux deux endroits pour ces deux mêmes octets.
Geobits

En parlant de cela, je ne pense pas avoir besoin de l'utiliser adddeux fois. Attendez un instant ...
TNT

Mais la deuxième boucle n'est pas nécessaire dans l'ensemble. Si vous avez un aque vous savez divise nproprement, alors vous ne devriez pas faire de boucle pour le trouver b, c'est juste n/a. À ce moment, il commence à se rapprocher de plus en plus du mien;)
Geobits

4

Java, 157 121

Voici une fonction récursive qui obtient les descendants de chaque descendant de n. Il renvoie un TreeSet, qui est trié par défaut.

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;}

Avec quelques sauts de ligne:

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;
}

2

Octave, 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

Jolie impression:

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

1
Je crois comprendre qu'Octave peut terminer les blocs avec juste endplutôt que endforet endfunction. Cela vous ferait économiser 11 octets.
Alex A.

Hé, tu as raison! Pas comment j'ai appris la langue et je n'ai jamais réalisé que c'était possible. Pourquoi êtes-vous le premier à le signaler après avoir fait plusieurs golfs avec?
dcsohl

Je le savais seulement parce que je l'ai récemment recherché après l'avoir vu dans le golf de quelqu'un d'autre sur une autre question. Je n'ai jamais utilisé Octave et cela fait des années que je n'ai pas utilisé Matlab. Je suppose qu'il n'y a pas beaucoup d'utilisateurs Octave actifs sur PPCG, mais je peux me tromper.
Alex A.

Eh bien, merci de l'avoir signalé.
dcsohl

Mon plaisir, heureux d'avoir pu aider. Belle solution.
Alex A.

1

Haskell, 102 100 octets

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]

Utilisation: p 16quelles sorties[7,10,16]

La fonction dcalcule récursivement tous les descendants, mais ne vérifie pas les doublons, donc beaucoup apparaissent plus d'une fois, par exemple d [4]retourne une liste infinie de 4s. La fonction pprend les premiers néléments de cette liste, supprime les doublons et trie la liste. Voilà.


1

CJam - 36

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

Essayez-le en ligne

Ou, méthode différente:

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

Je les ai écrits il y a presque 2 jours, je suis resté coincé à 36 ans, je suis frustré et je me suis endormi sans poster.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.