Randall Munroe (autor XKCD) przeprowadził ankietę, aby nadać nazwy kolorom . Głównym wynikiem jest lista nazw dla 954 najpopularniejszych kolorów monitorów RGB .
Dla ułatwienia programowania, oto lista w postaci zwykłego tekstu: http://xkcd.com/color/rgb.txt . Uwaga, pierwszy wiersz nie zawiera danych, ale zawiera licencję.
Napisz program lub funkcję, która pobiera prawidłową nazwę koloru z powyższej listy jako dane wejściowe i wyprowadza powiązany kod koloru RGB. Twój program nie musi obsługiwać nieprawidłowych danych wejściowych w żaden określony sposób.
Obowiązują standardowe luki. Ponadto twoja odpowiedź nie może używać wstępnie zdefiniowanych (wbudowanych lub zewnętrznych) kodów kolorów <-> map nazw kolorów. (Obejmuje to listę połączoną.) Zwycięża najkrótszy kod w bajtach. Jeśli czytasz z pliku, liczba bajtów pliku musi być uwzględniona.
Przykłady:
dark peach -> #de7e5d
robin's egg blue -> #98eff9
pink/purple -> #ef1de7
shit #7f5f00
-bubble gum pink #ff69af
,bubblegum pink #fe83cc
Odpowiedzi:
Perl
5-421239563930407 bajtów dla kodu i 3523 dla pliku danych. Dane binarne są odczytywane z pliku „g”, którego zrzut heksowy można znaleźć tutaj .
Wykorzystuje to idealną funkcję skrótu wygenerowaną za pomocą GNU gperf , która przypisuje nazwę każdego koloru do unikalnej liczby całkowitej z zakresu od 0 do 6304, której można użyć do indeksowania tabeli. Skompresowane dane zawierają wartości kolorów w formacie 1 bajtu wskazującego przesunięcie w tabeli względem poprzedniego koloru, a następnie 3 bajty dla samego koloru (z dwiema cyframi szesnastkowymi na bajt). (Bajt 0 dla przesunięcia oznacza, że tak naprawdę jest to następna wartość + 255, ponieważ nie każde przesunięcie mieści się w jednym bajcie).
Kod analizuje dane, aby utworzyć tabelę zawierającą kolorowy ciąg rgb, a następnie stosuje do funkcji wejściowej funkcję skrótu (przetłumaczoną na perl), aby wybrać pasujące dane wyjściowe z tabeli.
Stosowanie:
Edycja: dodatkowo zmniejszono rozmiar, gzipując plik danych
źródło
EXCEL, 18 (+ 18269)
Aby ustalić linię podstawową, pokażę najprostsze rozwiązanie Excela, o którym mogłem pomyśleć:
Kod
Kod w Excelu jest bardzo prosty:
Dane wejściowe należy umieścić między podwójnymi cudzysłowami.
Dane
Dane powinny być przechowywane w pliku .csv, wyglądającym mniej więcej tak:
Po kliknięciu pliku CSV program automatycznie otwiera program Excel i umieszcza dane w kolumnach A i B, może być potrzebny inny separator.
źródło
Rubinowy,
5,37988 + 9 + 5220 = 5317 bajtów+9 bajtów dla
-rdigest
flagi.... plus 5,220 bajtowy słownik jako dane binarne odczytane ze STDIN (lub argument nazwy pliku). Słownik w formacie xxd znajdziesz we fragmencie poniżej. Program przyjmuje nazwę koloru jako argument, więc wywołujesz ją w następujący sposób:
Jeśli ktoś może wymyślić krótszy sposób, w jaki sposób zarówno odczytać plik, jak i wziąć nazwę koloru jako argument, zostaw komentarz.
$*
(ARGV) i$<
(ARGF) wchodzą w interakcje w dziwny i okultystyczny sposób, ergo$*.pop
.Słownik (format xxd)
Pokaż fragment kodu
Wyjaśnienie
Kodowanie słownika
Budowa słownika jest bardzo prosta. Biorę szesnastkowy skrót MD5 nazwy koloru i łączę od drugiej do szóstej cyfry szesnastkowej (która jest unikatowa dla każdego koloru) z 6-cyfrowym kodem koloru. Łączę je w jeden ciąg 10439 cyfr szesnastkowych. Następnie przekonwertowałem to na równoważne 5219,5 bajtów, wypełnione zerami po prawej stronie, aby uzyskać nawet 5220 bajtów.
Zabawne: wypróbowałem słownik Gzipping, a nawet
zopfli -i100
stworzyłem plik o 40 bajtów większy . Dla zabawy obliczyłem entropię słownika binarnego i jest to 99,8% (na przykładrgb.txt
61,2%). Nie jest zły!Oto kod, który generuje słownik:
Dekodowanie i przeszukiwanie słownika
Jest to dokładne przeciwieństwo powyższego. Najpierw konwertuję dane binarne na 10,439-cyfrową reprezentację szesnastkową. Następnie biorę ciąg wejściowy (nazwa koloru) i uzyskuję od drugiej do szóstej cyfry szesnastkowej jego skrótu MD5 i używam wyrażenia regularnego, aby znaleźć te cyfry w 10,439-cyfrowym ciągu szesnastkowym o pewnym indeksie podzielnym przez 11 i zwrócić kolejne 6 cyfr , które są odpowiednim kodem koloru. Na przykład, dla hash
b9ca5
( „Clear blue”), poniższe wyrażenie regularne jest skonstruowany:/^.{11}*b9ca5\K.{6}/
. Te\K
odrzuty operatorowi dopasować się do tego punktu, tak zwracane są tylko ostatnie sześć znaków.źródło
pink/purple
to#a6814c
, ale poprawna odpowiedź to#ef1de7
.Perl, 7375 bajtów
Przechowuje lekko skompresowane dane (
grey
->E
itd.) Jako skompresowane dane binarne, rozwija je w hasz i zwraca pasujący klucz po zamianie spacji na wejściu_
. Nie wydaje mi się, żeby to było takie świetne i jestem pewien, że inni będą mieli znacznie bardziej inteligentne metody kompresji danych, mógłbym się tym później bawić.Odwracalny zrzut heksowy jest dostępny tutaj, który został wygenerowany przy użyciu tego skryptu .
Stosowanie
źródło
Rubinowy,
1213112030 +-p
= 12033 bajtówLiczba bajtów jest zastępowana
<compressed text>
danymi surowej pasty w http://pastebin.com/xQM6EF9Q . (Upewnij się, że otrzymujesz nieprzetworzone dane z powodu kart w pliku)Naprawdę mógłbym jeszcze bardziej zmniejszyć tekst, ale jestem przy nim już kilka godzin i muszę spać.
Dane wejściowe to wbudowany wiersz ze STDIN bez końcowego znaku nowej linii. Dodanie nowej linii wymaga +3 bajtów poprzez zmianę
($_+?\t)
na(chomp+?\t)
.źródło
BASH + bzip2,
805868096797 bajtówZapisano oryginalną listę do pliku po skompresowaniu, nie jestem pewien, czy jest to dozwolone.
Zadzwoń z:
źródło
dusty teal
. Zakończy się niepowodzeniem. Przeczytaj wszystkie argumenty za pomocą$*
lub coś takiego.bzgrep ..... c
zamiast tegoPython, 9360 znaków
Nie używa żadnej biblioteki kompresji. Na chwilę pozostawię tajemnicę, jak to działa, a następnie opublikuję link do techniki. Oczywiście można go skrócić, przechowując dane w formacie binarnym, ale jest to ćwiczenie na inny czas.
Wyjaśnienie:
Wykorzystuje adaptację kodu z http://stevehanov.ca/blog/index.php?id=119 w celu wygenerowania minimalnego idealnego wyszukiwania skrótów od nazw kolorów do kodów kolorów.
źródło
Python 3, 4927
Kod 182 + plik danych 4745
Teoria operacji:
md5((67*s).encode('ascii')).digest()[5:7]
to idealny skrót od nazw kolorów do wartości 2-bajtowej. Plik danych binarnych to po prostu lista 5-bajtowych fragmentów - 2-bajtowy skrót i 3-bajtowy kolor. Kod szyfruje nazwę koloru wejściowego i przeszukuje dane w celu znalezienia dopasowania.Kod do wygenerowania pliku binarnego:
Oto kod, za pomocą którego znalazłem idealny skrót. Nic szczególnego, tylko trzy zagnieżdżone pętle: liczba powtórzeń nazwy (np. „Niebieski”, „niebieski niebieski”, ...); dostępne algorytmy mieszające; i przesunięcia w skrótach. Drukuje kombinacje, dla których nie ma kolizji.
źródło
Python 3, 296 + 3960 = 4256 bajtów
Nie użyłem
gperf
, ponieważ byłoby zbyt nudne, aby po prostu powtórzyć tę sztuczkę. Zamiast tego zrobiłem od zera brutalną siłę i dlatego rozmiar nie jest optymalny (ale też nie jest taki zły).Jednak znalazłem sposób na bardziej wydajną kompresję kolorów - są one sortowane i wyrównane do 4 bajtów, LZMA korzysta z nich. (kolory są skompresowane do 2180 bajtów)
Aby znaleźć kolor według nazwy, używana jest 15-bitowa funkcja skrótu. Teoretycznie można go znaleźć za pomocą mniejszej liczby bitów (liczby 0..949 można zakodować za pomocą 10 bitów), ale mój komputer nie znalazł nic lepszego, to za dużo pracy.
Kod pobiera dane wejściowe ze standardowego wejścia i drukuje odpowiedź.
Kod:
Plik danych (binarny, powinien zostać nazwany
a
i umieszczony w tym samym folderze):Jak uruchomić:
źródło
C 19,566 bajtów
Nędzna 19 566 bajtów.
Bog-standard C. Plik rgb.txt jest przesyłany strumieniowo przez stdin. Kolor do znalezienia jest podany jako pierwszy argument.
Więc:
./xkcd "bright sea green" < colors.txt
Daje:
bright sea green -> #05ffa6
źródło
Java,
79787435 bajtówKod to 293 bajty, dane to 7.142 bajty
Gra w golfa:
Nie golfowany:
Plik o nazwie „c” w programie jest wynikiem odwrotnej operacji tego programu: weź kod skrótu każdego klucza w pliku wejściowym i zapisz go z całkowitą reprezentacją wartości koloru. To trafia do strumienia wyjściowego obiektu, strumienia wyjściowego GZip, a następnie strumienia wyjściowego pliku. Ten program odczytuje go przez odwrotne strumienie wejściowe.
Domyślne kody skrótu Java wszystkich kolorów są unikalne w tym zestawie danych, więc jest to dobry 32-bitowy klucz na mapie skrótów. Ta wartość jest już liczbą całkowitą, więc wszystko, co należy zrobić, to sformatować ją poprawnie jako ciąg szesnastkowy, w razie potrzeby uzupełniony sześcioma cyframi, ze znakiem skrótu z przodu.
źródło
Java, 4649 bajtów
Kod Java: 497 bajtów, plik danych: 4152 bajtów
Plik można znaleźć tutaj
bez golfa:
Program używa ulepszonej wersji kodu skrótu Java, który wykorzystuje tylko 17 bitów:
Kolory są sortowane według niebieskiego składnika rosnącego. Są one przechowywane na 18 bitach: 8 dla czerwonego, 8 dla zielonego i 2 dla niebieskiego delta.
Całkowity rozmiar pliku: 949 kolorów * (18 + 17) = 33 215 = 4152 bajtów
źródło
JavaScript (Node.js), 10785 bajtów
Stosowanie:
Zakodowane dane .
źródło
MATLAB, 94 + 7.243 = 7.337 bajtów
Wygeneruj plik MAT „h.mat” ze zmienną „c” zawierającą posortowaną listę sum kontrolnych CRC32 nazw (c = java.util.zip.CRC32; c.aktualizacja (uint8 (x)); c.getValue ();) i ta sama posortowana lista przekonwertowanych kodów szesnastkowych kolorów (sscanf (x (:, end), '% x')) co „e”. Powinien on mieć (R2013b, format pliku v7, rozmiar 7.243 bajtów.
Funkcja jest następująca
Wykorzystuje wbudowaną kompresję plików MAT i obsługę java dla funkcji CRC32.
źródło
Idź, 6709 bajtów
Kod to 404 bajty, dane to 6305 bajtów
Danych kodowany jest z
xxd -p
. Wyciąg do pliku o nazwie po prostuf
zxxd -r paste f
. Kod można uruchomić jakogo run file.go "tree green"
źródło
C #, 6422 bajtów
Kod to 575 bajtów, dane to 5847 bajtów
Dane istnieją w sąsiednim pliku GZipped, który zawiera przekształconą reprezentację oryginalnych danych. Kolorowe słowa, które pojawiają się więcej niż jeden raz, są wyodrębniane i umieszczane w tabeli nagłówków u góry pliku, poprzedzonej jednobajtową długością.
Wpisy danych (po nagłówku) składają się z zestawu:
Każda pozycja jest zakończona albo 0xFF, 0xFE, 0xFD, co oznacza, że następny jeden, dwa lub trzy bajty reprezentują odpowiednio przesunięcie wartości koloru.
Tabela jest analizowana w kolejności, a wartość koloru jest kumulowana, dopóki nie zostanie znaleziony pasujący ciąg do danych wejściowych.
Skrócony kod dekompresji / wyszukiwania:
Kod kompresji danych
źródło
C # 7 209 bajtów: 6 643 bajty danych + kod 566 bajtów (niezminimalizowane 878 bajtów)
Repozytorium Github znajduje się tutaj: https://github.com/nbcarey/color-map
Nazwy kolorów są kompresowane w pliku danych przy użyciu skrótu FNV-32-1a, ponieważ ten algorytm skrótu jest konwencjonalnie wolny od kolizji dla tego zestawu nazw kolorów. Więc nazwa każdego koloru jest przechowywana jako 4 bajty.
Każdy kolor jest przechowywany jako 3 bajty (po 1 dla czerwonego, zielonego i niebieskiego). Brak magii.
W konsekwencji każde mapowanie nazwy koloru na wartość RGV zajmuje 7 bajtów w skompresowanym pliku.
To jest jednowierszowa wersja skrótu FNV-32-1a (przy założeniu, że łańcuch zawiera tylko proste znaki ASCII:
Ten skompresowany plik danych znajduje się w repozytorium github pod adresem https://github.com/nbcarey/color-map/blob/master/color-map/hashed-color-map.dat
Oto zminimalizowany kod:
A oto czytelny dla człowieka kod:
źródło
PHP, 5014 bajtów
Nie najlepsze, ale jest już późno i muszę się trochę przespać. :-)
Zaletą PHP jest to, że możesz wstawić dane skryptu do skryptu i odczytać sam plik, dzięki czemu skrypt jest samowystarczalny. Wystarczy go pobrać , uruchomić, a pojawi się monit o podanie nazwy koloru.
Podstawową sztuczką jest tutaj mieszanie nazw kolorów i generowanie minimalnie identyfikujących podciągów tego skrótu. Odkryłem, że 4 znaki skrótu SHA1 są wystarczające, pierwsze 3 i 17, aby jednoznacznie zidentyfikować wszystkie te kolory. Klucz jest w formacie binarnym, a także kod koloru, który jest dogodnie jeden bajt na kanał koloru. Zatem każdy wpis zajmuje 5 bajtów, co daje 5 x 949 = 4745 bajtów ładunku (magiczna liczba widoczna w kodzie).
Kompresja nie pomogła bardzo, bzip2, LZMA wszystkie stworzyły większe pliki, więc bez dalszych sztuczek, jest to tak skompresowane, jak w przypadku tego podejścia.
źródło
Bash + (coreutils, gzip, xxd, openssl, sed, grep), 4946 bajtów
dane: 4482 bajtów, kod: 464 bajtów
Dane można znaleźć w base64 tutaj . Wiem, że kod może być bardziej golfowy. Teraz zbyt śpiący: / Wszelkie sugestie są mile widziane :-)
Wyjaśnienie
Oto działania, które wykonałem na oryginalnym pliku po usunięciu komentarza do licencji.
openssl dgst -md5 -binary|base64
base64
wykorzystuje zestaw 64 znaków do reprezentowania danychA-Za-z0-9+/
. Miałem więc nadzieję znaleźć 2 bajty, ponieważ wszystkie wpisy to 494 i 64 * 64 = 4096, ale nie mogłem znaleźć żadnego. Próbowałem także znaleźć 2-znakowe unikalne wpisy, używającsha512
kroku pierwszego, ale bez powodzenia. Zostałem więc z tymi 3 bajtami dla nazw kolorów.(echo '0:';echo -n "$line"|cut -d '#' -f 2)|xxd -rp -l 16|base64
zopfli -i1000
kompresowałem plik.Plik wynikowy przed kompresją wyglądałby tak:
Próbowałem również inne narzędzia kompresji, ale z najgorszych wyników z wyjątkiem
zopfli -i0000 --zlib
z 4470 bajtów orazzopfli -i10000 --defalte
z 4464 , ale nie był pewien, w jaki sposób rozpakować tam formatach.Aby znaleźć kod koloru, wykonuję czynności odwrotne. Tworzę 3-znakowy kod z podanej nazwy i częściowo odtwarzam oryginalne kody kolorów. Na przykład dla
adobe
tworzę wszystko, co zaczyna się odX
:Następnie grepuję
Xqy
linię i zwracam drugą część, która jest kolorem koloru.Naprawdę podobała mi się ta łamigłówka i jest tu wiele świetnych odpowiedzi. Dzięki i dobra robota wszystkim!
źródło
Bash + coreutils / xxd, 4064 bajty
Dane 3796 bajtów (zrzut heksadecymalny pliku danych)
Bash 268 bajtów
Bez golfa
Ogólny pomysł polega na skanowaniu 32-bitowych pól, znalezieniu pasującego unikalnego 14-bitowego skrótu i wydrukowaniu kodu koloru w tym miejscu. 18-bitowe kodowanie kolorów wykorzystuje podejście Super Chafouin.
Unikalny 14-bitowy skrót zaczyna się od podzestawu 14 bitów z 128-bitowej sumy md5. Aby znaleźć te bity Użyłem algorytmu genetycznego zakodowany w C ++ tutaj . Kod wstępnie ładuje stały plik o nazwie „dane”, który jest tylko wartością binarną md5sum, po jednej w wierszu. Jeśli potrzebujesz tego w formie przepisu, spowoduje to utworzenie pliku danych:
Znajduję najlepszego kandydata na 14 bitów (jaki do tej pory widziałem) z tego kodu w generacji 2, ale ten zestaw ma dwie kolizje. W szczególności: mapa „błotnista” i „jasnofioletowa” do tej samej wartości, a mapa „błękitna woda” i „jasnozielona” do tej samej wartości. Ponieważ są tylko dwie kolizje i nie znalazłem nic lepszego, po prostu je jednoznacznie; okazuje się, że połowa każdej z tych wartości nie jest używana.
Próbowałem już kompresji na d; ale ani bzip2, ani gzip, ani xz nie zmniejszają rozmiaru d.
źródło
Groovy,
153 + 10 697 = 10850253 + 9870 = 10123 bajtówZdecydowałem, że chcę rozwiązania obejmującego tylko jeden plik, więc (przy oczywistym koszcie miejsca) zakodowałem wersję danych GZIPped CSV na znaki Unicode 0x0020-0x007E (które, jak sądzę, byłyby kodowaniem podstawowym 95?). Kod składa się z 253 znaków, treść ciągu to 10123 znaków.
Dla czytelności, to samo z wykluczonym zakodowanym tekstem:
Moim oryginalnym rozwiązaniem było prostsze kodowanie Base 64 przy użyciu wbudowanego kodera
Dla czytelności, to samo z wyjątkiem tekstu:
źródło