10
votes

Comment combiner deux générateurs de manière non triviale

J'ai un générateur qui produit tous les entiers positifs qui sont des pouvoirs de 2, et une autre qui produit tous les entiers pouvant être des pouvoirs de 3. J'ai maintenant besoin d'utiliser celles pour produire des entiers de la forme 2 ^ i * 3 ^ j Où Je, j> = 0,0 dans l'ordre croissant.

Le point d'utilisation des générateurs est de réduire la consommation de mémoire, je pense. J'ai essayé de le faire depuis un moment maintenant en vain. S'il vous plaît aider.


7 commentaires

@Greg, vous avez une belle coupe de cheveux!


Vous voulez quelque chose qui trouve tout ce qui est un multiple de 2 ou 3 dans une commande croissante? Je ne suis pas sûr de ce que vous recherchez. Est-ce que vous analysez quelque chose? Ou est-ce un comptoir droit comme 2,3,4,6,8,9.


Désolé, une puissance de 2 ou 3 dans l'ordre croissant. Chaque fois que je l'appelle, je devrais avoir un nouveau numéro. Je ne fais rien. Oui, la sortie sera: 1, 2, 3, 4, 6, 8, 9, 12, ...


L'esprit si je pseudo vous codez-vous? LOL Est-ce que celles-ci prennent des graines ou quoi que ce soit ou vient d'exécuter et de produire une liste de chiffres? Puis-je obtenir le code actuel pour l'un d'entre eux?


Afin de créer un exemple de travail / travail à proximité, j'aurai besoin du code de l'un d'entre eux ou de la manière dont vous l'appelez.


Suis-je confus? Les réponses semblent jusqu'à présent donner des entiers qui sont 2 ^ I ou 3 ^ j, tandis que la question semble demander produits de 2 ^ i et 3 ^ j.


@Darius: Maintenant, il y a le mien :-p


7 Réponses :


1
votes

Au moins si je comprends votre question, il vous suffit de fusionner les résultats des deux générateurs:

  1. génère une sortie de chaque générateur
  2. Produit le plus petit des deux comme la prochaine sortie
  3. génère la sortie suivante de ce générateur
  4. retourne à l'étape 2

    Si les deux générateurs produisent des valeurs égales, produisent celles telles que la sortie et génèrent la valeur suivante de chaque générateur.

    Notez que, bien que cela soit généralement utilisé pour trier des données existantes au lieu de générer de nouvelles données, cela est similaire à la fusion utilisée dans un type de fusion normal, à l'exception que je supposais que vous ne voulez pas de duplicate, où une fusion sorte qu'il conserve normalement des doublons.

    Edit: Merci à LPTHNC, j'ai relu la question, et je pense qu'il a raison - j'ai mal interprété la question initiale. Pour obtenir la sortie correcte, vous auriez besoin de créer un troisième générateur et de produire les multiples de (dans ce cas) six, et utilisez une fusion à trois voies entre ce jeu de résultat et ceux des deux autres générateurs.

    Je n'ai pas beaucoup joué avec beaucoup, mais je crois que le niveau de langue paresseux (ou le module paresseux) dans les itérations récentes du schéma PLT vous permettrait d'écrire votre code pour générer toute la séquence infinie, qui utiliserait théoriquement une période infinie et mémoire, mais évaluez uniquement un sous-ensemble fini de celui-ci au besoin.


1 commentaires

Nan! Cela sauterait tous les multiples de 6.



1
votes

La solution simple sans quels exemples est la création d'une nouvelle.

int counter = 1000;
bool done = false;
while(!done)
{
 if (i%2 or i%3)
 {
  cout << i;
  counter--;
  if(counter <= 1)
   {
     done = true;
   }
 }
i++;
}


4 commentaires

Cela a la même limitation que le tamis du nom EratosfantsPellhis - Supposons que je souhaite les 1000 premiers articles. Comment choisir x?


Désolé, 15 ne devraient pas être dans cette liste.


Ça ne devrait pas. J'ai édité le q depuis lors. Je suis intéressé par tous les pouvoirs de 3, tous pouvoirs de 2, ou une combinaison des deux (E.g 6, 12 = 2 ^ 2 * 3 ^ 1)


J'ai répondu à votre question initiale>.> Je vais répondre à ce problème lorsque j'ai cependant une chance. . . ça a l'air drôle.



1
votes

Il suffit de fusionner les deux listes commandées a la xxx

soulevé de ici .


1 commentaires

Votre fonction de fusion produirait des pouvoirs de 2 ou 3, commandé, à des listes finies, mais ne produirait pas de produits arbitraires d'eux.



1
votes

expurgé. Plus je regarde cela, plus je pense avoir tout faux - et d'autres semblent avoir de meilleures réponses, déjà.

Désolé, rien de tout cela est dans le schéma, juste pseudocode ...

