Załącz 1009 pikseli

24

Dane wyjściowe to kształt obejmujący 1009 pikseli.

  • Kształt musi mieć postać pojedynczej, zamkniętej, nieprzecinającej się pętli.

Dane wejściowe to dodatnia niezerowa liczba całkowita.

  • Każde wejście musi dawać wyjście, które jest unikalne - to znaczy każde wyjście musi być unikalne od tych wygenerowanych przy użyciu niższego wejścia.

O zwycięstwie decyduje największy limit wejściowy:

  • Limit wejściowy przesłanych danych jest uważany za 1 mniej niż najniższy wkład, który daje nieunikalny lub w inny sposób nieprawidłowy wynik.
  • Na przykład, jeśli dla danych wejściowych 1, 2 lub 3, ale nie 4, generowane są prawidłowe i unikalne dane wyjściowe, limit wejściowy wynosi 3.

Kod źródłowy ma limit 1009 bajtów. Jeśli jest remis, wygrywa pozycja z najmniejszą liczbą bajtów.


Ograniczenia i wyjaśnienia:

  • Maksymalny rozmiar kształtu to 109 na 109 pikseli. Rozmiar obejmuje linię użytą do narysowania kształtu.
  • Linia ma stałą szerokość.
  • Zamknięta przestrzeń musi być całkowicie zamknięta przez linię - nie można użyć granicy pliku obrazu.
  • Zamknięte 1009 pikseli odnosi się tylko do zamkniętej przestrzeni. Nie zawiera linii.
  • Dane wyjściowe to obraz.
  • Nie ma żadnych dalszych ograniczeń graficznych - np. Dotyczących koloru, grubości linii itp.
  • Wyjątkowość wyjścia odnosi się tylko do zamkniętej przestrzeni. Zmiany linii lub inne zmiany graficzne nie mają znaczenia, jeśli zamknięta przestrzeń nie jest unikalna.
  • Tłumaczenie kształtu nie jest unikalne. Obroty, odbicia i wszelkie inne transformacje liczą się jako niepowtarzalne.
  • Wyjście musi być odtwarzalne - to samo wejście zawsze daje takie samo wyjście
  • Nie musi istnieć związek między wyjściami, kolejnymi lub innymi.
  • Poza „limitem wejściowym” przedłożenia nie ma określonego wyniku.
  • Żadne inne wprowadzanie lub pobieranie danych zewnętrznych jest niedozwolone.
  • Linia musi być ciągła - tzn. Piksele muszą się dotykać (dotknięcie rogu się liczy).
  • Piksel to najmniejsza jednostka „rysowania” używana w metodzie rysowania i niekoniecznie odpowiada pikselowi ekranowemu.

Przykłady:

  • Oto przykład prawidłowego kształtu:

    wprowadź opis zdjęcia tutaj

  • Następujące kształty są nieprawidłowe:

    Nieprawidłowy 1 Nieprawidłowy 2 nieważne 3

EDYCJA: Dotykanie linii:

  • Zamknięta przestrzeń musi być ciągła, co definiuje się jako dotykanie pikseli. Dotykanie narożników się liczy.
  • Linia nie może otaczać żadnej przestrzeni po swojej zewnętrznej stronie. Ten obraz opublikowany przez @Sparr ilustruje ten punkt - poprawny jest tylko pierwszy kształt w każdym rzędzie:

    wzruszające

  • Zewnętrzne boki linii mogą się dotykać, ale nie w sposób, który zamyka przestrzeń.

  • Linie dotykające nie mogą się nakładać - np. Dwie dotykające linie o grubości 1 piksela miałyby łączną grubość 2px, nigdy 1px.
jsh
źródło
Co z obrotami tego samego kształtu? Czy są różne?
Martin Ender
Jeśli gryzę z boku kształtu, czy dobrze jest mieć linię pierwszego planu (czarną) o szerokości jednego piksela? Czy też musi mieć szerokość 3 pikseli, aby linia wejściowa i wyjściowa się nie dotykały? czy może jest mieć szerokość 2 pikseli, więc linia wejściowa i wyjściowa dotykają się, ale się nie nakładają?
Level River St.
Kilka dodatkowych pytań: 1. Czy granica obrazu 109x109 może działać jak jedna granica kształtu? 2. Jeśli grubość linii zależy ode mnie, czy mogę powiedzieć, że to 200 pikseli, aby kształt był tylko białymi pikselami na czarnym obrazie? 3. Czy kształt jest połączony, jeśli jego piksele dotykają tylko rogu? 4. Nie jestem wielkim fanem limitu postaci. Wiele języków może użyć 3/4 tego tylko do skonfigurowania dokładnych specyfikacji wyjściowych.
Martin Ender
2
Pytanie, jak zdobyłeś 1009?
Claudiu
1
Który z tych kształtów jest prawidłowy i bezwzględny? i.imgur.com/FSV0nHz.png
Sparr

