Generieren Sie ein ganzzahliges Paar aus einem nicht negativen


25

Sie sollten ein Programm oder eine Funktion schreiben, die eine nicht negative Ganzzahl Nals Eingabe und Ausgabe verwendet oder zwei Ganzzahlen (negativ, null oder positiv) Xund zurückgibt Y.

Ganzzahlen sind im mathematischen Sinne gemeint, da es unendlich viele davon gibt.

Die implementierte Funktion muss bijektiv sein . Dies bedeutet, dass für jedes Nein anderes X YPaar X Yausgegeben werden muss und jedes Paar für eine Eingabe ausgegeben werden sollte, dh für einige sollten Nalle folgenden Paare ausgegeben werden N:

                 ...
    ┌─────┬─────┬────┬────┬────┐
    │-2 -2│-2 -1│-2 0│-2 1│-2 2│
    ├─────┼─────┼────┼────┼────┤
    │-1 -2│-1 -1│-1 0│-1 1│-1 2│
    ├─────┼─────┼────┼────┼────┤
... │0 -2 │0 -1 │0 0 │0 1 │0 2 │ ...
    ├─────┼─────┼────┼────┼────┤
    │1 -2 │1 -1 │1 0 │1 1 │1 2 │
    ├─────┼─────┼────┼────┼────┤
    │2 -2 │2 -1 │2 0 │2 1 │2 2 │
    └─────┴─────┴────┴────┴────┘
                 ...

Beachten Sie, dass U Vund V Uverschiedene Paare sind, wenn U!=V.

Einzelheiten

  • Wenn Ihre Sprache keine willkürlich großen Ganzzahlen unterstützt, ist dies in Ordnung, aber Ihr Algorithmus sollte mit einem willkürlich großen Ganzzahldatentyp arbeiten. Ihr Code sollte mindestens noch Eingabewerte unterstützen 2^31-1.
  • Wenn Sie die Ausgabe als Zeichenfolge drucken oder zurückgeben möchten, sind keine führenden Zeichen 0oder +Zeichen zulässig. Andernfalls ist die standardmäßige Ganzzahldarstellung Ihrer Sprache in Ordnung.

Beispiel

Wenn die Aufgabe darin bestehen würde, eine bijektive Funktion zu erstellen, die eine nicht negative Ganzzahl verwendet Nund eine Ganzzahl ausgibt, Xkönnte eine Lösung die Funktion sein

if (input mod 2 == 0) return N/2 else return -(N+1)/2,

in einer Sprache implementiert. Diese Funktion gibt X = 0 -1 1 -2 2...für zurück N = 0 1 2 3 4....


Kann eine der Ganzzahlen in der Ausgabe für verschiedene Eingaben wiederholt werden? zB 10=>11 12, 9=>10 11ist das ungültig, weil 11 wiederholt wird?
BrainSteel

1
Soweit "Bijektiv" definiert ist, ist "11 12" nicht dasselbe wie "10 11" und daher gültig. Dies liegt daran, dass eine bijektive Funktion als eine Funktion definiert ist, bei der jedes Element einer Menge mit genau einem Element der anderen Menge gepaart ist und jedes Element der anderen Menge mit genau einem Element der ersten Menge gepaart ist ungepaarte Elemente. "( en.wikipedia.org/wiki/Bijection ). Wenn Sie Ihre Funktion umkehren, sollte "11 12" 10 und "10 11" 9 ausgeben.
GiantTree

@BrainSteel Ihr Beispiel ist gültig. Nur die (geordneten) Paare können nicht wiederholt werden. GiantTree ist richtig. Der Frage wurde eine Erklärung hinzugefügt.
Randomra

Muss es eine Bijektion innerhalb des Integer-Bereichs der angegebenen Sprache sein oder sollte es für alle Integer funktionieren?
Fehler

1
@LegionMammal hatte eine gute mathematische Beschreibung der Aufgabe: "Sie müssen eine bijektive Funktion definieren $ f: N + → Z ^ 2 $. - LegionMammal978." dass ich denke, wäre irgendwo in der Aussage von Vorteil
Brian J