Le code suivant correspond au processus de pensée I Garner de votre question:

EDIT: Pseudocode révisé maintenant que je réalise que c'est "2 ^ i * 3 ^ j", pas "2 ^ i, 3 ​​^ j" xxx


4 commentaires

Vous ne pouvez pas simplement vérifier son modulo contre 2 et 3 car ce qui est demandé est des chiffres dont les seuls facteurs premiers sont 2 et 3. 14 et 15 seraient imprimés par votre algorithme, mais ils ne sont pas de la forme 2 ^ i * 3 ^ j.


@Kingerroneous: bon point - je n'ai pas réalisé que ce n'est que des exposants. Je vais réparer ma réponse dans un instant ...


Je crois que vous voulez dire laisser compter-by-trois = 1 , mais comme pour d'autres réponses, cela n'imprimerait que des pouvoirs de deux ou trois, et non les produits de pouvoirs de deux et trois.


@ Jeremie.Koenig: Oups! Faire des mises à jour du pseudocode, maintenant. Je l'ai mal interprété à l'origine comme "2 ^ i, 3 ​​^ j" au lieu de "2 ^ i * 3 * i".



1
votes

Ceci est assez facile dans HASKELLL:

[2,3,4,8,9,16,27,32,64,81,128,243,256,512,729,1024,2048,2187,4096,6561,8192,16384,19683,32768,59049]


3 commentaires

Veuillez imprimer les 25 premiers éléments de celui-ci ici. Je n'ai pas de haskell installé.


Ce ne sont pas des pouvoirs de 2 ou 3.


Droite ... j'ai changé les règles depuis lors :)



3
votes

Je ne sais pas beaucoup sur les générateurs, Cependant, je peux proposer une solution basée sur les flux em> (construit paresseux, éventuellement des listes infinies), qui sont quelque peu similaires.

Mon approche serait de créer un flux dont «l'état» lui-même serait un flux de flux. P>

L'individu, les flux internes de nombres, Appelons-les les 3-Streams, représenterait des listes des pouvoirs successifs de 3, en commençant par 1, multiplié par une puissance donnée de deux. Nous pouvons ensuite assembler une infinité de tels ruisseaux, un pour chaque puissance successive de 2, en commençant par 1. Appelons ceci le 2-ruisseau. P>

L'état initial, en ASCII-Art, est-ce: p> xxx pré>

maintenant, nous allons manipuler cela de sorte qu'à tout moment, Les 3-Streams seront commandés dans le 2-Stream en ce qui concerne leurs premiers éléments. En conséquence, le prochain nombre le plus petit généré sera toujours le premier élément du premier 3-flux. P>

Donc, pour obtenir le prochain numéro dans la séquence que vous souhaitez obtenir, Nous allons tirer le premier 3 stream, retirer son premier élément (qui est le nombre qui nous intéresse), puis réinsérez le 3-flux dans le 2-ruisseau à une position déterminée par son premier élément em> nouveau em>. Le nouvel état après le premier numéro (1) a été extrait sera: p> xxx pré>

Notez que cette méthode ne dépend pas de 2 ^ i, 3 ​​^ j ou multiplication spécifiquement spécifiquement (Juste sur 2 ^ I * 3 ^ J étant augmentant monotone avec I et J). J'ai posté une autre réponse qui fait, et est beaucoup plus simple et rapide en conséquence frappe>. ne me faites pas confiance: cela n'a rien à voir avec le maths em> p>

ci-dessous est un exemple de mise en œuvre, en utilisant SRFI-41 Streams: P>

$ mzscheme -f pow23.scm -e '(display (stream->list (stream-take 20 the-stream)))'
(1 2 3 4 6 8 9 12 16 18 24 27 32 36 48 54 64 72 81 96)

$ time mzscheme -f pow23.scm -e '(display (stream-ref the-stream 10000))'
161968247347450370721577384417107686788864605658546176
real    0m12.550s
user    0m11.005s
sys     0m0.340s


1 commentaires

Pardon mon ignorance - Quel est le diff entre un flux et un générateur dans le schéma?



8
votes

Utilisation d'un flux de lecture auto-lecture

Vous pouvez résoudre ceci à l'aide d'un flux d'auto-lecture: P>

$ time python feedback.py 
161968247347450370721577384417107686788864605658546176
real    0m0.150s
user    0m0.112s
sys     0m0.012s


4 commentaires

Wow, c'est fou! Pouvez-vous traduire cela en python?


Pas littéralement (Python n'a pas de courant Afaik), mais nous pouvons utiliser les générateurs et une file d'attente pour mettre en œuvre la même idée de base.


Bon sang, tu m'as emmené à l'école. Merci!


Au lieu de mettre en œuvre la fusion, vous pouvez également utiliser à partir de la fusion d'importation de HePQ.