Cubix, 16 bytes
$-!u'HIa'@/1@O<
Forma neta:
$ -
! u
' H I a ' @ / 1
@ O < . . . . .
. .
. .
Inténtalo tú mismo
Debe ingresar los valores de bytes decimales del archivo en una lista separada. El separador no importa, cualquier cosa que no sea un dígito o un signo menos es suficiente. El código realmente solo se preocupa por el primer byte, por lo que puede omitir el resto del archivo si lo desea. El programa genera salidas 0
sin pérdidas y 1
con pérdidas. Pruébalo aquí ! La entrada predeterminada usa un encabezado FLAC.
Explicación
Lo bueno de los archivos es que (casi) todos ellos tienen la llamada magia. Esos son los primeros bytes del archivo. Un buen software no verifica la extensión del archivo, sino la magia del archivo para ver si puede manejar un determinado archivo.
Dennis ha encontrado una manera de usar esta magia para encontrar el tipo de compresión, pero el hecho de que descartó el primer byte me hizo querer intentar encontrar un método que usara el primer byte, en lugar del segundo. Después de todo, esta comunidad se trata de guardar bytes.
Aquí hay una lista de los primeros bytes de los diferentes tipos de archivos. Los ordené en dos grupos: con pérdida y sin pérdida. Aquí están los valores de su primer byte en decimal, hexadecimal y binario. Es posible que ya veas un patrón ...
Lossy: Lossless:
255:0xFF:0b11111111 102:0x66:0b01100110
79:0x4F:0b01001111 84:0x54:0b01010100
35:0x23:0b00100011 82:0x52:0b01010010
11:0x0B:0b00001011 70:0x46:0b01000110
0:0x00:0b00000000
El patrón que vi fue que el segundo bit (contado de izquierda a derecha) siempre estaba activado en los bytes "sin pérdidas" y el quinto bit siempre estaba desactivado. Esta combinación no aparece en ninguno de los formatos con pérdida. Para "extraer" esto, simplemente haríamos un AND binario (by 0b01001000 (=72)
) y luego lo compararíamos con 0b01000000 (=64)
. Si ambos son iguales, el formato de entrada no tiene pérdida, de lo contrario es con pérdida.
Lamentablemente, Cubix no tiene ese operador de comparación, por lo que utilicé la resta (si el resultado es 64, esto produce 0, y de lo contrario resulta en 8, -56 o -64. Volveré a esto más adelante.
Primero, comencemos al comienzo del programa. El AND binario se realiza utilizando el a
comando:
'HIa
'H # Push 0b01001000 (72)
I # Push input
a # Push input&72
Luego, comparamos con 64 usando la resta (tenga en cuenta que golpeamos un espejo que refleja la IP en la cara superior [primera línea, segundo carácter, apuntando al sur] en el medio de esta parte).
'@-
'@ # Push 0b01000000 (64)
- # Subtract from (input&72)
# Yields 0 for lossy, non-zero otherwise
Después de que el IP cambia u
, usamos un poco de flujo de control para empujar a 1
a la pila si (y solo si) la parte superior de la pila no es cero:
!$1
! # if top = 0:
$1 # do nothing
# else:
1 # push 1
Después de envolver el cubo, tocamos la <
instrucción, que apunta la IP hacia el oeste en la cuarta línea. Todo lo que queda por hacer es generar y finalizar.
O@
O # Output top of the stack as number
@ # End program
Por lo tanto, el programa genera 0
pérdidas y 1
pérdidas.