Numéros malchanceux!

22

A savoir:

Tout d'abord, les numéros porte-bonheur.

Les numéros porte-bonheur sont générés comme suit:

Prenez tous les nombres naturels:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20...

Ensuite, supprimez chaque deuxième numéro.

1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39...

Maintenant, 3c'est sûr.

Supprimez chaque 3e numéro:

1, 3, 7, 9, 13, 15, 19, 21, 25, 27, 31, 33, 37, 39, 43, 45, 49, 51, 55, 59...

Maintenant, 7c'est sûr.

Supprimez tous les 7 numéros.

Continuez et supprimez chaque nnuméro, où nest le premier numéro sûr après une élimination.

La liste finale des numéros sûrs est les numéros porte-bonheur.


Les nombres malchanceux sont composés de listes distinctes de nombres, qui le sont [U1, U2, U3... Un].

U1 est le premier ensemble de chiffres retiré des "candidats" chanceux, ils sont donc:

2, 4, 6, 8, 10, 12, 14, 16, 18, 20...

U2 est le deuxième ensemble de nombres supprimé:

5, 11, 17, 23, 29, 35, 41, 47, 53, 59...

Et ainsi de suite et ainsi de suite ( U3est la troisième liste, U4est la quatrième, etc.)


Défi:

Votre tâche consiste, lorsque deux entrées sont données met n, à générer le mnuméro e dans la liste Un.

Exemples d'entrées et sorties:

(5, 2) -> 29
(10, 1) -> 20

Spécifications:

  • Votre programme doit fonctionner mjusqu'à 1e6et njusqu'à 100.
    • Vous êtes assuré que les deux met nsont des entiers positifs.
    • Si vous êtes curieux, U(1e6, 100)= 5,333,213,163. (Merci @pacholik!)
  • Votre programme doit calculer cela en 1 jour sur un ordinateur moderne et raisonnable.

C'est le , donc le code le plus court en octets gagne!

PS: Ce serait bien si quelqu'un venait avec une formule générale pour les générer. Si vous avez une formule, veuillez la mettre dans votre réponse!

clismique
la source
Sur OEIS: A219178 et A255543
Arnauld
6
En relation.
Martin Ender
2
Avez-vous mis en œuvre du code qui peut réellement fonctionner (1e6,1e6)?
Jonathan Allan
2
Si vous avez besoin de temps, vous devez spécifier l'environnement de synchronisation (tel que votre machine, une machine virtuelle en ligne librement disponible ou "un ordinateur moderne raisonnable").
Mego
1
Est-il acceptable que la fonction ne fonctionne pas pour le n=1cas? Comme c'est spécial - pour tous les autres cas, l'index basé sur 0 du prochain numéro porte-bonheur est n-1.
Myridium

Réponses:

1

CJam , 74 octets