Antworten:


15

Pyth, 15

u,-HyeGhGjQ2,ZZ

Probieren Sie es online aus.

u             reduce
                lambda G,H:    [implicit]
  ,-HyeGhG         (H-2*G[-1],G[0])
  jQ2           base(input(),2)
  ,ZZ           (0,0)
              print result     [implicit]

Eine Python-Übersetzung:

g=lambda Z,n:(n-2*Z[1],Z[0])
print reduce(g,binlist(input()),(0,0))

oder iterativ:

(x,y)=(0,0)
for b in binlist(input()):
    (x,y)=(b-2*y,x)
print (x,y)

wo binlistkonvertiert eine Zahl in eine Liste von Ziffern wie binlist(4) = [1,0,0].

Wie funktioniert das? Die Binärziffern der Zahl wie in meiner Python-Lösung als zwei verschachtelte Zahlen im Basisnegativ zwei interpretiert .n

Die Binärzahl entspricht dem Paar ( x , y ) = ( b 0 - 2 b 2 + 4 b 4 - 8 b 6 + , b 1 - 2 b 3 + 4 b 5 - 8 b 7 + )

n=b5b4b3b2b1b0
(x,y)=(b0-2b2+4b4-8b6+,b1-2b3+4b5-8b7+).

Wenn wir die letzte Ziffer von n noch nicht verarbeitet hätten , wären alle Indizes um $ 1 $ höher, n = b 5 b 4 b 3 b 2 b 1 entsprechend dem Paar ( x , y ) = ( b 1 - 2 b 3 + 4 b 5 - 8 b 7 + , b 2 - 2 b 4b0n

n=b5b4b3b2b1
(x,y)=(b12b3+4b58b7+,b22b4+4b68b8+).

Wir können dann die neuen Werte ausdrücken, sobald in Bezug auf die alten Werte gelesen wurdeb0

(x,y)=(b0-2y,x).

(x,y)(b-2y,x)bn(x,y)


Beachten Sie, dass die MathJax-Unterstützung deaktiviert wurde. Möglicherweise möchten Sie Ihre Erklärung aus Gründen der Lesbarkeit bearbeiten.
Alex A.

32

CJam, 24 22 21 Bytes

Mein Gehirn hat Probleme, die Mathematik zu verstehen, die andere Lösungen verwenden. Aber mein Gehirn versteht definitiv binär, also hier eine Lösung, die auf Bit-Manipulation basiert!

li4b2fmd2/z{)(\2b^}%p

Probieren Sie es online aus.

Erläuterung

Dieser Ansatz behandelt die Eingabe als zwei verschachtelte Binärwerte, einen für jede Ausgangsnummer. Alle außer dem niedrigstwertigen Bit von jedem codieren eine Größe, und das niedrigstwertige Bit signalisiert, ob das bitweise Komplement dieser Größe genommen werden soll oder nicht. Bei dieser Implementierung entsprechen die ungeradzahlig positionierten Bits der ersten Ausgangsnummer (und die geradzahlig positionierten Bits der zweiten) und einem LSB von 0Signalen, um das Komplement zu erhalten.

Zum Beispiel kann eine Eingabe von bestimmten 73, uninterleaving ihrer Binärdarstellung 1001001berzeugt 0 1|0(ungerade positionierte Bits) und 1 0 0|1(selbst positionierten Bits). Der erste Wert hat eine Größe von 01b = 1und sollte für einen Endwert von ergänzt werden ~1 = -2, und der zweite Wert hat eine Größe von 100b = 4und sollte nicht ergänzt werden.

Informeller Nachweis der Richtigkeit

Ich habe ein Testprogramm erstellt, das jede Eingabe von Null bis zu einer benutzerdefinierten Zahl minus Eins an der Ausgabestelle in einem 2D-Raster platziert. Sie können es auch online ausprobieren . Hier ist eine Ausgabe dieses Programms, die zeigt, wie der Algorithmus abbildet 0-99:

      -8 -7 -6 -5 -4 -3 -2 -1  0  1  2  3  4  5  6  7  8

-8                      92 84 86 94                     
-7                      88 80 82 90                     
-6                      76 68 70 78                     
-5                   96 72 64 66 74 98                  
-4                60 52 28 20 22 30 54 62               
-3                56 48 24 16 18 26 50 58               
-2                44 36 12  4  6 14 38 46               
-1                40 32  8  0  2 10 34 42               
 0                41 33  9  1  3 11 35 43               
 1                45 37 13  5  7 15 39 47               
 2                57 49 25 17 19 27 51 59               
 3                61 53 29 21 23 31 55 63               
 4                   97 73 65 67 75 99                  
 5                      77 69 71 79                     
 6                      89 81 83 91                     
 7                      93 85 87 95                     
 8                                                      

Das Füllmuster sieht etwas seltsam aus, ist aber tatsächlich bijektiv! Mit jeder 4er-Potenz füllt es ein Quadrat mit der doppelten vorherigen Seitenlänge. So ordnet der Algorithmus beispielsweise zu 0-15:

      -2 -1  0  1  2

-2    12  4  6 14   
-1     8  0  2 10   
 0     9  1  3 11   
 1    13  5  7 15   
 2                  

Dies macht das 4x4-Quadrat in der Mitte des 8x8-Quadrats aus 0-63:

      -4 -3 -2 -1  0  1  2  3  4

-4    60 52 28 20 22 30 54 62   
-3    56 48 24 16 18 26 50 58   
-2    44 36 12  4  6 14 38 46   
-1    40 32  8  0  2 10 34 42   
 0    41 33  9  1  3 11 35 43   
 1    45 37 13  5  7 15 39 47   
 2    57 49 25 17 19 27 51 59   
 3    61 53 29 21 23 31 55 63   
 4                              

Was macht das 8x8-Quadrat in der Mitte des 16x16-Quadrats aus 0-255:

         -8  -7  -6  -5  -4  -3  -2  -1   0   1   2   3   4   5   6   7   8

 -8     252 244 220 212 124 116  92  84  86  94 118 126 214 222 246 254    
 -7     248 240 216 208 120 112  88  80  82  90 114 122 210 218 242 250    
 -6     236 228 204 196 108 100  76  68  70  78 102 110 198 206 230 238    
 -5     232 224 200 192 104  96  72  64  66  74  98 106 194 202 226 234    
 -4     188 180 156 148  60  52  28  20  22  30  54  62 150 158 182 190    
 -3     184 176 152 144  56  48  24  16  18  26  50  58 146 154 178 186    
 -2     172 164 140 132  44  36  12   4   6  14  38  46 134 142 166 174    
 -1     168 160 136 128  40  32   8   0   2  10  34  42 130 138 162 170    
  0     169 161 137 129  41  33   9   1   3  11  35  43 131 139 163 171    
  1     173 165 141 133  45  37  13   5   7  15  39  47 135 143 167 175    
  2     185 177 153 145  57  49  25  17  19  27  51  59 147 155 179 187    
  3     189 181 157 149  61  53  29  21  23  31  55  63 151 159 183 191    
  4     233 225 201 193 105  97  73  65  67  75  99 107 195 203 227 235    
  5     237 229 205 197 109 101  77  69  71  79 103 111 199 207 231 239    
  6     249 241 217 209 121 113  89  81  83  91 115 123 211 219 243 251    
  7     253 245 221 213 125 117  93  85  87  95 119 127 215 223 247 255    
  8                                                                        

3
Sehr schlau! Sie können zwei Bytes speichern, indem Sie li4b2fmd2/anstelle von verwenden 0li2b+W%2/W%. Dies ergibt die gleichen ganzen Zahlen, jedoch in umgekehrter Reihenfolge.
Dennis

@Dennis Das ist auch sehr schlau. Ich habe die Antwort aktualisiert, um diesen Trick anzuwenden. Vielen Dank!
Runer112

12

Python 2, 49

Bearbeiten: Verbessert auf 49 durch Verwendung einer besseren Ein-Schritt-Rekursion für Basis -2.

def f(n):x,y=n and f(n/2)or(0,0);return n%2-2*y,x

Hier ist eine Pyth-Version mit reduce.

Edit: Verbessert auf 52 durch Umschalten auf Basis -2 vom ausgeglichenen Ternär .

Python 2, 52

h=lambda n:n and n%2-2*h(n/4)
lambda n:(h(n),h(n/2))

Python 2, 54

h=lambda n:n and-~n%3-1+3*h(n/9)
lambda n:(h(n),h(n/3))

Hierbei wird wie bei Runer112 eine Ziffernverschachtelung verwendet , jedoch mit ausgeglichener ternärer und nicht signierter Binärdatei. In Python ist keine Basiskonvertierung integriert, sodass der Code diese rekursiv implementiert.

Die Hilfsfunktion h(mit 3anstelle von 9) nimmt eine natürliche Zahl und wandelt sie mit den Stellensubstitutionen von ternär in ausgeglichenes ternär um

0 -> 0 
1 -> +1
2 -> -1

So wird beispielsweise 19, dessen Basis 201 ist, zu (-1) (0) (+ 1) im ausgeglichenen Ternär, was (-1) * 3 ^ 2 + (0) * 3 ^ 1 + (+) ist 1) * 3 ^ 0 = -8.

