[Question]
  [
# Challenge
Your task is to encode an integer as a string of [ASCII](https://codegolf.meta.stackexchange.com/a/5869/82619) characters, then successfully decode it after said string has been randomly shuffled.
You will write two [programs/functions](https://codegolf.meta.stackexchange.com/q/2419/82619), which will be referred to as *Encoder* and *Decoder*.
### *Encoder*
* **Input:** an integer \$n\$ in the range \$[0,2^{31}-1]\$.
* **Output:** a string \$s\$ of [ASCII](https://codegolf.meta.stackexchange.com/a/5869/82619) characters (not necessarily printable).
### *Decoder*
* **Input:** a random permutation \$s'\$ of the string \$s\$.
* **Output:** the integer \$n\$.
# Scoring
Let \$A\$ be the **maximum length** of \$s\$ across all possible values of \$n\$. If the *Encoder* acts non-deterministically (which is allowed, see below), then the \$A\$ will be the maximum length of \$s\$ that may occur (possibly \$\infty\$).
Let \$L\_E\$ be the **length of the *Encoder*** in bytes and \$L\_D\$ the **length of the *Decoder*** in bytes.
Then your score is \$A\cdot(L\_E+L\_D)\$.
Victory is awarded to the submission the **lowest score**.
# Time limit
There is a somewhat arbitrary **time limit of 1 minute** on the execution time of both the *Encoder* and the *Decoder* for a single testcase (i.e. a single value of \$n\$).
The goal is to avoid solution that find that brute-force the encoding by enumerating all sequences with certain properties. If your solution does something more clever than that, it will most likely fit the time constraint and will be considered valid. Likewise, if it works on [TIO](https://tio.run/#) for some randomly selected values of \$n\$ it will be considered valid. Otherwise I will test it on my machine, but note that if your solution is pure brute-force it will almost certainly fail.
# Rules
* The *Encoder* and the *Decoder* must be written in the **same language**.
* The *Decoder* must output the **correct** integer \$n\$ for every possible permutation \$s'\$ of the string \$s\$ returned by the *Encoder*.
* The *Encoder* and the *Decoder* are **not** allowed to **share information** in any way (e.g. by means of global variables or files).
* The output of the *Encoder* need **not** be **deterministic** (that is, the same input \$n\$ may produce different output strings if the *Encoder* is run multiple times), but the *Decoder* must always guess the correct integer \$n\$.
* The *Encoder* and the *Decoder* may take and return the integer \$n\$ in **any convenient way** (e.g. if \$n=14\$ it is fine for the input to be `14`, `"14"` or `[1,4]`).
* The *Encoder* may output the string \$s\$ either by **printing** it on `stdout` **or** by **returning** a string, a list/array of characters or a list/array of integers in the range \$[0,127]\$; note that the *Decoder* will receive as input a permutation of \$s\$ as returned by the *Encoder*, so it should accept the string \$s'\$ in the **same format** as \$s\$.
* [**Standard loopholes**](https://codegolf.meta.stackexchange.com/q/1061/82619) are forbidden.
* If possible, **explain** how your code works and why the score you claim is correct.
# Example
> 
> Assume \$n=14\$.
> 
> 
> * The *Encoder* receives `14` as input. It may output `"qwerty"`.
> * The *Decoder* receives a permutation of `"qwerty"` as input, for instance `"tweyqr"`. It must output `14` (in any convenient format).
> 
> 
> 
The *Encoder* could have returned `[113,119,101,114,116,121]` as well, in which case the *Decoder* would have received (for instance) `[116,119,101,121,113,114]`.
Note that the string returned by the *Encoder* may also include non-printable ASCII characters (but always in the range `[0x00, ..., 0x7F]`).
  
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), (17 bytes + 18 bytes) × length 6 = 210 points
```
b36µỤỤ+×3µŒ¿b3U+Ṣ
```
```
Ṣ:3_J
Ṣ%3Uḅ3œ?Çḅ36
```
[Try it online!](https://tio.run/##y0rNyan8/z/J2OzQ1oe7lwCR9uHpxoe2Hp10aH@Scaj2w52LuLiAhJVxvBeIVjUOfbij1fjoZPvD7SCG2X/DI/sf7mx5uKsLSJoc2f//v7GhkZmlpaGZOQA "Jelly – Try It Online") [(or with extra debug info)](https://tio.run/##y0rNyan8/z/J2OzhzpZDWx/uXgJCO1u0geydLYenG4OFj046tB/ISALxQrUf7lzExQUkrIzjvYACIKaqcSiQ9XBHK0jF0cn2h9uhXLP/hkdAWh/u6gKSJkf2//9vbGhkZmlpaGYOAA "Jelly – Try It Online")
Having had a go at solving this challenge aiming at the stated victory condition, I thought it'd be interesting to go for a hypothetical alternative victory condition: [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'") given a minimum possible maximum length for the output.
## Explanation
### Encoding
The first step in the encoding is to represent the input as base 36 (`b36`). 366 = 2176782336 > 2147483647, so there will be at most 6 digits in the result, each of which is in the range 0–35.
Next, we transform this into a representation that contains 6 *different* digits. There are multiple possible algorithms for this, but the one used here is to add 1 to the smallest digit, 2 to the second-smallest, 3 to the third-smallest, and so on. This means that if two digits were the same, one of them will be arbitrarily considered smaller, and thus they'll become different; and obviously, this algorithm can't cause two different digits to become the same. In order to represent this in Jelly, we use `Ụ` ("sort indexes by values") to get a list of the indexes in sorted order; `Ụ` again to invert that, effectively mapping each element of the original to its position in sorted order; and `µ…+` to add the original to the new list. The result is a representation of the input number as six *different* digits in the 1–41 range (minimum 0+1, maximum 35+6).
We then split this into yet another form: a *sorted* list of digits in the 1–41 range, alongside a number from 1 to 720 that represents which of the 720 possible permutations the digits were in. (The `Œ¿` and `Ṣ` extract the permutation number and sorted list respectively.)
Finally, we convert the number from 1 to 720 into base 3 (`b3`), reverse it (`U`), and encode the six base 3 digits and six 1–41 digits via packing them each into a single ASCII character using reverse divmod (the value of the character mod 3 is the base 3 digit, the value divided by 3 is the 1–41 digit). The possible range of results is (1×3)+0=3 at minimum, and (41×3)+2=125 at maximum, fitting within our ASCII range. The packing is done via `×3` and `+`, together with an additional `µ` to make sure that every command operates on the right bit of data. (There's a bit of a golfing trick here, in that we do the multiplication by 3 *before* extracting the permutation; that saves the need to spend a byte on a grouping character.)
Incidentally, the reason to reverse the base 3 number is because it may have fewer digits than the 1–41 number. (It can't have more; the smallest number for which *n*! > 3*n* is slightly above 6.) Jelly effectively inserts trailing zeros when adding together two numbers of different lengths, in order to make them match up; trailing zeroes would affect the interpretation of the number, but *leading* zeroes wouldn't, so the reverse is used to ensure that the extra zeroes end up somewhere that won't mess up our answer.
### Decoding
The first step in decoding is to extract the two numbers (the base 3 number and the 1–41 number). We can get their digits easily enough with division (`:3`) and modulo (`%3`) respectively, but how to know which order they were in? Well, the 1–41 number had its digits in sorted order, and digits in corresponding positions of the two numbers were stored in the same characters; thus, we can work out which order the 1–41 number's digits were shuffled into (by looking at their relative values) and know that the base-3 number's digits must have been shuffled the same way. In fact, because characters of our ASCII encoding sort the same way as the 1–41 number's digits (these were all distinct and they're more significant than the base 3 number's), we can simply put the characters of the encoding back into order with a sort `Ṣ`. So both extractions start with `Ṣ`, followed by `%3` or `:3` as appropriate.
While the 1–41 number's digits are still in sorted order, we have a very convenient/terse way to go back to the 0–35 digits of base 36; just subtract 1 from the first, 2 from the second, 3 from the third, and so on. In Jelly, we can do that with `_J` ("subtract index").
Meanwhile, in the other branch of the decode, we reverse the base 3 number's digits back into order (`U`), and convert it from base 3 back into a permutation index with `ḅ3`.
We can then combine the two branches with `œ?Ç`; `œ?` means "permute given this permutation index", and `Ç` means "the result of applying the line above", i.e. it's what tells Jelly to run both lines separately on the same input.
What we have now is the digits of the original number, in base 36 (due to the `_J`), and in the original order (due to the `œ?`), so we can simply do a `ḅ36` to convert back from base 36 into a single integer.
## Commentary
The TIO! link above uses 312699167 as the number to encode. This number in base 36 is `[5, 6, 6, 8, 7, 35]`, and thus shows off all aspects of the encoding: the 35 tests the limit of the 0–127 range we have; the duplicate 6s test the resolution of identical digits in the original base 36; and the fact that the digits are almost (but not quite) sorted means that the permutation number is very small, giving it many fewer digits than the base 36 number, and thus showing the need to reverse it before adding it to the original.
It's really convenient how all the constants here fit together. 366 is only *just* high enough to fit 231, 36 is only *just* high enough to fit 6!, and (36+6)×3 is only *just* high enough to fit within the 128 possibilities we have. (The last constraint here is the least tight, because we could use 0-indexing rather than 1-indexing to make use of characters in the 0-2 range. Still, that'd only give enough room to use 37 as the base rather than 36.)
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), (~~4~~ 3 bytes + ~~6~~ 5 bytes) × length 8 = ~~80~~ 64 points
```
b⁴Ä
```
```
ṢŻIḅ⁴
```
[Try it online!](https://tio.run/##y0rNyan8/z/pUeOWwy1cD3cuOrrb8@GOViD3v@GR/Q93tjzc1QUkjY7s///fyNDE3MTC2MzEHAA "Jelly – Try It Online")
# [Jelly](https://github.com/DennisMitchell/jelly), (~~2~~ 1 byte + ~~4~~ 3 bytes) × length 10 = ~~60~~ 40 points
```
Ä
```
```
ṢŻI
```
[Try it online!](https://tio.run/##y0rNyan8//9wC9fDnYuO7vb8b3hk/8OdLQ93dQFJoyP7//@PNtIx1DHRMQdiCx1jHTMQOxYA "Jelly – Try It Online")
## Explanation
### Solution 1
This is using a different algorithm from most of the other answers. We start by encoding the value in hexadecimal (`b⁴`), as with the other answers, then take a cumulative sum (`Ä`). Each input will clearly give a different output (as both these operations are reversible), and given that the hexadecimal encoding will contain at most 8 digits whose maximums are 7 (for the 8th-last digit) and 15 (for the last to 7th-last digits), the maximum number in the output list will be 7+(7×15) = 112, less than the 127 required by the question. Additionally, the output will necessarily be in sorted order, allowing us to reverse the shuffle.
For the decoder, we first reverse the shuffle with a sort (`Ṣ`); then reverse the cumulative sum, by prepending a zero (`Ż`) and taking the difference of consecutive pairs (`I`); then convert back from hexadecimal (`ḅ⁴`).
### Solution 2
The question actually allows us to take the input as a list of (presumably decimal) digits, so we can "cheat" by simply removing the base conversion; the maximum number used in the output will then be 2 + (9×9) = 83 (actually 82 because 2999999999 is out of range, so the worst possible input is 1999999999). The resulting encoding is pretty terrible as encodings for this problem go, but it has the advantage of being very terse to generate, which outweighs the verbosity of the encoding.
This answer feels so much like cheating that it's not my primary solution for this problem, but it seems like it's worth adding because it technically complies with the rules and produces a better score.
## Commentary
I have some algorithms in mind for getting below length 8, but it seems unlikely you could implement a length-7 algorithm in ≤9 bytes (non-cheating) or ≤5 bytes (cheating), so by the scoring in the question, this is likely the best way to do it. (I might have a go at a solution for the alternative "minimize the length of the encoding" challenge anyway, though, just for fun.)
Unlike some of the solutions, the use of 16 as the base here isn't critical; there are plenty of other numbers that would work for a length 8 solution (e.g. 18). I picked 16 for the first solution simply because Jelly has a 1-byte way to represent that, and other viable bases would need to use up multiple bytes from the program. Of course, the second solution needs to use 10 as the base in order to exploit the loophole.
Thanks to @Dennis for pointing out some newer Jelly commands that made this algorithm even terser to write.
[Answer]
# [Shakespeare Programming Language](https://github.com/TryItOnline/spl), 10 \* (264 + 494) = ~~8650 7910~~ 7580
### Encoder: 264 bytes
```
,.Ajax,.Ford,.Act I:.Scene I:.[Exeunt][Enter Ajax and Ford]Ajax:Open mind.Be you nicer zero?You be the sum ofyou the product ofthe sum ofI a big big pig the sum ofa big big big big cat a big big pig.If soSpeak thy.Ford:You are the sum ofyou a cat.If soLet usAct I.
```
[Try it online!](https://tio.run/##XY/NCsIwEIRfZR@gBMRitRdRUCgIHnqS0kOabLVqk5AfaH35mFSk6GFgZ@dbhjXq6X1Cdnc6JOQoNQ8zs1DkpGQoMA7VYUAnbF0dhEUNEQUqOES6ji4/KxTQd4KTPcIoHYiOBfKFWm4vwTYI9oZgXA@yjXl0SkvuQpVs56wACk13naSC5mTef8Wo/aVJ0YKRpUL6CIfj9E0e66n@76fx@sOf0IIz08/E@8UmzdL1cpVmbw "Shakespeare Programming Language – Try It Online")
### Decoder: 494
```
,.Ajax,.Ford,.Page,.Act I:.Scene I:.[Exeunt][Enter Ajax and Ford]Ajax:Open mind.Is you nicer a pig?If soRemember you.If soLet usAct I.Scene V:.Ford:Remember I.Ajax:Recall.Is you worse the sum ofPage twice the sum ofa big big cat a cat?If soYou be the difference betweenyou Page.If soOpen heart.If notlet usScene V.Scene X:.Ford:Recall.Ajax:Be I nicer zero?If soRemember I.If soLet usScene X.[Exit Ajax][Enter Page]Ford:You be the sum ofyou twice twice the sum ofa big big cat a pig.Let usAct I.
```
[Try it online!](https://tio.run/##hZBBS8RADIXxR3jzkLtlTp6KIAorFAVFQdRlD9M27Y60M2Umpat/vibT2aV48dDSpMnL914YunnO1O2XPmTq3vk6U8@6Re5UBEWuXiu0KB/bzQFHS7vtxhJ6kAXQtgbZ2UmVPw1ooTe2VkWAbzeCNRVPahhMe1M0ENwL9tiX3OO/KnYekWAM8VY69ZZHjPw0W0Q4rivddUfpyfmAQHuEMPbgGmEGmvjgqqmhNG18Kk3Mwe@F44MVymWyNk2DHi0vlkgTohV5kVsAo6k9ak9SW0ddJE6sifn9xBwZI@8dp5YS@EHv/gRQrO0nEYnYUEz2mLJw7KL0CnkxJ5jJ8D@2OX61znmez84vLq@uHz7r8As "Shakespeare Programming Language – Try It Online")
This was a thing.
The encoder encodes each digit as the digit plus the index of the digit times twelve. The decoder stores all the input in the Ford's memory and then loops over a counter, outputting then deleting each digit lower than the counter\*12 + 10.
## Explanation:
### Encoder
```
,.Ajax,.Ford,.Act I:.Scene I:.      Boilerplate introducing the two characters
[Exeunt][Enter Ajax and Ford]       Enter the two characters Ajax and Ford
                                    Ford will be handling the input
                                    Ajax will be the counter
Ajax:Open mind.                     Set Ford to the next character of input
Be you nicer zero?                  Check if it is EOF
You be the sum of                   Set Ford to the sum of 
    you                             His original value (48 to 58)
    the product of                 
          the sum of               
              I                     Ajax's value
              a big big pig         Minus 4 (this handles the offset of 48)
          the sum of                Multiplied by
              a big big big big cat 2^4
              a big big pig.        + -2^2 = 12
                                    This essentially sets Ford to (F+12*(A-4))
If soSpeak thy.                      If not EOF, print Ford's value
Ford:You are the sum ofyou a cat.   Increment Ajax's value
If soLet usAct I.                   If not EOF, Repeat again.
```
### Decoder
```
,.Ajax,.Ford,.Page,.Act I:.Scene I:.  Boilerplate introducing three characters
                                      Ajax is the spare stack
                                      Ford is the storage stack
                                      Puck is the counter, increasing by 12
[Exeunt][Enter Ajax and Ford]            Enter Ajax and Ford onto the stage
Ajax:Open mind.                          Get the next character of input
Is you nicer a pig?                      If not EOF
If soRemember you.                         Store the value in Ford's memory
If soLet usAct I.                          And repeat the loop
Scene V:.                                Otherwise move to the next scene
Ford:Remember I.                         Store Ford's value (initially -1 from EOF) in Ajax's memory
Ajax:Recall.                             Get the next value from Ford's memory
Is you worse the sum of                  Is the value smaller than
        Puck                                  Puck's value
        twice the sum ofa big big cat a cat?  + 10 ?
                                              i.e. is it the next digit?
If soYou be the difference betweenyou Puck.   If so, subtract Puck's value from Ford
If soOpen heart.                              And print Ford's value
If notlet usScene V.                     If that was not the digit, repeat
Scene X:.
Ford:Recall.                             Get the next value from Ajax's memory
Ajax:Be I nicer zero?                    Until the -1
If soRemember I.                         Returning the values to Ford's memory
If soLet us Scene X.                     Repeat until Ajax's memory is exhausted
[Exit Ajax][Enter Page]                  Swap Ajax and Page
Ford:You be the sum of                   Set Puck's value to
              you                        Puck +   
              twice twice the sum of     2*2*(
                           a big big cat      4
                           a pig.             -1) = 12
Let usAct I.                             And start from the beginning again, having removed one number
```
[Answer]
# Python 2.7, 31 \* (52 + 37) = 2759
**Encoder (~~69~~ 52 bytes):**
```
lambda n:[chr(i)if n&(1<<i)else""for i in range(32)]
```
**Decoder (~~41~~ 37 bytes):**
```
lambda s:sum([1<<(ord(c))for c in s])
```
Stores the all the non-zero bits in the input number as ascii values. The value of the ascii character stores the position of the set bit. For example the value 'a' would mean that the 97th bit is set.
A few improvements, thanks to @Delfad0r
[Try it online!](https://tio.run/##RY9LbsMwDET3OgXhRUMCQdHIKFIYSS8SZOFaVK1CogzKXrSXd@SmnxWH5JsBOX3OYxa7rl5zAu3F1RLSlHWG0qcpsnHsoYyL95G/sFAHyvOiArvd40cOgncMyz5ybYjIGIYzxD69uR6ka5o7dxlGxUDBozzg4XQK9PpEHAs3jc8KAYJsB7wzHuyRrmTcf0rpypLwUl2Y1eFAtFmGzVIqaaSitrXt87G1L2bSIDMK/Qiu8lc7/Hvle1wX63oD "Python 2 – Try It Online")
[Answer]
# [Stax](https://github.com/tomtheisen/stax), score 8 × (10+9) = 152
### Encoder, 10 [bytes](https://github.com/tomtheisen/stax/blob/master/docs/packed.md#packed-stax)
```
Ç·MÉJ'♀τ│½
```
[Run and debug it](https://staxlang.xyz/#p=80fa4d904a270ce7b3ab&i=16%0A2147483647%0A1823792&a=1&m=2)
```
16|E{i16*+m Full program, implicit input
16|E        Get hexadecimal digits
    {     m Map:
     i16*+    Add 16 * loop index
            Implicit output as string
```
The encoder outputs the string in an increasing order.
### Decoder, 9 [bytes](https://github.com/tomtheisen/stax/blob/master/docs/packed.md#packed-stax)
```
üL∟n╫k∞‼9
```
[Run and debug it](https://staxlang.xyz/#p=814c1c6ed76bec1339&i=%01%10%0A%0A%10%01%0A%0A%07%1F%2F%3FO_o%7F%0A%0A_%3F%7F%1F%2FoO%07%0A%0A%3F%07o%1FO%2F_%7F%0A%0A%01%1B-4CP%0A%0A-C%01P4%1B&m=1)
```
o{16%m16|E Full program, implicit input
o          Sort string
 {16%m     Module each element by 16
      16|E Interpret as array of hex digits
```
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), 8 maximum length \* (8 + 7) bytes = 120
### Encoder (8)
```
hεHN16*+
```
[Try it online!](https://tio.run/##yy9OTMpM/f8/49xWDz9DMy3t//@NDE3MTSyMzUzMAQ "05AB1E – Try It Online")
### Decoder (7)
```
{16%hJH
```
[Try it online!](https://tio.run/##yy9OTMpM/f@/2tBMNcPL4///aHMdBWNDHQUTIG1mrKNgbqmjYGmqo2BoCBQ0NDKPBQA "05AB1E – Try It Online")
Uses the same technique as [wastl](https://codegolf.stackexchange.com/a/172696/59487) and [Jonathan](https://codegolf.stackexchange.com/a/172697/59487).
[Answer]
# [Python 3](https://docs.python.org/3/), 8 \* (45 + 38) = 664
### Encoder (45 bytes):
```
lambda n:[16*i+(n>>4*i)%16 for i in range(8)]
```
### Decoder (38 bytes):
```
lambda l:sum(x%16<<x//16*4 for x in l)
```
[Try it online!](https://tio.run/##VY3djoIwEEbv@xRzY2wRfyqVdYlypU9hvCgC2oQOpELCZrPPzhaLqDdzzmS@yVf91LcSg6477gupk1QCRiceempGMY6Fp9iEh5CXBhQoBCPxmtEtO5PDM19E90bT1sZ2u3a5tL/ikW/7fME6pavS1P1nWmpC0iwH0yBFFhEACXs4WreaWJWn6GzVZRf3W5PnRUaT/nyx54PTyiis6fT3D@YxfM7pwlZrWVP0QfqQ@HBhjJC@cMUe4A5rh/DJYKAYuBkYOorVtxhtM9rr@jXadijwvIDPg/dl/b5w1v0D "Python 3 – Try It Online")
[Answer]
# JavaScript (ES6), 8 \* (40 + 32) = 576
The encoder outputs an array of \$0\$ to \$8\$ integers. The decoder takes the same format as input.
## Encoder (40 bytes)
```
E=(n,k=0)=>n?[k|n&15,...E(n>>4,k+16)]:[]
```
## Decoder (32 bytes)
```
s=>s.map(c=>s|=c%16<<(c/4&~3))|s
```
## Demo
[Try it online!](https://tio.run/##dU@xTsMwEN39FbfQ@prE1E1bJKjN0ixIhIGxqpBJQxqS2lVsIVUEfj04oTAgsdx7757u3t2relM2a8qji7TZ5V2XCKrDSkxRSH27qVo94ouQMZZQLeU8rAK@xO31ZkvIWhArpGUHdaSZJ63ILvhytaLZ5Xz0GSO2tnO5dSAgBSHhnQA0ufUyoSneeJUZbU2ds9oUNIUAxhBF0tcA7h4fUmZdU@qifDlRP4aDT3vTK1bnunD7ofd88ik4xt/1vW9N4@hTH3uv3J41Su/MgSJEwBb4J/q/sJ9j1kMLyQch/T90it94dUY@i89sNpnEPOLYfQE "JavaScript (Node.js) – Try It Online")
## How?
The input is divided into 8 blocks of 4 bits and each block is encoded with 1 among 16 possible characters. The most significant bit of the last block is never set.
```
       3222222222211111111110000000000
bit:   0987654321098765432109876543210
       \_/\__/\__/\__/\__/\__/\__/\__/
block:  7  6   5   4   3   2   1   0
block #0 is encoded with char. 00 to 0F (NUL to SI)
block #1 is encoded with char. 10 to 1F (DLE to ES)
block #2 is encoded with char. 20 to 2F (' ' to '/')
block #3 is encoded with char. 30 to 3F ('0' to '?')
block #4 is encoded with char. 40 to 4F ('@' to 'O')
block #5 is encoded with char. 50 to 5F ('P' to '_')
block #6 is encoded with char. 60 to 6F ('`' to 'o')
block #7 is encoded with char. 70 to 77 ('p' to 'w')
```
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), (8 + 9) [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page) \* 8 max-length = 136
```
b⁴+J’Ɗ⁴¡
```
**[Encoder](https://tio.run/##y0rNyan8/z/pUeMWba9HDTOPdQFZhxb@P9x@dNLDnTP@/7e0MDczNTE2MgQA "Jelly – Try It Online")** (footer formats the list as Python would for clarity)
```
Ṣ_J‘Ɗ⁴¡ḅ⁴
```
**[Decoder](https://tio.run/##y0rNyan8///hzkXxXo8aZhzretS45dDChztagfT///@jDQ3MdRSMzHQUTEx1FAwNjXUUgMjcQEfBzEhHwcIiFgA "Jelly – Try It Online")**
It's theoretically possible to have a max-length of six, can that be done in 22 bytes or fewer?
It's impossible with a max-length of five since \$\sum\_{i=0}^{i=5}\binom{127+i}{127}=321402081< 2^{31}-1\$
### How?
Since \$2^{31}-1\$ is encodable as 8 hexadecimal digits (`7fffffff` or `[7,15,15,15,15,15,15,15]`) we may then add the zero-based index of each hex-digit multiplied by 16 to ensure such a conversion is always in sorted order while keeping even the rightmost value in-bounds (i.e. `[7,15,15,15,15,15,15,15] + [0,16,32,48,64,80,96,112] = [7,31,47,63,79,95,111,127]`). Decoding is then reversing this same process.
**Encoder**:
```
b⁴+J’Ɗ⁴¡ - Link: integer, n    e.g. 1234
 ⁴       - literal 16               16          
b        - convert to base          [4,13,2]
       ¡ - repeat...
      ⁴  - ...16 times:
     Ɗ   -   last 3 links as a monad:
   J     -     range of length        [1,2,3]     iter 2    iter 3    ...  iter 16
  +      -     add                    [5,15,5]   [5,16,7]   [5,17,9]  ...  [5,30,35]
    ’    -     decrement              [4,14,4]   [4,15,6]   [4,16,8]  ...  [4,29,34]
         -                                                                 [4,29,34]
```
**Decoder**:
```
Ṣ_J‘Ɗ⁴¡ḅ⁴ - Link: list of integers   e.g. [29,34,4]
Ṣ         - sort                          [4,29,34]
      ¡   - repeat...
     ⁴    - ...16 times:
    Ɗ     -   last 3 links as a monad:
  J       -     range of length           [1,2,3]
 _        -     subtract                  [3,27,31]   [3,26,29]   [3,25,27]  ...  [3,12,1]
   ‘      -     increment                 [4,28,32]   [4,27,30]   [4,26,28]  ...  [4,13,2] 
        ⁴ - literal 16                    16
       ḅ  - from base                     1234
```
[Answer]
# [Shakespeare Programming Language](https://github.com/TryItOnline/spl), 31 \* (472 + ~~383~~ ~~379~~ 344) = ~~26505~~ ~~26381~~ 25296
Previous score: 16909322 \* (246 + 217) = **7829016086**
This is still very high, but it's the lowest I can think of right about now.
Encoder:
```
,.Ajax,.Ford,.Act I:.Scene I:.[Enter Ajax and Ford]Ajax:Remember a pig.Ford:Listen tothy.Scene V:.Ajax:Remember the remainder of the quotient betweenI a big cat.Ford:You be the quotient betweenyou a big cat.Be you nicer zero?If solet usScene V.Remember a pig.Scene X:.Ajax:Recall.Ford:Am I worse zero?If notremember I.If notlet usScene X.Ajax:You zero.Scene L:.Ford:Recall.Ajax:You be the sum ofyou a cat.Am I nicer zero?If sospeak thy.Am I worse zero?If notlet usScene L.
```
[Try it online!](https://tio.run/##bZDPbsIwDMZfxQ@AIrHtlAti0iZF6mmTJtDEIU0NhDVJSVwxePkuabKOIW7@8/nnzw5dOwwztjzI7xl7db6JsSIQnL0rtJiCzxdL6CFJQNoGkmqTMv6GBk0dexI6vRvHeaUDoQVytD8Xxgdn/@W0R/BopLZNzNx2LBx7RxotQY10QrQiUmu9AyUpk9euj7272nNs/amfEVLBahXpF/RuIbYQXIsEfSiW2I33XF5NTpVs27x2aUDAyfmAE8s68r/jguXCNX2VKclwGinwimdggU@SclPoTXxFviRdMe69vSF0KL8gvfa@rWsXFRuG@cPj0w8 "Shakespeare Programming Language – Try It Online")
Decoder:
```
,.Ajax,.Ford,.Page,.Act I:.Scene I:.[Exeunt][Enter Ajax and Ford]Ajax:You cat.Ford:Open mind.Remember the sum ofyou I.Scene V:.Ajax:Am I nicer a cat?If soyou be twice you.Ford:If soyou be the sum ofyou a pig.If solet usScene V.[Exit Ford][Enter Page]Page:Recall.Ajax:Am I worse a cat?If notyou be the sum ofyou Ford.If notlet usAct I.Open heart
```
[Try it online!](https://tio.run/##bVBLCsIwEAVBFLzEHKDkANmIC4WulAqCSBcxHbXSJKWZ0nr6mkkLKrgJmbw37xNfV8OQiM1T9YnYuaZIxEHdMbxoglSKo0aLfLlse2wt5ZetJWyAF0DZAngn50meXQtaUVSR@xotmNIWIkOD5hpW6IHgWwPu9grMdJI@yWguNwZSsKUORMUy6/QG3jHzikBdACAMo/gP9KOqoC7vIuIVErR@MuH4JY1hpwZcM@dDZqhVVX3F6Fzj8RPDOvprxmpixEez@GciVn@gamgYlrPFav4G "Shakespeare Programming Language – Try It Online")
Basically, if the string contains a character with the ASCII code (n+1), the nth binary digit is set.
[Answer]
# Python 3, (208 bytes + 200 bytes) \* 6 length = 2448
[Try it online!](https://tio.run/##nZHPbsIwDMbP7VP4RkpTIO0QCCmc2Bv0hjh0SroGBZc1raZd9urMLn/GruvBib/6c/xLzl9902JxuRhbw6tA2WiVr5NNHJXaV6c3UwFKs8FpKTBV0mQqmc8NuBrMVlkfLBio0ABC24GKI6O9XsRR0PtDHH02zlvArS5FIw03jTC7JbQ3qSZHTUYHDqGr8N2Ka9mzM/PSpN9u1G/@u8SKH7tEIdV7T2d2th86hBAz0E6E/6OEWWi7XtAhIxKRWaR@cYQ6DCdRCroouUt4/t3z/MkTU@ChOTv@Vnh5Z0n12CQ7jsOQ5LXje8mY6AaCF3c60xxsNu1pxCpt6AVyk2A/QPO7kfvcOSRZAomUhmaoH/@u5hlrtbeC14eDEwkWjZ7AhNR26Mm3@1tEYhI/sPYLCUpCTjFfcVhTsnzhsJSwLtbFGElQC/5oLdRiRfX5dFrkmTrwqzCFSy4/ "Python 3 – Try It Online") (contains both, the extra byte is the newline between them).
-4 bytes (-24 score) by utilizing the empty list (which allowed more things to start at 0)
### Encoder (208 bytes)
```
def E(n,h=128):
    T=lambda n,d:n*T(n+1,d-1)//d if d>1else d and n or 1
    d=l=0
    s=[]
    while n>=T(h,d):
        n-=T(h,d)
        d+=1
    for i in range(d):
        while n>=T(h-l,d+~i):
            n-=T(h-l,d+~i)
            l+=1
        s+=[l]
    return s
```
### Decoder (200 bytes)
```
def D(s):
    T=lambda n,d:n*T(n+1,d-1)//d if d>1else d and n or 1
    s.sort()
    l=0
    d=len(s)
    n=sum(T(128,D)for D in range(d))
    for i in s:
        for j in range(l,i):
            n+=T(128-j,d-1)
        l=i
        d-=1
    return n
```
Observations:
* Shuffling can be losslessly reversed for strictly non-increasing (i.e. sorted) lists.
* Strictly non-increasing numerical lists of the same length can be [totally ordered](https://en.wikipedia.org/wiki/Total_order) (as they are in Python).
* We can define that lists are ordered by length first to form a total order of all sorted lists.
* We can form an indexable sequence of these lists if we define that the only valid values in a list are integers from `0` to `127` inclusive (i.e. there exist a finite number of valid lists with length `L`).
Strategy:
* Encoder: Given a number `N`, find the `N`th valid strictly non-increasing list.
* Decoder: Given a (shuffled) valid list, sort it and return its index in the sequence of valid lists.
Common code explanation:
* `T=lambda n,d:n*T(n+1,d-1)//d if d>1else d and n or 1`
* Compute the `n`th [`d`-simplex number](https://en.wikipedia.org/wiki/Figurate_number#Triangular_numbers)
	+ For `d=0`, always `1`
	+ For `d=1`, `n` (the number of dots in a line of dots with length `n`)
	+ For `d=2`, \$\sum\_{i=1}^{n} i\$, (the number of dots in a triangle of dots with side length `n`)
	+ For `d=3`, \$\sum\_{j=1}^n \sum\_{i=1}^{j} i\$, (the number of dots in a tetrahedron of dots with side length `n`)
Encoder explanation:
* `def E(n,h=128):` `d=l=0`, `s=[]`
* `n` is the input number, `h` is the "high value" (i.e. the highest number allowed + 1), `d` is the length the output will be, `s` is the output, `l` is the "low value" (starting at 0, explained more later)
* `while n>=T(h,d):`, `n-=T(h,d)`, `d+=1`
* There are `T(h,d)` valid length-`d` lists, and our calculation is easier if `n` is an index relative to the list `[0]*d` (at index `0`) instead of an actual index, so decrement `n` accordingly. This also adjusts `d` (the length) to be correct for the given `n`.
* `for i in range(d):`
* Effectively: "for the `i+1`th number in the list"
	+ This is where I will explain `l`, the "low value"
	+ After a number has been put into the list, no number less than it can be put in the list (to keep it sorted), so `l` is the last number that was added to the list.
	+ `while n>=T(h-l,d+~i):`, `n-=T(h-l,d+~i)`, `i+=1`
	+ If `n` is too big to be encoded with an `l` at this "digit", then adjust `n` accordingly and increment `l`
	+ `s+=[l]`
	+ Encode `n` with an `l` at this "digit".
	+ At first, we have `h` options for what "digit" to put in next, but once we put in a "digit" (which is assigned to `l`), we are limited to `h-l` options for the next "digit".
	+ At first there were `T(h,d)` valid lists, but we have added a "digit" `l`, decreasing the number of "digits" left to `d-1` and the number of valid next "digits" to `h-l`, so the number of valid lists after this is `T(h-l,d-1)`
Decoder explanation:
* `def D(s):`, `s.sort()`, `l=0`, `d=len(s)`
* `s` is the (shuffled) input list, so `s.sort()` it; `l` is the "low value" (`h` the "high value" is just literal `128`s in the code to save bytes), `n` is the output number, `d` is the length.
* `n=sum(T(128,D)for D in range(d))`
* Adjust `n` to the point in the sequence of `[0]*length`
* `for i in s:`
* For each digit:
	+ `for j in range(l,i):`, `n+=T(128-j,d-1)`
	+ Adjust `n` to the point in the sequence of `[...prevdigits, thisdigit, 0...]`
	
	
		- `l=i`: Set the "low value" to the most recent digit
		- `d-=1`: Decrement the length since we used a digit
* `return n`: After `n` has been adjusted for all of the digits, it is the right number; return it.
Sorry if this isn't clear, but here's my original [nongolfed debug version Try it online!](https://tio.run/##jZTBjoIwEIbvPEUTPRQtKruXjdn6FN4IMZhWKcLAUozZp2cLaClQdcuFZqZ///k6bfFbxTl81nUszjH1P76cPU2j7MgiBIRtYbHHsPQJ83x3vWZInBDb@TyVHEE7Qe2/7zB@QnDNjrw8VPlB8h8M7tZB98Gor/8lDUI9SfMb3ejZLRapEt7RPW7sEGZIPAZ4fXQSZEtjo1NeIoEEoDKCM8c2sdGGnrKjShWq2GnuxICR/TRZpZiWNINVVBQcGFbxfnFRCqgwI5IAGQRKXl1LQLKlrNg2iDvYWBpO5UrmZYX7dWCwNY@gKzvloJbvmIXx8r@Mh@enicupZhNL@tNo2IlXlB8WvKRtPsdCloqpOc8wN@uAqj4mcgITau020LFFA5AzHIhw3D7qargusWSSJBwX1@Ta1jc3RnzTROnMLDrk0ildLErv1edPNEnaqaYWhXc7PdckWaeaWRRe7zTXDIMNuX/9gxBuR9dBkGHDC3d8YYbPziTbdeo/ "Python 3 – Try It Online"), which doesn't use the empty list, so is 1 off from all numbers used in this version
[Answer]
# [Ruby](https://www.ruby-lang.org/), (36+29 bytes)\*8, score 520
Encode:
```
->n{(0..7).map{|x|(n>>x*=4)%16+x*4}}
```
[Try it online!](https://tio.run/##KypNqvyfZmj7X9cur1rDQE/PXFMvN7GguqaiRiPPzq5Cy9ZEU9XQTLtCy6S29n@BQpphtImlhbG5kWHsfwA "Ruby – Try It Online")
Decode:
```
->a{a.sum{|x|x%16<<(x/4&28)}}
```
[Try it online!](https://tio.run/##PYxNCoMwEIX3nsJNq6Yk7YyhWjC5iLiw0NCFisQGUjRnT0dou3jwfj6edfd3NKC4ntb8IkRViLGf181v@aS1Z0oWB7iePJMhJAZV5Lpfe7G4cWc8bU2T@7M8Yl2EEOfUgjLQyltdVghdQgUqC2J5OmOGx55LZbC1SJt7LWkmOOd/ZQQgYyVwIEccfX1z9/vo4gc "Ruby – Try It Online")
### How it works:
The number is encoded using 4-bit chunks and a 3-bit index.
Decoder takes the input array and puts every nibble into its place again.
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), score 10 \* (10 + 15) = 250.
Uses decimal; previous base 16-based solution scored ~~328~~ ~~296~~ 264.
May output nonprintable characters. In particular, character 10 is tricky to input to Charcoal.
Encoder, 10 bytes:
```
⭆⮌Ｓ℅⁺Ｉι×χκ
```
[Try it online!](https://tio.run/##JYu7CoAwDAB/pWMKFezs6OQgiPoDoQQt1gdt7O/HqrccHJxbMboTg8gQ/cEwcdHS4wUjZYqJoDuum/8MWhvVlgMdU4Qh3AlaTAy@9NnvlMDWRm36oxGx9YtUOTw "Charcoal – Try It Online") Link is to verbose version of code.
Decoder, 15 bytes:
```
ＩΣＥＳ×﹪℅ιχＸχ÷℅ιχ
```
[Try it online!](https://tio.run/##S85ILErOT8z5/z@gKDOvRMM5sbhEI7g0V8M3sUDDM6@gtCS4BCiRrqGpoxCSmZtarOGbn1Kak6/hX5SSmZeYo5EJlDA0ABIB@eWpRRqGBjoKnnklLpllmSmp6IrAwPr/f@P/umU5AA "Charcoal – Try It Online") Link is to verbose version of code.
Version using a list of integers scores ~~360~~ 296 (base 16; decimal would score 310):
Encoder, 19 bytes:
```
ＮθＩＥ⁸⁺﹪÷θＸ¹⁶ι¹⁶×¹⁶ι
```
[Try it online!](https://tio.run/##S85ILErOT8z5/98zr6C0xK80Nym1SKNQ05oroCgzr0TDObG4RMM3sUDDQkchIKe0WMM3P6U0J1/DM6/EJbMsMyVVoxAokV8O1GRopqOQqampo2BoBiRCMnNTi2FiQGD9/7/Bf92yHAA "Charcoal – Try It Online") Link is to verbose version of code.
Decoder, 18 bytes:
```
ＩΣＥＥ⁸Ｎ×﹪ι¹⁶Ｘ¹⁶÷ι¹⁶
```
[Try it online!](https://tio.run/##LYrLCsMgEEX38xWznICFmAaxdNluukgItD9gE6GCxmA0/XxjHxfO5pw7vlQYvbI5D8HMkS5qjXRPjjq1fJEMb/OSYp/cUweqKoYP4/RKnZ@S9WQYclHk4N8lc/G5x6vZzKT/7bdzzjUicIFwbBBaiSBaBFkjnIrjvMmHze4 "Charcoal – Try It Online") Link is to verbose version of code.
Version using printable characters scores 360 (was ~~416~~ ~~384~~ 368 in base 16):
Encoder, 19 bytes:
```
⭆⮌Ｓ℅⁺Ｉι×χ⁺κ×⁵⊕×³÷κ⁵
```
[Try it online!](https://tio.run/##PcvBCsIwEATQX8lxAxFapCeP9dKDUNQfWNJFF9NYkm1@P01adC4Djxn7xmC/6HIeA3uBh5R63XCBOyUKkWDwyyoHg9ZG9eWBVijA6NYIPUYBLv7kmSK0jVG7f37SGTV4G2gmLzTBgeeKcuXEE9Vpp/@55Nw2NfmU3AY "Charcoal – Try It Online") Link is to verbose version of code.
Decoder, 17 bytes:
```
Ｆθ⊞υ⌈Φθ¬№υκ⭆υ﹪℅ιχ
```
[Try it online!](https://tio.run/##S85ILErOT8z5/z8tv0hBo1BTIaC0OEOjVEfBN7EiM7c0V8MtM6cktUijUEfBL79Ewzm/NK8EJJ2tCQLWXAFFmUCB4BIgle6bWADWmZ9SmpOv4V@UkpmXmKORqamjYGgAUvz/v5GNW0DU4d3/dctyAA "Charcoal – Try It Online") Link is to verbose version of code.
[Answer]
# [Brachylog](https://github.com/JCumin/Brachylog), 17+18 bytes \* 8 length = 280
## Encoder:
```
ḃ₁₆I∧7⟧₁;Iz₁~ḃ₁₆ᵐ
```
## Decoder:
```
ḃ₁₆I∧7⟧₁;Iz₁~ḃ₁₆ᵐp
```
A p can be added to the end of the encoder with no effect.
The decoder is run by putting the (shuffled) result as the output and getting the original number in the input.
If there would be a (properly implemented) cumulative sum predicate the score could drop down to 20
[Try it online!](https://tio.run/##SypKTM6ozMlPN/r//@GO5kdNjY@a2jwfdSw3fzR/OZBn7VkFJOvgUg@3Tij4/9/IAAb@RwEA "Brachylog – Try It Online")
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), score: (2 + 2 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)) \* 11 maximum length = 44
**Encoder (2 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)):**
```
.¥
```
[Try it online.](https://tio.run/##yy9OTMpM/f9f79DS//@jjXUMdEx0zHUsdIyALEMdy1gA)
**Decoder (2 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)):**
```
{¥
```
[Try it online.](https://tio.run/##yy9OTMpM/f@/@tDS//@jDU10zHWMjHSMTHWMTHSMdQzAFBDFAgA)
Input of the encoder and output of the decoder are a list of digits.
Port of [*@ais523*'s 2nd Jelly answer](https://codegolf.stackexchange.com/a/172706/52210).
**Explanation:**
```
.¥    # Undelta (automatically prepends a 0)
      #  i.e. [3,0,4,7,8,2,0,1,9] → [0,3,3,7,14,22,24,24,25,34]
{     # Sort
      #  i.e. [14,7,22,25,24,3,0,24,34,3] → [0,3,3,7,14,22,24,24,25,34]
 ¥    # Deltas
      #  i.e. [0,3,3,7,14,22,24,24,25,34] → [3,0,4,7,8,2,0,1,9]
```
Because `.¥` prepends a zero to the output, the length of the output is the length of the input + 1. Since \$2^{31}-1\$ has a length of 10 digits, the maximum length of the output is 11.
[Answer]
# [Gol><>](https://github.com/Sp3000/Golfish), 8 \* (14 + 13) = 216
Encoder [Try it online!](https://tio.run/##S8/PScsszvj/39PCLS0g2MVCy0c7v8b6//9HDWuByNDI2MTUzNzC0gAA "Gol><> – Try It Online"), 14 bytes:
```
I8FfPSD8*L+o|;
```
Decoder [Try it online!](https://tio.run/##S8/PScsszvj/P9M1wyLYxUTLSCVCS/v/f4FMIT9mE191AA "Gol><> – Try It Online"), 13 bytes:
```
iEh8SD4*2$X*+
```
Since this can output unprintable ascii characters, thus messing with the decoder, there is now a version using numbers in the output / input:
Encoder [Try it online!](https://tio.run/##S8/PScsszvj/39PCLS0g2MVCy0fbr8b6//9HDWuByNDI2MTUzBwA "Gol><> – Try It Online"), 14 bytes:
```
I8FfPSD8*L+N|;
```
Decoder [Try it online!](https://tio.run/##S8/PScsszvj/P9M1wyLYxUTLSCVCS/v/f4FMIT9mE191AA "Gol><> – Try It Online"), 13 bytes:
```
IEh8SD4*2$X*+
```
## Encoding:
The encoding works by breaking the given number into 8 x 4bit chunks. These chunks are then shifted right by 3 bit and the original location of the chunk is appended on the end as a number between 0 and 7. Thus the encoding looks like this:
```
0AAAABBB
 |__|    -> the original part of the number
     |_| -> the position of the chunk inside the original number 0 = LSB and 7 = MSB
```
[Answer]
# [Perl 6](https://github.com/nxadm/rakudo-pkg), 10 \* (10 + 12) = ~~340~~ 220
Encoder:
```
{^@_ Z~@_}
```
Decoder:
```
{.sort X%10}
```
[Try it online!](https://tio.run/##K0gtyjH7n1up4JBo@786ziFeIarOIb5Wh6tarzi/qEQhQtXQoBYkr5aqYAtUFG0Qa80F4qZAuIYQrkoekJuTmZdaDFOgUgEUSdVQydNLzs9N0rTmKk4ECVpzgSVUKvQKMpOzNbSQJEB0ioZKhab1fyNDE3MTC2MzE3MA)
The encoder function zips each digit with the 0-index of the number. Then the encoder sorts the list of numbers and gets the modulo by 10, in other words the second digit of the number.
The total is 10, since that's the maximum length of 231-1.
[Answer]
# [Haskell](https://www.haskell.org/), 10\*(23+51) = 740
Here's a program that encodes, shuffles, decodes and validates values: [Try it online!](https://tio.run/##ZVPBjtowEL3nK0YIqUkBQ1rUbREgrXZVCQmEtBx6oGjXwgMxBDuyDez25@k4DqGouTiZN2@e38wk43aPeX6Rh0IbB09aOaNzNtOKi6gKPnPH2aMx/INN5nfBqbTuGlh8WIcH9sKV0Ico6nTA8T0q2Bh9gMy5wg663bPcS5YFTabNthvSX2123GxyjKoTBgNY8hV0xjCZ@7caeLcwAqEjqB5uYNgBhefyfqAoocY22sxgmTKmVtCE39KX@4fqn51nm/IOL6QUy7ZK7hJOssxALoIA6cn7hN1/Cbu7hLORDm8YVbyDDbqjUVSGoucMDZaoIpc5qq3LroZqi9SaiXLey61D8WQeQI/w5J6gQtN8wM8rBOOUnBJwQbUm8I8sfkmXxXErYXHa@5wkyx5jq0igRw@8AKsEszTnOU3UOkah@E3I00yLt7SXXA5cqpA5e4WtBgYOrSPd4RC26PxeoaLvYJEuWMEQL3vttP2jndKRttP@ClqthOhe03eVXnOp0HoO1VWfbvOnFaO6J6TlcxnCiedHBKdBUmEht/6gyQI51AIpWpJydGV3q9rF0SAMm2OwmT5T9Xo2SDm@Nyq6ai2qFfRaoaYImmWCRb8H1zXFmvWMpbonVaCAhnVGqm2jvpDwpqjV9sZ7ynC9B7mBM8KGS0/zZgoiBrv0txVhNainCmIB3RHQTJvkyS2cgcbPx8l0AEElxKaKLFMBNGuec4fQ8AvUIM6y8t8OjcDqtPQiYDwelZ@rS1o/0Ze0/9D//vVb/@Ev "Haskell – Try It Online")
## Encoder, 23 bytes
```
zipWith((+).(10*))[0..]
```
[Try it online!](https://tio.run/##JYwxDsIwDAD3vsJjAiIqiLVdygO6gQQMVjBNRJJGjll4PKHAdiedzmF5UAjVxzyzwAEFzeCQQYF1DLppKFno4FJfPh@9OKXW2qhtu9L63BpzrRF9WoKJZJiTUJICfd9BZp8EDETMv5OB7@jviglvC@cnk6773dveA06lbk7DOH4A "Haskell – Try It Online")
## Decoder, 51 bytes
```
map snd.sortOn fst.map(`divMod`10)
import Data.List
```
[Try it online!](https://tio.run/##TY6xCsIwGAb3PsWHLoliqGuhLtVBUHRwcOjQ0CQ1mCYl@fHxje3megfHvWR6a@fyWmljvYbSPdo8ygnJK5FCpJuHSSRmxDplP9egun3JCztOs8RRkhQXmyj/g@YlIxhCVOBFMUrrUWPQ1ARP2lPC4VBjitYTBExwyoGxLRdsX244BytRVTh74rNejgSWoyUnELVUedWebo/WrL69cXJIefds7vcf "Haskell – Try It Online")
### Explanation
Since we're allowed to use input as decimal digits, we'll use that.. The encoder maps each digit that occurs to `10*index + digit`, note that all `digit`s will be in `[0..9]` so we can reverse the above by using `divMod`. After restoring the indices and the digits it's only a matter of sorting by the indices and getting rid of them.
The solution is expected to work for values up to \$2^{31} - 1 = 2147483647\$ which is 10 digits long, so the maximum code-point we get will be \$9 \cdot 9 = 81 < 128\$. Also each digit will be converted to a "character", so we'll end up with a maximal length of 10.
[Answer]
# [Husk](https://github.com/barbuz/Husk), 10\*(7+8) = 150
Straight port of my Haskell solution only with the observation that \$10 \cdot 9 = 90 < 128\$ (Husk's `N` is 1-based):
## Encoder, 7 bytes
```
zo+*10N
```
[Try it online!](https://tio.run/##yygtzv7/vypfW8vQwO/////RpjomOkaxAA "Husk – Try It Online")
## Decoder, 8 bytes
```
m→Ö←m‰10
```
[Try it online!](https://tio.run/##yygtzv7/P/dR26TD0x61Tch91LDB0OD////RhqY6xkY6RiaxAA "Husk – Try It Online")
[Answer]
# [APL (Dyalog Unicode)](https://www.dyalog.com/), \$L\_E+L\_D=36; A=8 \rightarrow 288\$.
```
d←{16⊥n-16×⍳≢n←⍵[⍋⍵]}
e←(⊢+16×⍳∘≢)16⊥⍣¯1⊢
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT///qG@qp/@jtgkG/1OAZLWh2aOupXm6hmaHpz/q3fyoc1EeUPRR79boR73dQCq2lisVKKDxqGuRNkxNxwygMk2wxke9iw@tNwRK/v@fqmBoZGzClaJgomBkqQBmAWkTCMvYBCwMljUGsQA "APL (Dyalog Unicode) – Try It Online") (contains 5 extra bytes for the assignments and the newline).
Uses `⎕IO←0`
### How:
```
(⊢+16×⍳∘≢)16⊥⍣¯1⊢ ⍝ Encoder; input 1234
          16⊥⍣¯1⊢ ⍝ Convert input to base 16 → 4 13 2
      ⍳∘≢          ⍝ [0..length of the list-1] → 0 1 2
   16×             ⍝ times 16 → 0 16 32
 ⊢+                ⍝ plus the original list → 4 29 34
```
---
```
{16⊥n-16×⍳≢n←⍵[⍋⍵]} ⍝ Decoder; input ⍵ → 34 4 29
              [⍋⍵]  ⍝ Grade ⍵ up → 2 0 1
             ⍵      ⍝ Index ⍵ with that list → 4 29 34
           n←       ⍝ assign that to n
      16×⍳≢         ⍝ 16×[0..length(n)-1] → 0 16 32
    n-              ⍝ subtract that from n → 4 13 2
 16⊥                ⍝ Decode from base 16 → 1234
```
[Answer]
# PHP, 8\*(44+53) = 776
## encoder, 44 bytes:
```
for(;$n=&$argn;$n>>=4)echo$n&15|16*$i++," ";
```
prints space separated list of integers. Run as pipe with `-nR`.
maximum 8 bytes with 4 data bits (lower nibble) and 3 weight bits (upper nibble).
Simply put:  
Put each hex digit in an own character and use the upper half of the byte to store the digit´s position.
## example:
`1457893891` (`0x56e5b203`) will turn into  
`0x03`, `0x10`, `0x22`, `0x3b`, `0x45`, `0x5e`, `0x66`, `0x75`  
→ `3 16 34 59 69 94 102 117`
## decoder, 53 bytes:
```
while($i++<8)$n+=(15&$x=$argv[$i])<<($x>>4)*4;echo$n;
```
or
```
while($i++<8)$n+=(15&$x=$argv[$i])<<($x/4&~3);echo$n;
```
or
```
for(;$i<9;$x=$argv[++$i])$n+=$x%16<<($x/4&~3);echo$n;
```
take integers from command line arguments. Run with `-nr`.
---
[Try them online](http://sandbox.onlinephpfunctions.com/code/d2366ed2c91a18dc9531ec1893193b048f65a0b7).
[Answer]
# [Python 2](https://docs.python.org/2/), 10\*(68+54) = 1220
```
e=lambda n:"".join(chr(int(`i`+j))for i,j in enumerate(`n`)if j<'L')
d=lambda s:int("".join(`ord(c)%10`for c in sorted(s)))
```
[Try it online!](https://tio.run/##NZDLbsMgEEX3fMUoVWVIkZXHzmq2XfUjIPZQY9kDgvHCX5@C7LBBiHvOcIkbj4FuL7/EkBiSpSEsQnzAiHPEBG6lnn2gFn5CAsbMnv40UGCItgDBwXNj7MNK3BYsj6tzM2awkDmV7KGct1YM6N73MqtOQFkJeU0ETdNOwZPcw222S6whPSOVqFIvfMx2eQ4WqDud9mw/JumJpfHma1LKlfd5PYEnQFoXTJZRGjLKO5i@m99GieEtyV0F3yIT0iB79Xm9mCrpqyKX38Bhn03wOFq0davoRd/O5/tVCRFLSQbSgJKUhoIcDeu5wP8 "Python 2 – Try It Online")
EDIT: Thanks to Jo King for the pointers - not sure why I was offsetting by 32, in retrospect.
Encodes the position and value of each place as a single character, starting with ~~[space] (position 0, value 0)~~ the NUL byte 0x0.
Decodes by:
* sorting the string (Python will sort characters by their ordinal value)
* converts each character into its ordinal value
* takes the last digit of each ordinal integer
* joins the integers into a string
* converts the joined string back into an int
[Answer]
# [C (gcc)](https://gcc.gnu.org/), 10\*112 = 1120
```
c,i;e(i,s)char*s;{for(c=1;i;c+=10,i/=10)*s++=c+i%10;*s=0;}
d(char*s){for(i=0;c=*s++;i+=--c%10*pow(10,c/10));s=i;}
```
[Try it online!](https://tio.run/##vZbNbqMwEMfvfopRK1Y2HxtIyEfl0ieo9ranbFaiBoIjQiMM6qHi1ZcdmzjbSHv2HwmG8cz87AEsRHQUYppEKHlJZaiYqPPOV/yzeu@oyBIuuQiyJA7lAs/MV0GQiUB6Scx9lcV8JAWdU5hJkegTmQ7jMsiiSGCkf3n/oFhCLLAC4yqTfJweZSuaoSjhWfVFI9@@1y/kn6@X51J7iPrILwYAvgphNnoGn2S2RQ0ZjnCCJ2312urREjUnIyFk4Yu6zC@g6qGqmtJfkKtli5pasu1BYlbMZ/uEtuq7pmypYugbWiWPbVmYQVWikQGlPqV3Az5TjMFv@M8A/ab26YGhsJopEGSgF0l//Hx9Nc4ubwuqh/SdrOjJzEz3lOPcnmEZ4zUIjBfA9AWLmizmnQ4hfL3TNUYymhYQoudwzmVLTfLd1OyqTTfUPkkOnJCbV78SYDpw6TC6og/eANEL7D110NeHEGyAbetd9NVZfM3xhl8t5uHTxOXqfsy4xDFvGTsGruKVY2Iax3HqFrk2csvcJOZwC91u1ul6s3UL3V3ljErsx7lc6dXunpy9wWB3BSvX4Js4uN2XkuVVjsHJyso1OLVyDV5buQZvrFyDt1auwbvb3uUY/GTlDtyV/dC1@gdK/35Nf0TV5Ec1Rc35Lw "C (gcc) – Try It Online")
I have global variables, but they are not actually passing any info between two functions. Variable declaration for `c` is used in both functions saving me 2 bytes in code length.
A version that uses printable ASCII only for a ~~3~~ 5 byte penalty is here:
```
c,i;e(i,s)char*s;{for(c=32;i;c+=10,i/=10)*s++=c+i%10;*s=0;}
d(char*s){for(i=0;c=*s++;i+=(c-=32)%10*pow(10,c/10));s=i;}
```
Thanks @ceilingcat for 70 points improvements.
]