Jede mögliche Zykluslänge


21

Man kann sagen, dass eine Funktion (oder ein Programm), die Eingaben entgegennimmt und Ausgaben bereitstellt, einen Zyklus hat, wenn der wiederholte Aufruf der Funktion an ihrem eigenen Ausgang schließlich die ursprüngliche Nummer erreicht. Nehmen Sie zum Beispiel die folgende Funktion:

Input:  n    1 2 3 4 5 6
Output: f(n) 5 7 1 3 4 9

Wenn wir beginnen mit n=1, f(n)=5, f(f(n))=f(5)=4, f(f(f(n)))=f(4)=3, f(f(f(f(n))))=f(3)=1.

Das steht geschrieben (1 5 4 3). Da diese Schleife 4 eindeutige Zahlen enthält, handelt es sich um einen Zyklus der Länge 4.


Ihre Herausforderung besteht darin, ein Programm oder eine Funktion zu schreiben, die Zyklen von jeder möglichen Länge enthält. Das heißt, es muss einen Zyklus der Länge 1, der Länge 2 usw. geben.

Außerdem muss Ihre Funktion / Ihr Programm von den positiven Ganzzahlen zu den positiven Ganzzahlen reichen und bijektiv sein , dh, für jeden möglichen Ausgabewert muss über alle positiven Ganzzahlen genau ein Eingabewert vorhanden sein. Anders ausgedrückt muss die Funktion / das Programm eine Permutaion der positiven ganzen Zahlen berechnen.


Details: Jedes Standard-Eingabe- / Ausgabesystem ist zulässig, einschließlich STDIN, STDOUT, Funktionsargument, Return usw. Standardlücken sind verboten.

Sie müssen sich keine Gedanken über die Einschränkungen Ihrer Datentypen machen - die obigen Eigenschaften müssen nur unter der Annahme gelten, dass beispielsweise ein intoder floatein beliebiger Wert enthalten sein kann.

Es gibt keine Einschränkungen für das Verhalten der Funktion bei Eingängen, die keine positiven ganzen Zahlen sind, und diese Ein- / Ausgänge werden ignoriert.


Scoring ist Codegolf in Bytes, kürzester Code gewinnt.


"Es muss einen Zyklus der Länge 1, der Länge 2 usw. geben." Sollte dies so interpretiert werden, dass es mindestens einen Zyklus der Länge 1, mindestens einen Zyklus der Länge 2 usw. geben muss. " sei genau ein Zyklus der Länge 1, einer der Länge 2 und so weiter ".
Bakuriu

@ Bakuriu Mindestens ein Zyklus jeder positiven Länge.
isaacg

Antworten:


11

Pyth, 11 8 Bytes

.<W-0zz1

Viel langweiliger als meine vorherige Antwort.

Jede Zahl, die eine 0-Stelle enthält, ist sich selbst zugeordnet. Jede andere Nummer ist der Nummer zugeordnet, deren Ziffern um 1 gedreht sind. Beispiel:

1 -> 1
10 -> 10
15 -> 51 -> 15
104 -> 104
123 -> 231 -> 312 -> 123

8

Python 2, 56 55 54 Bytes

n=input()
a=b=1
while a+b<=n:a+=b;b+=1
print(n+~a)%b+a

Hier sind die ersten 21 Ausgänge:

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

Das Muster ist offensichtlich, wenn wir die Liste in folgende Teile aufteilen:

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

Verdammt, das ist das Muster, nach dem ich auch gesucht habe, aber mit einer geschlossenen Form.
Orlp

1
Interessant .. die a-Werte folgen der Reihenfolge A000124 . Aber das
Kade

Beachten Sie, dass diese Sequenz oeis.org/A066182 lautet .
Orlp

8

Pyth, 25 Bytes

