| Bytes | Lang | Time | Link |
|---|---|---|---|
| 143 | Python 3 | 250513T191244Z | CrSb0001 |
| 101 | JavaScript Node.js | 230812T095735Z | l4m2 |
| 033 | 05AB1E | 220303T075757Z | Kevin Cr |
| 103 | JavaScript Node.js | 220227T152714Z | Arnauld |
| 137 | JavaScript Node.js | 220228T090024Z | tsh |
| 171 | JavaScript Node.js | 220227T091427Z | ophact |
| 047 | Charcoal | 220227T112926Z | Neil |
Python 3, 152 146 142 141 143 bytes
-6 bytes
-4 bytes thanks to @ceilingcat and @CrSb0001
-1 bytes thanks to @ceilingcat
+2 bytes due to an unforseen bug in the code
def t(i):
y,*b=64**(x:=-~len(bin(i))//5)-(4<<5*x)+i,
while y:b=[y%64]+b;y>>=6
for j in range(len(b)):b[j]+=2+(j==0)<<6
return[b,[i]][i<128]
Try it online (Link contains 156-byte version and ungolfed version, as well as a few tests.)
Here are some of the main tricks I used:
- From @KevinCruijssen's 05AB1E answer, I knew that we first calculate$$x=\left\lfloor\frac{\operatorname{len}(\operatorname{bin}(\text{input}))+ 3}5\right\rfloor$$However, since Python automatically attaches the
0bidentifier at the start of a binary string, we can keep that in there and instead define \$x\$ as$$\left\lfloor\frac{\operatorname{len}(\operatorname{bin}(\text{input}))+1}5\right\rfloor$$or instead as-~len(bin(i))//5. - We can use bitshift operators to save bytes. For example, instead of dividing by 64 each time in the
while y:loop, we can instead computey>>=6, which saves a byte. Also, we can write2+(j==0)<<6instead of(2+(j==0))<<6because Python bitshift operators work in a way that I don't really understand. - Since Python allows negative list indexes (the full range of allowed indexes of a list being \$-\operatorname{len}(\text{list})\le\text{idx}\lt\operatorname{len}(\text{list})\$), that actually means that instead of reversing the list before the
forloop, we can just writeb[~j]since~j == -j-1for any Python integer. Also, for any list,list[-i] == list[len(list) - i - 1]
Ungolfed version:
def to_base_inf(inp):
if inp < 128:
return [inp]
x = (len(bin(inp)[2:]) + 3) // 5
y = 64 ** x - 4 * 32 ** x + inp
BASE_64 = []
while y:
BASE_64 += [y % 64]
y //= 64
BASE_INF = BASE_64[::-1]
for i in range(len(BASE_INF)):
BASE_INF[i] += 128 + 64 * (i == 0)
return BASE_INF
JavaScript (Node.js), 101 bytes
n=>(h=x=>x>>8n?[...h(x>>6n),x%64n+128n]:[x])((g=x=>n>>7n?n>>1n+5n*x?g(++x):64n**x-32n**x:x)(0n)*4n+n)
05AB1E, 33 bytes
žy@ibg3+5÷U64Xm32Xm4*-+64вāΘÌ64*+
Port of @Neil's Charcoal answer.
Try it online or verify all test cases.
Explanation:
In pseudo-code:
For inputs \$<128\$, simply output the input
For inputs \$\geq128\$:
- With \$n\$ as input, first calculate: \$x=\left\lfloor\frac{len(bin(n))+3}{5}\right\rfloor\$
- Then calculate \$y=64^x-4\times32^x+n\$
- Convert this \$y\$ to a base-64 list
- Add 128 to each item, and an additional 64 to the very first item, which is the intended output
žy@i # If the (implicit) input-integer is >= 128:
b # Convert the (implicit) input to a binary string
g # Pop and push its length
3+ # Add 3
5÷ # Integer-divide that by 5
U # Pop and store it in variable `X`
64Xm # Push 64 to the power `X`
32Xm # Push 32 to the power `X`
4* # Multiply it by 4
- # Subtract it from each other
+ # Add the (implicit) input to it
64в # Convert this integer to a base-64 list
ā # Push a list in the range [1,length] (without popping)
Θ # Convert every non-1 to 0 (with an ==1 check)
Ì # Add 2 to each
64* # Multiply each by 64
+ # Add the values at the same positions in the lists together
# (after which this list is output implicitly as result)
# (implicit else:)
# (implicitly output the implicit input)
JavaScript (Node.js), 104 103 bytes
Saved 1 byte thanks to @emanresuA
Expects a BigInt. Returns a comma-separated string of bytes.
n=>n>127?(g=k=>k>63?g(k>>6n)+[,k&63n|128n]:k|192n)(2n**(x=(h=n=>n?-~h(n/2n):3n)(n)/5n)-4n<<x*5n|n):n+''
92 bytes
An alternate version taking a standard JS number. It only works up to 0x3FFFFFF, which somewhat defeats the purpose of using UTF-∞. :-/
n=>n>>7?(g=k=>k>>6?g(k>>6)+[,k&63|128]:k|192)(2**(x=(h=n=>n?-~h(n>>1):3)(n)/5|0)-4<<x*5|n):n
How?
This is essentially the same method as @Neil's.
Using the recursive function \$h\$, we compute \$x=\left\lfloor(b+3)/5\right\rfloor\$, where \$b\$ is the number of bits in the input.
We compute \$2^x-4\$ (a bit mask consisting of \$x-2\$ ones followed by \$2\$ zeros). We shift it by \$5x\$ positions to the left and OR it with \$n\$.
Using the recursive function \$g\$, we convert the result to base \$64\$ in big-endian order. We add \$192\$ to the leading byte and \$128\$ to the other ones.
JavaScript (Node.js), 137 bytes
n=>n<128?[n]:eval(`[0b${('1'.repeat((L=(s=n.toString(2)).length+3)/5)+'0'.repeat(~(4.8*~L%6-2))+s).match(/^.{8}|.{6}/g).join`n,0b10`}n]`)
StackExchange code highlight is broken again... Not sure if using string based idea could golf some more bytes or not.
JavaScript (Node.js), 171 bytes
n=>n<128?n:(F='0bxxxxxxxx '.repeat(c=((d=n.toString(2)).length+3)/5|0)[r='replace'](/ 0bxx/g,' 0b10',i=0))[r](/x/g,_=>i++<c?1:d.padStart(5*c+3,0)[i-c])[r](/0b\d{8}/g,eval)
Since n<128 is an edgecase, just handle it there and then.
Next, the code determines the number of bytes using a simple formula: if there are c bytes, then there are 5c+1 x's, so we use that. This means subtracting one from the number of bits in the binary representation and dividing that by five. We repeat xxxxxxxx that many times. Replace the first two x's of any byte that is not the first with a 10, then replace the remaining x's with the (padded) binary representation of n, then evaluate each byte.
Output format: as a number for n<128, as a space-separated string (with trailing newline) otherwise. Let me know if this is not allowed.
Fails on last testcase due to JavaScript's limitations.
Thanks @Neil for -7 bytes.
Charcoal, 47 bytes
Nθ≔÷⁺³L↨貦⁵ηI⎇‹θ¹²⁸θE↨⁺θ⁻X⁶⁴η×⁴X³²η⁶⁴⁺ι×⁶⁴⁺²¬κ
Try it online! Link is to verbose version of code. Explanation:
Nθ
Input the integer.
≔÷⁺³L↨貦⁵η
Calculate the number of bytes the extended representation would take.
I⎇‹θ¹²⁸θ
If the integer is less than 128 then just output the integer again, otherwise...
E↨⁺θ⁻X⁶⁴η×⁴X³²η⁶⁴⁺ι×⁶⁴⁺²¬κ
... calculate n-2 high-level bits, add that to the integer, convert to base 64, then add 192 to the first byte and 128 to the remaining bytes.