| Bytes | Lang | Time | Link |
|---|---|---|---|
| 071 | Python 3 | 250408T004145Z | CrSb0001 |
| 009 | Japt | 240829T115224Z | Shaggy |
| 022 | x86 | 240907T003125Z | qwr |
| 042 | APL+WIN | 240905T161648Z | Graham |
| 431 | Minecraft Function | 240902T031306Z | LostXOR |
| 077 | F# | 240831T012959Z | Juuz |
| 044 | C | 240830T092711Z | jpa |
| 017 | Jelly | 240829T223018Z | Unrelate |
| 126 | Python | 240829T140028Z | TheLittl |
| 089 | Go | 240829T144920Z | bigyihsu |
| 2112 | 05AB1E | 240829T103540Z | Kevin Cr |
| 034 | JavaScript ES6 | 240828T181212Z | Arnauld |
| 015 | Uiua | 240828T194612Z | nyxbird |
Python 3, 76 71 bytes
-5 bytes thanks to @ceilingcat
def r(v):
t=s=0
for b in v:t|=b&128<<s;s+=7
return t-(t>>31>0)*2**32
Takes input as a list of (hexadecimal) bytes. This is actually the same exact length as my solution for parsing Minecraft's VarLongInt, as we only need to change (t>2**31-1)*2**32 in the last line to (t>2**63-1)*2**64.
Japt, 10 9 bytes
Adheres to the OP's original, albeit severely lacking, spec which didn't require support for outputting negative values.
Takes input as a 2D-array of binary digits.
óv ÎÔc ì2
Try it (Includes all test cases)
23 21 bytes
This version does include support for negative outputs. Will try to golf it further if it's confirmed we actually need to support them.
óv ÎÔc ì2
¨2pHÉ
-VÑpH
x86, 24 23 22 bytes
Couldn't figure out any tricks to get rid of shift, so it's a straight-forward do-while loop, checking the byte's sign bit. Input in esi, output in ebx, everything clobbered.
-1 byte by using eax for the t calculations, so I can do 2-byte and al, imm8.
-1 byte by using lodsb instead of mov/inc (but I have to clear upper bits of eax).
parse: ; esi input pointer
31 DB xor ebx, ebx ; ebx result = 0
31 C9 xor ecx, ecx ; ecx shift = 0
.loop:
AC lodsb ; al byte = [esi++]
88 C2 mov dl, al ; save byte for test later
83 E0 7F and eax, 0x7F ; t &= 0x7F, clear upper bits
D3 E0 sal eax, cl ; t <<= shift
09 C3 or ebx, eax ; result |= t
80 C1 07 add cl, 7 ; shift += 7
84 D2 test dl, dl
78 EF js .loop ; loop if byte's sign bit is set
C3 ret ; return in ebx
I formatted all above manually from a NASM listing. Please tell me if there's an easier way.
APL+WIN, 42 bytes
Prompts for bytes as a nested vector.
((-2*32)×↑i)+2⊥i←¯32↑∊⌽(×\¯1↓1,↑¨b)/1↓¨b←⎕
Minecraft Function, 431 bytes
scoreboard objectives add a dummy
scoreboard players set c a 128
execute unless score a a < m a run scoreboard players set m a 1
execute store result score a a run data get storage x x[0]
data remove storage x x[0]
execute if score a a >= c a run schedule function p:f 1
scoreboard players operation a a %= c a
scoreboard players operation a a *= m a
scoreboard players operation v a += a a
scoreboard players operation m a *= c a
This question wouldn't be complete without a Minecraft solution.
Run as a function named f in a data pack named p. Input is given as a list of bytes in array x of storage x, and can be set like so:
/data modify storage x x set value [221,199,1,71]
Output is given as the scoreboard value for player v of objective a, and can be viewed with:
/scoreboard players get v a
The function first sets up a scoreboard for holding variables, sets c = 128 and m = 1, then iterates over each byte a, performing these operations:
- Reduce
amoduloc - Multiply
abym - Add
ato the totalv - Multiply
mby 128
This builds up the value 7 bits at a time. The function terminates one iteration after it finds an a less than c (equivalent to not having its high bit set). Minecraft stores scoreboard values as 32 bit signed integers, so they roll over appropriately for negative numbers.
F#, 77 bytes
let rec p s (x::r)=x&&&127y|>int<<<s|||if-128y&&&x=0y then 0 else p(s+7)r
p 0
A function expression that takes input as a list of signed bytes and outputs a 64-bit signed int.
Commented
let rec p s (x :: r) = // recursive function p that takes the bit shift amount
// and deconstructs a byte list to the first byte x and the tail r
x &&& 127y |> int // convert the current byte's end to a signed int
<<< s // and shift it by s
||| if -128y &&& x = 0y then 0 // OR the value with 0 if the first bit is 0
else p (s + 7) r // otherwise repeat this process for the tail
p 0 // apply the initial shift level to the full function
C, 44 bytes
p(char*x){return*x&127|(*x>>7?p(x+1)<<7:0);}
Input is a char array, decoded recursively and returned as platform native int type. Negative values work correctly on platforms where int is 32 bits (which includes most current platforms such as ARM and x86_64).
Jelly, 17 bytes
ḣṪ€i0ƊFUḄNæ%Ø%H¤N
Input as a list of bit lists, LSB first.
ḣ i Ɗ Remove all elements after the first element which
Ṫ€ has a last element (MSB)
i0 equal to 0,
Ṫ€ and remove every element's last element.
F Flatten,
U reverse,
Ḅ convert from binary.
N N Under negation,
æ% "symmetric modulo"
Ø% 2^32
H¤ divided by 2.
"Symmetric modulo 2y" maps into the half-open interval (-y, y] for positive y (and behaving somewhat strangely for negative y). Unfortunately, this interval is open on the wrong end for two's complement representation, so this is corrected by flanking it with Negates.
Python, 143 137 135 126 bytes
lambda x,s=-7,r=0,c=0:(lambda y:y-(y>2147483647)*4294967296)(sum((r|(b&127)<<(s:=s+7)+0*(c:=b<128))if not c else 0for b in x))
(-6 bytes thanks to @Kevin Cruijssen)
(-2 bytes thanks to @Jordan)
(-9 bytes after I realized I could refactor how lambda y worked, inspired by @Kevin Cruijssen's changing hex to dec)
First time trying code golf. Maybe I shouldn't have chosen parsing bits my first golf ¯\_(ツ)_/¯
Go, 89 bytes
func(B[]byte)(o int32){for i,b:=range B{o+=int32(b&127)<<(i*7)
if b&128<1{break}}
return}
Input is a byte slice, and outputs a 32-bit integer.
05AB1E, 21 (or 12) bytes
η.Δθн_}€¦RJCDžI&ĀžJ*-
Input as a list of binary-strings (e.g. example 0xdd,0xc7,0x01,0x47. is input as ["11011101","11000111","00000001","01000111"])
Try it online or verify all test cases.
Explanation:
Step 1: Main part of the challenge:
η # Get the prefixes of the (implicit) input-list
.Δ # Find the first prefix that's truthy for:
θ # Pop and leave the last string of the current prefix
н # Pop and leave its first bit
_ # Check that it's 0
}€ # After the find_first: map over each prefix:
¦ # Remove its first bit
R # Reverse this list of prefixes
J # Join them together
C # Convert it from a binary-string to a base-10 integer
Try just step 1 online for all test cases.
Step 2: Convert the unsigned to signed 32-bit integers:
D # Duplicate the current value
& # Bitwise-AND it with
žI # constant value 2147483648
Ā # Check whether this is NOT 0
* # Multiply this 0 or 1 by
žJ # constant value 4294967296
- # Subtract that from the value of step 1
# (after which the result is output implicitly)
JavaScript (ES6), 35 34 bytes
f=([v,...a])=>v&&v^(v&=128)|v*f(a)
Commented
f = ( // f is a recursive function taking:
[ v, // v = next byte from input array
...a ] // a[] = remaining bytes
) => //
v // stop if v is zero or undefined
&& // otherwise, get the 7 least significant bits of v
v ^ // by XOR'ing v ...
(v &= 128) // ... with its MSB
// and update v to its MSB
| // merge this with ...
v * // ... v (which is now 0x00 or 0x80) multiplied by
f(a) // the result of a recursive call
Uiua, 15 bytes
°⋯♭▽≤⊗0:°⊏≡⍜⇌°⊂
Takes input as an array of 8-bit bytes (lsb-first)
°⋯♭▽≤⊗0:°⊏≡⍜⇌°⊂
≡⍜⇌°⊂ # pull the msb from each row
:°⊏ # range by the length under the msbs
⊗0 # find the first 0
▽≤ # keep the rows <= to its location
°⋯♭ # flatten and convert from binary