Unglückszahlen!

22

Sachen zu wissen:

Erstens Glückszahlen.

Glückszahlen werden wie folgt generiert:

Nehmen Sie alle natürlichen Zahlen:

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

Entfernen Sie dann jede zweite Zahl.

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

Jetzt 3ist sicher.

Entfernen Sie jede dritte Nummer:

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

Jetzt 7ist sicher.

Entfernen Sie jede 7. Nummer.

Fahren Sie fort und entfernen Sie jede ndritte Nummer. Dabei nhandelt es sich um die erste sichere Nummer nach einer Eliminierung.

Die endgültige Liste der sicheren Zahlen sind die Glückszahlen.


Die Unglückszahlen setzen sich aus separaten Zahlenlisten zusammen, die es sind [U1, U2, U3... Un].

U1 ist der erste Satz von Zahlen, der von den glücklichen "Kandidaten" entfernt wurde, also sind sie:

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

U2 ist der zweite Satz von Zahlen entfernt:

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

Und so weiter und so fort ( U3ist die dritte Liste, U4ist die vierte usw.)


Herausforderung:

Ihre Aufgabe ist es, bei zwei Eingaben mund ndie mth Nummer in der Liste zu generieren Un.

Beispiel Ein- und Ausgänge:

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

Technische Daten:

  • Ihr Programm muss für mbis zu 1e6und nbis zu 100.
    • Sie sind garantiert, dass beide mund npositive ganze Zahlen sind.
    • Wenn Sie neugierig sind, U(1e6, 100)= 5,333,213,163. (Danke @pacholik!)
  • Ihr Programm muss dies innerhalb eines Tages auf einem vernünftigen modernen Computer berechnen.

Das ist , also gewinnt der kürzeste Code in Bytes!

PS: Es wäre schön, wenn jemand eine allgemeine Formel zur Erzeugung dieser Formeln ausdenken würde. Wenn Sie eine Formel haben, geben Sie diese bitte in Ihre Antwort ein!

Clismique
quelle
Auf OEIS: A219178 und A255543
Arnauld,
6
Verbunden.
Martin Ender
2
Haben Sie Code implementiert, der tatsächlich funktioniert (1e6,1e6)?
Jonathan Allan
2
Wenn Sie einen Zeitbedarf haben, müssen Sie die Zeitumgebung angeben (z. B. Ihren Computer, eine frei verfügbare Online-VM oder einen "vernünftigen modernen Computer").
Mego
1
Ist es akzeptabel, dass die Funktion für den n=1Fall nicht funktioniert ? Da dies besonders ist - für alle anderen Fälle ist der 0-basierte Index der nächsten Glückszahl n-1.
Myridium

Antworten:

1

CJam , 74 Bytes

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

Probieren Sie es online! Bei größeren Fällen tritt eine Zeitüberschreitung auf. Weitere Informationen zu Zeitbeschränkungen finden Sie weiter unten.


Erläuterung:

Unser Programm leiht sich schamlos den Code von Aditsu aus , um eine Liste mit N Glückszahlen zu erstellen. Wenn Sie 1 durch 2 ersetzen, erhalten Sie das Inkrement in jeder Phase des Siebs. Der verbleibende Code dekrementiert jedes Element, bis eine Null gefunden wird (durch Schneiden und Anhängen eines nicht dekrementierten Endes), und zählt effektiv die Schritte in jeder der N Phasen des Siebs gleichzeitig.

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

Zeitliche Koordinierung:

Wenn Sie das Programm für größere Zahlen unbedingt im Browser ausführen müssen, können Sie diesen Interpreter verwenden und zulassen, dass das Skript fortgesetzt wird, wenn Sie dazu aufgefordert werden. Dies ist jedoch möglicherweise zu langsam, um eine Qualifizierung vorzunehmen. Die Verwendung von ( M , N ) = (100, 100) dauert ~ 247s. Die Programmiteration ist in Bezug auf M relativ linear , daher kann die Berechnung (1e6,100) ~ 29 Tage dauern.

Unter Verwendung des Shell-Interpreters auf einem PC berechnet das Programm (100, 100) in ~ 6s und (1e4, 100) in ~ 463s. Das Programm sollte in der Lage sein, (1e6,100) in ~ 13-17 Stunden zu berechnen. In diesem Fall gehe ich davon aus, dass sich das Programm qualifiziert.

Beachten Sie, dass alle Zeiten in Messungen und Berechnungen aufgerundet wurden.

Linus
quelle
7

Perl, 87 85 82 81 Bytes

