Cubix, 16 bajtów
$-!u'HIa'@/1@O<
Formularz netto:
$ -
! u
' H I a ' @ / 1
@ O < . . . . .
. .
. .
Spróbuj sam
Należy wprowadzić wartości bajtów dziesiętnych pliku na oddzielnej liście. Separator nie ma znaczenia, wystarczy coś, co nie jest cyfrą ani znakiem minus. Kod naprawdę obchodzi tylko pierwszy bajt, więc możesz pominąć resztę pliku, jeśli chcesz. Program generuje dla stratnych 0
i bezstratnych 1
. Wypróbuj tutaj ! Domyślne wejście używa nagłówka FLAC.
Wyjaśnienie
Zaletą plików jest to, że (prawie) wszystkie mają tak zwaną magię. To kilka pierwszych bajtów pliku. Dobre oprogramowanie nie sprawdza rozszerzenia pliku, ale raczej magię pliku, aby sprawdzić, czy może obsłużyć określony plik.
Dennis znalazł sposób na użycie tej magii do znalezienia rodzaju kompresji, ale fakt, że odrzucił pierwszy bajt, sprawił, że chciałem wymyślić metodę, która użyłaby pierwszego bajtu, a nie drugiego. W końcu ta społeczność polega na oszczędzaniu bajtów.
Oto lista pierwszych bajtów różnych typów plików. Podzieliłem je na dwie grupy: stratne i bezstratne. Oto wartości ich pierwszego bajtu w postaci dziesiętnej, szesnastkowej i binarnej. Możesz już zobaczyć wzór ...
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
Wzorzec, który widziałem, był taki, że drugi bit (liczony od lewej do prawej) zawsze był włączony w „bezstratnych” bajtach, a piąty bit był zawsze wyłączony. Ta kombinacja nie pojawia się w żadnym z formatów stratnych. Aby to „wyodrębnić”, po prostu zrobilibyśmy binarne AND (by 0b01001000 (=72)
), a następnie porównaliśmy z 0b01000000 (=64)
. Jeśli oba są równe, format wejściowy jest bezstratny, w przeciwnym razie jest stratny.
Niestety Cubix nie ma takiego operatora porównania, więc użyłem odejmowania (jeśli wynikiem jest 64, daje to 0, a w przeciwnym razie daje 8, -56 lub -64. Wrócę do tego później.
Najpierw zacznijmy od początku programu. Binarne AND odbywa się za pomocą a
polecenia:
'HIa
'H # Push 0b01001000 (72)
I # Push input
a # Push input&72
Następnie porównujemy do 64 za pomocą odejmowania (zauważmy, że uderzamy w lustro, które odbija IP do górnej powierzchni [pierwsza linia, drugi znak, skierowany na południe] w środku tej części).
'@-
'@ # Push 0b01000000 (64)
- # Subtract from (input&72)
# Yields 0 for lossy, non-zero otherwise
Po odwróceniu adresu IP przez u
, używamy przepływu sterującego, aby wypchnąć a 1
na stos, jeśli (i tylko jeśli) góra stosu jest różna od zera:
!$1
! # if top = 0:
$1 # do nothing
# else:
1 # push 1
Po owinięciu sześcianu uderzamy w <
instrukcję, która wskazuje IP na zachód w czwartej linii. Wszystko, co pozostaje do zrobienia, to wyjście i zakończenie.
O@
O # Output top of the stack as number
@ # End program
Tak więc program generuje dane 0
bezstratne i 1
stratne.