Alfabet morskiej flagi ICS

14

Alfabet flagi Międzynarodowego Kodeksu Sygnałów jest wykorzystywany przez statki do komunikacji, szczególnie w przypadku sygnałów statycznych.

Wyzwaniem jest napisanie programu lub funkcji, która pobierze ciąg znaków ze STDIN lub jako argument i wyświetli odpowiedni tekst w alfabecie flagi ICS. Jeśli Twój język nie wyświetla się na ekranie, zapisywanie do pliku jest dopuszczalne.

Twój program lub funkcja obsługuje litery AZ pisane wielkimi i małymi literami oraz spację i znak nowej linii . Zachowanie z innymi postaciami jest niezdefiniowane.

Wyświetlacz musi być wystarczająco duży, aby wyświetlać co najmniej 8 flag w poziomie i 6 flag w pionie. Zachowanie jest niezdefiniowane, jeśli prawy brzeg zostanie osiągnięty przed otrzymaniem nowej linii lub jeśli wiadomość jest zbyt długa, aby zmieścić wyświetlacz pionowo.

Alfabet flagi jest pokazany poniżej (litery rzymskie służą wyłącznie jako odniesienie, nie są wymagane na wyjściu).

wprowadź opis zdjęcia tutaj

Wymiary

Nie ma uniwersalnie uzgodnionej normy dotyczącej wymiarów tych flag, dlatego do celów tego wyzwania obowiązują następujące zasady:

Flagi powinny mieć wymiary 60 x 60 pikseli, z odstępem 30 pikseli między nimi zarówno w poziomie, jak i w pionie.

Głębokie cięcie na A i B powinno mieć 15 pikseli głębokości.

Wszystkie pozostałe linie muszą być poziome, pionowe lub pod kątem 45 stopni.

Obiekty należy zlokalizować, dzieląc flagę na wyobrażoną siatkę NxN o boku 3,4,5 lub 6 kwadratów. Zobacz powyższy obraz, ale dla dalszego wyjaśnienia:

A, E, H, K, L i U są oparte na siatce 2x2: szerokość każdej strefy kolorów wynosi 30 pikseli. Również punkty diamentu w F powinny znajdować się w połowie długości po każdej stronie flagi.

J i T oparte są na siatce 3x3: każde pasmo ma 20 pikseli.

P, N i S oparte są na siatce 4x4. Również ukośne linie Y podzielą krawędzie flagi na 4.

C, D, R i X będą oparte na siatce 5x5. Pasma i ramiona krzyży powinny mieć szerokość 12 pikseli.

G, W, M, V oparte są na siatce 6x6. Pasma G i granice W mają szerokość 10 pikseli. Ramiona krzyżyków na M i V powinny obejmować pierwsze i ostatnie 10 pikseli każdej krawędzi flagi, pozostawiając strefy trójkąta o długości 40 pikseli wzdłuż długiej krawędzi.

Okrąg I powinien znajdować się na środku flagi i mieć średnicę 30 pikseli.

Dozwolony jest błąd +/- 1 piksela w powyższym tekście. Jeśli Twój język obsługuje tylko skalowalną grafikę, możesz interpretować „piksele” jako „jednostki”.

Zabarwienie

Kolory powinny być czerwony, biały, niebieski, żółty i czarny, zgodnie z językiem lub dokumentacją. Jeśli twój język nie definiuje kolorów, możesz użyć następujących elementów: Czerwony FF0000, Biały FFFFFF, Niebieski 0000FF, Żółty FFFF00, Czarny 0000000.

Tło powinno być szare (kanały r, gib są równe, intensywność między 25% a 75%).

Punktacja / Luki

To jest codegolf. Najkrótszy kod w bajtach wygrywa.

Standardowe luki są niedozwolone.

Nie można używać żadnych wbudowanych funkcji bibliotecznych do wyświetlania flag. Dane wyjściowe powinny być nietekstowe (w szczególności do ułożenia flagi nie należy używać znaków Unicode).

Przykład

JFK got
my VHS
PC
and XLR
web quiz

powinien produkować następujące

wprowadź opis zdjęcia tutaj

