Jest to problem z odniesieniem

49

Wzór referencyjny Tuppera (skopiowany z Wikipedii)

Samoreferencyjna formuła Tuppera jest formułą zdefiniowaną przez Jeffa Tuppera, która po wykreśleniu w dwóch wymiarach w bardzo konkretnym miejscu w płaszczyźnie może być „zaprogramowana” w celu wizualnego odtworzenia samej formuły. Jest wykorzystywany na różnych kursach matematycznych i informatycznych jako ćwiczenie w formułach graficznych.

Wzór referencyjny Tuppera

Gdzie piętro jest funkcja podłogi.

Niech kbędzie następujący 543-cyfrowy numer: 960939379918958884971672962127852754715004339660129306651505519271702802395266424689642842174350718121267153782770623355993237280874144307891325963941337723487857735749823926629715517173716995165232890538221612403238855866184013235585136048828693337902491454229288667081096184496091705183454067827731551705405381627380967602565625016981482083418783163849115590225610003652351370343874461848378737238198224849863465033159410054974700593138339226497249461751545728366702369745461014655997933798537483143786841806593422227898388722980000748404719

Jeśli jeden wykresy zbiór punktów (x, y)w 0 <= x < 106i k <= y < k + 17spełniającą nierówność podane powyżej, otrzymany wykres wygląda następująco (zauważ, że osie w tej działki zostały odwrócone, w przeciwnym razie obraz wychodzi do góry nogami):

Wynik samonaprowadzającej się formuły Tuppera

Więc co?

Ciekawą rzeczą w tej formule jest to, że można jej użyć do wykreślenia dowolnego możliwego czarno-białego obrazu 106x17. Teraz przeszukiwanie w celu wyszukiwania byłoby niezwykle uciążliwe, więc istnieje sposób, aby obliczyć wartość k, w której pojawia się twój obraz. Proces jest dość prosty:

  1. Zacznij od dolnego piksela pierwszej kolumny obrazu.
  2. Jeśli piksel jest biały, do wartości k zostanie dodane 0. Jeśli jest czarny, dodaj 1.
  3. Przejdź w górę kolumny, powtarzając krok 2.
  4. Na końcu kolumny przejdź do następnej kolumny i zacznij od dołu, wykonując ten sam proces.
  5. Po przeanalizowaniu każdego piksela przekonwertuj ten ciąg binarny na dziesiętny i pomnóż przez 17, aby uzyskać wartość k.

Jaka jest moja praca

