[Question]
  [
## Flavortext
So...this is awkward. It seems I accidentally turned into a monkey last night after eating one too many banana sundaes. This has made many things inconvenient, especially typing. You see, monkeys only need the following characters: uppercase letters (`A-Z`), space, comma (`,`), exclamation mark (`!`), and question mark (`?`). For all other purposes, the Stack Overflow keyboard is enough for copy-pasting a.k.a. monkey see, monkey do. Furthermore, since we are superior to humans and do not have opposable thumbs, we can use our thumbs for more than just the space bar. Finally, monkeys absolutely hate typing consecutive characters with the same finger, so typing combos such as "dee" and "un" on a QWERTY keyboard is very annoying.
## Task
That's why I've made a new ergonomic keyboard that looks like this, and your task is to assign its keys.
Left paw ¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†¬†Right paw  
`‚éï``‚éï``‚éï``‚éï``‚éï`¬†¬†¬†¬†`‚éï``‚éï``‚éï``‚éï``‚éï`  
`‚éï``‚éï``‚éï``‚éï``‚éï`¬†¬†¬†¬†`‚éï``‚éï``‚éï``‚éï``‚éï`  
`‚éï``‚éï``‚éï``‚éï``‚éï`¬†¬†¬†¬†`‚éï``‚éï``‚éï``‚éï``‚éï`
Every finger is used for the three keys in one column and only those keys (so the left pinky would be used for the first column and the right thumb for the sixth).
You will be given a string representative of what I usually type, and will design a keyboard according to the following requirements:
* It will be in the shape of the blank keyboard above.
* It will contain the characters `ABCDEFGHIJKLMNOPQRSTUVWXYZ ,!?` (note the space) and only those characters.
* None of the strings in the input will cause me to type consecutive characters using the same finger.
Here's an example:
```
Input: 'I LIKE BANANAS! WHERE BANANA?!'
```
A valid keyboard would be:
``I````L````A````N````R``¬†¬†¬†¬†``D````F````G````J````M``  
``E````K````!````S````?``¬†¬†¬†¬†``Z````O````P````Q````T``  
``B````Y````W````H````C``¬†¬†¬†¬†``,````U````V````X``
An invalid keyboard would be:
``I````E````A````N````R``¬†¬†¬†¬†``D````F````G````J````M``  
``L````K````!````S````?``¬†¬†¬†¬†``Z````O````P````Q````T``  
``B````W````H````C``¬†¬†¬†¬†``,````U````V````X````Y``
This violates the third requirement, because to type `LI` in `I LIKE BANANAS!`, I would have to use my left pinky twice for consecutive characters: once for `L` on the middle row and once for `I` on the top row. I would also have to use my left ring finger twice while typing `KE`.
## Rules
* The input will always consist only of the characters `ABCDEFGHIJKLMNOPQRSTUVWXYZ ,!?`, just like the keyboard.
* You may assume that a valid keyboard exists for the input.
* You may input and output in any reasonable format.
## Test cases
The output of each test case is formatted the same as the examples above, but without `<kbd>` and spaces between the two paws' keys. An underscore (`_`) is used instead of a space for clarity.
```
'Input'
Keyboard
'I HAVE A TAIL AND YOU DO NOT! WHY?! I PITY YOU!'
I_HAVETLND
Y?OUWPBCF,
!GJKMQRSXZ
'REJECT MODERNITY, RETURN TO MONKE! EAT BANANA!'
RECOD!BQSX
JNKI,FGAV?
TM_YUHLPWZ
```
[Here](https://tio.run/##XVDdT9swEH@e/4qLnxItiyi8oEqo6tZtdIOWj0LJMqsyiUs9EtuyXVj554sv7VjpQxz7fl93Z1Z@odXRsbHrtWyMth7cyqXgvJXqgZBaKuHgBAq8ZFg1Mf2taAJzbQGLIBVKAlZJlVnBq1YTJyDnsK9iBM1aQnHAyON99fb8dNRlhDTSuVm54BYzy0WbEn6Y0XaUcVdKOVsaI2zJnYCPQKNeChTTAlFpj2RKsz9aqjgEYCZvxKzU9bJRwdYtmziM43z8Etqy@rmTQjgPk81MWEAL7G37Pty@WQoFS3btZl789diq4dK29PYS6OiNeyw6Xdau4h@wow7zBqDoHKSw@RhEuI7QWsNNXAuVYmySdMkHE6b3MS3uGEytVg/g5IugCRF1sHjb2nvieSiHnQEivPTCui5N/5O34v1x3ntcBxTmwUVYFO@T0cOJHcktg1wvLTyK1b3mtgLp4InXssposl4P4bR/@xX6MOkPz6A/GkA@voHBGEbjSQTT07wXwRAuhpMcgYiQjWByNhqQvDe@mV58/vItJdH3Hz/PL6@u7369Ag) is a validator kindly provided by [tsh](https://codegolf.meta.stackexchange.com/users/44718/tsh).
  
[Answer]
# [Perl 5](https://www.perl.org/), 134 bytes
```
sub f{@k=(A..Z,$",',','!','?');splice@k,rand@k,0,pop@k for 1..1e3;@p{@k}=0..29;join('',map$p{$_}%10,split//,$_[0])=~/(.)\1/?f(pop):@k}
```
[Try it online!](https://tio.run/##RY9RT4MwFIXf@RWXhUmJTQsaHxwhozqSMRUMYZopZtkcGGSDBtjDQthfx8IezE17k3v6nd7D43J/13XVcQtJY2cWYoR8YGWE1b5kcaaqZlZ8n37HdobLTb4TTce84HYGSVGCQYgR35o2F3hr6YTc3Ju/RZojVcWHDVd4o6zbsaHj3qSmFCvrT/1Ls84UES0y6DRBwkybCLo7nMCu46q2kASgujBnbw4wCJn7DMybwcpfwswHzw9leJ@vpjK48OqGq14Qu/ZQ4CycxxBe/JkTeELCEDjhMvAg9MXQe3JkcFgID8wTJauSZkpSH0N8raQ5P9aAhhW0RrjBMM62O6tPJAJBgi6vBNbLvEzzOoGRO5DXkMWnbbEpd5Moj/Jx9X@P8IXDg9u5oqQx9JYqV1FOf0pTars/ "Perl 5 ‚Äì Try It Online")
```
sub f{
  @k=(A..Z,' ',',','!','?');          #put valid keys in array @k
  splice@k,rand@k,0,pop@k for 1..1e3; #shuffle array @k in random order
  @p{@k}=0..29;                       #assign a position 0-29 to each key
  join('',map$p{$_}%10,split//,$_[0]) #make string of each input char mapped...
                                 #to its key position modulus 10 = column number
    =~ /(.)\1/                   #check if two adjacent column numbers exists...
                                 #for current input
    ?  f(pop)                    #if yes, try new keyboard on same input
    :  @k                        #if no, return current random valid keyboard...
                                 #as an array of 30 chars
}
```
This approach tries random keyboards until it hits a valid one for the current input string. In a test of 1000 runs of both the given test strings, a valid keyboard was found at the 20th trial on average. üêµ
[Answer]
# [Jelly](https://github.com/DennisMitchell/jellylanguage), 18 bytes
```
30≈í!√∞i‚±Æ‚Äô:3n∆ù·∫†√∞∆á·∏¢s3
```
[Try It Online!](https://jht.hyper-neutrino.xyz/tio#WyIiLCIzMMWSIcOwaeKxruKAmTozbsad4bqgw7DGh+G4onMzIiwiw5hBO+KAnCAsIT/igJ3CpGnisa7Dh+G7i+KBuMqLWlkiLCIiLFsiJ0kgTElLRSBCQU5BTkFTISBXSEVSRSBCQU5BTkE/ISciXV0=)
-1 byte thanks to caird coinheringaahing
This should work in theory. However, it is \$O(N! \times NM)\$ where \$N\$ is the size of the alphabet and \$M\$ is the size of the input.
You can try this for a restricted alphabet of "ABCDEF" [here](https://jht.hyper-neutrino.xyz/tio#WyIiLCI2xZIhw7Bp4rGu4oCZOjM9xp3hurjDsMOQ4bif4biiczMiLCLDmEE74oCcICwhP+KAncKkaeKxrsOH4buL4oG4yotaWSIsIiIsWyJBQ0JFRkQiXV0=).
```
30≈í!√∞i‚±Æ‚Äô:3n∆ù·∫†√∞∆á·∏¢s3   Main Link; accept a list of numbers from 1 to 30 on the left
30≈í!                 Get all permutations of 1..30
    √∞        √∞∆á      Filter to keep; map over a dyad, which feeds the input to the right
     i‚±Æ              Get the index of each input in the permutation
       ‚Äô             Decrement to get into the range 0..29
        :3           Floor divide by 3
          n∆ù         For each overlapping pair, check if the column indices are inequal
            ·∫†        Are all inequal? (Filter will keep these)
               ·∏¢     Take the first valid permutation
                s3   Divide it into non-overlapping chunks of length 3
```
Borrowing Kjetil's idea to use random permutations (which I actually had, but I wasn't sure if it'd be valid), we get the following solution, which is way faster (as in you can actually run it):
# [Jelly](https://github.com/DennisMitchell/jellylanguage), 18 bytes
```
i‚±Æ¬≥‚Äô:3=∆ù·∫∏
30R·∫ä√á¬øs3
```
[Try It Online!](https://jht.hyper-neutrino.xyz/tio#WyIiLCJp4rGuwrPigJk6Mz3GneG6uFxuMzBS4bqKw4fCv3MzIiwiIiwiIixbIls5LCAyNywgMTIsIDksIDExLCA1LCAyNywgMiwgMSwgMTQsIDEsIDE0LCAxLCAxOSwgMjksIDI3LCAyMywgOCwgNSwgMTgsIDUsIDI3LCAyLCAxLCAxNCwgMSwgMTQsIDEsIDMwLCAyOV0iXV0=)
-1 byte thanks to caird coinheringaahing by observing that we can bind the input to the right of the index link to avoid needing a combinator that we would've needed from binding it to the link reference call in the while loop.
You can translate test cases from words to numbers [here](https://jht.hyper-neutrino.xyz/tio#WyIiLCLDmEE74oCcICwhP+KAncKkaeKxriIsIiIsIiIsWyInSSBMSUtFIEJBTkFOQVMhIFdIRVJFIEJBTkFOQT8hJyJdXQ==) and translate the output back to text [here](https://jht.hyper-neutrino.xyz/tio#WyIiLCLhu4vDmEE74oCcICwhP+KAncKkWlkiLCIiLCIiLFsiW1s1LCAxMywgN10sIFszMCwgMTcsIDNdLCBbMTAsIDE0LCAxOV0sIFsyOSwgMSwgMThdLCBbMiwgMjYsIDE1XSwgWzIzLCA5LCAyNV0sIFs0LCAxMiwgOF0sIFsyMCwgMTEsIDZdLCBbMjIsIDI4LCAyMV0sIFsyNCwgMTYsIDI3XV0iXV0=).
```
i‚±Æ¬≥‚Äô:3=∆ù·∫∏    Helper Link; check if a permutation is invalid
i‚±Æ¬≥          Get the index of each input in the permutation
   ‚Äô         Decrement to get into the range 0..29
    :3       Floor divide by 3
      =∆ù     For each overlapping pair, check if the column indices are equal
        ·∫∏    Are any equal?
30R·∫ä√á¬øs3     Main Link
30R          1..30
     ¬ø       While
    √á        The permutation is invalid
   ·∫ä         Shuffle it
      s3     Divide it into non-overlapping chunks of length 3
```
Unfortunately, I have to explicitly bind the input as the right argument to `√ß` because otherwise the while loop will Fibonacci.
[Answer]
# [Haskell](https://haskell.org), 181 bytes
```
import Data.List
f[]=[]
f(a:b:c:x)=[a,b,c]:f x
g(a:b:x)=(a,b):g(b:x)
g _=[]
q s=head$filter(\x->not$any(\(a,b)->any(\r->a`elem`r&&b`elem`r)$f x)$g s)$permutations$['A'..'Z']++"?!, "
```
[Try it online](https://tio.run/##LY1BDoIwFET3PcWXNNBG5ABN0GhcGjfuBCIfLdgIBdua4OmxEDOLmXnJZJ5oX7Jtp0l1Q28cHNFhclLWkTor0qwgNUNRibsYeZphXMX3QtQwkmbBHjIPuWjYXEgDt3nzBps@JT5orVonDcvHzVb3jqL@snwZbLZLNt5L2cquNGFY/ROn/oDTBiyngzTdx6FTvbY0i/ZRkkTXqFivg90qhoCQDpWGFAajtAP2huCwP3tddquAT9MP)
Goes through all permutations and picks the first one that does not have any adjacent characters on the same column. Output is flattened. It should work in theory with an awful complexity of O(SNS!) where S the size of the alphabet and N the length of input.
[Answer]
# [Python 3](https://docs.python.org/3/), 163 bytes
```
s=input()
l=k=''.join({}.fromkeys(s).keys())
while any(x+y in l for x,y in zip(k,k[1:])):k=''.join({*k})
print(k+''.join({*'ABCDEFGHIJKLMNOPQRSTUVWXYZ ,!?'}-{*k}))
```
[Try it online!](https://tio.run/##K6gsycjPM/7/v9g2M6@gtERDkyvHNttWXV0vKz8zT6O6Vi@tKD83O7WyWKNYUw9Ma2pylWdk5qQqJOZValRoVypk5inkKKTlFylU6IA5VZkFGtk62dGGVrGamlZIhmll12pyFRRl5pVoZGsjRNUdnZxdXN3cPTy9vH18/fwDAoOCQ0LDwiMioxR0FO3Va3XBOjX///dU8PH0dlVwcvQDwmBFBQA "Python 3 ‚Äì Try It Online")
Returns keyboard transposed flat and joined
[Answer]
# JavaScript (ES6), 136 bytes
*-16 bytes thanks to @tsh*
Expects an array of characters. Returns a random keyboard as an array of 3 strings.
```
f=a=>a.some(c=>p==(p=k.indexOf(c)%10),p=k=[...'ABCDEFGHIJKLMNOPQRSTUVWXYZ ,!?'].sort(_=>Math.random()-.5))?f(a):k.join``.match(/.{10}/g)
```
[Try it online!](https://tio.run/##bY1Nb4JAGITv/RUvh4bdRF/10EuThayFlq0IfqCWNqZu@FBUWAKkadL0tyOa9NbMaWbyzBzll6yjKiubfqHipG1TJpkhsVZ5QiJmlIyRkp0wK@Lk209JRO9HQ9rrIvaBiDofP1n284sjXifu1PNn88UyWK03b@E79DRT33ZDVUM@mTGVzQErWcQqJ7SPD5SaKZH08YRHlRW7HeayiQ5kgD@j4e9gT9tIFbU6J3hWe5KS25kAh69t4BBw4QL3LAj9FVg@eH6gwcYJTQ0EzEQQXgtN31J69@@MKyY2jLnXaXkF7cWfNW9UewE "JavaScript (Node.js) ‚Äì Try It Online")
]