Generate a pair of integers from a non-negative one

25

2

You should write a program or function which takes a non-negative integer N as input and outputs or returns two integers (negative, zero or positive) X and Y.

Integers are meant in the mathematical sense as there are infinitely many of them.

The implemented function has to be bijective. This means that for every N it has to output a different X Y pair and every X Y pair should be outputted for some input N i.e. all of the following pairs should be outputted for some 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 │
    └─────┴─────┴────┴────┴────┘
                 ...

Note that U V and V U are different pairs if U!=V.

Details

  • If your language doesn't support arbitrarily large integers that's fine but your algorithm should work with an arbitrarily large integer data-type. Your code should still support input values for at least 2^31-1.
  • If you choose to print or return the output as string no leading 0's or + signs are allowed. Otherwise your language's standard integer representation is fine.

Example

If the task would be to make a bijective function taking a non-negative integer N and output one integer X a solution could be the function

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

implemented in some language. This function returns X = 0 -1 1 -2 2... for N = 0 1 2 3 4....

randomra

Posted 2015-04-10T14:09:47.007

Reputation: 19 909

Can any of the integers in the output be repeated for different input? e. g. 10=>11 12, 9=>10 11 is this invalid because 11 is repeated? – BrainSteel – 2015-04-10T14:54:58.847

1

As far as "bijective" is defined "11 12" not the same as "10 11" and therefore valid. This is because a bijective function is defined as a function "where every element of one set is paired with exactly one element of the other set, and every element of the other set is paired with exactly one element of the first set. There are no unpaired elements."(http://en.wikipedia.org/wiki/Bijection). If you were to inverse your function "11 12" should output 10 and "10 11" should output 9.

– GiantTree – 2015-04-10T15:05:13.780

@BrainSteel Your example is valid. Only the (ordered) pairs can't be repeated. GiantTree is correct. Added some more explanation to the question. – randomra – 2015-04-10T15:08:11.490

Does it have to be a bijection within the integer range of the given language or should it work for all integers? – flawr – 2015-04-10T17:56:32.097

@flawr You can't do a bijection in a fixed range as the two sets will be of different size. Your algorithm should work for all integers using it on a proper datatype (see the first point of the Details section). – randomra – 2015-04-10T18:57:22.247

1@LegionMammal had a good mathematical description of the task: "You need to define a bijective function $f:N+→Z^2$. – LegionMammal978." that I think would be beneficial somewhere in the statement – Brian J – 2015-04-10T19:12:07.253

@BrianJ It was more like $f:\mathbb{N}^+\rightarrow\mathbb{Z}^2$ = $f:\mathbb{N}^+\rightarrow\mathbb{Z}^2$. – LegionMammal978 – 2015-04-11T14:23:15.220

@LegionMammal978 thanks! I couldn't see the markdown to copy directly. – Brian J – 2015-04-11T14:33:11.080

Answers

15

Pyth, 15

u,-HyeGhGjQ2,ZZ

Try it online.

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

A Python translation:

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

or iteratively:

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

where binlist converts a number to a list of digits like binlist(4) = [1,0,0].

So, how does this work? It interprets the binary digits of the number \$n\$ as two interleaved numbers in base negative two like in my Python solution.

The binary number $$n=\dots b_5 b_4 b_3 b_2 b_1 b_0 $$ corresponds to the pair $$ (x,y) = (b_0 - 2 b_2 + 4 b_4 - 8 b_6 + \cdots, b_1 - 2 b_3 + 4 b_5 - 8 b_7 + \cdots).$$

If we hadn't yet processed the last digit \$b_0\$ of \$n\$, we'd have all indices higher by $1$, $$n'=\dots b_5 b_4 b_3 b_2 b_1 $$ corresponding to the pair $$ (x',y') = (b_1 - 2 b_3 + 4 b_5 - 8 b_7 + \cdots, b_2 - 2 b_4 + 4 b_6 - 8 b_8 + \cdots).$$

We can then express the new values once \$b_0\$ is read in terms of the old values

$$(x,y) = (b_0 - 2y', x').$$

So, by repeatedly performing the transformation \$(x,y) \to (b - 2y, x)\$ on each successive bit \$b\$ of \$n\$, we build the point \$(x,y)\$ that comes from extracting its digits.

xnor

Posted 2015-04-10T14:09:47.007

Reputation: 115 687

Note that MathJax support has been disabled. You might want to consider editing your explanation for readability. – Alex A. – 2015-04-12T05:12:17.953

32

CJam, 24 22 21 bytes

My brain has trouble understanding the math other solutions are using. But my brain definitely understands binary, so here's a soultion based on bit manipulation!

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

Try it online.

Explanation

This approach treats the input as two interleaved binary values, one for each output number. All but the least significant bit of each encode a magnitude, and the least significant bit signals whether or not to take the bitwise complement of this magnitude. In this implementation, the odd-positioned bits correspond to the first output number (and the even-positioned bits correspond to the second) and an LSB of 0 signals to take the complement.

For example, given an input of 73, uninterleaving its binary representation of 1001001b produces 0 1|0 (odd-positioned bits) and 1 0 0|1 (even-positioned bits). The first value has a magnitude of 01b = 1 and should be complemented for a final value of ~1 = -2, and the second value has a magnitude of 100b = 4 and should not be complemented.

Informal demonstration of correctness

I made a testing program that places each input from zero to a user-specified number minus one in its output location on a 2D grid. You can try it online as well. Here's an output of this program showing how the algorithm maps 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                                                      

The fill pattern looks a bit weird, but it is in fact bijective! With each successive power of 4, it fills a square with double the previous side length. For example, here's how the algorithm maps 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                  

This makes up the 4x4 square in the middle of the 8x8 square of 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                              

Which makes up the 8x8 square in the middle of the 16x16 square of 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                                                                        

Runer112

Posted 2015-04-10T14:09:47.007

Reputation: 3 636

3Very clever! You can save two bytes by using li4b2fmd2/ instead of 0li2b+W%2/W%. This gives the same integers, but in reversed order. – Dennis – 2015-04-10T19:08:06.730

@Dennis That's also very clever. I've updated the answer to use that trick. Thanks! – Runer112 – 2015-04-10T19:27:30.403

12

Python 2, 49

Edit: Improved to 49 by using better one-step recursion for base -2.

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

Here's a Pyth version using reduce.

Edit: Improved to 52 by switching to base -2 from balanced ternary.

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

This uses digit interleaving like Runer112's solution, but with balanced ternary rather than signed binary. Python doesn't have built-in base conversion, so the code implements it recursively.

The helper function h (with 3 in place of the 9) takes a natural number and converts it from ternary to balanced ternary with the digit substitutions

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

So, for example, 19, which is 201 in base, becomes (-1)(0)(+1) in balanced ternary, which is (-1)*3^2 +(0)*3^1+(+1)*3^0 = -8.

Balanced ternary suffices to encode every integer, and so gives a mapping from natural numbers to integers.

To map to pairs of integers, we interleave the digits in n. To do so, we have h look at every other digit by doing n/9 as the recursive step rather than n/3. Then, for one coordinate, we shift n by floor-dividing by 3.

Here are the first 81 outputs, which cover the region [-4,4]^2.

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)