Ausgeglichenes Ternär genügt, um jede ganze Zahl zu codieren, und gibt so eine Abbildung von natürlichen Zahlen auf ganze Zahlen.

Um Paare von ganzen Zahlen abzubilden, verschachteln wir die Ziffern in n. Zu diesem Zweck betrachten wir hjede andere Ziffer n/9als rekursiven Schritt und nicht als n/3. Dann verschieben wir uns für eine Koordinate ndurch Teilen des Bodens durch 3.

Hier sind die ersten 81 Ausgänge, die den Bereich [-4,4] ^ 2 abdecken.

0 (0, 0)
1 (1, 0)
2 (-1, 0)
3 (0, 1)
4 (1, 1)
5 (-1, 1)
6 (0, -1)
7 (1, -1)
8 (-1, -1)
9 (3, 0)
10 (4, 0)
11 (2, 0)
12 (3, 1)
13 (4, 1)
14 (2, 1)
15 (3, -1)
16 (4, -1)
17 (2, -1)
18 (-3, 0)
19 (-2, 0)
20 (-4, 0)
21 (-3, 1)
22 (-2, 1)
23 (-4, 1)
24 (-3, -1)
25 (-2, -1)
26 (-4, -1)
27 (0, 3)
28 (1, 3)
29 (-1, 3)
30 (0, 4)
31 (1, 4)
32 (-1, 4)
33 (0, 2)
34 (1, 2)
35 (-1, 2)
36 (3, 3)
37 (4, 3)
38 (2, 3)
39 (3, 4)
40 (4, 4)
41 (2, 4)
42 (3, 2)
43 (4, 2)
44 (2, 2)
45 (-3, 3)
46 (-2, 3)
47 (-4, 3)
48 (-3, 4)
49 (-2, 4)
50 (-4, 4)
51 (-3, 2)
52 (-2, 2)
53 (-4, 2)
54 (0, -3)
55 (1, -3)
56 (-1, -3)
57 (0, -2)
58 (1, -2)
59 (-1, -2)
60 (0, -4)
61 (1, -4)
62 (-1, -4)
63 (3, -3)
64 (4, -3)
65 (2, -3)
66 (3, -2)
67 (4, -2)
68 (2, -2)
69 (3, -4)
70 (4, -4)
71 (2, -4)
72 (-3, -3)
73 (-2, -3)
74 (-4, -3)
75 (-3, -2)
76 (-2, -2)
77 (-4, -2)
78 (-3, -4)
79 (-2, -4)
80 (-4, -4)

