Format PBM (Portable BitMap) to bardzo prosty czarno-biały format bitmap ASCII.
Oto przykład litery „J” (skopiowany z linku wikipedii):
P1 # To jest przykładowa mapa bitowa litery „J” 6 10 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Czas zbudować małe narzędzie do generowania plików w tym fajnym małym formacie!
Twoim celem jest napisanie najkrótszego programu (w dowolnym języku), który będzie zgodny z następującymi zasadami:
- Twój program pobiera jeden ciąg ze standardowego wejścia (na przykład
CODEGOLF.STACKEXCHANGE.COM!
) - Generuje plik PBM z bitmapową (czytelną) reprezentacją ciągu.
- Każda postać jest zbudowana jako siatka 8x8.
- Musisz obsługiwać znaki [AZ] (wszystkie wielkie litery), spację, punkt („.”) I wykrzyknik („!”).
- Żadne zewnętrzne biblioteki nie są dozwolone (z pewnością nie związane z PBM)!
- Używany zestaw znaków nie może być po prostu zewnętrzny dla twojego programu. Częścią wyzwania jest efektywne przechowywanie postaci ...
Testowanie poprawności formatu PBM można wykonać za pomocą GIMP (lub innych). Nie pokazuj przykładowych danych wejściowych i wyjściowych!
Najkrótsze rozwiązanie otrzyma punkty odpowiedzi w dniu 31.01.2012.
Miłej zabawy w golfa!
PS: Dodałem nagrodę (procentowo ogromną część mojej reputacji codegolf), aby (mam nadzieję) przyciągnąć więcej konkurentów.
code-golf
string
graphical-output
ChristopheD
źródło
źródło
letters
innymi słowy). Podobnie jak w przypadku przykładu związanego z.Odpowiedzi:
GolfScript, 133 bajty
Opiera się to na moim 164-bajtowym rozwiązaniu Perl i używa tej samej, wypełnionej czcionką czcionki 4 na 5 pikseli. Ponownie dam najpierw czytelną wersję:
Tutaj
FONT DATA HERE
oznacza 71 bajtów binarnie spakowanych danych czcionek. Kodowanie jest nieco inne niż w wersji Perla: zamiast rozdzielać spakowany ciąg znaków na białe znaki, najpierw go rozwijam, a następnie dzielę na skrobanie3
(wybrane, ponieważ po prostu nie występuje nigdzie w czcionce).Ponieważ dane czcionki w rzeczywistym skrypcie zawierają znaki niedrukowalne, podaję je jako zrzut heksowy poniżej. Użyj,
xxd -r
aby zmienić zrzut heksów z powrotem w wykonywalny kod GolfScript:W przeciwieństwie do skryptu Perl, ten kod drukuje żadnych znaków spoza zestawu
A
-Z
,!
,.
,space
jak śmieszne wyglądające trochę zawijasów. Zastąpienie squiggles pustymi miejscami kosztuje 2 dodatkowe znaki; ich całkowite usunięcie kosztowałoby 4.To mój pierwszy program GolfScript, więc nie zdziwiłbym się, gdyby pozostało trochę miejsca na optymalizację. Oto jak to działa:
{91,65>"!. "+?}%:s
odwzorowuje prawidłowych znaków wejściowych (A
-Z
,!
,.
,space
) do numerów 0 - 28 i przypisuje wynik dos
. Wszelkie znaki poza prawidłowym zestawem są odwzorowywane na -1, co powoduje powstanie zawirowań po wydrukowaniu."P4"\,8*8
wypycha wartości „P4”, 8-krotność długości wejścia i 8 na stos. Po wydrukowaniu na końcu utworzą nagłówek PBM.{16base}%[3]/
pobiera poprzedzający ciąg danych czcionki, dzieli każdy bajt na dwie wartości, i dzieli wynik na bloki rozdzielone wartością3
.{:p;{[p=0]0=}s%}%
następnie zapętla te bloki, najpierw przypisując każdy blok do zmiennej,p
a następnie zapętla przemapowany ciąg wejściowys
, zastępując każdy znak wartością o odpowiednim przesunięciu wp
. Zabawnie wyglądająca konstrukcja[p=0]0=
działa tak samop=
, z tym wyjątkiem, że zwraca 0 dla wszelkich przesunięć poza koniecp
; Nie podoba mi się to, ale nie udało mi się znaleźć krótszego sposobu, aby sobie z tym poradzić.Na koniec
]n*
bierze wszystko ze stosu (trzy wartości nagłówka i tablicę danych obrazu) i łączy je razem z znakami nowej linii do drukowania.źródło
Perl, 164 bajty, bez kompresji zlib / gzip
Po przespaniu się z problemem udało mi się wymyślić znacznie krótsze rozwiązanie niż moje pierwsze. Sztuką jest skorzystanie z niewielkiej luki w zasadach: postacie muszą zmieścić się w rozmiarach 8 na 8 pikseli, ale nic nie mówi, że muszą wypełnić całą tę przestrzeń. Narysowałem więc własną czcionkę 4 na 5 pikseli, co pozwoliło mi upakować dwa znaki w 5 bajtach.
Dane wyjściowe wyglądają następująco:
(skalowane x 4)
(oryginalny rozmiar)
Zanim podam rzeczywisty kod z osadzonymi danymi czcionek, pozwól mi pokazać wersję bez golfa:
W rzeczywistym kodzie
PACKED FONT DATA
zastępuje go ciąg binarny składający się z ośmiu wierszy oddzielonych spacjami (cztery wiersze 14-bajtowe i jeden 13-bajtowy oraz trzy pojedyncze bajty puste dla wierszy pustych). Celowo zaprojektowałem czcionkę, aby spakowane dane nie zawierały białych znaków, pojedynczych cudzysłowów ani ukośników odwrotnych, aby można je było zakodowaćqw'...'
.Ponieważ spakowany ciąg czcionek zawiera znaki niedrukowalne, rzeczywisty skrypt podałem jako zrzut heksadecymalny. Użyj,
xxd -r
aby zmienić go z powrotem w wykonywalny kod Perla:Oto jak to działa:
Pierwszy wiersz (w wersji do gry w golfa) odczytuje jeden wiersz danych wejściowych, dzieli go na tablicę znaków (wygodnie pomijając wszelkie znaki nowej linii) i odwzorowuje litery
A
naZ
oraz znaki!
i.
kody znaków od 0 do 28, które zwykle odpowiadają niedrukowalnym znakom sterującym w ASCII / Unicode. (Niewielkim skutkiem ubocznym jest to, że wszystkie tabulacje na wejściu są drukowane jakoJ
s.) Znak spacji pozostaje niezapisany, ponieważ pętla wyjściowa zamienia wszelkie kody powyżej 28 na puste.Drugi wiersz po prostu wypisuje nagłówek PBM. Korzysta z funkcji Perl 5.10
say
, więc musisz uruchomić ten skryptperl -M5.010
, aby działał.Pętla wyjściowa pobiera rozdzieloną spacjami listę wierszy upakowanych obrazów i przypisuje kolejno każdy z nich
$p
. (Czcionkę zaprojektowałem tak, aby spakowane dane nie zawierały żadnych białych znaków ani'
znaków.) Następnie zapętla znaki wejściowe@a
, używającvec
polecenia Perla do wyodrębnienia 4-bitowego skrawka odpowiadającego odwzorowanemu kodowi znaków z wiersza obrazu, wstawia go do 8-bitowego bajtu i drukuje.Stara odpowiedź, 268 bajtów:
To szybka i brudna pierwsza próba. Ukradłem czcionkę PleaseStand i skompresowałem ją wraz z kodem źródłowym. Ponieważ wynikowy skrypt jest w większości niedrukowalny, oto zrzut heksowy; użyj,
xxd -r
aby zmienić go w wykonywalny kod Perla:Zdekompresowany kod Perla składa się z następującej preambuły:
a następnie osiem powtórzeń następującego kodu:
z
BITMAP DATA HERE
zastąpionym 29 bajtami kodującymi jeden wiersz czcionki.źródło
8086 Kod maszynowy
190 bajtów (122 bajtów przy użyciu systemu BIOS)
Oto plik WinCP / MSDos zakodowany w formacie Base64 .COM:
(Użyj czegoś takiego ), aby zdekodować tekst i zapisać jako „pbm.com”. Następnie w wierszu polecenia wpisz:
Przetestowałem to na moim komputerze WinXP, używając zarówno standardowego wiersza polecenia, jak i DosBox V0.74.
AKTUALIZACJA
Ta wersja ma 190 bajtów i używa małej czcionki Ilmari Karonen (tutaj nie ma dostępu do biografii!): -
źródło
puts
w Ruby jest biblioteka zewnętrzna. Tak, korzysta z czcionek bios, do których dostęp uzyskuje się poprzez odsunięcie wskaźnika (brakload
operacji wprowadzania czcionek do pamięci RAM). Być może zbyt wyginanie zasad. Uciekłbym z tego, gdyby nie te nieznośne dzieci ;-)Skrypt powłoki (kod + dane = 295 znaków)
Mam nadzieję, że tail, gzip i dd nie liczą się jako „biblioteki zewnętrzne”. Uruchom jako
echo -n 'YOUR TEXT HERE' | ./text.sh > out.pbm
. Czcionka, której użyłem, to Small Fonts rozmiar 7,5, chociaż musiałem odciąć descender od Q.Przykładowe dane wyjściowe
Kod (137 znaków)
Kompletny skrypt
(użyj,
xxd -r
aby odtworzyć oryginalny plik)Wyjaśnienie
od
to standardowy program narzędziowy „octal dump”. Ta-tu1
opcja nakazuje zamiast tego utworzenie dziesiętnego zrzutu pojedynczych bajtów (wystarczające obejście dla braku bash'a braku asc (), ord (), .charCodeAt () itp.)P4
to magiczna liczba dla pliku PBM w formacie binarnym, który pakuje osiem pikseli w każdym bajcie (w porównaniuP1
do pliku PBM w formacie ASCII). Zobaczysz, jak to się przyda.dd
. (tail -2 $0
wyodrębnia dwa ostatnie wiersze skryptu; skompresowane dane zawierają jeden bajt wysuwu linii 0x0a.) Zdarza się, że osiem pikseli to szerokość pojedynczego znaku. Puste bajty wypełniające luki między obsługiwanymi znakami są łatwo kompresowalne, ponieważ wszystkie są takie same.wc -c
drukuje nazwę pliku wejściowego „8” po liczbie bajtów.źródło
Python 2,
248247 bajtówWykorzystuje czcionkę 3x5, zapakowaną w ciąg do drukowania, 3 bajty na znak. Czcionka jest wyraźnie czytelna, chociaż n jest małymi literami, a v może być mylone z au, jeśli nie jest widziane w kontekście.
Rzeczywisty rozmiar:
Powiększony x3:
Wyjściem jest PBM typu P1, jak na przykładzie w wyzwaniu. To było zabawne wyzwanie.
źródło
Ruby 1.9, 346 bajtów (kod 122 + dane 224 bajty)
Oto wynik:
(Fajnie, prawda?)
Czcionka została wygenerowana przez
figlet -f banner -w 1000 $LETTERS
i ten skrypt .Uruchom z
echo -n 'CODEGOLF.STACKEXCHANGE.COM!' | ruby script.rb > image.pbm
.Skrypt generuje wszystkie wiersze i po prostu je drukuje.
Oto zrzut heksowy (użycie
xxd -r
):Przy użyciu goruby zajmuje 93 bajty kodu:
Używając ZLib przycinamy rozmiar danych do 142 bajtów zamiast 224, ale dodaje 43 bajty w kodzie, więc 307 bajtów:
Co daje w sumie 268 podczas używania Goruby:
źródło
Java
862826:Oto inne podejście. Myślę, że „awt” nie liczy się jako lib zewnętrzny.
I bez golfa:
Robot to ciekawy sposób, w jaki Java wywołuje getPixel. Tworzę Etykietę z alfabetem i sprawdzam, gdzie jest piksel dla każdej litery.
W metodzie malowania
int py = (y < 3) ? y : y +1;
i(8*a+x+17+x/4, py+81)
jest to skomplikowany sposób, aby dostosować pozycję czcionki. Huuuh! w przeciwnym razie potrzebowałoby 9 linii, a co 4 literę jest dodatkowy piksel w poziomie. Próba i błąd doprowadziły mnie do tego rozwiązania.Następnie zapisywany jest nagłówek PBM i każdy wiersz wiadomości. Wiadomość jest przekazywana jako tytuł ramki.
Otóż to. Nie był to najkrótszy kod, ale nie było konieczne ręczne malowanie czcionek.
Może być krótszy w BeanShell lub Scala.
A teraz - jak to wygląda?
Zastosowano wiele zoomów:
Unzoomed:
Nie chodzi o to, że liczba znaków jest liczbą znaków z rozwiązania Perla przetasowanymi.
(grał trochę bardziej w golfa. Uczyniono Robota statycznym, co pozwala uniknąć jednej deklaracji wyjątku).
źródło
eog
(Eye of Gnome) i zrzutu ekranu. Prześlę nieskalowanąjpg
wersję; może Twoja przeglądarka używa interpolacji najbliższego sąsiada :).C ++ ZA DUŻO, ABY WYGRAĆ
Napisałem w pełni funkcjonalny program do rysowania PPM w C ++, z własną czcionką bitmapową. Nawet usunięcie wszystkich niepotrzebnych funkcji jest wciąż ogromne w porównaniu z odpowiedziami tutaj z powodu definicji czcionki.
Tak czy inaczej, oto wynik dla HELLO WORLD:
I kod:
ppmdraw.h
ppmdraw.cpp
main.cpp
Makefile
Jeśli jesteś zainteresowany, pełna biblioteka PPMDraw jest tutaj :
źródło
SmileBASIC, 231 bajtów
Każda postać zawiera tylko 2 różne wzory wierszy, wybrane z „palety” 8 kombinacji. Dane dla każdego symbolu są przechowywane w 1 bajcie, a paleta jest przechowywana osobno.
źródło