Neue Bestellung Nr. 6: Osterei

13

Einleitung (kann ignoriert werden)

Es ist ein bisschen langweilig, alle positiven ganzen Zahlen in die reguläre Reihenfolge (1, 2, 3, ...) zu bringen, nicht wahr? Hier ist also eine Reihe von Herausforderungen im Zusammenhang mit Permutationen (Umformungen) aller positiven ganzen Zahlen. Dies ist die sechste Herausforderung in dieser Reihe (Links zur ersten , zweiten , dritten , vierten und fünften Herausforderung).

Diese Herausforderung hat ein mildes Osterthema (weil es Ostern ist). Ich habe mich von diesem hoch dekorierten (und meiner persönlichen Meinung nach eher hässlichen) Gänseei inspirieren lassen.

Gänseei dekoriert

Es erinnerte mich an die Ulam-Spirale , bei der alle positiven ganzen Zahlen in einer Spirale gegen den Uhrzeigersinn angeordnet sind. Diese Spirale hat einige interessante Merkmale im Zusammenhang mit Primzahlen, aber das ist für diese Herausforderung nicht relevant.

Ulam-Spirale

Wir kommen zur Permutation dieser Herausforderung von positiven ganzen Zahlen, wenn wir die Zahlen in der Ulam-Spirale nehmen und alle ganzen Zahlen in einer im Uhrzeigersinn drehenden Spirale ab 1 verfolgen. Auf diese Weise erhalten wir:

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

Wenn Sie beide Spiralen zeichnen würden, würden Sie eine Art unendliches Netz von (Eierschalen-) Spiralen erhalten ( beachten Sie die New Order- Referenz dort ).

Diese Sequenz ist im OEIS unter der Nummer A090861 vorhanden . Da dies eine „reine Sequenz“ Herausforderung ist, die Aufgabe zu Ausgang ist ein(n) für eine gegebene n als Eingabe, wobei ein(n) ist A090861 .

Aufgabe

Bei einem gegebenen ganzzahligen Eingangs n , Ausgabe ein(n) im Ganzzahlformat, wobei ein(n) ist A090861 .

Hinweis: Hier wird eine 1-basierte Indizierung angenommen. Sie können eine 0-basierte Indizierung verwenden, also ein(0)=1;ein(1)=6 usw. Bitte erwähnen Sie dies in Ihrer Antwort, wenn Sie dies verwenden möchten.

Testfälle

Input | Output
---------------
1     |  1
5     |  3
20    |  10
50    |  72
78    |  76
123   |  155
1234  |  1324
3000  |  2996
9999  |  9903
29890 |  29796

Regeln

  • Eingabe und Ausgabe sind Ganzzahlen.
  • Ihr Programm sollte mindestens Eingaben im Bereich von 1 bis 32767 unterstützen.
  • Ungültige Eingaben (0, Gleitkommazahlen, Zeichenfolgen, negative Werte usw.) können zu unvorhergesehenen Ausgaben, Fehlern oder (un) definiertem Verhalten führen.
  • Es gelten die Standard- E / A-Regeln .
  • Standardlücken sind verboten.
  • Das ist , also gewinnt die kürzeste Antwort in Bytes
wie auch immer
quelle

Antworten:

12

Jelly ,  16 14 11 10 9  8 Bytes

-1 dank Lynn (mod-2; logische NICHT; add to self: Ḃ¬+-> bitweise OR mit 1: |1)

|1×r)ẎQi

Ein monadischer Link, der eine Ganzzahl akzeptiert n, die eine Ganzzahl ergibt a(n).

n2

½‘|1×rƲ€ẎQin+12

Wie?

Die Permutation besteht darin, die natürlichen Zahlen in umgekehrten Längenschnitten zu nehmen [1,5,3,11,5,17,7,23,9,29,11,35,13,...]- die ungeraden positiven ganzen Zahlen, durchsetzt mit den positiven ganzen Zahlen, die zu fünf Modulo Sechs kongruent sind, dh [1, 2*3-1, 3, 4*3-1, 5, 6*3-1, 7, 8*3-1, 9, ...].