Odpowiedzi:

25

Python + Pycairo, 2 100 kształtów

Zacznijmy od oczywistości.

Animacja 1

from cairo import *
from sys import argv

n = int(argv[1]) - 1

s = ImageSurface(FORMAT_ARGB32, 109, 109); c = Context(s)
c.set_antialias(ANTIALIAS_NONE); c.set_line_width(1); c.translate(54, 54)
def pixel(x, y): c.rectangle(x, y, 1, 1); c.fill()

W, H, R = 100, 10, 9
X1, Y1 = -W / 2 - 1, -H / 2 - 1
X2, Y2 = X1 + W + 1, Y1 + H + 1

pixel(X2 - 1, Y1)
c.move_to(X1, Y1 + 1); c.line_to(X1, Y2 + 1)
c.move_to(X2 + 1, Y1); c.line_to(X2 + 1, Y1 + R + 1);
c.move_to(X2, Y1 + R + 1); c.line_to(X2, Y2 + 1)
c.stroke()

for i in xrange(W):
    offset = (n >> i) & 1
    for y in Y1, Y2: pixel(X1 + i, y + offset)

s.write_to_png("o.png")

Pobiera numer z wiersza poleceń i zapisuje o.png.

Łokieć
źródło
Bardzo dobrze. Prosty pomysł, dobrze wykonany. Nie będzie to zwycięski wynik, ale wyznacza dobry pasek dla kolejnych zgłoszeń.
Sparr
... * 2, asRotations [...] count as unique.
edc65
@ edc65: Właściwie * 4, ponieważ nie jest symetryczny.
justhalf
19

BBC Basic, wynik 10 ^ 288 (minus 1, jeśli zero nie jest liczone)

Pobierz interpretator ze strony http://sourceforge.net/projects/napoleonbrandy/ (nie mój zwykły podstawowy interpreter BBC, ten nie obsługuje wystarczająco długich łańcuchów.)

Aby zakodować wiele informacji, potrzebujesz dużo obwodu. To oznacza cienki kształt. Zaczynam od pionowego paska 49 pikseli po lewej stronie i dodaję do niego dziesięć macek po 96 pikseli. Każda macka może zakodować 96 bitów w podobny sposób jak w rozwiązaniu @ ell, w sumie 960 bitów.

Ponieważ BBC Basic nie obsługuje tak dużych liczb, liczba do 288 cyfr dziesiętnych jest wprowadzana jako ciąg, a każdy zestaw 3 cyfr dziesiętnych jest konwertowany na 10-bitową liczbę binarną. Każdy bit jest następnie używany do poruszania jedną macką w górę o jeden piksel, jeśli jest to 1(ale nie, jeśli jest to 0). Program może obsłużyć do 288/3 = 96 takich zestawów 3 cyfr

    1MODE1:VDU19,0,7;0;19,15,0;0;               :REM select an appropriate screen mode and change to black drawing on white background
   10INPUT a$
   20a$=STRING$(288-LEN(a$)," ")+a$             :REM pad input up to 288 characters with leading spaces
   50RECTANGLE0,0,8,200                         :REM draw a rectangle at the left, enclosing 49 pixels
   60FOR n=0 TO 95
   70  b=VAL(MID$(a$,n*3+1,3))                  :REM extract 3 characters from a$ and convert to number
   80  FOR m=0 TO 9                             :REM plot the ten tentacles
   90    PLOT71,n*4+8,m*20+8+(b/2^m AND 1)*4    :REM plot (absolute coordinates) a background colour pixel for tentacle m at horizontal distance n
  100    POINT BY 0,-4                          :REM offsetting vertically by 1 pixel according to the relevant bit of b
  110    POINT BY 4,4
  120    POINT BY -4,4                          :REM then plot foreground colour pixels (relative coordinates) above, below and to the right.
  130  NEXT
  140NEXT