Beinhaltet +4 für -pX

Geben Sie STDIN als eine Zeile mit n als erstes ein (beachten Sie, dass dies die Umkehrung der in der Challenge vorgeschlagenen Reihenfolge ist). So berechnen Sie U(1000000, 100):

unlucky.pl <<< "100 1000000"

Algorithmus basierend auf der Antwort von aditsu auf Glückszahlen Die Zeitkomplexität ist so, dass sie für den erforderlichen Bereich ziemlich schnell ist. Der Fall gibt in 0,7 Sekunden. Aufgrund der Probleme, die Perl mit der basierten Rekursion hat , verbraucht es viel Speicher. Das Umschreiben als Funktion würde den Speicher belegen , ist aber einige Bytes längerO(n^2)100, 10000005333213163do$0O(n)

unlucky.pl:

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

Dies funktioniert wie gezeigt, aber verwenden Sie Literal ^S, um die beanspruchte Punktzahl zu erhalten.

Mir ist keine frühere Verwendung von $^SPerlgolf bekannt.

Tonne Hospel
quelle
Aber wie lange dauert das (1e6,100)?
Myridium
@Myridium Aufgrund der dadurch verursachten Speicherexplosion do$0ist es auf keinem realistischen Computer erreichbar. Aber wenn so viel Gedächtnis vorhanden ist, dann ungefähr 2 Jahre. Ich habe noch nicht wirklich eine normale, auf Unterprogrammen basierende Version geschrieben und getestet, aber ich würde erwarten, dass diese in ein paar Monaten fertig ist und sogar auf Computern mit sehr wenig Arbeitsspeicher ausgeführt wird. Gut, dass diese Werte für diese Herausforderung nicht im erforderlichen Bereich liegen.
Ton Hospel
Ist es nicht eine Herausforderung, (1e6,100)innerhalb eines Tages zu rechnen ? Was meinst du, diese Werte sind nicht erforderlich?
Myridium
@Myridium Beachten Sie, dass in meinem Programm nund min umgekehrter Reihenfolge angegeben werden. Die 100 1000000Eingabe berechnet U(1000000, 100)und gibt 5,333,213,163in 0,7 Sekunden. Es ist bei weitem das schnellste Programm dieser derzeit geposteten
Ton Hospel
Ah, okay, ich habe erwartet (100,1e6), dass es viel schneller geht als (1e6,100)und dachte, das wäre die Erklärung für die blitzschnellen 0,7 Sekunden!
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))

Die Funktion L erzeugt die Reihe möglicher Glückszahlen (wenn k Wahr ist) oder Un (wenn Falsch). Faul ausgewertet (damit ich keine n-1 unendlichen Listen generieren muss, wenn ich Un will ).

Führen Sie die Funktion U aus .

Geschwindigkeit

U (1.000.000; 100) benötigt ca. 1 Stunde und 45 Minuten, um mit PyPy auf meinem Computer ausgeführt zu werden. Ich vermute etwa vier Stunden mit CPython. (Ja, 4h 20min um genau zu sein.)

Wenn ich eine Liste anstelle von Generatoren verwenden würde, könnte ich etwas an Geschwindigkeit gewinnen, aber ich würde eine Liste mit größerer Größe benötigen, als mir Python erlaubt. Und wenn doch, würde es Dutzende von Gigabyte RAM benötigen.


Ja und U (1.000.000; 100) = 5.333.213.163 .

pacholik
quelle
Sollte jetzt gültig sein.
Clismique
3

Haskell

Für n = 1: 175 160 Byte kann nicht berechnet werden

Beim Kompilieren benötigte mein Computer 2 Stunden 35 Minuten, um eine Eingabe zu berechnen, in der Folgendes (1000000,100)verwendet wurde:

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)

Ich habe versucht, die whereModule zu bereinigen , aber sie scheinen die Geschwindigkeit zu beeinträchtigen, und ich bin mir nicht sicher, warum ... Aber ich denke, hier gibt es mehr zu bereinigen.

Die zu verwendende Methode dient m?nzum Abfragen der Antwort mit mund n.

Ungolfed

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.

Ich gehe davon aus, dass es möglich sein könnte, die Funktionen 'skipeverynth' und 'everynth' zu einer einzigen Funktion zu kombinieren, die ein Paar zurückgibt.

Ich habe den Code dieser freundlichen Person verwendet, um jedes n-te Element zu überspringen. Ich habe es selbst ein paar Mal gemacht, aber es war immer viel ineffizienter und ich konnte nicht herausfinden, warum.