Twoim zadaniem jest stworzenie programu, który może przyjmować dowolny obraz 106x17 i wyświetlać odpowiednią wartość k. Możesz przyjąć następujące założenia:

  1. Wszystkie obrazy będą miały dokładnie 106 x 17
  2. Wszystkie obrazy będą zawierać tylko czarne (# 000000) lub białe (#FFFFFF) piksele, nic pomiędzy.

Jest też kilka zasad:

  1. Dane wyjściowe to po prostu wartość k. Musi mieć odpowiednią podstawę, ale może mieć dowolny format.
  2. Obrazy należy odczytać z pliku PNG lub PPM.
  3. Brak standardowych luk.

Testuj obrazy

[ Nintendo] powinien dać ~ 1,4946x10 542

[ Duża liczba] powinien dać ~ 7,2355x10 159

[ 2 ^ 1801 * 17] powinien dać 2 1801 * 17

[ 2 ^ 1802 - 1 * 17] powinien produkować (2 1802 -1) * 17

Sprawdź tę listę, aby uzyskać dokładne rozwiązania.

To jest , więc wygrywa najmniejsza liczba bajtów.


Przydatne linki

Wikipedia

Wolfram Mathworld

Kade
źródło
Czy mogę wziąć PPM?
Maltysen
EDYCJA: Tak, format PPM jest dozwolony. Kiedy wymyśliłem program, zamierzałem używać PNG, ale zezwolenie PPM powinno pozwolić na udział większej liczby języków golfowych.
Kade
3
Kiedy czytałem to pytanie, zanim dotarłem do części „Jaka jest moja praca”, byłem pewien, że quinegdzieś to słowo zobaczę .
Jacob
Nie będę udawał programisty, który potrafi robić takie rzeczy, zamiast tego po prostu przedstawię niewinne, poważne pytanie: Tak, ale czy można to zrobić odwrotnie? Czyli karmienie roztworem i zobaczenie * .png wygenerowanego w wyniku?
@NotAsSharpAsYouGuys: jeśli masz dowolną arytmetykę precyzji, jest to trywialne, musisz tylko sprawdzić wynik tej formuły dla każdego piksela i wygenerować obraz wynikowy.
Matteo Italia,

Odpowiedzi:

12

CJam, 16 lat

l,l~q:~f*/W%ze_b

Z wielkimi podziękowaniami dla Dennisa. Wypróbuj online

W przypadku problemów z adresem URL przetestowałem dane wejściowe:

P1
106 17
0000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000011111100000000000000000000000
0000000000000000000000000000000000000000000000000000000000000111111000
0000011111100110000000000000000000000000000000000000000000000000000000
0000000000000000000000000110011111100000100111100001000000000000001100
0110000000000000000000000000000000000000000000000000000000001000011110
0100010011111100001000000000000100101001110000000000000000000000000000
0011000000000000000000000100001111110010010110000110001000000000000100
0110010010000000011000000000000000000100100000000000000000000100011000
0110101111000000111111000000000001000110010011111100100100111001111100
0111001011110000000000000011111100000011111111000000110111000000000001
0000100111100000110000110001100000101000001100001000000000000011101100
0000111110110000001000010000000000010010000100100110011001100100100110
0100110010011001000000000000100001000000110110011000011000010000000000
0100110001001001100110011000001001100100110010011001000000000000100001
1000011001100111111111001100000000000100110001001001100110011001111001
1001001100100110010000000000001100111111111001101111111111111100000000
0001001010010010011001100101000110011001100000110000100000000000001111
1111111111010111001001001110000000000000110001101101100110011000111001
1001100111110011110000000000000001110010010011100010001001000100000000
0000000000000000000000000000000000000000000000000000000000000000000000
1000100100010000100000000001000000000000000000000000000000000000000000
0000000000000000000000000000000000001000000000010000010000000010000000
0000000000000000000000000000000000000000000000000000000000000000000000
0001000000001000000011111111000000000000000000000000000000000000000000
0000000000000000000000000000000000000000111111110000

Użyłem formatu wygenerowanego przez GIMP podczas eksportowania jako ASCII pbm, z usuniętym komentarzem.

Wyjaśnienie:

l,    read the first line ("P1" magic number) and get its length (2)
l~    read and evaluate the second line (106 17)
q     read the rest of the input (actual pixels)
:~    evaluate each character ('0' -> 0, '1' -> 1, newline -> nothing)
f*    multiply each number by 17
/     split into rows of length 106
W%    reverse the order of the rows
z     transpose
e_    flatten (effectively, concatenate the lines)
      now we have all the pixels in the desired order, as 0 and 17
b     convert from base 2 "digits" to a number
aditsu
źródło
Mam to dla ciebie w adresie URL.
mbomb007
@ mbomb007 dzięki, nie jestem pewien, co poszło nie tak.
aditsu
Jeśli nie masz do czynienia z komentarzami, l;l~\qN-/W%zs:~2b*powinno działać równie dobrze.
Dennis
@Dennis OMG, istnieje kilka poziomów świetności :) chcesz opublikować to sam?
aditsu
Nie sądzę, aby osobna odpowiedź byłaby wystarczająco różna od twojej.
Dennis
17

Pyth - 21 bajtów

Prosty w obsłudze z ipodstawową konwersją Pytha . Pobiera dane wejściowe jako PBMnazwę pliku i odczytuje za pomocą 'polecenia. Musiałem użyć !Mdo zanegowania czerni i bieli. Wszystko inne jest oczywiste.