Wydajność

Typowe wyjście dla liczby 288 cyfr. Zauważ, że 999 to 1111100111 w systemie binarnym. Możesz zobaczyć, jak zestawy 9 cyfr powodują falowanie macek.

wprowadź opis zdjęcia tutaj

Techniczne

A. Odpowiedź na punkt 3 Martina „czy kształt jest połączony, jeśli jego piksel dotyka tylko narożnika?” było „tak”, więc rozumiem, że moja odpowiedź jest zgodna. Niemniej jednak, jeśli naprzemiennie (na przykład) 999 i 000 w każdym rzędzie, wygląda na bardzo zajęty.

B. Jeśli widzimy to jako prostokąt z ukąszeniami wyciągniętymi z boku, widać, że pozwoliłem na trzy piksele między każdą parą sąsiednich macek, aby upewnić się, że czarna linia wokół zewnętrznej strony nigdy się nie dotyka. Nie ma w tym żadnej konkretnej zasady (mam nadzieję, że mój powód pytania jest jaśniejszy w świetle mojej odpowiedzi). Jeśli linia może dotykać się NA ZEWNĄTRZ kształtu, mogłabym przesunąć macki razem i użyć mniejszej liczby pikseli dla pionowy pasek (a więc sprawiają, że macki są nieco dłuższe). Jednak byłoby bardzo mylące ustalanie wzrokowo, czy piksel znajduje się wewnątrz czy na zewnątrz kształtu, więc myślę, że moja interpretacja, że ​​zewnętrzna strona czarnej linii nigdy nie powinna się dotykać sam jest najlepszy.

C. BBC basic w tym trybie ekranu traktuje kwadrat 2x2 pikseli ekranu jako pojedynczy piksel. Zostawiłem to tak, jak jest, ponieważ pomaga zobaczyć, czy kształt nie jest zbyt mały. Każdy z tych podstawowych pikseli BBC jest traktowany jako pudełko jednostek logicznych 4x4. Od samego początku twórcy BBC basic mieli zdolność przewidywania, że ​​któregoś dnia wzrosną rozdzielczości ekranu, więc sprawili, że rozdzielczość logiczna była wyższa niż rozdzielczość fizyczna.

Level River St
źródło
Odp .: Odpowiedź brzmi „tak”, chociaż widzę, że jest to trochę dziwne. B. Rozumiem teraz twój punkt i dokonałem edycji w celu wyjaśnienia, przepraszam za zamieszanie.
jsh
C: To nie jest problem. Piksel jest teraz definiowany jako najmniejsza używana jednostka rysunku.
jsh
6

Mathematica, 496 bajtów, Wynik: duża (> 1157)

Dolna granica, którą tam mam, jest absurdalnie niska, ale jeszcze nie znalazłem lepszego sposobu niż brutalna siła, by to sprawdzić.