Eine alternative Codierung mit Viertel-Imaginär fiel länger aus, obwohl sie sehr hübsch ist.

Python 2, 63

h=lambda n:n and n%4+2j*h(n/4)
lambda n:(h(n).real,h(n).imag/2)

In einer Sprache mit weniger umständlichem Umgang mit komplexen Konvertierungen wäre dies wahrscheinlich ein besserer Ansatz. Wenn wir komplexe Zahlen ausgeben könnten, könnten wir Folgendes tun:

Python 2, 38

f=lambda n:n and n%2+n/2%2*1j-2*f(n/4)

1
Ihre ursprüngliche Basis-2-Funktion würde eine mittlere Pyth-Antwort ergeben. L&b-%b2*2y/b4,yQy/Q2ist nur 20 Bytes lang.
Dennis

4
@ Tennis Ich habe gerade eine 15-Zeichen-Pyth-Lösung geschrieben.
XNOR

Ausgeglichenes Ternär und Viertel-Imaginär. Zwei meiner Lieblingsbasen. Gefolgt nur von Base-e.
Brian Minton

11

Python 2, 98 Bytes

Beginnen wir mit einem einfachen Ansatz:

def f(N):
 x=a=0;b=2
 while N:x+=1j**b;b+=a<1;a=a or b/2;N-=1;a-=1
 return int(x.real),int(x.imag)

