Mały Chandler jest smutny. Narysuj mu chmurę, aby go pocieszyć

57

Mały Chandler jest smutny. Narysuj mu chmurę, aby go pocieszyć.
Uwaga: narysowanie chmury tak naprawdę go nie poprawi.

Okrąg można zdefiniować jako 3- krotny, (x,y,r)gdzie xpozycja x koła na płaszczyźnie kartezjańskiej, ypozycja y koła na płaszczyźnie kartezjańskiej i rjest promieniem okręgu. xi ymoże być negatywny. rjest zawsze pozytywne. Dane wejściowe to lista okręgów w postaci 3-krotek oddzielonych spacjami. Na przykład:

3,1,1 3,2,1.5 1,2,0.7 0.9,1.2,1.2 1,0,0.8

Te 3,1,1środki „okręgu z punktem środkowym w 3,1z 1 promień. 3,2,1.5Oznacza” okręgu z punktem środkowym w 3,21,5 promienia.

Jeśli narysujemy wszystkie te okręgi danych wejściowych na wykresie, wygląda to tak (zamieściłem linie siatki i etykiety tylko dla przejrzystości; nie są one wymagane):

Wykres

Zauważ, że wszystkie kręgi są spójne . Oznacza to, że wszystkie one zachodzą na siebie tak, że tworzy jedną dużą grupę bez małych grup kół oddzielonych od reszty. Wejście jest gwarantowana być spójna.

Załóżmy, że teraz narysujemy linię, która biegnie wokół „granicy” utworzonej przez te koła, bez żadnych innych linii. To byłoby jak narysowanie granicy sylwetki utworzonej przez wszystkie koła. Powstała chmura wyglądałaby mniej więcej tak:

Chmura

Ta chmura została utworzona przez narysowanie tylko łuków okręgów na wejściu, które tworzą granicę, w wyniku czego powstaje pojedynczy kształt. Innymi słowy, chmura jest tworzona tylko przez rysowanie łuków, które nie znajdują się w innym okręgu. Twój program pobierze dane wejściowe w powyższej formie i wyświetli obraz, który wyświetli wynikową chmurę. Ogólny kształt chmury musi być prawidłowy, ale to od Ciebie zależy skala, kolor, grubość linii i sposób, w jaki wygląda na wierzchołki. Zauważ, że chmura musi być widoczna, więc nie możesz wyciągnąć czegoś takiego: „Ten program rysuje chmurę na białym tle”, „Ten program rysuje chmurę w nieskończenie małej skali”, „Ten program rysuje chmurę z 0 grubość linii ”itp. Należy również pamiętać, że kolor obramowania musi różnić się od koloru wypełnienia lub tła.

Inny przykład. Wejście:

1,4,2 5,2,1 3,1,1 3.5,2,1.2 3,3,0.7 1,2,0.7

Wynik:

chmura2

Jeśli w chmurze jest „dziura”, również należy narysować dziurę. Wejście:

0,5,4 3,4,4 4,3,4 5,0,4 4,-3,4 3,-4,4 0,-5,4 -3,-4,4 -4,-3,4 -5,0,4 -4,3,4 -3,4,4 

Wynik:

chmura3

Oto ważna zasada: twój program musi rysować tylko linie tworzące granicę. Oznacza to, że NIE MOŻESZ po prostu narysować okręgów w pełni, a następnie narysować koła nieco mniejsze za pomocą białego wypełnienia - ponieważ ta metoda nadal rysuje linie, które nie tworzą granicy, po prostu je zakrywa. Celem tej reguły było zapobieżenie „narysowaniu okręgów, a następnie narysowaniu kół ponownie za pomocą białego wypełnienia” lub czegoś podobnego. Oczekuje się, że odpowiedź faktycznie obliczy, gdzie narysować rzeczy przed narysowaniem.

To jest golf golfowy, więc wygrywa najmniejsza liczba znaków.