Level River St
źródło
Nie jestem do końca pewien, co masz na myśli przez „ Wyświetlacz powinien być wystarczająco duży, aby wyświetlać co najmniej 8 flag w poziomie i 6 flag w pionie ”, szczególnie biorąc pod uwagę, że twój przypadek testowy pokazuje wynik, który ma tylko 5 flag wysokości. Czy to po prostu, że odpowiedzi muszą obsługiwać wiadomości do tych wymiarów i nie są wymagane do obsługi większych, czy też zamierzasz wymagać, aby wszystkie linie były dopełniane do co najmniej 8 znaków, a wszystkie wiadomości do co najmniej 6 linii?
Peter Taylor,
1
@PeterTaylor Jeśli twój program lub język jest wystarczająco inteligentny, aby zmienić rozmiar wyświetlacza zgodnie z wyjściem, nie ma potrzeby zwiększania wyświetlacza do 8x6, jeśli wyjście jest mniejsze. Wyjście powinno mieć szare tło i być prostokątne (wszystkie linie wypełnione co najmniej do długości najdłuższej linii.)
Level River St

Odpowiedzi:

15

CJam, 464 bajty

Myślałeś, że CJam nie ma funkcji manipulacji obrazem? Cóż, pomyślałeś dobrze! Ale nie chciałem, żeby to mnie powstrzymało.

"P3
690 690 4
"3a3*a690_@*a*qeuN/{0:U;{_'C<.5*:N;i[{XY+Z<[E8][9C]?XY<=}WWWW{XH<9F?}C{YC/[9FCF]=}{YC/3&9E?}{YH<9F?}{X29.5:R-zYR-z+H>FC?}{XA/1&9E?}{XH<FC?}{XR-_*YR-_*+F_*>E8?}{YK/(9F?}{XH<E9?}{XH<YH<^8E?}{XY+Z-A/XY-A/e&9F?}{XF/YF/^1&F9?}{XY<EC?}{XH-F/YH-F/|9F?}E{XHm6/YHm6/e&CE?}{XH-F/YH-F/|F9?}{XK/[CF9]=}{XH<YH<^FC?}{XY+Z-A/XY-A/e&FC?}{XR-zYR-ze>iA/[CF9]=}{XHm6/YHm6/e&F9?}{XY+F/1&CE?}]=:P~!!{60:Z{Z30:HYH-z-N*-{YV+_2$=XU+P2b1>4f*tt}fX}fY}*U90+:U;}/V90+:V;}/`"[]"-

Ten program wysyła obraz w najlepszy sposób, w jaki CJam może: jako tekst reprezentujący obraz, gdy jest zapisany jako plik PPM . Nawiasem mówiąc, nawet nie próbuj uruchamiać go z tłumaczem online; zdmuchniesz stos. Uruchom go za pomocą interpretera Java i potokuj dane wyjściowe do pliku za pomocą polecenia podobnego do java -jar cjam-0.6.4.jar flags.cjam > flags.ppm. Po wprowadzeniu danych wyślij EOF (może być konieczne natychmiast po nowej linii) z ctrl + D w systemie Unix lub ctrl + Z w systemie Windows.

Próba

Jeśli jest to naprawdę pożądane, mogę spróbować gdzieś wkleić oryginalne źródło ~ 3 MB obrazu. Ale oto wynik otwarty w GIMP i przekazany do PNG:

ABCDEFG
hijklmn
OPQRSTU
vwxyz z

flags_alphabet.png

Wyjaśnienie

Nagłówek obrazu, łatwo identyfikowalny w źródle, składa się z magicznej liczby, szerokości, wysokości i maksymalnej wartości kanału. Tak więc obrazem wyjściowym jest obraz 690 * 690 (wystarczający dla flag 8 * 8 60px z odstępami 30px) z każdą wartością R, G i B w zakresie od 0 do 4.

Dane obrazu są inicjowane jako tablica 690 * 690 * 3 wypełniona trójkami, dzięki czemu cały obraz jest jasnoszary. Następnie dane wejściowe są odczytywane, konwertowane na wielkie litery i dzielone na linie. Linie są przetwarzane w pętli, zwiększając współrzędną flagi Y o 90 w każdej iteracji, aw każdym wierszu każdy znak jest przetwarzany w pętli, zwiększając współrzędną flagi X o 90 w każdej iteracji. Teraz zaczyna się magia.

Każdy znak jest odwzorowany na funkcję piksela flagi, która po wywołaniu zwraca kolor piksela w pozycji (X, Y) na fladze. Właśnie tam poszła większość ciężkiej pracy: zwięzłe opisanie 26 obrazów jako funkcji matematycznych. Każda z tych funkcji zwraca wartość koloru od 8-15. Ten zakres wykorzystuje fakt, że po przekonwertowaniu na bazę 2 wynikową tablicę bitów można interpretować jako [1, R, G, B]. Pierwszy element można usunąć, a resztę pomnożyć przez 4, aby łatwo podać wartość piksela w żądanym formacie, który obejmuje wszystkie możliwe kolory flag (a także zielony, cyjan i magenta). Ładnie działa również to, że zmienne jednoznakowe są inicjowane na 10-15, a ponieważ zmienne nie potrzebują spacji do ich syntaktycznego rozdzielenia,