Kann für alle n: 170 Bytes rechnen

Dies ist im Grunde das gleiche, aber ein paar maxFunktionen mussten eingebaut werden, um den Sonderfall von zu behandeln 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
quelle
2

R 82 Bytes

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

Verwendung

f(5,2)
Returns 29

Zunächst muss der Vektor groß genug sein, damit genügend Zahlen übrig bleiben, um den Wert zurückzugeben. Der erzeugte Vektor ist bereits ungefähr 800 MB groß und die Funktion kann bis zu m = 1e4 und n = 100 verarbeiten, also immer noch weit hinter dem Ziel.

Um einen Vektor zu erstellen, der groß genug ist, um f (1e6,100) zu berechnen, würde ein Startvektor von 1: 2e10 verwendet. Aufgrund der Zuweisung von Rs-Daten wird ein Vektor> 70 GB erstellt, der auf keinem mir bekannten Computer ausgeführt werden kann, obwohl der Code ausgeführt werden würde.

Error: cannot allocate vector of size 74.5 Gb

Als Referenz läuft f (1e4,100) in ungefähr 30 Sekunden. Basierend auf diesem und ein paar kleineren Tests würde f (1e6,100) ungefähr eine Stunde dauern.

gtwebb
quelle
Das Markieren Ihrer Antwort als nicht konkurrierend entschuldigt sie nicht, die Herausforderungsanforderungen nicht zu erfüllen.
Mego
@Mego Ich habe viele Antworten gesehen, die die Anforderungen nicht erfüllen (es gibt mindestens eine andere in dieser Herausforderung). Ich habe es codiert und ich habe das Gefühl, dass es dem Geist der Codierungsanforderung entspricht. Ich habe auch klar angegeben, wo es zu kurz gekommen ist. Wie Sie auch in Ihren Kommentaren zu der Frage erwähnt haben, gibt es nicht an, auf welchem ​​Computertyp es getestet werden muss. Ich bin mir sicher, dass es Computer gibt, die 7 GB in den Speicher schreiben und ihn verarbeiten können. Das, auf dem ich war, konnte es nicht tun, aber ich wollte immer noch posten und ich dachte, die klare Aussage sei ein gültiger Kompromiss.
gtwebb
Wir haben eine klare Richtlinie für Antworten, die nicht der Herausforderungsspezifikation entsprechen . Trotzdem bin ich mir nicht sicher, warum Sie Ihre Antwort als nicht konkurrierend bezeichnet haben. Wenn ich das richtig verstehe, sollte dies funktionieren, wenn genügend Arbeitsspeicher vorhanden ist. Sie konnten es jedoch nicht testen, da Sie nicht über genügend Arbeitsspeicher verfügen. Ist das korrekt?
Dennis
1
1. Diese Richtlinie wird durchgesetzt, aber vier Moderatoren können nicht alle Antworten auf der Website testen. Wenn Sie eine Einsendung finden, die nicht den Regeln entspricht, melden Sie sie dem Moderator, damit wir einen Blick darauf werfen können. 2. Sie müssen keine Golfsprache lernen, um teilnehmen zu können. Produktionssprachen wie R sind ebenso willkommen. Ich poste Python antwortet mir regelmäßig.
Dennis
1
3. In der Spezifikation sind keine Speicherbeschränkungen angegeben, es gibt jedoch eine 24-Stunden-Beschränkung. In Abwesenheit eines Computers mit 70 GiB (oder haben Sie mittlere giga Bits ) , dies zu testen , auf, ist es schwer zu bestimmen , ob diese Antwort gültig ist oder nicht. Ich schlage vor, die Laufzeit so gut wie möglich zu extrapolieren. Wenn es weniger als einen Tag ist, entfernen Sie den nicht konkurrierenden Header und fügen Sie Ihre Hochrechnung in den Beitrag ein. Wenn es länger dauert, sollte Ihr Beitrag optimiert oder entfernt werden.
Dennis
1

Schläger 332 Bytes

(λ(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)))))))

Ungolfed-Version:

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

Testen:

(f 100 5 2)

Ausgabe:

29
rnso
quelle
1

Clojure, 221 Bytes

Mächtig lang aber behandelt den Fall (f 1). Ohne diesen Sonderfall waren es 183 Bytes. Das war zu viel Aufwand, um es nicht zu veröffentlichen.

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

Beispielausgaben:

(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 Fall wurde in ca. 4,7 Stunden berechnet, zumindest stürzte es nicht ab.

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