Schrotflinten-Nummern


45

Die Schrotflinten-Nummern sind eine Sequenz mit einer ziemlich einfachen Definition, aber einer interessanten Struktur. Beginnen Sie mit den natürlichen Zahlen:

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

Nehmen Sie nun alle Zahlen bei durch 2 teilbaren Indizes , gruppieren Sie sie in Paare und tauschen Sie die Zahlen in jedem Paar aus:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ...
   ^     ^     ^     ^      ^       ^       ^  
    <--->       <--->        <----->         <----
1, 4, 3, 2, 5, 8, 7, 6, 9, 12, 11, 10, 13, 16, ...

Machen Sie jetzt dasselbe mit Indizes, die durch 3 teilbar sind :

1, 4, 3, 2, 5, 8, 7, 6, 9, 12, 11, 10, 13, 16, ...
      ^        ^        ^           ^          
       <------>          <--------->           
1, 4, 8, 2, 5, 3, 7, 6, 10, 12, 11, 9, 13, 16, ...

Und dann für 4 , 5 , 6 und so weiter:

1, 4, 8, 2, 5, 3, 7, 6, 10, 12, 11, 9, 13, 16, ...
1, 4, 8, 6, 5, 3, 7, 2, 10, 12, 11, 14, 13, 16, ...
1, 4, 8, 6, 12, 3, 7, 2, 10, 5, 11, 14, 13, 16, ...
1, 4, 8, 6, 12, 14, 7, 2, 10, 5, 11, 3, 13, 16, ...
...

Nach k solchen Schritten werden die ersten k + 1 Zahlen festgelegt. Wir können also die unendliche Folge von Schrotflinten-Zahlen als die Grenze definieren, bis zu der k gegen unendlich gehen darf . Die ersten 66 Zahlen sind:

1, 4, 8, 6, 12, 14, 16, 9, 18, 20, 24, 26, 28, 22, 39, 15, 36, 35, 40, 38, 57, 34, 48, 49, 51, 44,
46, 33, 60, 77, 64, 32, 75, 56, 81, 68, 76, 58, 100, 55, 84, 111, 88, 62, 125, 70, 96, 91, 98, 95,
134, 72, 108, 82, 141, 80, 140, 92, 120, 156, 124, 94, 121, 52, 152, 145, ...

Unterhaltsame Tatsache: Obwohl diese Sequenz nur durch Permutieren der natürlichen Zahlen erhalten wird, enthält sie keine Primzahlen.

Die Herausforderung

Ermitteln Sie bei einer Ganzzahl n > 0die nNummer der Schrotflinte. Sie können ein Programm oder eine Funktion schreiben, Eingaben über STDIN (oder die nächstgelegene Alternative), ein Befehlszeilenargument oder ein Funktionsargument vornehmen und die Ausgabe zurückgeben oder an STDOUT (oder die nächstgelegene Alternative) ausgeben.

Dies ist Codegolf, daher gewinnt die kürzeste Übermittlung (in Bytes).

Bestenlisten

Das gibt mehr Antworten, als ich dachte, und es treten mehrere Personen in derselben Sprache gegeneinander an. Hier ist also ein Stack-Snippet, um sowohl eine reguläre Rangliste als auch eine Übersicht der Gewinner nach Sprache zu generieren.

Um sicherzustellen, dass Ihre Antwort angezeigt wird, beginnen Sie Ihre Antwort mit einer Überschrift. Verwenden Sie dazu die folgende Markdown-Vorlage:

# Language Name, N bytes

Wo Nist die Größe Ihres Beitrags? Wenn Sie Ihren Score zu verbessern, Sie können alte Rechnungen in der Überschrift halten, indem man sich durch das Anschlagen. Zum Beispiel:

# Ruby, <s>104</s> <s>101</s> 96 bytes


1
Diese lustige Tatsache ist verrückt, mischt dieser Algorithmus alle Primzahlen bis zum Ende? Oder gibt es andere natürliche Zahlen, die auch nicht vorkommen werden?
Devon Parsons