An alternative coding with quarter-imaginary turned out longer, though it is very pretty.

Python 2, 63

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

In a language with less clunky handling of complex conversion, this would probably be a better approach. If we could output complex numbers, we could do:

Python 2, 38

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

xnor

Posted 2015-04-10T14:09:47.007

Reputation: 115 687

1Your original base -2 function would make a mean Pyth answer. L&b-%b2*2y/b4,yQy/Q2 is only 20 bytes long. – Dennis – 2015-04-11T06:52:28.283

4@Dennis I just wrote a 15-char Pyth solution. – xnor – 2015-04-11T07:05:45.110

Balanced Ternary and Quarter-imaginary. Two of my favorite bases. Followed only by Base-e. – Brian Minton – 2017-06-08T12:16:42.520

11

Python 2, 98 bytes

Let's start out with a simple approach:

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)

It just forms a rectangular spiral N units long on a 2d grid, starting from the origin, and returns the coordinates of the last point.

The function is bijective since:

  • Each point can be covered, given a long enough spiral
  • Each point will only be intersected by the spiral once

The spiral looks something like this (except starting at 0 rather than 1):

Ulam Spiral

grc

Posted 2015-04-10T14:09:47.007

Reputation: 18 565

@AlexA. 0**0 == 1 in python, so it's just the same as if a == 0: a = b/2 – grc – 2015-04-11T03:51:54.813

Cool, thanks for explaining. – Alex A. – 2015-04-11T03:54:12.510

@AlexA. turns out a=a or b/2 is shorter – grc – 2015-04-11T03:56:22.177

@grc 0^0=1 in all math, not just python. – Daenyth – 2015-04-11T11:45:25.237

1

@Daenyth 0**0 is actually indeterminate form in maths

– Sp3000 – 2015-04-11T17:00:55.933

This is quite a cool solution, I like the elegance. – Nit – 2015-04-11T21:23:26.000

