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


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

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).


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


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)

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}]]&
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.