1
@ DevonParsons Ja, es mischt alle Primzahlen "bis zum Ende". Aber ich denke, es fehlen auch andere Zahlen. Es sieht aus wie 10, 21, 25und 30erscheint auch nicht, zum Beispiel.
Martin Ender

3
Das klingt nach einer Project Euler-Frage. Ich denke nicht, dass es so ist ... aber vielleicht sollte es so sein.
Corey Ogburn

9
Im Allgemeinen wird bei der kdritten Iteration das kdritte Element im Array in die 2kdritte Position transponiert und erst bei der 2kdritten Iteration wieder berührt , wenn es in die 4kdritte Position unendlich transponiert wird . Ein Prim wird erst transponiert, wenn er sozusagen an der Reihe ist, und alle Primzahlen werden vorwärts gemischt. Aber wir können leicht eine Liste der unschuldigen Opfer erstellen, indem wir einfach das erste Element ausdrucken, das bei Iteration 2 und jeder ungeraden Iteration transponiert werden soll. Die Liste lautet: 2, 3, 5, 7, 10, 11, 13, 21, 17, 19, 30, 23, 27, 25, 29, 31, 45, 42, 37, 54, 41, 43, 65, ...
Théophile

3
@ Sherlock9 Fertig! Wenn es genehmigt wird, lautet es https://oeis.org/A266679 . Frohes neues Jahr!
Théophile

Antworten:


5

Pyth, 19 22

u-G*H^_!%GH/GHrhQ2Q

Eine ziemlich naive Implementierung von @ PeterTaylors Golfscript-Antwort .

Probieren Sie es hier online aus

Dies verwendet die gleichen Tricks, um eine while-Schleife in eine Falte umzuwandeln wie das andere Pyth-Programm unten.


u+G**H!%GHty%/GH2rhQ2Q

Eine naive Kopie des in Pyth übersetzten @ Sp3000- Algorithmus.

Sie können es hier online ausprobieren

Verwendet reduct (Pythons Name für fold), um die while-Schleife zu emulieren. Es zählt über das auf, range(input, 2)was in Pyth klappt range(2, input)[::-1]. Bei den anderen Pyth-bezogenen Golfspielen wird notanstelle von <2und unter Verwendung ydes versteckten Modus der Wertverdopplung von numerischen Argumenten verwendet.


21

> <>, 52 45 Bytes

Esolangs Seite für> <>

i:&&:&1-?vn;
2*1-*+20.>:&:&%1(&:&*{:}&:1-&,2%

Durch die verschiedenen erforderlichen Module und Multiplikationen werden viele Elemente kopiert und verschoben. Die Logik entspricht genau meiner Python-Lösung .

Nimmt Eingang über einen Codepunkt von STDIN, zB "!" = 33 -> 75.


10
Und Sie haben die Auszeichnung für das umständlichste Eingabeformat aller Zeiten erhalten: P
Caridorc

+1 sowieso keine Sorge :)
Caridorc

@ Sp3000 IMO sollte es nur als eins zählen
SuperJedi224 31.12.15

@ SuperJedi224 Eigentlich zählt laut diesem Meta-Post anscheinend -vdrei: /
Sp3000

17

Python 2, 58 Bytes

i=n=input()
while~-i:n+=(n%i<1)*i*(n/i%2*2-1);i-=1
print n

Wie bei den meisten anderen Antworten geht es darum, rückwärts zu arbeiten.


Nennen wir step k+1step i, damit bei step ialle Vielfachen von igetauscht werden. Wir brauchen zwei einfache Beobachtungen:

  • Die Position nim Array wird nur bei Schritt getauscht, iwenn dies ndurch teilbar iist.
  • Sehen Sie sich an, um festzustellen, ob Sie die niedrigere oder die höhere Zahl im Swap sind n/i mod 2. Wenn dies 1 ist, sind Sie die niedrigere Nummer (und werden nach oben tauschen), andernfalls sind Sie die höhere Nummer (und werden nach unten tauschen).

Dies gibt uns einen Algorithmus zum Rückwärtsarbeiten. Versuchen wir es mit 6, beginnend mit dem letzten Schritt (Schritt i = 6):