Es bildet einfach eine rechteckige NSpiraleinheit, die vom Ursprung ausgehend in einem 2D-Raster lang ist, und gibt die Koordinaten des letzten Punkts zurück.

Die Funktion ist bijektiv, da:

  • Jeder Punkt kann mit einer ausreichend langen Spirale abgedeckt werden
  • Jeder Punkt wird nur einmal von der Spirale geschnitten

Die Spirale sieht ungefähr so ​​aus (außer bei 0 anstatt 1 zu beginnen):

Ulam-Spirale


@AlexA. 0**0 == 1In Python ist es also genau das Gleiche wieif a == 0: a = b/2
grc

Cool, danke fürs Erklären.
Alex A.

@AlexA. stellt sich heraus, a=a or b/2ist kürzer
grc

@grc 0^0=1in Mathe, nicht nur Python.
Daenyth

1
@ Daenyth 0**0ist eigentlich unbestimmte Form in Mathematik
Sp3000

8

dc, 49

[1+2~2*1-*n]sm?dsa8*1+v1-2/dd1+*2/lar-dlmx32P-lmx

Dies beginnt damit, dass die nicht negativen ganzen Zahlen in einem Raster angeordnet werden:

..| 
4 | 14
3 |  9 13
2 |  5  8 12
1 |  2  4  7 11
0 |  0  1  3  6 10
Y +-----------------
  X  0  1  2  3  4 ...

Beachten Sie, dass die Gitterpositionen mit zunehmendem N diagonal gefüllt werden. Beachten Sie, dass die Linie Y = 0 die dreieckige Zahlenfolge enthält, die durch gegeben ist N = X(X+1)/2. Dies ist eine quadratische Gleichung, die unter Verwendung der normalen Formel unter Verwendung nur der + ve-Wurzel gelöst wird, so dass wir X aus N bestimmen können, wenn Y = 0 ist. Als nächstes folgt ein einfaches arithmetisches Mischen, um für jedes N ein eindeutiges {X, Y} zu erhalten.

Dies liefert die erforderliche bijektive Qualität, aber X und Y sind nur nicht negativ, aber die Frage erfordert alle möglichen ganzen Zahlen. Also werden X und Y mit gemappt ((t+1)/2)*((t+1)~2*2-1), um alle möglichen ganzen Zahlen zu erhalten.

dchat eine willkürliche Genauigkeit, daher ist der Eingabebereich bis 2^31-1kein Problem. Beachten Sie auch, dass die Standardgenauigkeit 0 Dezimalstellen beträgt und das sqrt()und die /Abrundung das Verhalten ist, das hier benötigt wird.

Ausgabe:

$ for i in {0..10}; do dc biject.dc <<< $i; echo; done
0 0
0 -1
-1 0
0 1
-1 -1
1 0
0 -2
-1 1
1 -1
-2 0
0 2
$

5

Matlab, 54 Bytes

n=input('')+1;[i,j]=find(spiral(2*n)==n);disp([i,j]-n)

Der Schlüssel hierbei ist spiral, dass dadurch eine Spiralmatrix beliebiger Größe erzeugt wird.

