Tournament bracket placement algorithm

前端 未结 10 643
生来不讨喜
生来不讨喜 2020-12-02 09:37

Given a list of opponent seeds (for example seeds 1 to 16), I\'m trying to write an algorithm that will result in the top seed playing the lowest seed in that round, the 2nd

10条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-02 10:17

    For JavaScript code, use one of the two functions below. The former embodies imperative style & is much faster. The latter is recursive & neater, but only applicable to relatively small number of teams (<16384).

    // imperative style
    function foo(n) {
      const arr = new Array(n)
      arr[0] = 0
      for (let i = n >> 1, m = 1; i >= 1; i >>= 1, m = (m << 1) + 1) {
        for (let j = n - i; j > 0; j -= i) {
          arr[j] = m - arr[j -= i]
        }
      }
      return arr
    }
    

    Here you fill in the spots one by one by mirroring already occupied ones. For example, the first-seeded team (that is number 0) goes to the topmost spot. The second one (1) occupies the opposite spot in the other half of the bracket. The third team (2) mirrors 1 in their half of the bracket & so on. Despite the nested loops, the algorithm has a linear time complexity depending on the number of teams.

    Here is the recursive method:

    // functional style
    const foo = n =>
      n === 1 ? [0] : foo(n >> 1).reduce((p, c) => [...p, c, n - c - 1], [])
    

    Basically, you do the same mirroring as in the previous function, but recursively:

    • For n = 1 team, it's just [0].

    • For n = 2 teams, you apply this function to the argument n-1 (that is, 1) & get [0]. Then you double the array by inserting mirrored elements between them at even positions. Thus, [0] becomes [0, 1].

    • For n = 4 teams, you do the same operation, so [0, 1] becomes [0, 3, 1, 2].

    If you want to get human-readable output, increase each element of the resulting array by one:

    const readableArr = arr.map(i => i + 1)
    

提交回复
热议问题