Step 6: Position 6 swaps with position 12 (6 is divisible by 6, 6/6 = 1 == 1 mod 2)

Jetzt wissen wir also, dass die Nummer von Position 12 kam. Dann:

Step 5: No swap (12 not divisible by 5)
Step 4: Position 12 swaps with position 16 (12 is divisible by 4, 12/4 = 3 == 1 mod 2)

Jetzt wissen wir also, dass es von 16 vorher gekommen ist. Endlich:

Step 3: No swap (16 not divisible by 3)
Step 2: Position 16 swaps with position 14 (16 divisible by 2, 16/2 = 8 == 0 mod 2)

Da dies der erste Schritt ist (denken Sie daran, k+1), sind wir fertig und die Nummer, die auf Position 6 landet, stammt ursprünglich von Position 14, dh die 6. Schrotflintennummer ist 14.

Nun zur Python-Erklärung:

i=n=input()             Read input, and store into i (step) and n (position)
while~-i:               while i-1 != 0:, or since we're descending with i this is just while i>1:
  n+=                   Add to the current position...
    (n%i<1)*            1* whatever's next if n is divisible by i, otherwise 0* (i.e. nothing)
    i*                  How many positions n might go up/down
    (n/i%2*2-1)         n/i%2 tell us higher/lower, *2-1 maps 0 or 1 to -1 (down) or +1 (up)
  i-=1                  Decrement the step number
print n                 Output

interessante Art zu schreiben i-1als~-i
mbomb007

6
@ mbomb007: Einverstanden. Clever, da es die gleiche Bedeutung hat, jedoch keinen Platz mehr benötigt while. Gute Arbeit, Sp3000.
Alex A.

Das Kürzeste, was ich in u+G**H!%GHty%/GH2rhQ2Q
Pyth

1
@FryAmTheEggman, Sp3000, wird keiner von euch das posten?
Martin Ender

@ MartinBüttner Ich habe es ursprünglich nicht gepostet, da ich der Meinung war, dass es sich um eine zu große Kopie handelt. Ich werde es vorerst als CW-Antwort posten.
FryAmTheEggman

6

Haskell, 68 Bytes