spiral(3)

kehrt zurück

ans =

 7     8     9
 6     1     2
 5     4     3

In Matlab, das funktioniert für ganze Zahlen, aber Sie werden Speicherprobleme Art und Weise vor , dass bekommen, (na ja, ich nehme an, dass Sie als der Befehl spiralzuerst eine vollständige Matrix erstellt, die Größe hat von etwa4n2. Um ungefährn104Diese Matrix belegt mehr als 1 GB Speicherplatz. Mit 1 TB RAM kommen Sie also zurechtn105, und über 2.91011 GB RAM bringt Sie dazu n=232.


2

Haskell, 78 74 Bytes

(concat[[(x,i-x),(x,x-1-i),(-1-x,x-1-i),(-1-x,i-x)]|i<-[0..],x<-[0..i]]!!)

Testlauf:

*Main> mapM_ (print . (concat[[(x,i-x),(x,x-1-i),(-1-x,x-1-i),(-1-x,i-x)]|i<-[0..],x<-[0..i]]!!) ) [0..20]
(0,0)
(0,-1)
(-1,-1)
(-1,0)
(0,1)
(0,-2)
(-1,-2)
(-1,1)
(1,0)
(1,-1)
(-2,-1)
(-2,0)
(0,2)
(0,-3)
(-1,-3)
(-1,2)
(1,1)
(1,-2)
(-2,-2)
(-2,1)
(2,0)

So funktioniert es: Listen Sie alle Paare im ersten Quadranten in der folgenden Reihenfolge auf

  |
 2| #4
  |
 1| #2  #5
  | 
 0| #1  #3  #6
  +---------------
     0   1   2   3 

Spiegeln Sie jeden Punkt in die anderen Quadranten, um eine Liste mit 4 Elementlisten zu erstellen. Verketten Sie alle zu einer einzigen Liste und nehmen Sie das nth-Element.

Bearbeiten: Funktion benötigt keinen Namen, Mathe neu angeordnet. Ausdrücke.


Sie können mit do-notation 4 Bytes sparen: Probieren Sie es online aus!
1.

1

Haskell , 50 Bytes

(0!).succ
l!n=(last$(!).succ:[(,)|odd n])l$div n 2

Probieren Sie es online aus oder versuchen Sie es mit der Umkehrung!

Ungolfed

ntoN2 n = 0 ! (n + 1)

xCounter ! remainingNum
  | odd remainingNum = (xCounter, div remainingNum 2)
  | otherwise        = (xCounter + 1) ! div remainingNum 2

Erläuterung

Dies nutzt die Tatsache, dass jeder (x,y)N2 kann 1-zu-1 zugeordnet werden 2x(2y+1)-1N. Der obige Operator (!)berechnetxDurch Teilen der Eingabe, solange sie gerade ist, verfolgen Sie die mit Null initialisierte Variable l( xCounter). Sobald wir die gerade Zahl erreicht haben, wird eine Ganzzahldivision berechnet y.

Beachten Sie, dass die aktuelle Funktion f( ntoN2) die Eingabe erhöht, bevor Sie mit der Prozedur beginnen.


1

05AB1E , 35 Bytes

>©DÝʒo®sÖ}àsÅÉʒ®sÖ}à<2÷‚εDÈi2÷ë>2÷(

Probieren Sie es online! oder als Testsuite

Erläuterung

Erwägen

f:NN×Nn(x,y),
woher x ist die größte Zahl damit 2x teilt n+1, und wo 2y+1 ist die größte ungerade Zahl, die sich teilt n+1. Das Gegenteil vonf ist die bekannte Bijektion f-1(x,y)=2x(2y+1)-1.

Dann überlegen Sie

G:N×NZ×Z(m,n)(h(m),h(n)),
woher
h:NZn{n2,n sogar-n+12,n ungerade.
Schon seit f, G und h Alles sind Bijektionen, die Komposition Gf:NZ×Z ist eine Schande.

Das Programm berechnet einfach Gf.

>©DÝʒo®sÖ}àsÅÉʒ®sÖ}à<2÷‚εDÈi2÷ë>2÷( # Full program

                                    # Implicit input: Integer n
>©                                  # Compute n+1 and save it to the register
  DÝ                                # Duplicate n+1 and push the list [0,...,n+1]
    ʒo®sÖ}                          # Only keep those numbers x so that 2^x divides n+1
          à                         # Get maximum element in the list.
           sÅÉ                      # Swap so that n+1 is on top and push [1,3,5,...,n+1]
              ʒ®sÖ}                 # Only keep those numbers z which divides n+1
                   à<2÷             # Compute y = (z-1)/2
                       ‚            # Push the pair [x,y]
                        ε           # Apply the function h to x (and y):
                           i        # if...
                         DÈ         # x is even
                            2÷      # then compute x/2
                              ë>2÷( # else compute -(x+1)/2
                                    # Implicit output: [h(x),h(y)]

wow, danke für die nette erklärung. aber sicher 05AB1E sollte in der Lage sein, Pyth zu schlagen?
Nur ASCII

Danke :) Kann sicherlich verbessert werden, wird aber wahrscheinlich einen anderen Ansatz als Computing verwenden müssen Gf. Kann es wahrscheinlich ein bisschen niedriger Golf spielen, aber wahrscheinlich nicht von sehr viel ich vermute
Wisław