Po pobraniu funkcji wystarczy powtórzyć X i Y od 0 do 60, wywołać funkcję na każdym kroku i zapisać wynik z powrotem do tablicy danych obrazu. Bystry obserwator może zauważyć, że wartości kolorów zwracane przez każdą funkcję flagi nie zezwalają na kolor szary. Jest więc trochę dodatkowej logiki do pomijania spacji. Ale nadal istnieją cięcia typu „swallowtail” na „A” i „B”. Jest też trochę dodatkowej logiki. Jeśli wartość znaku jest mniejsza niż „C”, wartość jest ustawiana w taki sposób, że górna granica na pętli X zmienia się poprawnie w odniesieniu do Y, a obszary wycięcia nigdy nie są rysowane.

Ogólnie jestem bardzo zadowolony z tego, jak to wyszło. Zajęło to dużo pracy, ale było fajnie. Niektóre flagi nie pasują idealnie do obrazu odniesienia, ale myślę, że wszystkie kształty znajdują się w odległości 1 piksela od celu (jeśli jakieś są wyłączone o więcej niż to, daj mi znać, a ja je naprawię). I zdecydowanie istnieje potencjał do optymalizacji, ponieważ istnieje znaczna nadmiarowość między 26 funkcjami flagi.


Niepokojąca pierwsza próba, 559 bajtów