*J17i!MsC_cJrstt.z7 2

Wypróbuj tutaj online . (Tłumacz internetowy nie może odczytać plików, dlatego został zmodyfikowany i pobiera plik jako dane wejściowe).

Maltysen
źródło
60
Nie sądzę, żeby cokolwiek w Pythie było zrozumiałe. : /
Alex A.
3
Żaden język, który znam, nie może go pokonać. Ale z drugiej strony żaden z języków, które znam, nie jest „stworzony do gry w golfa”.
Mahesh,
Nie można otworzyć linku, ścieżka jest za długa, do cholery (Safari 8.1)
Kametrixom
Twój przykładowy obraz wydaje się nieprawidłowy. Czy chciałeś użyć P2 zamiast P3?
aditsu
Och, czekaj, to nie jest nawet P2, wygląda na P1, ale odwrócone
aditsu
9

Python 2: 133 110 bajtów

Pierwsza próba w Pythonie przy użyciu PIL:

from PIL.Image import*
j=open(input()).load()
a=k=0
while a<1802:k=(j[a/17,16-a%17][0]<1)+k*2;a+=1
print k*17

Dzięki pomocnym komentującym poniżej

żart
źródło
2
ponieważ używasz tylko raz Image.open (input ()). load i nie wygląda na to, że go modyfikujesz, czy nie lepiej byłoby używać go takim, jakim jest, zamiast var j? byłoby coś takiegofrom PIL import Image k=0 for a in range(1802):y=a%17;x=a/17;k=(0 if Image.open(input()).load()[x,16-y][0]else 1)+k*2 print k*17
Katenkyo,
3
Kontynuując punkt @ Katenkyo, możesz również po prostu podłączyć a/17i a%17w odpowiednich lokalizacjach, a także możesz nadużywać faktu, że 1 jest prawdą, a 0 jest fałszem. Oto wynik tych zmian, będziesz miał do 111 bajtów :)
Kade
@Kateyenko, niestety input()wywoływana jest przy każdej iteracji pętli z tą modyfikacją. Dziękuję za edycję z innymi wskazówkami.
JOC
1
(...<1) --> 0**...może?
Sp3000,
7

C #, 199

To była zabawa! Nie ma nic złego w przeładowaniu bitmapy 106 * 17 razy, prawda? Zrobiłem to w celu zaoszczędzenia niektórych bajtów, nie jestem pewien, czy to legalne.

BigInteger s(string i){return (Enumerable.Range(0,106).SelectMany(x=>Enumerable.Range(0,17).Select(y=>new BigInteger(new Bitmap(i).GetPixel(x,y).B==0?1:0)).Reverse()).Aggregate((x,y)=>(x<<1)+y)*17);}

i to nazwa pliku wejściowego.

Ponadto jako pojedyncze wyrażenie tylko dlatego, że jest to jedno wyrażenie, z ipodanym lub podrzędnym (167 bajtami)

(Enumerable.Range(0,106).SelectMany(x=>Enumerable.Range(0,17).Select(y=>new BigInteger(new Bitmap(i).GetPixel(x,y).B==0?1:0)).Reverse()).Aggregate((x,y)=>(x<<1)+y)*17)
DL
źródło
1
Pytanie brzmi: „Twoim zadaniem jest stworzenie programu ...”
Sean Latham,
1

Mathematica 69 bajtów

17*FromDigits[1-Flatten[Reverse/@Transpose[ImageData@Binarize@#]],2]&

Binarize @ można pominąć, jeśli obraz ma format monochromatyczny.

Ta funkcja odtworzy obraz:

   ArrayPlot[Table[Boole[1/2<Floor[Mod[Floor[y/17]2^(-17Floor[x]-Mod[Abs[y],17]),2]]],{y,1+#,17+#},{x,106,1,-1}]]&
Kelly Lowder
źródło