n#k|mod k(2*n)<1=k-n|mod k n<1=k+n|k>0=k
s n=foldr((.).(#))id[2..n]n

Wahrscheinlich weiter golfbar, vor allem die erste Reihe. Dies definiert eine Funktion s, die ndie nNummer der Schrotflinte annimmt und zurückgibt .

map s [1..66]
[1,4,8,6,12,14,16,9,18,20,24,26,28,22,39,15,36,35,40,38,57,34,48,49,51,44,46,33,60,77,64,32,75,56,81,68,76,58,100,55,84,111,88,62,125,70,96,91,98,95,134,72,108,82,141,80,140,92,120,156,124,94,121,52,152,145]

Erläuterung

Die Hilfsfunktion #nimmt zwei Zahlen nund auf kund gibt die kth-Zahl in der Liste zurück, die durch Anwenden der Paartauschoperation auf jede nth-Zahl definiert wird. Wenn Sie es beispielsweise auf die ersten 20 Zahlen anwenden, erhalten Sie n = 4Folgendes:

map (4#) [1..20]
[1,2,3,8,5,6,7,4,9,10,11,16,13,14,15,12,17,18,19,24]

Das Ergebnis von s nwird durch Reduzieren ("Falten") der Liste [2..n]durch die Funktion zweiter Ordnung erhalten (.).(#), die eine Zahl mund eine Funktion f(anfangs die Identitätsfunktion id) aufnimmt kund eine Funktion zurückgibt, die nimmt und zurückgibt f (m # k). In diesem Fall wird n = 4die Liste [2,3,4]beispielsweise auf eine Funktion reduziert, die dauert kund zurückgibt id (4 # (3 # (2 # k))). Das idwird nur für den Basisfall benötigt n = 1, bei dem die Liste leer ist. Schließlich geben wir dieser Funktion die Eingabe k = nund erhalten die nNummer der Schrotflinte.


6

CJam, 32 Bytes

Folgen Sie einfach der Spezifikation auf den Punkt. Ausführen der Anweisungen auf einem größeren Satz, um die n- te Zahl nicht zu beeinflussen .

ri:N)2#,:)N{))/2/{:)~\@}%:+}/N(=

Probieren Sie es hier online aus


5

Ruby, 92 Bytes

def s(d,n)
d==1?n:s(d-1,n%d==0?n+(n%(d*2)==0?-d :d):n)
end
n=ARGV[0].to_i
print s(n,n).to_s

Meine erste Code Golf Anstrengung. Keine andere Antwort.


Nun, da ich mir einige der anderen angeschaut habe, stelle ich fest, dass die meisten nur eine Funktion definieren, kein vollständiges Programm, das Eingaben akzeptiert und Ausgaben erzeugt. Das OP forderte ein vollständiges Programm mit Ein- und Ausgängen. Ist es üblich, solche Anforderungen zu ignorieren?


84 Bytes

n=ARGV[0].to_i
d=n
while d>1
n+=(n%d==0?(n%(d*2)==0?-d :d):0)
d-=1
end
print n.to_s

Nachdem Sie sich andere Antworten angesehen und erkannt haben, dass eine iterative Lösung möglich ist.


2
Einige Verbesserungen für Ihre 84-Byte-Lösung: 1. Wechseln Sie ARGVzum $*Magic Global. 2. Das to_sist unnötig. 3. Anstatt din neiner separaten Zeile d=n=...zuzuweisen, müssen Sie nur einen Buchstaben abschneiden. Gute Arbeit für dein erstes Golfspiel! :)
Türklinke

1
Wo bitte ich um ein komplettes Programm? "Sie können ein Programm oder eine Funktion schreiben ...";) (Dies ist auch die Standardeinstellung für Code-Golf- Herausforderungen, aber der Vollständigkeit
Martin Ender

Um die Vorschläge von @ Doorknob zu ergänzen, sind zwei Sätze von Klammern in der n+=Zeile nicht erforderlich, und beide Vorkommen von ==0können sicher in geändert werden <1.
Peter Taylor

5

Python 2, 97 79 Zeichen

g=lambda n,k:n>1and g(n-1,k-(k%n<1)*n*(-1)**(k/n%2))or k
n=input()
print g(n,n)

Sie ermittelt für jeden Index den richtigen Wert, indem sie die Zahl rekursiv rückwärts jagt. Der Algorithmus wurde eigenständig entdeckt.

edit: Jetzt wird nur noch die nth Nummer anstatt der ersten nNummern gedruckt . Ein iterativer Ansatz wäre natürlich kürzer, aber ich möchte den Code von Sp3000 nicht kopieren.


Ja, ich denke, jeder wird sich dem annähern. Ich fand das g(i,i)Teil allerdings besonders ärgerlich ...
Sp3000

2
Die Sprache sollte aufgrund der printAnweisung als Python 2 markiert werden .
mbomb007

@ mbomb007 Es wurde korrigiert.
Jakube,

4

Haskell, 79 Bytes

1#i=i
s#i|i`mod`(2*s)==0=(s-1)#(i-s)|i`mod`s==0=(s-1)#(i+s)|1<2=(s-1)#i
p n=n#n

Verwendung: p 66welche Ausgänge145

Nicht viel zu erklären: Die Funktion #berechnet rekursiv die Schrotflintenanzahl an ider Schrittposition s. p nGibt die Nummer an der Position nvon step zurück n.


Oh, ich habe Ihre Antwort nicht gesehen, bevor ich meine eingereicht habe. Scheint, als hätten wir ganz andere Ansätze.
Zgarb

4

k, 41 Bytes

{{x+$[y!x;0;$[2!_x%y;y;-y]]}/[x;|2+!x-1]}

 / apply to an int
 {{x+$[y!x;0;$[2!_x%y;y;-y]]}/[x;|2+!x-1]} 42
111
 / apply to 1 through 66
 {{x+$[y!x;0;$[2!_x%y;y;-y]]}/[x;|2+!x-1]}'1+!66
1 4 8 6 12 14 16 9 18 20 24 26 28 22 39 15 36 35 40 38 57 34 48 49 51 44 46 33 60 77 64 32 75 56 81 68 76 58 100 55 84 111 88 62 125 70 96 91 98 95 134 72 108 82 141 80 140 92 120 156 124 94 121 52 152 145
  • {...} Lambda, x und y sind das implizite 1. und 2. Argument
  • $[b;t;f] ternärer Operator, bewertet b, gefolgt von t / f
  • b!a ein Modulo b
  • _ Boden, wirft das Ergebnis der Teilung zu einem int
  • % Einteilung
  • {...}/[x;y] {...} mit x beginnen und über die Liste y anwenden, entspricht f [f [.. f [f [x; y0]; y1]; .. yn-1]; yn]
  • | umkehren
  • ! iota-Funktion, generiere Liste 0 bis n-1

4

Common Lisp, 113 91

(iterativ: 91)

(defun s(n)(do((r n(1- r)))((= r 1)n)(if(= 0(mod n r))(incf n(* r(if(oddp(/ n r))1 -1))))))

(original, rekursiv: 113)

(defun s(n &optional(r n))(cond((= r 1)n)((= 0(mod n r))(s(+ n(* r(if(oddp(/ n r))1 -1)))(1- r)))(t(s n(1- r)))))

Beispiel

Mit der rekursiven Version:

(trace s)
(s 10)

  0: (S 10)
    1: (S 20 9)
      2: (S 20 8)
        3: (S 20 7)
          4: (S 20 6)
            5: (S 20 5)
              6: (S 15 4)
                7: (S 15 3)
                  8: (S 18 2)
                    9: (S 20 1)
                    9: S returned 20
         ...
    1: S returned 20
  0: S returned 20

Tests

Überprüft und misst die iterative Version:

(let ((list '(1 4 8 6 12 14 16 9 18 20 24 26 28 22 39 15 36 35 40 38 57 34 48 49 51 44
              46 33 60 77 64 32 75 56 81 68 76 58 100 55 84 111 88 62 125 70 96 91 98 95
              134 72 108 82 141 80 140 92 120 156 124 94 121 52 152 145)))
  (time
   (loop for r in list
         for n from 1
         always (= r (s n)))))

 => T

Evaluation took:
  0.000 seconds of real time
  0.000000 seconds of total run time (0.000000 user, 0.000000 system)
  100.00% CPU
  807,160 processor cycles
  32,768 bytes consed

4

Mathematica, 53 49 Bytes

(For[i=n=#,n>1,--n,If[n∣i,i+=Mod[i,2n]2-n]];i)&

Ich entschied mich für meine Referenzimplementierung. Das ist das Unicode-Symbol für "Divides" und zählt für 3 Bytes. Andernfalls wird derselbe Algorithmus wie für alle anderen verwendet.

Es definiert eine unbenannte Funktion, die neinen einzelnen Parameter annimmt und die nNummer der Schrotflinte zurückgibt .


4

GolfScript, 27 Zeichen

~.,(~%{):i\.@%!~)1$i/?i*-}/

Erläuterung

Wenn f(i, n)ist der Wert an der Position nnach i-1Transformationen, haben wir

f(1, n) = n
f(i, n) = f(i - 1, n % i == 0 ? (((n / i - 1) ^ 1) + 1) * i : n)  for i > 1

wo ^bezeichnet bitweises xor; gegebene Eingabe nwollen wir berechnen f(n, n).

Die Konvertierung von einer rekursiven Funktion in eine Schleife ist uninteressant. Interessant ist die Art und Weise, in der

n % i == 0 ? (((n / i - 1) ^ 1) + 1) * i : n

kann umgeschrieben werden. Der naheliegendere Ansatz ist zu sagen, dass es sein muss

n + (n % i == 0 ? i : 0) * g(n / i)

für manche g. Offensichtlich gwechselt zwischen 1und -1, während die Positionen abwechselnd auf und ab wechseln; da g(1) = 1(weil 1tauscht 2) haben wir

n + (n % i == 0 ? i : 0) * -1**(1 + n / i)

wo **Exponentiation bezeichnet. Die endgültigen Einsparungen ergeben sich aus der Umschreibung als

n - i * (n % i == 0 ? -1 : 0)**(n / i)

Präparation

~             # Evaluate input to get n
.,(~%{        # For n-1 downto 1...
  ):i         #   Let i be that value + 1, so for i = n downto 2...
  \.@%!       #   Find n % i == 0 ? 1 : 0
  ~)          #   Negate
  1$i/?       #   Raise to the power of n/i
  i*-         #   Multiply by i and subtract
}/

Wenn Sie die kürzesten GS- und CJam-Antworten haben, warum nicht auch die kürzeste Pyth-Antwort? u-G*H^_!%GH/GHrhQ2QWenn Sie dies nicht selbst posten möchten, teilen Sie es mir mit / fügen Sie es der CW-Antwort hinzu.
FryAmTheEggman

@FryAmTheEggman, ich bin vielleicht nicht sehr geübt bei CJam, aber ich kann es zumindest mehr oder weniger lesen. Ich habe keine Ahnung, was der Pyth in Ihrem Kommentar sagt, obwohl ich aus dem Kontext annehme, dass es eine Portierung dieser Antwort ist. Am besten postest du es, weil du Fragen dazu beantworten kannst.
Peter Taylor


4

Julia, 61 57 Bytes

n->(i=n;while~-i!=0 n+=(n%i<1)*i*(n÷i%2*2-1);i-=1;end;n)

Dadurch wird eine unbenannte Funktion erstellt, die ein einzelnes Argument verwendet nund die nNummer der Schrotflinte zurückgibt . Um es zu nennen, geben Sie ihm einen Namen, z f=n->(...).

Beispiele:

julia> for i = 1:10 println(f(i)) end
1
4
8
6
12
14
16
9
18
20

Derzeit basiert dies auf der großartigen Python-Antwort von @ Sp3000 . Ich werde das bald wiederholen, denn es muss einen kürzeren Weg geben, dies in Julia zu tun als das, was ich hier getan habe. Jede Eingabe ist wie immer willkommen.



3

CJam, 28 27 Byte

Das ist also etwas peinlich ... bevor ich das gepostet habe, habe ich es selbst versucht und bin in CJam auf 30 Bytes gekommen. Keine der vorhandenen Antworten hat das bisher geschlagen. In der Zwischenzeit habe ich auch noch drei Bytes gespart. Es gibt eine kürzere Pyth-Lösung in einem Kommentar, aber in einer Antwort wurde nichts Kürzeres gepostet. Vielleicht inspiriert es die APL / J-Leute, sich etwas mehr anzustrengen (oder jemand, der die Pyth-Lösung tatsächlich veröffentlicht), bevor ich meine eigene Antwort akzeptieren muss. ;)

l~__(,f-{_I_+%_+I-_zI=*+}fI

Teste es hier.

Erläuterung

l~                          "Read input N and eval.";
  __(,                      "Duplicate twice, create range [0 1 2 ... N-2].";
      f-                    "Subtract each from N, giving [N N-1 N-2 ... 2].";
        {               }fI "For each element, storing the element in I.";
         _I_+%_+I-          "Compute 2(N % 2I)-I - the shuffling offset";
                  _zI=      "Check that this offset is ±I.";
                      *+    "Multiply the offset by this boolean and update to N.";

3

J, 34 32 Bytes

   (]+[*(1-~2*2|%~)*0=|)/@(_1}2+i.)

   ((]+[*(1-~2*2|%~)*0=|)/@(_1}2+i.)) every 1+i.20  NB. running with inputs 1..20
1 4 8 6 12 14 16 9 18 20 24 26 28 22 39 15 36 35 40 38

Ich werde versuchen, ein bisschen mehr Golf zu spielen und später eine Erklärung hinzufügen.

Probieren Sie es hier online aus.



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.