Étant donné un fichier audio, déterminez s'il est codé dans un format avec perte ou dans un format sans perte. Aux fins de ce défi, seuls les formats suivants doivent être classés:
Règles
- Si l'entrée est prise sous la forme d'un nom de fichier, aucune hypothèse ne doit être faite sur le nom de fichier (par exemple, l'extension n'est pas garantie d'être correcte pour le format, ni même présente).
- Aucune métadonnée ID3 ou APEv2 ne sera présente dans les fichiers d'entrée.
- Deux sorties uniques et distinctes peuvent être utilisées, telles que
0
et1
,lossy
etlossless
,foo
etbar
, etc.
Cas de test
Les cas de test pour ce défi consistent en un fichier zip situé ici qui contient deux répertoires: lossy
et lossless
. Chaque répertoire contient plusieurs fichiers audio qui sont tous des ondes sinusoïdales de 0,5 seconde à 440 Hz, encodés dans différents formats. Tous les fichiers audio ont des extensions correspondant aux formats ci-dessus, à l'exception de A440.m4a
(qui est de l'audio AAC dans un conteneur MPEG Layer 4).
Réponses:
Gelée ,
75 octetsLes formats avec perte renvoient 0 , les formats sans perte renvoient 1 .
Essayez-le en ligne! (permaliens dans Gist)
Contexte
Les formats que nous devons prendre en charge ont les nombres magiques suivants, c'est-à-dire qu'ils commencent par ces octets.
Les entrées en retrait sont des conteneurs pour le format précédent qui apparaissent dans les cas de test.
?
désigne un octet variable..
désigne un octet non imprimable. Tous les autres octets sont affichés comme leur caractère ISO 8859-1.En ne regardant que le deuxième octet, nous pouvons déterminer le format de manière simple:
Les formats sans perte ont une lettre majuscule comme deuxième octet, contrairement aux formats avec perte.
Comment ça fonctionne
la source
C,
828032 octetsInspiré par la réponse de @Dennis , cela peut être réduit beaucoup plus:
Dirigez les données du fichier vers stdin. Renvoie 0 pour lossless, ou différent de zéro pour lossy.
Ou le chèque original plus long:
Dirigez les données du fichier vers stdin. Renvoie une valeur non nulle (1) pour lossless ou 0 pour lossy.
D'après ce que je peux dire, tous les formats que vous avez répertoriés ont des nombres magiques distincts (sauf AIFF / WAV, mais ils sont tous les deux sans perte), donc cela vérifie simplement ce nombre magique pour une valeur sans perte connue. Il
*v&&
s'agit simplement de se protéger contre les fichiers correspondants qui commencent par un octet nul (M4A).J'ai inclus les valeurs que j'ai trouvées dans les fiches techniques (
fLaC
= FLAC,RIFF
= WAV / AIFF,TTA1
= TTA), etFORM
= AIFF etFFM2
= TTA proviennent des exemples de fichiers fournis (je ne peux que deviner que ce sont des formats d'emballage ou des versions ultérieures).Ou une alternative plus courte à la sensation de tricherie:
Fichier Bash +, 61 octets
Prend le nom de fichier comme argument. Renvoie 0 pour lossless, ou différent de zéro pour lossy.
Fait exactement ce que vous attendez; demande
file
quel est le type de fichier, puis vérifie les modèles connus. Correspondances TTA: d
(: data
), correspondance AIFF / WAVIF
et correspondances FLACFL
. Aucun des résultats sans perte ne correspond à aucun de ceux-ci, et j'ai testé qu'il fonctionne toujours si les noms de fichiers sont supprimés.Essai:
la source
file
que ne fait pas confiance aux extensions de toute façon (beaucoup de choses que les utilisateurs renomment un png en jpeg reviennent à le convertir!)GS2 , 3 octets
Les formats avec perte renvoient 0 , les formats sans perte renvoient 1 .
Essayez-le en ligne! (permaliens dans Gist)
Contexte
Les formats que nous devons prendre en charge ont les nombres magiques suivants, c'est-à-dire qu'ils commencent par ces octets.
Les entrées en retrait sont des conteneurs pour le format précédent qui apparaissent dans les cas de test.
?
désigne un octet variable..
désigne un octet non imprimable. Tous les autres octets sont affichés comme leur caractère ISO 8859-1.En ne regardant que le deuxième octet, nous pouvons déterminer le format de manière simple:
Les formats sans perte ont une lettre majuscule comme deuxième octet, contrairement aux formats avec perte.
Comment ça fonctionne
la source
JavaScript (ES6), 20 octets
Explication
Prend le contenu du fichier en entrée et retourne
true
si le fichier est sans perte oufalse
si elle entraîne des pertes en testant le premier caractère de cette entrée pour voir si elle estf
,F
,R
ouT
.Essayez-le
Collez le contenu d'un fichier dans le
textarea
.Deuxième effort,
8163 octetsRécupère le contenu d'un fichier à partir d'une URL fournie, qui s'est avérée exagérée.
Premier effort,
14611689 octetsNon valide car les types MIME sont liés aux extensions et, apparemment, les en-têtes de réponse sont considérés comme des entrées supplémentaires.
la source
AddType <mime> <extension>
ou IIS<MimeMap>
. Bien sûr, une configuration spécifique ou un outil d'hébergement de fichiers pourrait faire une inspection appropriée, et cela mériterait que le choix du serveur fasse partie de la réponse (puisque c'est le serveur qui détermine le type de fichier!)Puce , 11 octets
Réplique sans vergogne de Dennis 'Jelly dans Chip.
Retours sans
0x0
perte, retours avec perte0x1
.Essayez-le en ligne , liens dans l'essentiel (merci Dennis pour la stratégie TIO ici)
Explique!
Cette portion est d'ordre administratif: elle
S
coupe le premier octet ett
disparaît après le second.C'est la chair de la décision. Chaque octet d'entrée est accessible par les bits
HGFEDCBA
. SiG
est défini etF
ne l'est pas, cela signifie que l'octet se situe dans la plage0x40
de0x5f
(ce qui équivaut à peu près à «majuscule» et suffisamment bon pour la tâche à accomplir).Cependant, pour les économies d'octets, j'inverse cette décision de
G and (not F)
à(not G) or F
, car or peut être implicite dans Chip.Cette valeur vraie / fausse résultante est ensuite placée dans
a
, qui est le bit le plus bas de la sortie. (Tous les autres bits seront nuls). Dans le TIO, j'exécute la sortie via hexdump afin que les valeurs soient visibles.De manière équivalente, en C-ish, on dirait quelque chose comme:
la source
Cubix, 16 octets
Forme nette:
Essayez-le vous-même
Vous devez entrer les valeurs d'octets décimaux du fichier dans une liste séparée. Le séparateur n'a pas d'importance, tout ce qui n'est pas un chiffre ou un signe moins suffit. Le code ne se soucie vraiment que du premier octet, vous pouvez donc laisser de côté le reste du fichier si vous le souhaitez. Le programme génère
0
des sorties sans perte et1
avec perte. Essayez-le ici ! L'entrée par défaut utilise un en-tête FLAC.Explication
La bonne chose à propos des fichiers est que (presque) tous ont une soi-disant magie. Ce sont les premiers octets du fichier. Un bon logiciel ne vérifie pas l'extension du fichier, mais plutôt la magie du fichier pour voir s'il peut gérer un certain fichier.
Dennis a trouvé un moyen d'utiliser cette magie pour trouver le type de compression, mais le fait qu'il ait supprimé le premier octet m'a donné envie d'essayer de trouver une méthode qui utilise le premier octet plutôt que le second. Après tout, cette communauté consiste à économiser des octets.
Voici une liste des premiers octets des différents types de fichiers. Je les ai classés en deux groupes: avec et sans perte. Voici les valeurs de leur premier octet en décimal, hexadécimal et binaire. Vous pourriez déjà voir un motif ...
Le motif que j'ai vu était que le deuxième bit (compté de gauche à droite) était toujours activé sur les octets "sans perte" et le cinquième bit était toujours désactivé. Cette combinaison n'apparaît dans aucun des formats avec perte. Pour «extraire» cela, nous ferions simplement un ET binaire (par
0b01001000 (=72)
), puis nous comparerions à0b01000000 (=64)
. Si les deux sont égaux, le format d'entrée est sans perte, sinon c'est avec perte.Malheureusement, Cubix n'a pas un tel opérateur de comparaison, j'ai donc utilisé la soustraction (si le résultat est 64, cela donne 0, et il en résulte 8, -56 ou -64 sinon. J'y reviendrai plus tard.
Commençons d'abord par le début du programme. L'ET binaire se fait à l'aide de la
a
commande:Ensuite, nous comparons à 64 en utilisant la soustraction (notez que nous avons frappé un miroir qui reflète l'IP vers la face supérieure [première ligne, deuxième caractère, pointant vers le sud] au milieu de cette partie).
Une fois l'IP retournée par le
u
, nous utilisons un flux de contrôle pour pousser a1
vers la pile si (et seulement si) le haut de la pile n'est pas nul:Après avoir fait le tour du cube, nous avons frappé l'
<
instruction, qui pointe l'IP vers l'ouest sur la quatrième ligne. Il ne reste plus qu'à sortir et à terminer.Ainsi, le programme génère
0
des sorties sans perte et1
avec perte.la source