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
Я бачив, що другий біт (рахується зліва направо) завжди був на байтах без втрат, а п'ятий біт завжди був відключений. Ця комбінація не відображається в жодному із форматів втрат. Щоб "витягти" це, ми просто зробимо двійковий І (від0b01001000 (=72)
), а потім порівняємо 0b01000000 (=64)
. Якщо обидва рівні, формат вводу без втрат, інакше втрачається.
На жаль, у Cubix немає такого оператора порівняння, тому я використовував віднімання (якщо результат 64, це дає 0, а в іншому випадку це призводить до 8, -56 або -64. Я повернусь до цього пізніше.
Спочатку почнемо з початку програми. Двійковий AND виконується за допомогою 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-адресою 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
для втрат.