Chociaż nigdy tego nie skończyłem, opublikuję to, ponieważ jest dość interesujące. Zamiast modelować każdą flagę za pomocą funkcji (X, Y) → kolor, flagi są rysowane jako kompozycja prostych kształtów. Martwiłem się jednak o konieczność napisania znacznej ilości kodu renderującego dla każdego innego kształtu. Po wielu rozmyślaniach zdałem sobie sprawę, że mogę je wszystkie renderować, z pewnym sprytnym nakładaniem się i nakładaniem, za pomocą tylko jednego pseudo-kształtu: wszystkie punkty w określonej odległości od określonego punktu, gdzie definicja „odległości” jest zmienna. Odległość od szachownicy daje kwadrat, odległość Manhattan daje diament, a odległość euklidesowa daje okrąg. Oznaczało to, że każdy kształt miał te same pięć parametrów (kolor, tryb odległości, x, y,

"P3
690 690 4
"3a3*a690_@*a*qeuN/{0:U;{_'C<.5*:N;i[[8EX30:Q0Q9X60:ZQQCXQZQ]LLLL[F9TTQQ]Ca[9FTQ42QCTQ54QFTQ66Q9TQ78Q][E9TIQI9T42QI][9FTQZQ][FCXQQQ][E9T40QQET50QQ9TZQQET70QQ9T80QQ][FCTZQQ][E8YQQF][9FTQAQ9TQ9~Q][E9TZQQ][8ETTTQETZZQ][F9XQTK9XZQK9XQZK9XTQK][F4{4{JW^1&6*9+TJ)F*W)F*F}fJ}fW][CEX0ZZ][9FTQQF]Ea[E[TZ]_m*{CT@~24}/][F9TQQF][9FTAQQCT9~QQ][FCTTTQCTZZQ]C9$1>9a/Fa*+[9FTQQKCTQQA]9 6$1>Ca/Fa*+[C7{7\-_1&2*C+X@TT@F*}/]]=_!!{([TQQQ]+\+}*5/{~:R;.5-:H;.5-:G;:M;2b1>4f*:O;Z{ZQWQ-z-N*-{JG-{zM_!+#}:P~WH-PM{+}{e>}?RP<{WV+_2$=JU+Ott}*}fJ}fW}/U90+:U;}/V90+:V;}/`"[]"-
Runer112
źródło
1
Znakomicie, tego rodzaju twórczej odpowiedzi szukałem. Spróbuje uruchomić go później.
Level River St
1
Jest to prawdopodobnie najdłuższy kod CJam, jaki kiedykolwiek widziałem. Dobra robota, +1.
Alex A.,
Znowu CJam wydaje się uratować dzień.
ASCIIThenANSI
9
Niestety publikowanie kodu CJam dłuższego niż 200 bajtów jest przestępstwem federalnym. Będę musiał zabrać cię do aresztu.
Deusovi
2

PHP, 811 bajtów

function f($s){echo"<body bgcolor=#ccc>";$z=split("\n",gzinflate(base64_decode("vVfNasMwDL7vKQK7xlT+iaHQ9LDTLnuIQus6ENhgxS19+kmO0yRrkhbqGIxtyV8sWbIkZ/Prjtm52p9suYbMHqqjPdHMVYfzx/elhBzyNbXtZoXQ7dvm+Q9+dieb7csvZFkJToNlEq6Zqeq6fAcw2arDqCKXUPMCEYQicIc1xmNfUkBDzXgQkpMQ3W0PEGF7fz49dT7IuSCQ1APJ5h9IKAIhdGn1jIHH6oUzvCpZzhtGjoDiePzuzAPJEkG1JPk1uw29G5rC7pxAvAFxuHqd+nQxpCP65S4gR6wzAkphE4rPHfbYaAueky59BrmrZ4wU0Ss8SES/pCNugMduiBSYs25oJTeBSYNMbHO6+bUg22PPhA8E5LCWhT3SFBjEwxaWiOMYD1+FtZSZxateEAZ7pvsEL7w1aQxD3HxLcmayfNA9ZeXzcdteJLm0H5ZITzAwolDkXeGwVAvlSzUOSDDkMRqRxDkuLquVecbKMRKFaESLSYOMg4b6qVHQMnkMns5jyZLBAnksRehirQWrwClEqakDNrqKpjqKpZ8K5rVYTFE56ZmCyT68KinJX+n/puFpyHXg4RRLwg1oW6YipqfimfJTt6/c6XIv6Tnc/HxNXIj+a9nORdwN5Qa3qzvGHw==")));while($c=ord(ucfirst($s))){$s=substr($s,1);echo$c<32?'<br>':($c^32?$z[$c-64]:$z[0]);}}

Skompresowany obiekt blob zawiera kod SVG dla każdej z 26 flag. Prosta pętla następnie wyodrębnia i wysyła obraz SVG odpowiadający każdemu znakowi wejścia.

Przykładowe dane wyjściowe dla „To jest \ntest”:

<body bgcolor=#ccc><svg width=90 height=90 viewBox=0,0,90,90><path d=M0,0h20v60h-20z fill=#f00 /><path d=M20,0h20v60h-20z fill=#fff /><path d=M40,0h20v60h-20z fill=#00f /></svg><svg width=90 height=90 viewBox=0,0,90,90><path d=M0,0h30v60h-30z fill=#fff /><path d=M30,0h30v60h-30z fill=#f00 /></svg><svg width=90 height=90 viewBox=0,0,90,90><path d=M0,0h60v60h-60z fill=#ff0 /><path d=M15,30a15,15,0,0,1,30,0a15,15,0,0,1-30,0z fill=#000 /></svg><svg width=90 height=90 viewBox=0,0,90,90><path d=M0,0h60v60h-60z fill=#fff /><path d=M15,15h30v30h-30z fill=#00f /></svg><svg width=90 height=90 viewBox=0,0,90,90></svg><svg width=90 height=90 viewBox=0,0,90,90><path d=M0,0h60v60h-60z fill=#ff0 /><path d=M15,30a15,15,0,0,1,30,0a15,15,0,0,1-30,0z fill=#000 /></svg><svg width=90 height=90 viewBox=0,0,90,90><path d=M0,0h60v60h-60z fill=#fff /><path d=M15,15h30v30h-30z fill=#00f /></svg><br><svg width=90 height=90 viewBox=0,0,90,90><path d=M0,0h30v60h-30z fill=#00f /><path d=M45,30l15-30h-30v60h30z fill=#fff /></svg><svg width=90 height=90 viewBox=0,0,90,90></svg><svg width=90 height=90 viewBox=0,0,90,90><path d=M0,0h20v60h-20z fill=#f00 /><path d=M20,0h20v60h-20z fill=#fff /><path d=M40,0h20v60h-20z fill=#00f /></svg><svg width=90 height=90 viewBox=0,0,90,90><path d=M0,0h60v30h-60z fill=#00f /><path d=M0,30h60v30h-60z fill=#fff /></svg><svg width=90 height=90 viewBox=0,0,90,90><path d=M0,0h60v60h-60z fill=#fff /><path d=M15,15h30v30h-30z fill=#00f /></svg><svg width=90 height=90 viewBox=0,0,90,90><path d=M0,0h20v60h-20z fill=#f00 /><path d=M20,0h20v60h-20z fill=#fff /><path d=M40,0h20v60h-20z fill=#00f /></svg>

( Możesz to wypróbować na ideone , chociaż nie wyrenderuje strony za ciebie).

r3mainer
źródło