[Question]
  [
Problem 4 in the [2019 BMO, Round 1](https://bmos.ukmt.org.uk/home/bmo1-2020.pdf) describes the following setup:
> 
> There are \$2019\$ penguins waddling towards their favourite restaurant. As
>  the penguins arrive, they are handed tickets numbered in ascending order
>  from \$1\$ to \$2019\$, and told to join the queue. The first penguin starts the queue.
>  For each \$n > 1\$ the penguin holding ticket number \$n\$ finds the greatest \$m < n\$
>  which divides \$n\$ and enters the queue directly behind the penguin holding
>  ticket number \$m\$. This continues until all \$2019\$ penguins are in the queue.
> 
> 
> 
The second part of the question asked candidates to determine the penguins standing directly in front of, and directly behind, penguin \$33\$. This could be done by examining the patterns in the queue, considering prime factors: see the online [video solutions](https://bmos.ukmt.org.uk/solutions/bmo1-2020/) for more information.
---
## The Challenge
Your task is to design a program or function which, given a positive integer \$k\$ representing the penguin with ticket number \$k\$, outputs the ticket numbers of the penguins *directly before and after* this penguin.
For example, penguin \$33\$, stands directly behind \$1760\$ and directly in front of \$99\$, so the program should output, in some reasonable format, \$[1760, 99]\$.
---
## Rules
* The input will be an integer in the range \$1 < k \le 2019\$.
* Your program should output two integers, in any reasonable format, representing the ticket numbers of the penguins before and after.
* These can be output in any order, (front first or behind first) but this order must be consistent.
* The penguin will not be at the front or back of the queue: so you don't have to handle the edge cases of \$k = 1\$ or \$k = 1024\$.
* As penguins find it difficult to read human glyphs, your program should be as short as possible. This is a [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'") - so the shortest program (in bytes) wins!
---
## Test Cases
These outputs are given in the format `[front, behind]`.
```
33   -> [1760, 99]
512  -> [256, 1024]
7    -> [1408, 49]
56   -> [28, 112]
1387 -> [1679, 1241]
2019 -> [673, 1346]
2017 -> [1, 2011]
2    -> [1536, 4]
```
  
[Answer]
# [Perl 6](https://github.com/nxadm/rakudo-pkg), ~~79~~ ~~76~~ 71 bytes
```
{($!=sort {[R,] -$_,{first $_%%*,$_^..1}...1},^2020)[+(@$!...$_)X-2,0]}
```
[Try it online!](https://tio.run/##K0gtyjH7n1upoJamYPu/WkNF0bY4v6hEoTo6SCdWQVclXqc6LbOouERBJV5VVUtHJT5OT8@wVg9E6MQZGRgZaEZrazioKAJFVOI1I3SNdAxia/8XJ1YqpGkYG2ta/wcA "Perl 6 – Try It Online")
Sorts numbers 1 to 2019 lexicographically by the reversed, negated sequence of largest divisors, then finds the neighbors. Example mappings:
```
1760 => (-1 -11 -55 -110 -220 -440 -880 -1760)
  33 => (-1 -11 -33)
  99 => (-1 -11 -33 -99)
```
In other words, the negated cumulative product of prime factors in descending order.
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 15 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
⁽¥ØÆfṚNƊÞṣị"@Ø.
```
A monadic Link accepting an integer between 1 and 2019 \* which yields a list of two integers, `[in-front, behind]`.
\* If `1` or `1024` is input the missing ticket number will be shown as `0`.
**[Try it online!](https://tio.run/##ASkA1v9qZWxsef//4oG9wqXDmMOGZuG5mk7GisOe4bmj4buLIkDDmC7///8zMw "Jelly – Try It Online")**
### How?
```
⁽¥ØÆfṚNƊÞṣị"@Ø. - Link: n
⁽¥Ø             - literal 2019
        Þ       - sort (range [1..2019]) by: 
       Ɗ        -   last three links as a monad:
   Æf           -     prime factorisation (e.g. 1100 -> [2,2,5,5,11])
     Ṛ          -     reversed
      N         -     negated
         ṣ      - split at (n)
             Ø. - literal [0,1]
            @   - with swapped arguments:
           "    -   zip with:
          ị     -     index into (1-based & modular)
                      - i.e. [last of left list, first of right list]
```
[Answer]
# JavaScript (ES6), ~~105 ... 101~~ 100 bytes
A straightforward implementation that builds the full queue and looks for the penguin with the input ticket within it.
Returns `[front, behind]`.
```
k=>[eval("for(n=q=[];m=++n%2020;q.splice(q.indexOf(m),0,n))while(n%--m)q")[i=q.indexOf(k)+1],q[i-2]]
```
[Try it online!](https://tio.run/##bcrdCoMgGADQ@z1GEPhRhhr7I9wr7AHEiyjdLNOs0fb2bndjuNvDGdqtXbvFzA/sfK@i5nHkF6G21qJM@wU5HriQzcSLwuWMMNKEap2t6RQKlXG9el01mqAkpQN43o1VyOUYTxAyEIZ/zwgFlWUQBjMpY@fd6q2qrL8hjeoaYPdLe8oSO6brkBCtT@ljhJ7/4WfGNw "JavaScript (Node.js) – Try It Online")
### Commented
The code in `eval()` builds and returns the queue in reverse order:
```
for(                      // outer loop:
  n = q = [];             //   q[] = queue, n = counter (initially zero'ish)
  m = ++n % 2020;         //   increment n; set m to n mod 2020, so that we
                          //   stop when n = 2020
  q.splice(               //   after each iteration:
    q.indexOf(m), 0, n    //     insert n before m in q[] (should be *after* m to build
  )                       //     the queue from first to last, but it's shorter this way)
) while(n % --m)          //   inner loop: decrement m until it divides n
    q                     //     dummy loop statement so that q[] is returned by eval()
```
which gives \$q[\:]=[1024,512,...,2017,1]\$.
Wrapper code:
```
k => [                    // k = input
  eval("...")             // build q[]
  [i = q.indexOf(k) + 1], // return the element after k ('in front of')
  q[i - 2]                // and the element before k ('behind')
]                         //
```
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), ~~16~~ 15 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
Ž7ëLΣÒR(}ûI¡€θ¨
```
Port of [*@JonathanAllan*'s Jelly answer](https://codegolf.stackexchange.com/a/196778/52210), so make sure to upvote him!  
-1 byte thanks to *@Grimmy*.
Outputs in the order `[front, behind]`.
[Try it online](https://tio.run/##ASUA2v9vc2FiaWX//8W9N8OrTM6jw5JSKH3Du0nCoeKCrM64wqj//zMz) or [verify all test cases](https://tio.run/##yy9OTMpM/V9Waa@k8KhtkoKS/f@je80Pr/Y5t/jwpCCN2sO7Kw8tfNS05tyOQyv@6/yPNjbWMTU00jHXMTXTMTS2MNcxMjC0BBHmsQA).
**Explanation:**
```
Ž7ë              # Push compressed integer 2019
   L             # Pop and push a list in the range [1,2019]
    Σ            # Sort this list by:
     Ò           #  Get the prime factors (with duplicates)
      R          #  Reverse it
       (         #  Negate each inner value
        }û       # After the sort: palindromize this list ([a,b,c] → [a,b,c,b,a])
          I¡     # Split this pallindromized list by the input-integer
            €θ   # For each inner list: only leave the last value
              ¨  # And remove the last value, so the pair remains
                 # (after which this pair is output implicitly as result)
```
[See this 05AB1E tip of mine (section *How to compress large integers?*)](https://codegolf.stackexchange.com/a/166851/52210) to understand why `Ž7ë` is `2019`.
[Answer]
# [Python 2](https://docs.python.org/2/), ~~137~~ ~~133~~ 121 bytes
```
q=[1]
for n in range(2,2020):j=q.index(max(m for m in q if n%m<1))+1;q=q[:j]+[n]+q[j:]
print q[q.index(input())-1::2][:2]
```
[Try it online!](https://tio.run/##PZBPb8IwDMXP@FP4MkFFmRqntLRbd2PXXXaLcmAQRrs1baKiwadnTvlzcGT98vye5f48HDpLl223M9V0Or24SgkN@86jxdqi39hvM6OYEkqisqncc2135jRrN1wYZG2QOaz3aJ/aVxFFc/HiKqfKRs@V1XOnmlJD72s7oFP3@dr2x2EWRQtRlqQV14XTAf4O9a/BT380JUwGf@Z3Yk5mi2FB4HZr@gHXH@9r7zsffr@82fwAhGkpEXHxhkrkWRJjUWhYCroiWmYxioRSDTneZWmyijENsuyGiIEQpEHIVX4VZXnBjFI@CyWiGGGWS2YyzUZ2E8bIfVA9/JeSQzkxHFbKsAzknDWaj2bjNNA/ "Python 2 – Try It Online")
4 bytes thx to [Arnauld](https://codegolf.stackexchange.com/users/58563/arnauld); 11 bytes thx to [FlipTack](https://codegolf.stackexchange.com/users/60919/fliptack).
Another naive implementation.
[Answer]
# [C++ (clang)](http://clang.llvm.org/), ~~288~~ \$\cdots\$ ~~210~~ 203 bytes
Saved a whopping ~~22~~ 29 bytes thanks to [ceilingcat](https://codegolf.stackexchange.com/users/52904/ceilingcat)!!!!  
Saved a byte thanks to @AZTECCO!!!!
```
#import<bits/stdc++.h>
#define l find(begin(q),end(q)
using v=std::vector<int>;v f(int p){v q{1};for(int n=1,d,i;d=i=++n<2020;q.insert(l,d),n))for(;++i<n&d<2;)d=n%i?d:n/i;auto t=l,p);return{*++t,t[-2]};}
```
[Try it online!](https://tio.run/##TVDLboMwELzzFatErXDtJED6xEA/JM2BYJNagsWAoQfEt6fGVFF92J0Ze9c7W2i9K6ocr7fbVtW66UxyUaY/9EYUlO6/M28rZKlQQgU2Cf8irwr9ljBpSUu8oVd4hTG1BXE8ysI0XaLQZHyE0rcANJlGaKdw5mXTOQXTkAmmuEhVSikmURAFvN0r7GVn/IoJwpCQ5TWnVCX4KJKIE5Hig/oUMR4UzwfTgEkrpgnvpBk6nJ4oNcycdtF55rP1gkU1CAmJanrTyby2Rv5pdY5KZ94yTZ1bP8SbPLBnBNFDCtPxyOAljBi82fzKIDy@WxQF4YeLC565q7BjgnMlILbFxIlrs@W4SbVtWfqC8LvstlU0g4EkWUkvzY//TO68kqW7FEvYwC6D02aB@hScncTgj4crP3/hZv1g9lxaFwMB9@bbLw "C++ (clang) – Try It Online")
Ungolfed:
```
#include <vector>
#include <algorithm>
auto f(int p)
{
    std::vector<int> q{1};
    for (int n = 2; n <= 2019; ++n)
    {
        int d = 1;
        for (int i = 2; i < n; ++i)
        {
            if (n % i == 0)
            {
                d = n / i;
                break;
            }
        }
        auto it = find(begin(q), end(q), d);
        q.insert(it, n);
    }
    auto it = find(begin(q), end(q), p);
    std::vector<int> r = {*(it + 1), *(it - 1)};
    return r;
}
```
[Answer]
# [Perl 5](https://www.perl.org/), 88 bytes
```
sub f{$_=1;for$n(2..2019){map{$n%$_ or$m=$_}1..$n/2;s/\b$m\b/$&,$n/}/(\d+),$_[0],(\d+)/}
```
[Try it online!](https://tio.run/##VZDBioMwEIbvfYqhzC7KBnVi1FpJ6QvsbW8qomyEwpqK2sMiPrsbtUg3p5/vy59h0qruJ5jn/lFBPWIhKanvHWqLOw73KLbHpmxH1G9YgOGNxGIix0Ht8qR3swqbrHLxnRkwuVb2/WEzLFIvZ2t2p/nRK/hS/XA@f947BYOJvbyQSA5mjgWp7wOAvABFoccgjnN2gOWkAfFV8CBkQB4Xu4ngWRHeiYF4qYSb4AYT8Z2Tf4rWQhjFxnBBu1p2XFQY@cb4Inw1W4mBiZTb4yqaXws1w4phacsrFslK2@6mBzhqaRxUyqympLkDZT2oTmKZ6WPyrMO1lrV5w97ArbcA6@XHACv4D2mB5QKn@Q8 "Perl 5 – Try It Online")
Same ungolfed:
```
sub f {
  $_=1;                             # $_ is the comma separated queue "array string"
                                    # ...with 1 as the first penguin
  for $n (2..2019){                 # process the rest of the penguins 2-2019
    map { $n%$_ or $m=$_ } 1..$n/2; # find max $m divisible by current $n
    s/\b$m\b/$&,$n/                 # search-replace to place current $n behind $m
  }
  /(\d+),$_[0],(\d+)/               # find and return the two numbers:
                                    # the one before and the one after the input
                                    # parameter $_[0] in the $_ array string
}
```
[Answer]
# [R](https://www.r-project.org/), ~~90~~ 89 bytes
```
for(i in 2:2019)T=append(T,i,match(max(which(!i%%1:(i-1))),T));T[match(scan(),T)+c(-1,1)]
```
[Try it online!](https://tio.run/##K/r/Py2/SCNTITNPwcjKyMDQUjPENrGgIDUvRSNEJ1MnN7EkOUMjN7FCozwjE8hSzFRVNbTSyNQ11NTU1AnR1LQOiYaoKU5OzNMACWkna@ga6hhqxv4HGfcfAA "R – Try It Online")
Builds up the list into `T` and extracts the relevant values.
As a bonus, it works for `1` and *almost* works for `1024`, as R's 1-based indexing returns nothing for index `0` and `NA` for index `2020`.
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~23~~ 21 bytes
```
ḍƇṀ=⁸k⁸j
⁽¥ØRç/ṣ⁸ṪḢƭ€
```
[Try it online!](https://tio.run/##y0rNyan8///hjt5j7Q93Ntg@atyRDcRZXI8a9x5aenhG0OHl@g93LgYKPdy56uGORcfWPmpa8///f3MA "Jelly – Try It Online")
Naïve answer that simply generates the list of penguins and finds the relevant place. A pair of links which, when called as a monad, takes an integer as its argument and returns a pair of integers indicating the penguins before and after in the list of penguins. 
[Answer]
# [Ruby](https://www.ruby-lang.org/), ~~104 101~~ 95 bytes
```
->n{*w=1;(2..2019).map{|z|w.insert(1+w.index(w.select{|x|z%x<1}.max),z)};w[w.index(n)-1,3]-[n]}
```
[Try it online!](https://tio.run/##Nc1LCsIwFIXhrTgREr0N3oQapdaNhA58pCDopbSVxDRde0wRJ4cz@ODv39dPautUnGnauBorJoWQOzxy8bp0UwzRiQcNth8Zbpd7t545MdinvY1T9DGs/QnnjD2HwOfKmb8iXiCopjDUzMkoBSVK0FDuAdVBwxJZRje/EsVuZQjazLP/Ag "Ruby – Try It Online")
[Answer]
# [Japt](https://github.com/ETHproductions/japt), 36 [bytes](https://en.wikipedia.org/wiki/ISO/IEC_8859-1)
```
1k
#É9ò2@iUaXâ n- gJÑ)ÄX
g[J1]c+UaNg
```
[Try it](https://petershaggynoble.github.io/Japt-Interpreter/?v=1.4.6&code=MWsKI8k58jJAaVVhWOIgbi0gZ0rRKcRYCmdbSjFdYytVYU5n&input=MzM)
```
1k               assign [1] to U
#É9ò2            pass range 2...2019 to function:
     @i ...  X   insert each value in U at index:
 Ua               find max divisor of X in U:
   Xâ              divisors
      n-           sorted
         gJÑ)Ä     2nd to last
g                get elements at
 [J1]             [-1,1]
     c+UaNg       add index of 1st input in U
```
[Answer]
# [Retina 0.8.2](https://github.com/m-ender/retina/wiki/The-Language/a950ad7d925ec9316e3e2fb2cf5d49fd15d23e3d), 109 bytes
```
^
2019$*_
_
$`_¶
(_+)\1+¶
$1 $&
+m`^(_+)¶((_+¶)*)\1 (_+¶)
$1¶$4$2
_+
$.&
^(.+¶)*(.+)¶(.+)(¶.+)(¶.+)*¶\3$
$2$4
```
[Try it online!](https://tio.run/##PYs7DoMwEET7OQXFCBlbQrHNcZCXFClSQIFytj3AXsxZiJRm5mk@5@vzPp69N5RHZhQIuIkpgqRpzcmJeeCItG/tykyDm@kUvR5@6BNTLiyQBM4jWpjvidt1cA2mf42mayVYuPRe6xc "Retina 0.8.2 – Try It Online") Note: Link only goes to 201 as 2019 is too slow for TIO. Explanation:
```
^
2019$*_
```
Prepend 2019 in unary.
```
_
$`_¶
```
Count from 1 to 2019.
```
(_+)\1+¶
$1 $&
```
Precede each number with its highest proper factor (except 1, which remains unchanged).
```
+m`^(_+)¶((_+¶)*)\1 (_+¶)
$1¶$4$2
```
Insert in turn each number after its highest proper factor.
```
_+
$.&
```
Convert to decimal.
```
^(.+¶)*(.+)¶(.+)(¶.+)(¶.+)*¶\3$
$2$4
```
Extract the predecessor and successor of the original input.
118 byte version that's fast enough to handle 2019 on TIO:
```
^
2019$*_
_
$`_¶
(_+)\1+\b
$.1;$.&
_
1
m{`^(\d+)¶\1;
$1¶
}`^(\d+¶)(\d+;\d+¶)
$2$1
^(.+¶)*(.+)¶(.+)(¶.+)(¶.+)*¶\3$
$2$4
```
[Try it online!](https://tio.run/##K0otycxL/P8/jsvIwNBSRSueK55LJSH@0DYujXhtzRhD7ZgkLhU9Q2sVPTWgjCFXbnVCnEZMirbmoW0xhtZcKoZAlbUQoUPbNEGUNYTJpWKkYsgVp6EH4mgBKaAOEKlxaBuc1AIaYqwCUmny/7@xMQA "Retina 0.8.2 – Try It Online") Explanation:
```
^
2019$*_
_
$`_¶
```
Prepend all of the unary numbers from 1 to 2019.
```
(_+)\1+\b
$.1;$.&
```
Convert to decimal and prepend the largest factor.
```
_
1
```
Except 1, which just becomes the first entry in the list.
```
m{`^(\d+)¶\1;
$1¶
}`^(\d+¶)(\d+;\d+¶)
$2$1
```
Bubble up each line until it finds its insertion point.
```
^(.+¶)*(.+)¶(.+)(¶.+)(¶.+)*¶\3$
$2$4
```
Extract the predecessor and successor of the original input.
[Answer]
# [Scala](http://www.scala-lang.org/), 163 bytes
```
n=>{val a=(2 to 2019).map(x=>(x,((1 to x/2).filter(x%_==0)).max)).foldLeft(Seq(1))((l,e)=>l.patch(l.indexOf(e._2)+1,Seq(e._1),0));val i=a indexOf n;(a(i-1),a(i+1))
```
[Try it online!](https://tio.run/##VZDfa8IwEMff/SuOwuCCWdektbWVCHscDPbg4xiS2dR1xrarZUTEv7276pzuIZdLPve9X7uVtrqv3z/NqoMaDpCbAra6rFBn8Ni2ev@66NqyWr8xgt/aQpE9VZ2aI1lOh6m@UvPDQLRCCV0NMhAp87e6QUdxjiOK4ds9SOYXpe1Mi@5uqVTAhihHtqht/myKDhfmCwVjiJYbpubWb3S3@kDrl1Vu3EuBxl9KNhZ8CCRfME5ZZkP1Umn4jYJqhhrLe6J0jSlhfxwNg9UbdNlf53x/9RkoaGjOzlZYFtS42jOv3njG7oxX1bSbTQZrur2xG3tgXEMLMzk992xEaaHAMGQcAFAkccDTlMEFTIQcCMpJzEUgoytJTgqSRMGUR7eS@JxLTrkg9d@/CKeDBkWcpFzISFzRaeuE4iTkIozif@Qs4uTdKi7VJ2HMT10dj/0P "Scala – Try It Online")
]