Dado un archivo de audio, determine si está codificado en un formato con pérdida o sin pérdida. Para los propósitos de este desafío, solo se deben clasificar los siguientes formatos:
Reglas
- Si la entrada se toma en forma de un nombre de archivo, no se deben hacer suposiciones sobre el nombre de archivo (por ejemplo, no se garantiza que la extensión sea correcta para el formato, ni siquiera presente).
- No habrá metadatos ID3 o APEv2 presentes en los archivos de entrada.
- Se pueden utilizar dos salidas únicas y distinguibles, como
0
y1
,lossy
ylossless
,foo
ybar
, etc.
Casos de prueba
Los casos de prueba para este desafío consisten en un archivo zip ubicado aquí que contiene dos directorios: lossy
y lossless
. Cada directorio contiene varios archivos de audio que son todas ondas sinusoidales de 440 Hz de 0,5 segundos, codificadas en varios formatos. Todos los archivos de audio tienen extensiones que coinciden con los formatos anteriores, con la excepción de A440.m4a
(que es audio AAC en un contenedor MPEG Layer 4).
Respuestas:
Jalea ,
75 bytesLos formatos con pérdida devuelven 0 , los formatos sin pérdida devuelven 1 .
Pruébalo en línea! (enlaces permanentes en Gist)
Antecedentes
Los formatos que tenemos que admitir tienen los siguientes números mágicos, es decir, comienzan con estos bytes.
Las entradas sangradas son contenedores para el formato anterior que aparecen en los casos de prueba.
?
denota un byte variable..
denota un byte no imprimible. Todos los demás bytes se muestran como su carácter ISO 8859-1.Al observar solo el segundo byte, podemos determinar el formato de una manera fácil:
Los formatos sin pérdida tienen una letra mayúscula como segundo byte, mientras que los formatos con pérdida no.
Cómo funciona
fuente
C,
828032 bytesInspirado por la respuesta de @Dennis , esto se puede reducir mucho más:
Canalice los datos del archivo a stdin. Devuelve 0 para sin pérdida, o distinto de cero para con pérdida.
O el cheque original más largo:
Canalice los datos del archivo a stdin. Devuelve distinto de cero (1) para sin pérdida, o 0 para con pérdida.
Por lo que puedo decir, todos los formatos que enumeró tienen números mágicos separados (excepto AIFF / WAV, pero ambos son sin pérdida de todos modos), por lo que esto solo verifica ese número mágico para un valor sin pérdida conocido. Esto
*v&&
es solo para proteger contra archivos coincidentes que comienzan con un byte nulo (M4A).He incluido los valores que encontré en las hojas de especificaciones (
fLaC
= FLAC,RIFF
= WAV / AIFF,TTA1
= TTA), yFORM
= AIFF yFFM2
= TTA son de los archivos de muestra proporcionados (solo puedo adivinar que estos son formatos de envoltura o versiones posteriores).O una alternativa más corta para hacer trampa:
Bash + archivo, 61 bytes
Toma el nombre de archivo como argumento. Devuelve 0 para sin pérdida, o distinto de cero para con pérdida.
Hace exactamente lo que esperarías; pregunta
file
cuál es el tipo de archivo, luego busca patrones conocidos. TTA coincide: d
(: data
), coincide con AIFF / WAVIF
y coincide con FLACFL
. Ninguno de los resultados sin pérdida coincide con ninguno de estos, y he probado que aún funciona si se eliminan los nombres de archivo.Pruebas:
fuente
file
que no confía en las extensiones de todos modos (¡muchos usuarios consideran que cambiar el nombre de un png a jpeg es lo mismo que convertirlo!)GS2 , 3 bytes
Los formatos con pérdida devuelven 0 , los formatos sin pérdida devuelven 1 .
Pruébalo en línea! (enlaces permanentes en Gist)
Antecedentes
Los formatos que tenemos que admitir tienen los siguientes números mágicos, es decir, comienzan con estos bytes.
Las entradas sangradas son contenedores para el formato anterior que aparecen en los casos de prueba.
?
denota un byte variable..
denota un byte no imprimible. Todos los demás bytes se muestran como su carácter ISO 8859-1.Al observar solo el segundo byte, podemos determinar el formato de una manera fácil:
Los formatos sin pérdida tienen una letra mayúscula como segundo byte, mientras que los formatos con pérdida no.
Cómo funciona
fuente
JavaScript (ES6), 20 bytes
Explicación
Toma el contenido del archivo como entrada y devuelve
true
si el archivo es sin pérdidas, ofalse
si se trata de pérdidas probando el primer carácter de esa entrada para ver si se trata de unf
,F
,R
oT
.Intentalo
Pegue el contenido de un archivo en el
textarea
.Segundo esfuerzo,
8163 bytesObtiene el contenido de un archivo de una URL proporcionada, que resultó ser exagerado.
En primer esfuerzo,
14611689 bytesNo es válido ya que los tipos mime están vinculados a extensiones y, aparentemente, los encabezados de respuesta califican como entrada adicional.
fuente
AddType <mime> <extension>
o IIS<MimeMap>
. Por supuesto, una configuración específica o una herramienta de alojamiento de archivos podría hacer una inspección adecuada, y eso merecería hacer que la elección del servidor sea parte de la respuesta (¡ya que es el servidor el que determina el tipo de archivo!)Chip , 11 bytes
Replicó descaradamente la respuesta de Dennis 'Jelly en Chip.
Devoluciones sin
0x0
pérdidas, devoluciones con pérdidas0x1
.Pruébelo en línea , enlaces en esencia (gracias Dennis por la estrategia TIO aquí)
¡Explique!
Esta porción es limpieza:
S
elimina el primer byte yt
ermina después del segundo.Esta es la carne de la decisión. A cada byte de entrada se accede por los bits
HGFEDCBA
. SiG
está establecido, yF
no lo está, eso significa que el byte está dentro del rango0x40
de0x5f
(que es más o menos equivalente a 'mayúscula' y lo suficientemente bueno para la tarea en cuestión).Sin embargo, para el ahorro de bytes, invierto esta decisión de
G and (not F)
a(not G) or F
, ya que o puede estar implícito en Chip.Este valor verdadero / falso resultante se coloca en
a
, que es el bit más bajo de la salida. (Todos los demás bits serán cero). En el TIO, ejecuto la salida a través de hexdump para que los valores sean visibles.De manera equivalente, en C-ish, uno diría algo como:
fuente
Cubix, 16 bytes
Forma neta:
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 y1
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 ...
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 con0b01000000 (=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: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).
Después de que el IP cambia
u
, usamos un poco de flujo de control para empujar a1
a la pila si (y solo si) la parte superior de la pila no es cero: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.Por lo tanto, el programa genera
0
pérdidas y1
pérdidas.fuente