8

dc, 49

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

This starts off by arranging the non-negative integers on a grid thus:

..| 
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 ...

Note that how the grid positions are filled diagonally with increasing N. Notice the Y=0 line contains the triangular number sequence, given by N = X(X+1)/2. This is a quadratic equation which is solved using the normal formula, using just the +ve root, so that we can determine X from N when Y=0. Next is some simple arithmetic shuffling to give unique {X,Y} for every N.

This provides the required bijective quality, but X and Y are only non-negative, but the question requires all possible integers. So X and Y are mapped using ((t+1)/2)*((t+1)~2*2-1) to give all possible integers.

dc has arbitrary precision numbers, so input range to 2^31-1 is no problem. Note also that default precision is 0 decimal digits, and the sqrt() and / round down which is the behavior needed here.

Output:

$ 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
$

Digital Trauma

Posted 2015-04-10T14:09:47.007

Reputation: 64 644

5

Matlab, 54 bytes

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

The key here is spiral, this creates a spiral matrix of an arbitrary size.

spiral(3)

returns

ans =

 7     8     9
 6     1     2
 5     4     3

In Matlab, this works for integers, but you will get memory issues way before that, (well, I am assuming you as the command spiral creates a full matrix first, that has size of about \$4n^2\$. At around \$n \simeq 10^4\$ this matrix takes up more than 1GB of space. So with 1TB of RAM you will get to around \$n \simeq 10^5\$, and about \$2.9\cdot 10^{11}\$ GB of RAM will get you to \$n=2^{32}\$.

flawr

Posted 2015-04-10T14:09:47.007

Reputation: 40 560

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]]!!)

Test run:

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

How it works: list all pairs in the first quadrant in the following order

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

mirror each point into the other quadrants to make a list of 4 element lists. Concatenate all into a single list and take the nth element.

Edit: function doesn't need a name, reordered math. expressions.

nimi

Posted 2015-04-10T14:09:47.007

Reputation: 34 639

You can save 4 bytes by using do-notation: Try it online!

– ბიმო – 2018-08-01T13:07:52.927

1

Haskell, 50 bytes

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

Try it online or try it with its inverse!

Ungolfed

ntoN2 n = 0 ! (n + 1)

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

Explanation

This uses the fact that each \$(x,y) \in \mathbb{N}^2\$ can be 1-to-1 mapped to \$2^x \cdot (2\cdot y + 1) - 1 \in \mathbb{N}\$. The above operator (!) computes \$x\$ by dividing the input as long as it's even, keeping track with the zero-initialized variable l (xCounter). Once we reached the even number an integer division computes y.

Note that the actual function f (ntoN2) increments the input before starting with the procedure.

ბიმო

Posted 2015-04-10T14:09:47.007

Reputation: 15 345

1

05AB1E, 35 bytes

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

Try it online! or as Test suite

Explanation

Consider

$$\begin{align*} f: \mathbb{N} &\longrightarrow \mathbb{N} \times \mathbb{N} \\ n&\longmapsto (x,y)\, , \end{align*} $$ where \$x\$ is the largest number so that \$2^x\$ divides \$n+1\$, and where \$2y+1\$ is the largest odd number which divides \$n+1\$. The inverse of \$f\$ is the well-known bijection \$f^{-1}(x,y) = 2^x(2y+1)-1\$.

Then consider $$\begin{align*} g: \mathbb{N} \times \mathbb{N} &\longrightarrow \mathbb{Z} \times \mathbb{Z} \\ (m,n)&\longmapsto (h(m),h(n))\, , \end{align*} $$ where $$\begin{align*} h: \mathbb{N} &\longrightarrow \mathbb{Z} \\ n&\longmapsto \begin{cases}\frac n2, & n \text{ even}\\ -\frac{n+1}2, & n \text{ odd}\end{cases}\, . \end{align*} $$ Since \$f\$, \$g\$ and \$h\$ all are bijections, the composition \$g\circ f:\mathbb{N} \longrightarrow \mathbb{Z} \times \mathbb{Z}\$ is a bijection.

The program simply computes \$g\circ f\$.

>©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)]

Wisław

Posted 2015-04-10T14:09:47.007

Reputation: 554

wow, upvoted for the nice explanation. but surely 05AB1E should be able to beat Pyth? – ASCII-only – 2019-01-19T02:05:00.340

Thanks :) Can for sure be improved, but will probably have to use another approach rather than computing $g\circ f$. Can probably golf it a bit lower, but probably not by very much I suspect – Wisław – 2019-01-19T02:13:17.913