+hK/*J/h@h*8tQ2 2tJ2%-QKJ

Dies ist die gleiche Sequenz wie bei @ Sp3000, jedoch in geschlossener Form. Die geschlossene Form ist:

M (n) = Etage ((1 + Quadratmeter (1 + 8 * (n - 1))) / 2) B (n) = M (n) * (M (n) - 1) / 2 f (n) = B (n) + ((n - B (n) + 1) mod M (n))


5

Python3, 40 Bytes

n=input();print([n[1:]+n[0],n]['0'in n])

Jede Zahl, die eine 0-Stelle enthält, ist sich selbst zugeordnet. Jede andere Nummer ist der Nummer zugeordnet, deren Ziffern um 1 gedreht sind. Beispiel:

1 -> 1
10 -> 10
15 -> 51 -> 15
104 -> 104
123 -> 231 -> 312 -> 123

1
Déjà vu! Cool, es in zwei Sprachen zu sehen!
Denham Coote

3

Rubin, 22 + 1 = 23

Mit Befehlszeilenflag -pFühren Sie aus

~/(.)(.?)/
$_=$1+$'+$2

Wenn als Eingabe eine Zeichenfolgendarstellung einer Zahl (ohne abschließende Zeilenumbrüche) angegeben wird, wird die erste Ziffer konstant gehalten und der Rest nach links gedreht 1234 wird1342 .

Dies kann mit auf 21 Zeichen reduziert werden $_=$1+$'+$2if/(.)(.)/, gibt aber eine Warnung aus.


3

Rubin, 16 + 1 = 17

-pFühren Sie mit dem Befehlszeilenflag aus

$_=$_[/.0*$/]+$`

Dies ist eine kompliziertere Funktion als meine andere Antwort, ist aber zufälligerweise besser zum Golfen geeignet (und tolerant gegenüber Zeilenumbrüchen). Es wird die letzte Ziffer der Eingabe ungleich Null sowie alle nachfolgenden Nullen verwendet und an den Anfang der Zahl verschoben. So 9010300wird es 3009010. Jede Zahl mit n Ziffern ungleich Null ist Teil eines n-langen Zyklus.

Die Eingabe ist eine Zeichenfolge in einer beliebigen Basis über STDIN, die Ausgabe ist eine Zeichenfolge in dieser Basis.


2

Python, 43

Die Umkehrung der Sp3000-Funktion , rekursiv implementiert.

f=lambda n,k=1:n>k and k+f(n-k,k+1)or n%k+1

Die Funktion ist ein Ein-Zyklus, gefolgt von einem Zwei-Zyklus, gefolgt von einem Drei-Zyklus, ...

(1)(2 3)(4 5 6)(7 8 9 10)(11 12 13 14 15)...

Die Operation n%k+1wirkt wie ein kZyklus auf die Zahlen 1..k. So finden Sie die entsprechenden kGebrauch, Verschiebung alles nach unten durch k=1, dann k=2, und so weiter, bis n<=k.


2

Pyth, 15 Bytes

Die bisher kürzeste Antwort, bei der numerische Operationen anstelle von Zeichenfolgenoperationen verwendet werden.

.|.&Q_=.&_=x/Q2

    Q                input
            /Q2      input div 2
           x   Q     that XOR input
          =          assign that to Q
         _           negate that
       .&       Q    that AND Q
      =              assign that to Q
     _               negate that
  .&                 input AND that
.|               Q   that OR Q

Die Wirkung dieser Funktion auf die Binärdarstellung besteht darin, den äußersten rechten Einsenblock auf die nächste 0 zu erweitern; oder wenn es keine 0 gibt, um es wieder auf eine einzelne 1 zurückzusetzen:

10010110100000 ↦  
10010110110000 ↦  
10010110111000 ↦  
10010110111100 ↦  
10010110111110 ↦  
10010110111111 ↦
10010110100000  

Pyth, 26 Bytes, lustige Variante

.|.&Q_h.&/Q2+Qy=.&/Q2_h.|y

    Q                           input
         /Q2                    input div 2
             Q                  input
                  /Q2           input div 2
                         yQ     twice input
                       .|  Q    that OR input
                     _h         NOT that
                .&              (input div 2) AND that
               =                assign that to Q
              y                 twice that
            +                   input plus that
       .&                       (input div 2) AND that
     _h                         NOT that
  .&                            input AND that
.|                          Q   that OR Q

Führt die obige Operation gleichzeitig mit allen Blöcken von 1 aus, nicht nur mit dem am weitesten rechts stehenden. Dabei werden nur bitweise und arithmetische Operationen verwendet.

1000010001001 ↦
1100011001101 ↦
1110011101001 ↦
1111010001101 ↦
1000011001001 ↦
1100011101101 ↦
1110010001001 ↦
1111011001101 ↦
1000011101001 ↦
1100010001101 ↦
1110011001001 ↦
1111011101101 ↦
1000010001001

1

Schnelle 1.2, 66 Bytes

func a(b:Int){var c=0,t=1,n=b
while n>c{n-=c;t+=c++}
print(n%c+t)}
Input:  1,   2, 3,  4, 5, 6,   7, 8, 9, 10,   11, 12, 13, 14, 15
Output: 1,   3, 2,  5, 6, 4,   8, 9, 10, 7,   12, 13, 14, 15, 11

1

Brachylog , 5 Bytes

∋0&|↺

Probieren Sie es online!

Port von @ orlps Pyth-Antwort. Kommt einfach und ordentlich heraus:

∋0    % If input contains a 0 (since input is a single number, "contains" ∋ treats it as an array 
      %   of its digits, so this means "if any of input's digits are 0")
&     % Then output is the input
|     % Otherwise
↺     % Circularly shift the input once, and unify that with the output

Eigentlich wollte ich die Python-Lösung von @ Sp3000 portieren, aber das hat satte 23 Bytes gekostet :

⟧∋B-₁⟦++₁A≤?;A--₁;B%;A+

Probieren Sie es online!


0

JavaScript (ES6), 43 Byte

f=(n,i=1,j=1)=>n>j?f(n,++i,j+i):n++<j?n:n-i

0

Matlab (189)

  function u=f(n),if(~n|n==1)u=n;else,u=n;y=factor(n);z=y(y~=2);if ~isempty(z),t=y(y~=max(y));if isempty(t),u=y(end)*2^(nnz(y)-1);else,g=max(t);e=primes(g*2);u=n/g*e(find(e==g)+1);end,end,end

  • Die Funktion:

    Ordnet eine beliebige Ganzzahl entsprechend ihren Primfaktoren zu. Wenn die Zahl Null ist oder in 2 oder 1 zerlegt ist, wird die Zahl auf sich selbst abgebildet. Andernfalls wählen wir den größten Primfaktor dieser Zahl aus und erhöhen die verbleibenden unterschiedlichen Primfaktoren um den nächsten größer Primfaktor , bis wir die Zahl erreichen , biggest_prime^nwo nist die Summe aller Exponenten aller Faktoren, wenn wir diesen Betrag erreichen, wenden wir uns an max_prime*2^(n-1)und wir den gleichen Zyklus wieder reproduzieren.


0

Matlab (137)

  function u=h(n),if(~n|n==1)u=n;else,u=n;y=factor(n);z=y(y~=2);if~isempty(z),e=nnz(y);f=nnz(z);if(~mod(e,f)&e-f)u=n/2^(e-f);else,u=u*2;end

  • Ein etwas ähnlicher Ansatz, bei dem nach und nach eine beliebige Zahl ungleich {0,1,2 ^ n} multipliziert wird, 2bis wir auf einen Exponenten 2stoßen, der durch die Summe der Exponenten anderer Primfaktoren teilbar ist. dann bewegen wir uns zum Anfang des Zyklus, der durch geteilt wird 2^(sum of exponents of other primes). Die anderen Zahlen sind auf sich selbst abgebildet.
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.