Absynt
źródło
13
+1 za pytanie o wynik graficzny z obiektywnym kryterium wygranej (i akapit pierwszy).
Dennis
2
Jak rozpoznać, czy narysujemy linię i usuniemy ją później? Czy renderowanie wspomnianych linii na wewnętrznych bitmapach jest prawidłowe? Jeśli nie, gdzie jest granica między wektorem a reprezentacją bitmapy? Jeśli tak, dlaczego nie zrobić tego samego z głównym płótnem (wiemy, że jest podwójnie buforowany, aby użytkownik nie widział naszych linii tymczasowych)?
John Dvorak,
1
@JanDvorak Celem tej reguły było zapobieżenie „narysowaniu okręgów, a następnie narysowaniu kół ponownie za pomocą białego wypełnienia” lub czegoś podobnego. Oczekuje się, że odpowiedź faktycznie obliczy, gdzie narysować rzeczy przed narysowaniem. Będę edytować, aby było bardziej jasne.
absynt
15
To pytanie jest absolutnie zabawne z zainstalowanym Cloud to Butt ( chrome.google.com/webstore/detail/cloud-to-butt-plus/... ).
Erty Seidohl,
9
@ SomeKittens Zgubiłem to w „Jeśli w chmurze jest„ dziura ”, również należy ją narysować”.
Erty Seidohl,

Odpowiedzi:

25

Mathematica 177 126 121 119

Rozwiązywanie według regionów dyskowych: podejście matematyka

Logika polega na tym

  • Utwórz Region 1 (R1), koła (bez ich wnętrz);
  • Utwórz Region 2 (R2), dyski (bez obramowania okręgu).
  • Utwórz region 3 (R3 = R1-R2).
  • -

wnioskowanie o regionie

Właśnie takie podejście zastosowano poniżej. Wyprodukowano 3 liczby powyżej.