Dies ist dasselbe wie das Verketten und anschließende Deduplizieren umgekehrter Bereiche [1..x]von wo xist die kumulative Summe dieser Schnittlängen (dh das Maximum jedes Schnitts) - [1,6,9,20,25,42,49,72,81,110,121,156,169,...]das sind die ungeraden Ganzzahlen im Quadrat durchsetzt mit geraden Zahlen multipliziert mit sich selbst inkrementiert, dh [1*1, 2*3, 3*3, 4*5, 5*5, 6*7, 7*7,...].

Da die Differenzen alle größer als 1 sind, können wir ein Byte (die Umkehrung) speichern, indem wir Bereiche [x..k]direkt aufbauen . Dabei khandelt es sich um den 1-indexierten Index des Slices.

P(n)=vP(v)=nn|1×r)ẎQị@n|1×r)ẎQi

|1×r)ẎQi - Link: integer, n       e.g. 10
    )    - for each k in [1..n]:  vs = [ 1, 2, 3, 4, 5, 6, 7, 8, 9,10]
|1       -   bitwise-OR (k) with 1     [ 1, 3, 3, 5, 5, 7, 7, 9, 9,11]
  ×      -   multiply (by k)           [ 1, 6, 9,20,25,42,49,72,81,110]
   r     -   inclusive range (to k)    [[1],[6..2],[9..3],[20..4],...,[110..10]]
     Ẏ   - tighten                     [1,6,5,4,3,2,9,8,7,6,5,4,3,20,...,4,......,110,...,10]
      Q  - de-duplicate                [1,6,5,4,3,2,9,8,7,20,...,10,......,110,...82]
       i - first index with value (n)  20
Jonathan Allan
quelle
2
Sehr schön. Und Sie haben die MATL-Antwort übertroffen!
immer
1
Jetzt gebunden ... :-)
Luis Mendo
@ LuisMendo Ich habe gerade festgestellt, dass ich hier etwas hinterhältiges tun und ein Byte speichern kann :)
Jonathan Allan
1
@ JonathanAllan Aww. Das verdient eine positive Bewertung :-)
Luis Mendo
1
@Lynn Ich aktualisiere gerade auf ein anderes 9-Byte. Dein wird wohl 8 machen!
Jonathan Allan
6

JavaScript (ES7),  46 45  41 Byte

0-indiziert.

n=>((x=n**.5+1&~1)*2-(n<x*x+x)*4+3)*x+1-n

Probieren Sie es online!

Wie?

Dies basiert auf der 1-indizierten Formel, die in den Beispielprogrammen von A090861 verwendet wird .

xn0

xn=n-1+12

Probieren Sie es online!

kn6-2

