Cubix, 16 байтов
$-!u'HIa'@/1@O<
Чистая форма:
$ -
! u
' H I a ' @ / 1
@ O < . . . . .
. .
. .
Попробуй сам
Вы должны ввести десятичные байтовые значения файла в отдельный список. Разделитель не имеет значения, достаточно всего, что не является цифрой или знаком минус. Код действительно заботится только о первом байте, поэтому вы можете оставить остальную часть файла, если хотите. Программа выводит 0
как без потерь, так и 1
с потерями. Попробуй это здесь ! Вход по умолчанию использует заголовок FLAC.
объяснение
Хорошая вещь о файлах состоит в том, что (почти) все они имеют так называемую магию. Это первые несколько байтов файла. Хорошее программное обеспечение проверяет не расширение файла, а волшебство файла, чтобы увидеть, сможет ли оно обработать определенный файл.
Деннис нашел способ использовать эту магию, чтобы найти тип сжатия, но тот факт, что он отбросил первый байт, заставил меня захотеть придумать метод, который использовал первый байт, а не второй. В конце концов, это сообщество о сохранении байтов.
Вот список первых байтов разных типов файлов. Я разделил их на две группы: с потерями и без потерь. Вот значения их первого байта в десятичном, шестнадцатеричном и двоичном виде. Вы можете увидеть шаблон уже ...
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
Шаблон, который я увидел, состоял в том, что второй бит (считая слева направо) всегда был включен в байтах «без потерь», а пятый бит был всегда выключен. Эта комбинация не отображается ни в одном из форматов с потерями. Чтобы «извлечь» это, мы просто сделали бы двоичное И (by 0b01001000 (=72)
) и затем сравнили бы с 0b01000000 (=64)
. Если оба равны, формат ввода без потерь, в противном случае это с потерями.
К сожалению, у Cubix нет такого оператора сравнения, поэтому я использовал вычитание (если результат равен 64, это дает 0, а в противном случае - 8, -56 или -64. Я вернусь к этому позже.
Сначала давайте начнем с начала программы. Двоичный И делается с помощью a
команды:
'HIa
'H # Push 0b01001000 (72)
I # Push input
a # Push input&72
Затем мы сравниваем с 64, используя вычитание (обратите внимание, что мы ударяем зеркало, которое отражает IP на верхнюю грань [первая строка, второй символ, указывающий на юг] в середине этой части).
'@-
'@ # Push 0b01000000 (64)
- # Subtract from (input&72)
# Yields 0 for lossy, non-zero otherwise
После того, как IP обернут IP u
, мы используем некоторый поток управления для перемещения a 1
в стек, если (и только если) вершина стека отлична от нуля:
!$1
! # if top = 0:
$1 # do nothing
# else:
1 # push 1
После обтекания куба мы нажимаем на <
инструкцию, которая указывает IP на запад на четвертой строке. Все, что осталось сделать, это вывести и завершить.
O@
O # Output top of the stack as number
@ # End program
Итак, программа выводит 0
как без потерь, так и 1
с потерями.