ri0Lri:U{1$W%{1$\(1e>/+}/)+}/2t:A0@{@:B:(_0#):D{D(_A=tD<BD>+}&@)@DU=-}h]1=

Essayez-le en ligne! Expirera pour les cas plus gros, plus sur les contraintes de temps ci-dessous.


Explication:

Notre programme emprunte sans vergogne le code d' Aditsu pour générer une liste de N numéros porte-bonheur, remplacer 1 par un 2 donne l'incrément dans chaque phase du tamis. Le code restant diminue sur chaque élément jusqu'à ce qu'un zéro soit trouvé (en découpant et en ajoutant une queue non décrémentée) et compte efficacement les étapes dans chacune des N phases du tamis à la fois.

ri                               e# read M
0Lri:U{1$W%{1$\(1e>/+}/)+}/2t:A  e# list steps (also becomes B)
0@                               e# arrange stack [B I M]
{                                e# while M
   @:B                           e#   get current B
   :(                            e#   decrement every element in B
   _0#):D                        e#   find first 0
   {                             e#   if there is a 0
      D(_A=t                     e#     reset that element in B
      D<BD>+                     e#     replace tail after 0
   }&                            e#   end if
   @)                            e#   increment I
   @DU=-                         e#   decrement M if N-th phase of sieve
}h                               e# end loop
]1=                              e# return I

Timing:

Si vous devez absolument exécuter le programme dans le navigateur pour un plus grand nombre, vous pouvez utiliser cet interpréteur et permettre au script de continuer si vous y êtes invité, mais cela peut être trop lent pour être qualifié. L'utilisation de ( M , N ) = (100,100) prend ~ 247s. L'itération des programmes est relativement linéaire en termes de M , donc le calcul (1e6,100) pourrait prendre environ 29 jours.

En utilisant l'interpréteur de commandes shell sur un PC, le programme calcule (100,100) en ~ 6s et calcule (1e4,100) en ~ 463s. Le programme devrait être capable de calculer (1e6,100) en ~ 13-17hrs. Dans ce cas, je suppose que le programme est admissible.

Notez que tous les temps ont été arrondis dans les mesures et les calculs.

Linus
la source
7

Perl, 87 85 82 81 octets

Comprend +4 pour -pX

Donnez une entrée sur STDIN comme une ligne avec n en premier (notez que c'est l'inverse de l'ordre suggéré dans le défi). Donc pour calculer U(1000000, 100):

unlucky.pl <<< "100 1000000"

Algorithme basé sur aditsu « s nombres chanceux répondent La complexité de temps est O(n^2)il est assez rapide pour la gamme requise. L' 100, 1000000affaire donne 5333213163en 0,7 secondes. En raison des problèmes que Perl a avec la do$0récursivité basée, il utilise beaucoup de mémoire. La réécrire en tant que fonction rendrait l'utilisation de la mémoire O(n)mais est un nombre d'octets plus long

unlucky.pl:

#!/usr/bin/perl -pX
$_=$a{$_}||=/\d+$/>--$_?2*$&+$^S:($_=$_.A.(do$0,$^S?0|$&+$&/~-$_:$&*$_-1),do$0)

Cela fonctionne comme indiqué, mais utilisez le littéral ^Spour obtenir le score réclamé.

Je ne suis au courant d'aucune utilisation antérieure de $^Sin perlgolf.

Ton Hospel
la source
Mais combien de temps cela prend-il (1e6,100)?
Myridium
@Myridium En raison de l'explosion de mémoire causée par do$0elle, elle est pratiquement inaccessible sur tout ordinateur réaliste. Mais si tant de mémoire existait environ 2 ans. Je n'ai pas vraiment écrit et testé une version basée sur un sous-programme normal, mais je m'attends à ce que cela se termine dans quelques mois et s'exécute même sur des ordinateurs avec très peu de mémoire. C'est donc une bonne chose que ces valeurs ne soient pas dans la plage requise pour ce défi.
Ton Hospel
Le défi n'est-il pas de calculer (1e6,100)en une journée? Que voulez-vous dire que ces valeurs ne sont pas obligatoires?
Myridium
@Myridium Notez que dans mon programme net msont donnés dans l'ordre inverse. L' 100 1000000entrée calcule U(1000000, 100)et donne 5,333,213,163en 0,7 seconde. C'est de loin le programme le plus rapide de ces programmes actuellement publié
Ton Hospel
Ah d'accord, je m'attendais (100,1e6)à être beaucoup plus rapide que (1e6,100), et j'ai pensé que c'était l'explication du rapide comme l'éclair de 0,7 seconde!
Myridium
7

Python 3, 170

from itertools import*
def L(n,k=1):
 if n<2:yield from count(2+k,2)
 t=L(n-1);l=next(t)
 for i in t:
  n+=1
  if(n%l>0)==k:yield i
U=lambda m,n:sum(islice(L(n,0),m-1,m))

La fonction L génère la ligne de nombres porte-bonheur possibles (si k est Vrai) ou Un (si Faux). Évalué paresseusement (donc je n'ai pas à générer n-1 listes infinies si je veux Un ).

Fonction de temporisation U .

La vitesse

U (1 000 000; 100) prend environ 1 h 45 pour fonctionner sur ma machine avec PyPy. Je soupçonne environ quatre heures avec CPython. (Oui, 4h 20min pour être précis.)

Si j'utilisais une liste au lieu de générateurs, je gagnerais peut-être en vitesse, mais j'aurais besoin d'une liste de plus grande taille que Python ne me le permet. Et si c'était le cas, il lui faudrait des dizaines de gigaoctets de RAM.


Oui, et U (1.000.000; 100) = 5.333.213.163 .

pacholik
la source
Devrait être valide maintenant.
clismique
3

Haskell

Impossible de calculer pour n = 1: 175 160 octets

Une fois compilé, il a fallu 2h 35m à mon ordinateur pour calculer une entrée d' (1000000,100)utilisation de ceci:

n#s=y:(n#p)where y:p=drop(n-1)s
n%s=f n s$[]where f n s=(take(n-1)s++).f n(drop n s) 
l 2=[1,3..]
l m=((l$m-1)!!(m-2))%(l$m-1)
m?n=(((l n)!!(n-1))#(l$n))!!(m-1)

J'ai essayé de débarrasser les wheremodules, mais ils semblent affecter la vitesse et je ne sais pas pourquoi ... Mais je pense qu'il y a plus d'élagage à faire ici.

La méthode à utiliser consiste m?nà interroger la réponse en fonction d'un met n.

Non golfé

everynth n xs = y:(everynth n ys) -- Takes every nth element from a list 'xs'
  where y:ys = drop (n-1) xs

skipeverynth n xs = f' n xs $ []  -- Removes every nth element from a list 'xs'
  where f' n xs = (take (n-1) xs ++) . f' n (drop n xs) 

l 2 = [1,3..] -- The base case of the list of lucky numbers for 'n=2'
l m = skipeverynth ((l$m-1)!!(m-2)) (l$m-1) -- Recursively defining next case as being the last one with every 'ath' element skipped. Here, 'a' is the (m-1)th elemnent of the (l (m-1)) list.
ul m = everynth ((l m)!!(m-1)) (l$m) -- This is not used other than to compute the final, required unlucky number list. It picks out every 'ath' element.

ans m n = (ul n)!!(m-1) -- The function giving the answer.

Je pense qu'il peut être possible de combiner les fonctions «skipeverynth» et «everynth» en une seule fonction qui renvoie une paire.

J'ai utilisé le code de cette personne aimable pour sauter chaque nième élément. Je l'ai fait moi-même plusieurs fois, mais c'était toujours beaucoup plus inefficace et je n'arrivais pas à comprendre pourquoi.

Capable de calculer pour tous n: 170 octets

C'est fondamentalement la même chose, mais quelques maxfonctions ont dû être ajoutées pour gérer le cas spécial de n=1.

n#s=y:(n#p)where y:p=drop(n-1)s
n%s=f n s$[]where f n s=(take(n-1)s++).f n(drop n s) 
l 1=[1..]
l m=((l$m-1)!!(max 1$m-2))%(l$m-1)
m?n=(((l n)!!(max 1$n-1))#(l$n))!!(m-1)
Myridium
la source
2

R 82 octets

f<-function(m,n){a=1:2e8
i=1
while(i<n){a=c(0,a)[c(F,rep(T,i))]
i=i+1}
a[(n+1)*m]}

Usage

f(5,2)
Returns 29

Cela doit avoir un vecteur suffisamment grand pour commencer, donc il reste suffisamment de nombres pour renvoyer la valeur. Le vecteur créé est déjà d'environ 800 Mo et la fonction peut gérer jusqu'à m = 1e4 et n = 100, donc encore bien en deçà de l'objectif.

Pour créer un vecteur suffisamment grand pour calculer f (1e6,100), il faudrait un vecteur de départ de 1: 2e10. En raison des procédures d'allocation de données Rs, cela crée un vecteur> 70 Go qui ne peut pas être exécuté sur n'importe quel ordinateur que je connais bien que le code s'exécute.

Error: cannot allocate vector of size 74.5 Gb

Pour référence f (1e4,100) s'exécute en environ 30 secondes environ. Sur cette base, et quelques tests plus petits f (1e6,100) prendraient environ une heure.

gtwebb
la source
Marquer votre réponse comme non concurrente ne l'exempte pas de ne pas répondre aux exigences du défi.
Mego
@Mego Ive vu beaucoup de réponses qui ne répondent pas aux exigences (il y a au moins 1 autre dans ce défi). Je l'ai codé et je sens qu'il répond à l'esprit de la demande de codage, j'ai également clairement indiqué où il était en deçà. De plus, comme vous le mentionnez dans vos commentaires à la question, il n'indique pas sur quel type d'ordinateur il doit tester. Je suis sûr qu'il existe des ordinateurs qui pourraient écrire 7 Go dans la mémoire et les traiter. Celui sur lequel je me trouvais ne pouvait pas le faire, mais je voulais toujours poster et je pensais que la déclaration claire était un compromis valable.
gtwebb
Nous avons une politique claire concernant les réponses ne répondant pas aux spécifications du défi . Cela étant dit, je ne sais pas pourquoi vous avez qualifié votre réponse de non concurrente. Si je comprends bien, cela devrait fonctionner avec suffisamment de mémoire, mais vous ne pouvez pas le tester car vous n'avez pas assez de RAM. Est-ce exact?
Dennis
1
1. Cette politique est appliquée, mais quatre modérateurs ne peuvent pas tester toutes les réponses sur le site. Si vous trouvez une soumission qui ne respecte pas les règles, signalez-la à l'attention du modérateur afin que nous puissions y jeter un œil. 2. Vous n'avez pas à apprendre une langue de golf pour participer. Les langages de production comme R sont tout aussi bienvenus. Je poste régulièrement des réponses Python moi-même.
Dennis
1
3. La spécification ne mentionne aucune limite de mémoire, mais il y a un délai de 24 heures. En l'absence d'un ordinateur avec 70 Gio (ou vouliez-vous dire des bits giga ) pour tester cela, il est difficile de déterminer si cette réponse est valide ou non. Je suggère d'essayer d'extrapoler le runtime aussi bien que possible. Si c'est moins d'une journée, supprimez l'en-tête non concurrent et incluez votre extrapolation dans le post. Si cela prend plus de temps, votre soumission doit être optimisée ou supprimée.
Dennis
1

Raquette 332 octets

(λ(N m n)(let loop((l(filter odd?(range 1 N)))(i 1))(define x (list-ref l i))(if(= i (sub1 n))
(begin(set! l(for/list((j(length l))#:when(= 0(modulo(add1 j)x)))(list-ref l j)))(list-ref l(sub1 m)))
(begin(set! l(for/list((j(length l))#:unless(= 0(modulo(add1 j) x)))(list-ref l j)))(if(>= i(sub1 (length l)))l
(loop l(add1 i)))))))

Version non golfée:

(define f
  (λ(N m n)
    (let loop ((l (filter odd? (range 1 N))) (i 1))
      (define x (list-ref l i))
      (if (= i (sub1 n))
          (begin (set! l (for/list ((j (length l)) 
                                   #:when (= 0 (modulo (add1 j) x)))
                           (list-ref l j)))
                 (list-ref l (sub1 m)))
          (begin (set! l (for/list ((j (length l)) 
                                   #:unless (= 0 (modulo (add1 j) x)))
                           (list-ref l j)))
                 (if (>= i (sub1 (length l)))
                     l
                     (loop l (add1 i))))))))

Essai:

(f 100 5 2)

Sortie:

29
rnso
la source
1

Clojure, 221 octets

Mighty long mais gère le boîtier (f 1). Sans ce cas particulier, il s'agissait de 183 octets. C'était trop d'efforts pour ne pas l'avoir affiché.

(defn f([n](if(< n 2)(take-nth 2(drop 2(range)))(f n 1(take-nth 2(rest(range))))))([n i c](if (< n 2)c(let[N(first(drop i c))F #((if(= 2 n)= >)(mod(inc %)N)0)](f(dec n)(inc i)(filter some?(map-indexed #(if(F %)%2)c)))))))

Exemples de sorties:

(pprint (map #(take 10 (f %)) (range 1 10)))
((2 4 6 8 10 12 14 16 18 20)
 (5 11 17 23 29 35 41 47 53 59)
 (19 39 61 81 103 123 145 165 187 207)
 (27 57 91 121 153 183 217 247 279 309)
 (45 97 147 199 253 301 351 403 453 507)
 (55 117 181 243 315 379 441 505 571 633)
 (85 177 277 369 471 567 663 757 853 949)
 (109 225 345 465 589 705 829 945 1063 1185)
 (139 295 447 603 765 913 1075 1227 1377 1537))

1000000 100 cas a été calculé en environ 4,7 heures, au moins il ne s'est pas écrasé.

java -jar target\stackoverflow-0.0.1-SNAPSHOT-standalone.jar 1000000 100
5333213163
"Elapsed time: 1.7227805535565E7 msecs"
NikoNyrh
la source