0

JavaScript, 166 168 bytes/characters

New approach using a rectangular spiral like others are using.

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

I used this answer on Math.SE, translated it to JS and compressed it using UglifyJS.

This approach does not use any loops nor does it create the spiral in any way.

Because the spiral's coordinates cover all integers the function is bijective in the sense of \$f:\mathbb{N}^0\rightarrow \mathbb{Z}^2\$.

Update: Saved 2 characters by storing Math in b.

Update 2: Replaced t-=1 with t+=4 to fix the issue that caused \$f(0)=f(8)\$. This does not generate a spiral anymore but works for all non-negative integers \$\mathbb{N}^0\$ (all natural numbers including \$0\$).

GiantTree

Posted 2015-04-10T14:09:47.007

Reputation: 885

>

  • Reposting the exact same question won't really help. 2) Copying another answer and then using a minifier for golfing won't too :)
  • < – Optimizer – 2015-04-10T20:48:33.860

    At least it follows all the rules stated in the question and it's a different approach. Also I am not stealing another one's work, but I refer to it on how I made this answer. – GiantTree – 2015-04-10T20:54:17.087

    @Optimizer: 1) I suggested GiantTree should repost since he got 3 (deserving) downvotes for his original, invalid approach. 2) The code he took from Math.SE isn't even JavaScript, so he did more than just copying it in a minifier. – Dennis – 2015-04-10T20:54:19.560

    @Dennis people can retract their downvote, you know. Also, using a minifier to minify code is not really encouraged imo. – Optimizer – 2015-04-10T20:55:42.600

    @Optimizer I tried to golf the code, but using a compressor led to a better result (less characters) so I used that one instead. – GiantTree – 2015-04-10T20:58:41.533

    @Optimizer: People can do a lot of things. But since the edit doesn't notify them, three downvoters coming back to revert their vote is highly unlikely. The minifier didn't do a very good job anyway. There are a lot of unneeded brackets, Math could be saved in a variable, etc. – Dennis – 2015-04-10T20:59:07.527

    I will update the answer with a little bit more golfed version in a moment. Is that ok? – GiantTree – 2015-04-10T21:00:02.220

    Golfing personally always helps. – Optimizer – 2015-04-10T21:12:50.823

    N+ is every integer > 0 ? Try again, the question is about non-negative integers and f(0)==f(8). – edc65 – 2015-04-10T23:08:24.213

    @edc65 I fixed it and changed $N^+$ (the definition before) to $N^0$ (the correct definition of all non-negative integers including $0$). – GiantTree – 2015-04-11T09:46:49.690

    now f(71)==f(150) ... why try random changes, it was off by 1, it was simple to fix ... function F(n){return n<(m=(t=2*(k=Math.ceil((Math.sqrt(++n)-1)/2)))*t+1)+t?n<m?n<m-t?[k,m-n-t-k]:[m-n-k,-k]:[-k,n-m-k]:[n-m-t-k,k]} 126 – edc65 – 2015-04-11T10:36:21.687

    @edc65 Thanks for your improvement on my submission. I see what you did there. You increment n so that it works again because the function itself is defined for $N^+$ only. Shifting the input up by one fixes this issue. You also connected the variable declarations because they return the value assigned to a variable so it can be used in another declaration, I didn't know this was possible. Another improvement you did was moving t around so that there is no need to subtract it every time it's compared to n, removing the need of all the parentheses. – GiantTree – 2015-04-11T12:15:58.037

    @edc65 I have an issue with your script. Technically it looks good and I learned something form comparing it to mine, but your script fails to generate pairs for the top part of the spiral. I always get the error: Reference error: n is not defined. – GiantTree – 2015-04-11T12:50:51.520

    I'm using FireFox and no error. Using this to test g=[],o=10;for(i=0;i<o*o*4;i++)[x,y]=F(i),g[y+o]=g[y+o]||[],g[y+o][x+o]=i;g.map(r=>r.map(c=>(' '+c).slice(-3))).join('\n') – edc65 – 2015-04-11T13:17:50.113

    But check for invisible characters added by the editor formatter! Rats! Try http://jsfiddle.net/c40y9ynj/

    – edc65 – 2015-04-11T13:25:00.423

    @edc65 it works now. There was an invisible character that only appeared in the stacktrace. It was somewhere between n and a space. – GiantTree – 2015-04-11T14:07:23.157

    0

    Mathematica, 46

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

    Sort the vectors their norm, then take the nth one.

    alephalpha

    Posted 2015-04-10T14:09:47.007

    Reputation: 23 988