Wyzwaniem golfowym jest zakodowanie i skompresowanie następującego obrazu w pliku źródłowym.
Aby to zrobić, trzeba napisać 3 funkcje: red
, green
, i blue
które akceptują X / Y współrzędne obrazu i powrócić odpowiedni / G / B R wartość piksela pomiędzy 0-255.
Oto kod testowy C / C ++:
#include <stdio.h>
#include "your_file"
int main() {
int x, y;
for(y = 0; y < 32; ++y)
for(x = 0; x < 32; ++x)
printf("%i %i %i\n", red(x, y), blue(x, y), green(x, y));
}
I wynik: http://pastebin.com/A770ckxL (możesz użyć tego do wygenerowania danych obrazu)
Zasady i szczegóły:
- To jest golf
- Golfowany jest tylko Twój kod / plik - kod testowy jest osobny
- Używanym zestawem znaków jest ASCII, jednak znaki kontrolne w ciągach znaków można stosować tylko w przypadku zmiany znaczenia (np. „\ N” i „\ r” itp.)
- Wszystko musi być zawarte w źródle - bez ładowania pliku
- Twoje dane wyjściowe muszą być zgodne z przykładowymi danymi wyjściowymi. Oznacza to bezstratną kompresję.
Języki:
Problem został napisany z myślą o C / C ++, ale usuwam te ograniczenia. Powiedziawszy to, nadal zalecam ich używanie.
Odpowiedzi:
C,
796 754 712 703 692 685 682 670 666 662 656648 znakówDziennik zmian:
return
do#define
zastępującif
z?
oświadczenia (dzięki @FUZxxl), usuwającint
z listy parametrów funkcji.#define
p[]
ih[]
kilka?:
ulepszeńb
więci
nie jest już potrzebne.m=b
zamiastm=11
in<2e3
zamiasti<356
- są bliskie nieokreślonemu zachowaniu / uszkodzeniu pamięci, ale wygląda na to, że mam szczęście :)k
jest teraz (32,16,8,4,2,1,0) zamiast (5,4,3,2,1,0). Gotcha, DC;)p[]
ih[]
przekonwertowaneh[]
nachar*
- awwww, ma w sobie śpiącego kotka^<+_=>-
while
=>for
,l=l*2+...
=>l+=l+...
m=m>9?...
=>c[n++]=m>9?...
b[]
, więc możemy zmapować do 64-127 zamiast 0-63 i nie potrzebujemyk
już indeksu bitów . Dzięki @Piotr Tarsa . Zamieniono?:
(rozszerzenie GCC) na||
. Dzięki @JamesBp[]
)Obraz jest konwertowany na ciąg podobny do Base64 (ASCII 37-100), przy użyciu kodowania Huffmana do kodowania kolorów 0-9 przy użyciu 3-6 bitów i specjalnego koloru 10 (piksel jest taki sam jak poprzedni) przy użyciu tylko 1 bitu.
Skopiowałem dwie rzeczy z odpowiedzi bunnita,
#define
a cały obraz jest dekodowany całkowicie za każdym razem, gdy wywoływane sąred
/green
/blue
. Jest miejsce na dodatkowe usprawnienia, więc spodziewaj się aktualizacji :) Nie jestem pewien zgodności kodu, użyłem GCC 4.6.1 do kompilacji i testowania.Jeśli chodzi o kompresję, myślę, że kodowanie arytmetyczne pomogłoby, ponieważ dystrybucja jest dość wypaczona, ale może w tym przypadku narzut kodu byłby zbyt duży. LZW powinien również wykonać bardzo dobrą robotę. Kolory są dość lokalne, więc kodowanie adaptacyjne może być pomysłem.
Bardziej czytelna wersja 754 znaków z kilkoma komentarzami:
źródło
int
z list parametrów, aby usunąć więcej bajtów.m=m>9?c[n-1]:m;
naif(m>9)m=c[n-1];
?if(k<0){j=b[i++]-37;k=5;}
dlaczego niek>=0?:(j=b[i++]-37,k=5);
? (Ten kod używa rozszerzenia C gcc,x=a?:b
jest taki samx=a?a:b
, z tą różnicą, że a jest oceniane tylko raz.red(x,y){while(i<356){--k>=0?:(j=b[i++]-37,k=5);l*=2;if(j&(1<<k))l++;for(m=0;m<11;m++)l!=h[m]?:(m=m<=9?:c[n-1],c[n++]=m,l=0,m=12);}return P;}
Python (
684592 znaków)Ponieważ to wyzwanie jest teraz otwarte dla wszystkich, dlaczego nie! To znana trasa kodowania zlib -> base64, więc przepraszam za to. Mam nadzieję, że pozycja z pozorem pomysłowości będzie krótsza!
Oto fragment testowy analogiczny do oryginału:
źródło
C ++, 631 znaków; C - 613
Jednorazowy koder mtf base-92, C ++, 631 znaków:
I powyższa wersja C (613 znaków):
Wystarczy dołączyć wpis z danymi 95 i kodowaniem arytmetycznym + adaptacyjny model statystyczny.
kod schnaader używa danych ~ 438 znaków, a kopie tylko 318 (311 bez maskowania).
Ale zgodnie z oczekiwaniami kodowanie arytmetyczne jest zbyt skomplikowane dla takiej małej próbki.
(To jest 844 znaków)
Testy (z wcześniejszej wersji base-96):
http://codepad.org/qrwuV3Oy
http://ideone.com/ATngC
Jakoś SO zjada kody 7F, więc musiałem zaktualizować go do base = 95
źródło
C ++ -
15251004964 znakówUtworzono tablicę z, która przechowuje wszystkie możliwe kolory jako jedną liczbę całkowitą. (R << 16 | g << 8 | b). Utworzono tablicę d, która przechowuje {ilość, wartość}, wartość jest pozycją w tablicy z, ilość jest liczbą kolejnych pikseli o tej wartości. (Tj. 3,0, oznacza, że kolor t [0] pojawia się następne 3 piksele. Rzeczywista tablica pikseli (c) jest następnie obliczana za każdym razem, gdy wywoływane jest czerwone. Wartość w tablicy jest następnie przesuwana w prawo i AND w razie potrzeby, aby uzyskać poprawny składnik.
Prawdopodobnie mógłbym zapisać jeszcze kilka znaków (~ 50), usuwając więcej wzorów z tablicy, jak zdefiniowano.Edytuj 1 - zmieniono tablicę d dla tablicy char z każdą wartością przesuniętą o 48, co oznacza, że mogę ją przedstawić jako ciąg oszczędzający ładunek przecinków.
Edycja 2 - Wziął większą część funkcji z instrukcji defin.
źródło
int
(takint f(int x,int y)
będzief(x,y)
.JavaScript,
696694 znakówDzięki schnaader za 696 -> 694.
Wymyśliłem inny format kodowania, który zasadniczo jest kodowaniem Run-length z tabelą wyszukiwania kolorów. Działa całkiem nieźle, ponieważ jest mniej niż 16 kolorów i pojawiają się mniej niż 16 razy z rzędu; więc każda definicja pikseli, w tym długość, mieści się w jednym bajcie. Kolor umieszczam w górnej części bajtu, a liczbę w dolnej części.
Ostatecznie łańcuch base64 okazał się dłuższy niż się spodziewałem (472 znaków), ale program dekodujący jest naprawdę krótki.
Uwaga: Podzieliłem kod, aby mieć małą czytelność. Musi być w jednej linii, aby uruchomić.
Kod testowy:
Myślę, że przykładowy wynik to tak naprawdę wynik czerwony, zielony, niebieski (nie czerwony, niebieski, zielony, jak w oryginalnym kodzie testowym); i tak to dla mnie działa.
źródło
[0,16354410,4671418,6379596,7783255,5295994,5390379,3435360,9975021,5131894]
- zapisuje to 1 znak i jest kolejnością GBR zamiast RGB.C ++, 1357 znaków
Odrobinę trochę:
C
zawiera wartości RGB dla dziesięciu różnych kolorów obrazu.E
zawiera dane dla obrazu, w którym każdy elementE[i]
koduje zarówno liczbę powtórzeń, jakE[i]/10
i indeks kolorówE[i]%10
.źródło
int red(x,y){R Q(x+32*y)[0]}(only
zmienisz definicje w funkcje bez nazw typu, takich jak #definicjareturn
), możesz być w stanie ogolić więcej znaków.Python 3 (589 znaków)
Kod testowy
Na podstawie rozwiązania Dillona Cowera
źródło
PHP (5.4) - 822
Zrobiłem to celowo, nie używając żadnej z wbudowanych funkcji kompresji . To rozwiązanie nie jest skończone, nie jestem pewien, czy się poddałem, widzę obszary wymagające poprawy, ale nie mogę znaleźć czasu / siły woli, aby zreformować całość, więc publikuję to, co ja jak dotąd.
Nowe linie + komentarze do usunięcia dla 822 bajtów.
Testowy odcinek:
Kompresja samych danych obrazu jest całkiem dobra, ale funkcje pobierania wartości RGB zajmują 1/4 kodu.
Używam niestandardowego mechanizmu kodowania długości run70 +.
Zakodowane dane obrazu odwołują się do indeksu tablicy RLE, który z kolei indeksuje tablicę kolorów. Nie jestem pewien, ile narzutu to dodaje lub odejmuje od bezpośredniego odniesienia do kolorów.
Sinus jest 10 kolorów (od 0 do 9), RLE są przechowywane jako
run_length * 10 + colour_index
. Zapewnienie zakresu kodowania od 10 do 145 bez eksperymentowania z optymalizacjami opartymi na uporządkowaniu kolorów. (tzn. mógłbym ustawić zakres od 19 do 140, przesuwając kolory od 0 do 5, od 5 do 9 i od 9 do 0 - ale może to mieć także inne efekty domina)Poprzednia odpowiedź mówi, że ich zakodowane dane to 472 bajty. Moje zakodowane dane obrazu to 352 bajty, ale pośrednia mapa RLE / kolor (która nie jest kodowana binarnie) to kolejne 129 bajtów, co daje łączną wartość 481. (jak również dodatkowe koszty związane z połączeniem dwóch). Podejrzewam jednak, że moja metoda może lepiej skalować się w przypadku większych obrazów.
DO ZROBIENIA:
global
jest suką, ale nie może uzyskać dostępu do indeksów znaków na stałych.źródło
C (gcc) , 602 bajtów
Wypróbuj online!
Zniszczony
źródło