kn={-2wenn n4xn2+2xn6Andernfalls

Probieren Sie es online!

einn

einn=8xn2+knxn+2-n

Probieren Sie es online!

Welches kann übersetzt werden in:

n=>8*(x=(n-1)**.5+1>>1)*x+(n<=4*x*x+2*x?-2:6)*x+2-n

Wenn Sie den Index auf 0 setzen, werden sofort 5 Bytes gespart:

n=>8*(x=n**.5+1>>1)*x+(n<4*x*x+2*x?-2:6)*x+1-n

Die Formel kann weiter vereinfacht werden durch:

xn=2×n+12

was ausgedrückt werden kann als:

x=n**.5+1&~1

führt zu:

n=>2*(x=n**.5+1&~1)*x+(n<x*x+x?-1:3)*x+1-n

und schlussendlich:

n=>((x=n**.5+1&~1)*2-(n<x*x+x)*4+3)*x+1-n
Arnauld
quelle
3

Python 3.8, 104 74 65 60 57 Bytes

lambda n:(-2,6)[n>4*(x:=(n**.5+1)//2)*x+2*x]*x+2+~n+8*x*x

Edit: Danke an Johnathan Allan für die 74 bis 57 Bytes!

Diese Lösung verwendet eine 0-basierte Indizierung.

Kapocsi
quelle
1
Speichern Sie 39, indem Sie die Importe vermeiden, überflüssige Klammern entfernen und >anstelle von <=und x*xanstelle von x**2... def f(n):x=((n-1)**.5+1)//2;return 8*x**2+(-2,6)[n>4*x*x+2*x]*x+2-n
Jonathan Allan
Genial! Ich werde die Änderungen übernehmen. Ich habe einige Änderungen vorgenommen, bevor ich Ihren Kommentar gesehen und auf 74 Bytes reduziert habe. Ist es wichtig, dass Ihr Floats zurückgibt? Ich nehme nicht an ...
Kapocsi
Float-Darstellungen von Ganzzahlen sollten in Ordnung sein. Sparen Sie mit Python 3.8 etwas mehr ... BEARBEITEN: Indizieren Sie
Jonathan Allan
Sehr cool. Fühlen Sie sich frei, weitere Änderungen direkt vorzunehmen!
Kapocsi
2

Befunge, 67 57 Bytes

Diese Lösung setzt eine 0-basierte Indizierung der Eingabewerte voraus.

p&v-*8p00:+1g00:<
0:<@.-\+1*g00+*<|`
0g6*\`!8*2+00g4^>$:0

Probieren Sie es online!

Erläuterung

Wir beginnen mit der Berechnung des "Radius", bei dem die Eingabe n gefunden wird, mit einer Schleife:

radius = 0
while n > 0
  radius += 1
  n -= radius*8

Am Ende der Schleife ist der vorherige Wert von n der Versatz in die Spirale bei diesem Radius:

offset = n + radius*8

Wir können dann wie folgt feststellen, ob wir uns im oberen oder unteren Bereich der Spirale befinden:

bottom = offset >= radius*6

Und wenn wir alle diese Details haben, wird der Spiralwert berechnet mit:

value = ((bottom?10:2) + 4*radius)*radius + 1 - offset

Der Radius ist der einzige Wert, den wir als "Variable" speichern müssen. Er ist in Befunge-93 auf einen Maximalwert von 127 begrenzt, sodass dieser Algorithmus Eingaben bis zu 65024 verarbeiten kann.

James Holderness
quelle
1

Japt , 15 Bytes

Port of Jonathans Jelly-Lösung. 1-indiziert.

gUòȲ+X*v)õÃcÔâ

Versuch es

gUòȲ+X*v)õÃcÔâ     :Implicit input of integer U
g                   :Index into
 Uò                 :  Range [0,U]
   È                :  Map each X
    ²               :    Square X
     +X*            :    Add X multiplied by
        v           :    1 if X is divisible by 2, 0 otherwise
         )          :    Group result
          õ         :    Range [1,result]
           Ã        :  End map
            c       :  Flatten
             Ô      :    After reversing each
              â     :  Deduplicate
Zottelig
quelle
Ich sagte Jonathan gerade das x+(1-x%2)ist x|1(ein Byte in Jelly zu speichern), die diese Antwort auch profitieren können, ich wette.
Lynn
0

C ++ (gcc) , 88 Bytes

#import<cmath>
int a(int n){int x=(sqrt(n-1)+1)/2;return x*(8*(x+(n>4*x*x+2*x))-2)+2-n;}

1-indiziert; Verwendet die Formel auf der OEIS-Seite, wurde jedoch manipuliert, um einige Bytes zu sparen.

Probieren Sie es online!

Neil A.
quelle
Schlagen Sie sqrt(n-1)/2+.5anstelle von(sqrt(n-1)+1)/2
ceilingcat vor