Cubix, 16 bytes
' H I a ' @ / 1
@ O < . . . . .
Try it yourself
You should input the file decimal byte values in a separated list. The separator doesn't matter, anything that is not a digit or a minus sign suffices. The code really only cares about the first byte, so you can leave out the rest of the file if you like. The program outputs
0 for lossless, and
1 for lossy. Try it here! The default input uses a FLAC header.
The nice thing about files is that (nearly) all of them have a so-called magic. Those are the first few bytes of the file. Good software doesn't check the file extension, but rather the file magic to see if it can handle a certain file.
Dennis has found a way to use this magic to find the compression type, but the fact that he discarded the first byte made me want to try to come up with a method that used the first byte, rather than the second. After all, this community is all about saving bytes.
Here's a list of the first bytes of the different file types. I ordered them into two groups: lossy and lossless. Here are the values of their first byte in decimal, hexadecimal and binary. You might see a pattern already...
The pattern I saw, was that the second bit (counted from left to right) was always on on the "lossless" bytes and the fifth bit was always off. This combination does not appear in any of the lossy formats. To "extract" this, we would simply do a binary AND (by
0b01001000 (=72)) and then compare to
0b01000000 (=64). If both are equal, the input format is lossless, otherwise it's lossy.
Sadly, Cubix doesn't have such a comparison operator, so I used subtraction (if the result is 64, this yields 0, and it results in 8, -56 or -64 otherwise. I'll get back to this later.
First, let's start at the beginning of the program. The binary AND is done using the
'H # Push 0b01001000 (72)
I # Push input
a # Push input&72
Then, we compare to 64 using subtraction (note we hit a mirror that reflects the IP to the top face [first line, second character, pointing south] in the middle of this part).
'@ # Push 0b01000000 (64)
- # Subtract from (input&72)
# Yields 0 for lossy, non-zero otherwise
After the IP is turned around by the
u, we use some control flow to push a
1 to the stack if (and only if) the top of the stack is non-zero:
! # if top = 0:
$1 # do nothing
1 # push 1
After we wrap around the cube, we hit the
< instruction, which points the IP west on the fourth line. All that's left to do is output and terminate.
O # Output top of the stack as number
@ # End program
So, the program outputs
0 for lossless, and
1 for lossy.