SeedRandom@Input[];
g = 0 &~Array~{109, 109};
g[[2, 2]] = 1;
h = {{2, 2}};
For[n = 1, n < 1009,
  c = RandomChoice@h;
  d = RandomChoice[m = {{1, 0}, {0, 1}}];
  If[FreeQ[e = c + d, 1 | 109] && 
    Count[g[[2 ;; e[[1]], 2 ;; e[[2]]]], 0, 2] == 1,
   ++n;
   h~AppendTo~e;
   g[[## & @@ e]] = 1
   ];
  ];
(
    c = #;
    If[e = c + #; g[[## & @@ e]] < 1,
       g[[## & @@ e]] = 2
       ] & /@ Join @@ {m, -m}) & /@ h;
ArrayPlot[g, ImageSize -> 109, PixelConstrained -> True, 
 Frame -> 0 > 1]

Nie grałem jeszcze w golfa, ponieważ nie było takiej potrzeby. Zrobię to, gdy ktoś udowodni, że faktycznie się ze mną wiąże.

Algorytm zasadniczo wykonuje wypełnienie zalewowe z lewego górnego rogu obrazu 109x109 (przesunięty o jeden piksel, aby uwzględnić linię), a kiedy zalałem 1009 komórek, zatrzymuję się i zaznaczam ramkę. Powiedziałeś, że kolory zależą od nas, więc tło jest białe, linia jest czarna, a wnętrze jest szare (w razie potrzeby mogę usunąć szarość dla garści znaków).

Wypełnienie powodziowe jest dość ograniczone, ale to zapewnia, że ​​nie muszę się martwić o dziury. Złagodzenie tych ograniczeń prawdopodobnie znacznie zwiększy mój (jeszcze nieznany) wynik.

Spróbuję teraz ustawić dolne granice na wynik.

Martin Ender
źródło
Czy jesteś w stanie dostarczyć plik CDF , abym mógł to wypróbować?
jsh
1
@jsh Spróbuj tego
Martin Ender
Myślę, że wszystkie rozwiązania, które zależą od liczb losowych, będą wymagały brutalnej siły, aby sprawdzić poprawność. Nie jestem pewien, czy sprawdzasz piksel po pikselu, ale możesz spróbować zapisać każde wyjście w monochromatycznej bitmapie (mały rozmiar pliku) i porównać skróty. Wyobrażam sobie, że jest to tak szybkie, jak to możliwe w przypadku porównań obrazów.
stokastic
@stokastic Obecnie buduję bardzo naiwny skrót (suma wszystkich współrzędnych pikseli), a następnie szczegółowo sprawdzam zderzające się pojemniki. Problem polega na tym, że bez względu na to, jak wyrafinowane podejście stosuję do sprawdzania kolizji, metoda generowania jest tak wolna, że ​​nie będę w stanie rozwiązać więcej niż kilku nasion 10 000 lub 100 000 w rozsądnym czasie. Sądzę, że istnieje kilka sposobów na znaczne przyspieszenie algorytmu, więc w pewnym momencie mogę się tym zająć.
Martin Ender
@ MartinBüttner Prawdopodobnie już go przetestowałeś (lub matematyka go nie obsługuje), ale skróty plików od razu mogą być szybsze. Tylko sugestia, jeśli jeszcze tego nie próbowałeś.
stokastic
1

Python 2, wynik> 10 ^ 395

Jest bardzo wolny i nie udało mi się uzyskać żadnego wyniku innego niż n = 0, ale jeśli chcesz go przetestować niżej SIZE(liczba pikseli) i BOUNDmaksymalnej długości boku ograniczającego kwadratu i powinieneś być w stanie aby uzyskać mnóstwo wyników. Bardzo trudno było obliczyć, ile wyprodukuje; Jestem całkiem pewien, że dolna granica, którą podaję, jest dokładna, ale podejrzewam, że faktyczna liczba jest znacznie większa i mogę spróbować poprawić ją później.

import sys
import pygame
sys.setrecursionlimit(1100)

def low(s):
    return min(sum(e[1] for e in s[:i+1]) for i in range(len(s)))
def high(s):
    return max(sum(e[1] for e in s[:i+1])+s[i][0] for i in range(len(s)))

BOUND = 109
SIZE = 1009

def gen(n,t=0):
    if n <= (BOUND-t)*BOUND:
        for i in range(1,min(n,BOUND)):
            for r in gen(n-i,t+1):
                a,b=r[0]
                for x in range(max(1-a,high(r)-low(r)-BOUND),i):
                    yield [(i,0),(a,x)]+r[1:]
        yield [(n,0)]

def create(n):
    g=gen(SIZE)
    for i in range(n+1):shape=g.next()
    s=pygame.Surface((BOUND+2,BOUND+2))
    l=low(shape);x=0
    for y,(t,o) in enumerate(shape):
        x+=o;pygame.draw.line(s,(255,255,255),(x-l+1,y+1),(x-l+t,y+1))
    out=[]
    for x in range(BOUND+2):
        for y in range(BOUND+2):
            if all((0,0,0)==s.get_at((x+dx,y+dy))for dx,dy in[(-1,0),(1,0),(0,-1),(0,1)]if 0<=x+dx<BOUND+2 and 0<=y+dy<BOUND+2):
                out.append((x,y))
    for x,y in out:
        s.set_at((x,y),(255,255,255))
    pygame.image.save(s,"image.png")
KSab
źródło
2
Czy możesz podać obraz n=0? A także czy możesz wyjaśnić, w jaki sposób osiągasz 10 ^ 395?
justhalf