0

Mathematica, 46

SortBy[Tuples[Range[2#]-#,2],Norm][[#]]&[#+1]&

Sortieren Sie die Vektoren nach ihrer Norm und nehmen Sie dann die nth.


0

JavaScript, 166 168 Bytes / Zeichen

Neuer Ansatz mit einer rechteckigen Spirale wie andere.

function f(n){return b=Math,k=b.ceil((b.sqrt(n)-1)/2),t=2*k+1,m=b.pow(t,2),t+=4,m-t>n?(m-=t,m-t>n?(m-=t,m-t>n?[k,k-(m-n-t)]:[-k+(m-n),k]):[-k,-k+(m-n)]):[k-(m-n),-k]}

Ich habe diese Antwort in Math.SE verwendet, in JS übersetzt und mit UglifyJS komprimiert .

Dieser Ansatz verwendet weder Schleifen noch erzeugt er die Spirale in irgendeiner Weise.

Da die Koordinaten der Spirale alle ganzen Zahlen abdecken, ist die Funktion bijektiv im Sinne von f:N0Z2.

Update: 2 Zeichen durch Speichern Mathin gespeichert b.

Update 2: Ersetzt t-=1durch t+=4, um das verursachte Problem zu behebenf(0)=f(8). Dies erzeugt keine Spirale mehr, funktioniert aber für alle nicht negativen ganzen ZahlenN0 (alle natürlichen Zahlen einschließlich 0).


1) Genau die gleiche Frage erneut zu posten, wird nicht wirklich helfen. 2) Eine andere Antwort zu kopieren und dann einen Minifier zum Golfen zu verwenden, wird es auch nicht :)
Optimizer

Zumindest befolgt es alle in der Frage angegebenen Regeln und es ist ein anderer Ansatz. Auch ich klaue nicht jemandes Arbeit, aber ich beziehe mich darauf, wie ich diese Antwort gemacht habe.
GiantTree

@Optimizer: 1) Ich schlug vor, dass GiantTree erneut posten sollte, da er 3 (verdiente) Abwertungen für seinen ursprünglichen, ungültigen Ansatz erhielt. 2) Der Code, den er aus Math.SE genommen hat, ist nicht einmal JavaScript, also hat er mehr getan, als ihn nur in einem Minifier zu kopieren.
Dennis

@Dennis Leute können ihre Ablehnung zurückziehen, wissen Sie. Auch die Verwendung eines Minifiers zur Minimierung von Code wird imo nicht wirklich empfohlen.
Optimierer

@Optimizer Ich habe versucht, den Code zu spielen, aber mit einem Kompressor habe ich ein besseres Ergebnis erzielt (weniger Zeichen), also habe ich stattdessen diesen verwendet.
GiantTree
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.