Maximise the squared difference

Jelly, 24 21 15 14 10 9 bytes

RUĖµ«/€ị"

To compute the total squared difference, append µ_ṙ1$²S to the code. Try it online!

Background

One way to generate a permutation with maximized squared difference is to take the integers 1 to n in ascending order, and swap the second from the left with the second from the right, the fourth from the left with the fourth from the right, and so forth until we meet in the middle.

For example, for n = 8, 9 we have

1 2 3 4 5 6 7 8        1 2 3 4 5 6 7 8 9
  ^   ^ ^   ^            ^   ^   ^   ^

(carets mark integers to be swapped), which results in

1 7 3 5 4 6 2 8        1 8 3 6 5 4 7 2 9

after swapping.

One way to achieve these swaps, independently of the parity of n, is as follows.

Start by writing the integers in ascending order and in descending order, one below the other.

1 2 3 4 5 6 7 8        1 2 3 4 5 6 7 8 9
8 7 6 5 4 3 2 1        9 8 7 6 5 4 3 2 1

For each pair of integers, compute the minimum of the pair. This gives the distance to the nearest edge, i.e., the index from the left or the right (whichever is lower).

1 2 3 4 5 6 7 8        1 2 3 4 5 6 7 8 9
8 7 6 5 4 3 2 1        9 8 7 6 5 4 3 2 1

1 2 3 4 4 3 2 1        1 2 3 4 5 4 3 2 1

If the minimum is odd, the integer should stay in its place, so we select the one from the first row; if it is even, the integers should be swapped, so we select the one from the second row.

1   3     6   8        1   3   5   7   9
  7   5 4   2            8   6   4   2

This is the desired output.

How it works

RUĖµ«/€ị"    Main link. Input: n

R            Range. Yields [1, ..., n].
 U           Upend. Yields [n, ..., 1].
  Ė          Enumerate. Yields p := [[1, n], [2, n-1], ... [n-1, 2], [n, 1]].

   µ         Begin a new, monadic chain. Argument: p
     /       Reduce...
      €        each pair of p...
    «          by minimum.
        "    For each minimum and the corresponding pair of p:
       ị       Select the element at that index.
            Indices are modular and 1-based in Jelly, so this selects the first
            element if the minimum is odd, and the second one if it is even.

JavaScript (ES6), 52 bytes

n=>[...Array(n)].map((_,i)=>(i<n/2|n%2)^i%2?i+1:n-i)

9 bytes saved thanks to @Neil!

Explanation

This approach determines the number that should be at index i with a length of n rather than concatenating the results to an array. This is based on the following observation (using n = 7 as an example):

  • Start with the lowest number on the left and the highest on the right: [ 1, 7 ]
  • Switch the order so the lowest is on the right and the highest is on the left, increment the lowest, decrement the highest, and place them in the middle of the array: [ 1, 6, 2, 7 ]
  • Repeat until the highest and lowest converge: [ 1, 6, 3, 4, 5, 2, 7 ]

The higher and lower numbers can easily be expressed as n-i and i+1 respectively.

var solution =

n=>
  [...Array(n)] // create an array of length n
  .map((_,i)=>  // set each value of the array at index i
    (i<n/2      // if we're on the left side,
    |n%2)       // or we're on the right and n is odd, even i => lower, odd i => higher
    ^i%2?       // else even i => higher, odd i => lower
    i+1:n-i
  )
N = <input type="number" id="input" oninput="result.textContent=solution(+this.value)" />
<pre id="result"></pre>


Python2, 105 98 bytes

7 bytes saved thanks to the comment by @Dennis

n=input()
r=([],[n/2+1])[n%2]
for i in range(n/2,0,-1):k=[n+1-i];r=([i]+r+k,k+r+[i])[i%2]
print r

Edited version 58 bytes

lambda n:[(n-i-1,i)[(i+(n,1)[i<n/2])%2]for i in range(n)]

I already believed it should be possible to do it as a one-liner, but the logic was too complex for me. Seeing the JavaScript-answer by @user81655 and the lambda-notation in @Dennis Python-answer, I gave it new try.

The condition is equal to

if i < n/2:
    i%2 != n%2
else:
    (i+1)%2

Unfortunately all the transformation effort saves only one no byte compared to the direct translation (i<n/2or n%2)!=i%2 of the JavaScript-logic.