input = "3,1,1 3,2,1.5 1,2,0.7 0.9,1.2,1.2 1,0,0.8";
circles = ((x - #)^2 + (y - #2)^2 == #3^2) & @@@ 
     ToExpression[#~StringSplit~","] &@(StringSplit@input);
R1 = ImplicitRegion[Or @@ circles, {x, y}];
r1 = RegionPlot[R1, PlotLabel -> "R1: circles containing borders", 
   AspectRatio -> 1, PlotRange -> {{-1, 5}, {-1, 5}}];

innerDisks = ((x - #)^2 + (y - #2)^2 < #3^2) & @@@ 
     ToExpression[#~StringSplit~","] &@(StringSplit@input);
R2 = ImplicitRegion[Or @@ innerDisks, {x, y}];
r2 = RegionPlot[R2, PlotLabel -> "R2: disks within circle borders", 
   AspectRatio -> 1, PlotRange -> {{-1, 5}, {-1, 5}}];
R3 = RegionDifference[R1, R2]
r3 = RegionPlot[R3, PlotLabel -> "R3 = R1-R2", AspectRatio -> 1, 
   PlotRange -> {{-1, 5}, {-1, 5}}];
GraphicsGrid[{{r1, r2, r3}}, ImageSize -> 600]

Region niejawny nr 1 to połączenie kręgów. Region niejawny nr 2 to połączenie dysków leżących w kręgach. Różnica polega na granicy.

RegionDifference [
ImplicitRegion [(- 3 + x) ^ 2 + (-1 + y) ^ 2 == 1 || (-3 + x) ^ 2 + (-2 + y) ^ 2 == 2,25 || (-1 + x) ^ 2 + (-2 + y) ^ 2 == 0,49 || (-0,9 + x) ^ 2 + (-1,2 + y) ^ 2 == 1,44 || (-1 + x) ^ 2 + y ^ 2 == 0,64, {x, y}],
region niejawny [(- 3 + x) ^ 2 + (-1 + y) ^ 2 <1 || (-3 + x) ^ 2 + (-2 + y) ^ 2 <2,25 || (-1 + x) ^ 2 + (-2 + y) ^ 2 <0,49 || (-0,9 + x) ^ 2 + (-1,2 + y) ^ 2 <1,44 || (-1 + x) ^ 2 + y ^ 2 <0,64, {x, y}]]


Rozwiązywanie według regionów dyskowych: podejście inżyniera (119 znaków)

Poniżej przedstawiono połączenie regionów dyskowych, dyskretyzację tego regionu i znalezienie jego granicy. Punkty na schemacie wyznaczają interwały siatki Delaunaya. Pokazujemy poniżej dyskretny region, aby podświetlić obiekt, który stanowi granicę zainteresowania (kontur chmury).

s = StringSplit;RegionBoundary@DiscretizeRegion[RegionUnion[Disk[{#, #2}, #3] &@@@
ToExpression[#~s~","] &@(s@InputString[])]]

„3,1,1 3,2,1,5 1,2,0,7 0,9,1,2,2,2 1,0,0,8”

Granica regionu jest dyskrecjonalna.

reg1


Rozwiązywanie problemów przez wykrywanie krawędzi: Podejście fotografa - 121 znaków

wykrywanie krawędzi

Rysuje dyski na czarno, rasteryzuje obraz, wykrywa krawędzie i odwraca czarno-biały.

s=StringSplit;ColorNegate@EdgeDetect@Rasterize@Graphics[Disk[{#,#2},#3]&@@@
((ToExpression/@s[#,","])&/@s[InputString[]])]
DavidC
źródło
Ogolono 5 bajtów:RegionBoundary@DiscretizeRegion@RegionUnion[{#,#2}~Disk~#3&@@@ToExpression[#~s~","]&@s@InputString[s=StringSplit]]
Martin Ender
Potencjalnie s=StringSplitwewnątrz zachęty? Spróbuj przesunąć to na przód, nadal powinno być krótsze niż bieżąca wersja.
Martin Ender
27

T-SQL 235 234 229 212 171 73 bajty

Wykorzystuje to funkcje przestrzenne w SQL Server 2012+. Po uruchomieniu w SSMS (SQL Server Management Studio) tworzy okienko wyników przestrzennych. Dane wejściowe pochodzą ze zmiennej @i. Mógłbym to jeszcze bardziej zmniejszyć, gdyby dane wejściowe można było pobrać z tabeli.

Ponieważ wprowadzanie tabeli jest teraz dozwolone.

SELECT Geometry::UnionAggregate(Geometry::Point(X,Y,0).STBuffer(R))FROM A

Poprzednie rozwiązanie pozostawiłem poniżej.

DECLARE @ VARCHAR(999)='WITH a AS(SELECT *FROM(VALUES('+REPLACE(@i,' ','),(')+'))A(X,Y,R))SELECT Geometry::UnionAggregate(Geometry::Point(X,Y,0).STBuffer(R))FROM a'EXEC(@)

Edycja : Usuń zbłąkane miejsce, nadwyżkę do i podzapytanie

171: Zastąpiono tworzenie tabeli CTE i @s @.

wprowadź opis zdjęcia tutaj

Podział dynamicznego SQL

DECLARE @i VARCHAR(100) = '1,4,2 5,2,1 3,1,1 3.5,2,1.2 3,3,0.7 1,2,0.7' -- Input
DECLARE @ VARCHAR(999) = '
WITH a AS(                                       --CTE to produce rows of x,y,r 
    SELECT *FROM(VALUES('+
        REPLACE(@i,' ','),(')                    --Format @i to a value set
        +'))A(X,Y,R)
)
SELECT Geometry::UnionAggregate(                 --Aggregate Buffered Points
    Geometry::Point(X,Y,0).STBuffer(R)           --Create point and buffer
    )               
FROM a                                           --from the table variable
'
EXEC(@)                                          --Execute Dynamic sql
MickyT
źródło
Dostaję komunikat o błędzie'A' has fewer columns than were specified in the column list
Jesan Fafon
@JesanFafon Upewnij się, że zmienna wejściowa @i jest ustawiona poprawnie. DECLARE @i VARCHAR(100) = '1,4,2 5,2,1 3,1,1 3.5,2,1.2 3,3,0.7 1,2,0.7'. Niestety nie mogę w tej chwili przetestować, a SQLfiddle nie gra ładnie w 2012 roku.
MickyT
Dobra praca z funkcjami geometrii SQL. Dobre wieści! Wprowadzanie przez istniejącą tabelę jest teraz wyraźnie dozwolone . Tworzenie tabeli i populacja nie muszą być uwzględniane w liczbie bajtów.
BradC
Grałem w kilka postaci. Link nie daje rezultatu. Ale działa w studiu zarządzania serwerami ms-sql. Skrypt jest tutaj , ciesz się. Możesz go używać
t-clausen.dk
@ t-clausen.dk dzięki za to, ale ponieważ zamierzam to zaktualizować, zmienię to na dozwolone dane wejściowe do tabeli. Nie zamierzałem go
kopać
23

Mathematica, 175 158 149 bajtów

s=StringSplit;l=ToExpression[#~s~","]&@s@InputString[];RegionPlot[Or@@(Norm@{x-#,y-#2}<#3&@@@l),{x,m=Min@(k={{##}-#3,{##}+#3}&@@@l),M=Max@k},{y,m,M}]

Pamiętam z dyskusji w piaskownicy, że to podejście miało być poprawne, ale nie jestem całkowicie pewien, jak to się dzieje z nowym brzmieniem reguł, więc @Lilac, daj mi znać, jeśli uważasz, że to narusza reguły.

Zasadniczo tworzę warunek logiczny, który jest prawdziwy dla wszystkich punktów w chmurze i fałszywy dla wszystkich punktów poza nim. Karmię to tym, RegionPlotco następnie renderuje region wszystkich punktów, w których znajduje się wyrażenie, Trueoraz kontur wokół niego.

wprowadź opis zdjęcia tutaj

Nie golfowany:

s = StringSplit;
l = ToExpression[#~s~","] &@s@InputString[];
RegionPlot[
 Or @@ (Norm@{x - #, y - #2} < #3 & @@@ l), 
 {x, m = Min@(k = {{##} - #3, {##} + #3} & @@@ l), M = Max@k},
 {y, m, M}
]
Martin Ender
źródło
1
ImplicitRegionautomatycznie znajduje odpowiednie wartości x i y do kreślenia. 122 znaki:s = StringSplit; RegionPlot@ ImplicitRegion[ Or @@ (((x - #)^2 + (y - #2)^2 < #3^2) & @@@ (ToExpression[#~s~","] &@(s@InputString[]))), {x, y}]
DavidC
@DavidCarraher Niestety zniekształca to proporcje obrazu. (Fajnie jest wiedzieć, że wszystkie funkcje regionu - także te, których używałeś - widziałem tylko do RegionPlottej pory.)
Martin Ender
Prawdopodobnie już zauważyłeś, że ,AspectRatio-> 1kod wraca do 149 bajtów, dokładnie tam, gdzie teraz stoi.
DavidC
2
Czy to ja, czy ten obraz wygląda jak Marvin the Paranoid Android?
paqogomez
16

Python 3.3 ( 183 177 164 160 bajtów)

B=list(map(eval,input().split()))
print("".join(" ## "[sum(any(r*r>(x-d%80/4+10)**2+(y+d//80/4-10)**2for
x,y,r in B)for d in[i,i+1,i+80])]for i in range(6400)))

Wymaga konsoli o szerokości 80 znaków, która, jak wiem, jest domyślna w systemie Windows. Działa najlepiej, jeśli twoja konsola ma kwadratową czcionkę. Oto niektóre fragmenty niektórych danych wejściowych testu.

Oryginał:

           ########
          ##       #
         ##         #
     #####          #
    ##   #          #
   ##               #
  ##                #
 ##                 #
 #                  #
 #                 ##
  #               ##
  #       ##      #
   #      # #    ##
   #      #  #####
   #      #
    #    ##
     #  ##
      ###

Inne:

    ########
  ###       ##
 ##           #
 #            #
##             #
#              #
#              #
#              #
#              #
#               ##
#                 #
 #                 ##
 #                   ######
  #                        #
   ##      ###             #
     #    ## #             #
     #    #  #             #
      #  ## ##             #
       ###  #             ##
            #       #######
            #      ##
            #      #
             #    ##
              #####

Otwór:

                              ############
                            ###           ##
                          ###               ##
                         ##                   #
                  ########                     #######
                ###                                   ##
              ###                                       ##
             ##                                           #
            ##                                             #
           ##                                               #
          ##                                                 #
         ##                                                   #
        ##                                                     #
       ##                                                       #
      ##                                                         #
      #                                                          #
     ##                                                           #
     #                                                            #
    ##                                                             #
    #                                                              #
    #                                                              #
    #                                                              #
    #                                                              #
    #                                                              #
    #                                                              #
   ##                                                               #
  ##                                                                 #
  #                                                                  #
 ##                                                                   #
 #                                                                    #
##                                                                     #
#                                 ####                                 #
#                                ##   #                                #
#                               ##     #                               #
#                              ##       #                              #
#                              #        #                              #
#                              #        #                              #
#                               #      ##                              #
#                                #    ##                               #
#                                 #  ##                                #
#                                  ###                                 #
 #                                                                    ##
 #                                                                    #
  #                                                                  ##
  #                                                                  #
   #                                                                ##
    #                                                              ##
    #                                                              #
    #                                                              #
    #                                                              #
    #                                                              #
    #                                                              #
    #                                                              #
     #                                                            ##
     #                                                            #
      #                                                          ##
      #                                                          #
       #                                                        ##
        #                                                      ##
         #                                                    ##
          #                                                  ##
           #                                                ##
            #                                              ##
             #                                            ##
              #                                          ##
               ##                                      ###
                 ##                                  ###
                   #######                    ########
                          #                  ##
                           ##              ###
                             ##          ###
                               ###########
rekurencyjny
źródło
1
Uwielbiam to, że jest to jedyne rozwiązanie ascii art.
vmrob
bez importu ... imponujące!
Richard Green
15

Python - 253 249 215 199

To jest reklama niesamowitej, zgrabnej biblioteki, której operacje geometryczne sprawiły, że pisanie rozwiązania było proste, poprzez narysowanie konturu połączenia nakładających się kół (= zbuforowanych punktów):

from pylab import*
from shapely.geometry import*
c=Point()
for s in raw_input().split():
 x,y,r=eval(s)
 c=c.union(Point(x,y).buffer(r))
plot(*c.exterior.xy)
for i in c.interiors:
 plot(*i.xy)
show()

Wynik:

trzy chmury

Edycja:

  • 249: Zastąpiony sys.argv[1:]przez raw_input().split(), zapisywanie aimport sys
  • 215: Usunięto k={'color':'k'}luksus, zastąpiono savefigprzezshow
  • 199: Zastąpiony map(float,s.split(','))przezeval(s)
ojdo
źródło
11

Python - 535

import math as m
import matplotlib.pyplot as l
c = "3,1,1 3,2,1.5 1,2,0.7 0.9,1.2,1.2 1,0,0.8"
a = [[float(y) for y in x.split(",")] for x in c.split(" ")]
for a2 in a:
    for x in xrange(0,200):
        q=x*m.pi/100.0
        p=(a2[0]+m.sin(q)*a2[2], a2[1]+m.cos(q)*a2[2])
        cc = []
        for z in a:            
            if z != a2:               
                if ((z[0] - p[0]) ** 2 + (z[1] - p[1]) ** 2 ) < (z[2] ** 2) :
                    cc.append(z)
        if not cc: 
            l.scatter(p[0],p[1])
l.show()
Richard Green
źródło
2
Ma to duży potencjał do dalszej gry w golfa, np. Przez from math import*usunięcie niepotrzebnych spacji, używanie tylko literowych nazw zmiennych, używanie list (np cc=[z for z in a if z!=a2 and (z[0]…)].). Zobacz także wskazówki dotyczące gry w golfa w Pythonie .
Wrzlprmft
Możesz zapisać niektóre znaki, używając zamiast jednej litery nazwy zmiennej a2.
ProgramFOX
dzięki wrzl ... Prawdopodobnie zacznę dzisiaj grać w golfa (inne rzeczy do zrobienia teraz, ale chciałem postawić kołek w ziemi)
Richard Green
1
tak @ProgramFOX ... to była wersja, która działała i którą mogłem debugować .. otrzymam ją dziś wieczorem ...
Richard Green
3
@JamesWilliams, jeśli chcesz wziąć pałeczkę ... proszę zrób ... Nie chronię kodu !! Dodaj go jako swój własny wpis (pod warunkiem uznania oryginału!)
Richard Green
9

Python - 296 249 231 223 212

from pylab import*
a=map(eval,raw_input().split())
for x,y,r in a:
 for i in range(200):
  q=i*pi/100;p=x+r*sin(q);t=y+r*cos(q);[z for z in a if z!=(x,y,r)and(z[0]-p)**2+(z[1]-t)**2<z[2]**2]or scatter(p,t)
show()

Podziękowania dla @ richard-green (pozwolenie zostało wydane) za oryginalne rozwiązanie, po prostu trochę go zmniejszyłem.

James Williams
źródło
7
cóż, dostaje mój głos ...
Richard Green,
1
Możesz zaoszczędzić trochę więcej, importując pylabzamiast matplotlib.pyplot.
ojdo
@odjo Obecnie na telefon komórkowy, jeśli kiedyś from pylab import *będę jeszcze mógł zadzwonić show()i scatter()bez jakichkolwiek odniesień?
James Williams
1
@JamesWilliams potwierdzone! Pylab jest zanieczyszczającym przestrzeń nazw, w tym wiele funkcji podobnych do MATLAB :-)
ojdo
Możesz to skrócić, używając, [eval(i)for i in raw_input().split()]gdy python evalzamienia 1,2,3się w krotkę. Będzie również oczywiście trzeba zmienić [x,y,r]aby (x,y,r).
KSab
7

JavaScript (E6) + HTML 322

JSFiddle

Każde koło jest podzielone na około 100 małych łuków, a każdy łuk jest rysowany, jeśli jego środkowy punkt nie znajduje się w żadnym z pozostałych okręgów.

<canvas id='c'/>
<script>
t=c.getContext("2d"),z=99,c.width=c.height=400,
l=prompt().split(' ').map(c=>c.split(',').map(v=>40*v)),
l.map(c=>{
  for(i=z;--i+z;)
    s=4/z,r=c[2],x=c[0]+r*Math.cos(a=i*s),y=c[1]+r*Math.sin(a),
    t.beginPath(),
    l.some(q=>c!=q&(d=x-q[0],e=y-q[1],d*d+e*e<q[2]*q[2]))||t.arc(z+c[0],z+c[1],r,a-s,a+s),
    t.stroke()
})
</script>
edc65
źródło
7

Python 274 bajtów

To pobiera dane wejściowe ze standardowego wejścia i sprawdza każdy punkt na wyświetlaczu, rysując piksele jeden po drugim. Nie do końca wydajny, ale spełnia wszystkie zasady.

c=[eval(s)for s in raw_input().split()]
import pygame
S=pygame.display.set_mode((500,500))
S.fill([255]*3)
for p in((x,y)for x in range(500)for y in range(500)if 0<min((((x-250)/25.-a)**2+((y-250)/25.-b)**2)**.5-r for(a,b,r)in c)<.1):S.set_at(p,[0]*3)
pygame.display.update()

Zauważ, że wyświetlanie gry pygame zakończy się po zakończeniu rysowania, nie byłem pewien, czy powinienem dołączyć ją jako część mojej odpowiedzi, ale aby ją wyświetlić, możesz albo wrzucić ją raw_inputna końcu, albo dodać małą pętlę, jeśli chcesz powstrzymać system operacyjny przed narzekaniem, że nie odpowiada i takie:

alive = True
while alive:
    pygame.display.update()
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            alive = False

Przykładowe obrazy:

1,4,2 5,2,1 3,1,1 3.5,2,1.2 3,3,0.7, 1,2,0.7 wprowadź opis zdjęcia tutaj

0,5,4 3,4,4 4,3,4 5,0,4 4,-3,4 3,-4,4 0,-5,4 -3,-4,4 -4,-3,4 -5,0,4 -4,3,4 -3,4,4 wprowadź opis zdjęcia tutaj

KSab
źródło
3
@ edc65 Nie jestem pewien, co masz na myśli. To, co robi dokładnie, to wypełnienie dowolnego piksela, który znajduje się między 0 a 0,1 jednostek (między 0 a 2,5 pikseli) poza okręgami. Czy mówisz, że matematycznie powinno znaleźć odpowiednie łuki do narysowania? Po przeczytaniu pytania nie wydawało mi się, że jest to ograniczenie.
KSab
4

Perl - 430

@e=map{[map{int($_*32)}split',']}(split' ',<>);for$g(@e){for(0..3){($a[$_]>($q=$$g[$_&1]+(($_>>1)*2-1)*$$g[2]))^($_>>1)&&($a[$_]=$q)}}for(2,3){$a[$_]-=$a[$_-2]-1}for(@e){($x,$y,$r)=@$_;$x-=$a[0];$y-=$a[1];for$k($x-$r..$x+$r){for$l($y-$r..$y+$r){$i=(int(sqrt(($x-$k)**2+($y-$l)**2)+0.5)<=>$r)-1;$f[$l][$k]=($j=$f[$l][$k])<-1||$i<-1?-2:$i||$j;}}}print"P1
$a[2] $a[3]
".join("
",map{join' ',map{$_+1?0:1}@$_,('0')x($a[2]-@$_)}@f)."
"

Zapisuje plik PBM na standardowe wyjście.

Obraz testowy (przekonwertowany na png):

Drugi obraz testowy (przekonwertowany na png)

faubi
źródło