Questo è un problema autoreferenziale


49

Formula autoreferenziale di Tupper (copiata da Wikipedia)

La formula autoreferenziale di Tupper è una formula definita da Jeff Tupper che, se rappresentata in due dimensioni in una posizione molto specifica nel piano, può essere "programmata" per riprodurre visivamente la formula stessa. È utilizzato in vari corsi di matematica e informatica come esercizio di formule grafiche.

Formula autoreferenziale di Tupper

Dov'è pavimento la funzione pavimento.

Sia kil seguente numero di 543 cifre: 960939379918958884971672962127852754715004339660129306651505519271702802395266424689642842174350718121267153782770623355993237280874144307891325963941337723487857735749823926629715517173716995165232890538221612403238855866184013235585136048828693337902491454229288667081096184496091705183454067827731551705405381627380967602565625016981482083418783163849115590225610003652351370343874461848378737238198224849863465033159410054974700593138339226497249461751545728366702369745461014655997933798537483143786841806593422227898388722980000748404719

Se uno grafici l'insieme dei punti (x, y)in 0 <= x < 106e k <= y < k + 17soddisfare la disuguaglianza di cui sopra, le risultanti aspetto grafico come questo (si noti che gli assi in questa trama sono stati invertiti, altrimenti l'immagine viene fuori a testa in giù):

Risultato della formula autoreferenziale di Tupper

E allora?

La cosa interessante di questa formula è che può essere utilizzata per rappresentare graficamente qualsiasi immagine 106x17 in bianco e nero. Ora, la ricerca attraverso la ricerca sarebbe estremamente noiosa, quindi c'è un modo per capire il valore k dove appare la tua immagine. Il processo è abbastanza semplice:

  1. Inizia dal pixel inferiore della prima colonna della tua immagine.
  2. Se il pixel è bianco, verrà aggiunto uno 0 al valore k. Se è nero, aggiungi un 1.
  3. Sposta in alto la colonna, ripetendo il passaggio 2.
  4. Una volta alla fine della colonna, passa alla colonna successiva e inizia dal basso, seguendo lo stesso processo.
  5. Dopo aver analizzato ogni pixel, converti questa stringa binaria in decimale e moltiplica per 17 per ottenere il valore k.

Che lavoro faccio?

Il tuo compito è creare un programma che possa contenere qualsiasi immagine 106x17 e produrre il suo valore k corrispondente. È possibile formulare le seguenti ipotesi:

  1. Tutte le immagini saranno esattamente 106x17
  2. Tutte le immagini conterranno solo pixel neri (# 000000) o bianchi (#FFFFFF), nulla in mezzo.

Ci sono anche alcune regole:

  1. L'output è semplicemente il valore k. Deve essere nella base corretta, ma può essere in qualsiasi formato.
  2. Le immagini devono essere lette da un PNG o PPM.
  3. Nessuna scappatoia standard.

Immagini di prova

[ Nintendo] dovrebbe produrre ~ 1.4946x10 542

[ Un gran numero] dovrebbe produrre ~ 7.2355x10 159

[ 2 ^ 1801 * 17] dovrebbe produrre 2 1801 * 17

[ 2 ^ 1802 - 1 * 17] dovrebbe produrre (2 1802 -1) * 17

Dai un'occhiata a questo Gist per le soluzioni esatte.

Questo è , quindi vince il numero minimo di byte.


Collegamenti utili

Wikipedia

Wolfram Mathworld


Posso prendere un PPM?
Maltysen,

EDIT: Sì, il formato PPM è consentito. Quando ho ideato il programma intendevo utilizzare PNG, ma consentire a PPM di consentire la partecipazione di più lingue per giocare a golf.
Kade,

3
Mentre stavo leggendo questa domanda, prima di arrivare alla parte "Qual è il mio lavoro", sono stato sicuro che vedrò la parola quineda qualche parte.
Jacob,

Non pretendo di essere un programmatore che può fare questo tipo di cose, invece presenterò semplicemente una domanda innocente e seria: Sì, ma può essere fatto al contrario? Ossia alimentare la soluzione e vedere il * .png generato come risultato?

@NotAsSharpAsYouGuys: se hai un'aritmetica di precisione arbitraria è banale, devi solo controllare il risultato di quella formula per ogni pixel e produrre l'immagine risultante.
Matteo Italia,

Risposte:


12

CJam, 16 anni

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

Grazie mille a Dennis. Provalo online

In caso di problemi con l'URL, questo è l'input che ho testato:

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

Ho usato il formato generato da GIMP durante l'esportazione come pbm ASCII, con il commento rimosso.

Spiegazione:

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

L'ho trovato nell'URL per te.
mbomb007,

@ mbomb007 grazie, non sono sicuro di cosa sia andato storto.
aditsu,

Se non hai a che fare con i commenti, l;l~\qN-/W%zs:~2b*dovrebbe funzionare altrettanto bene.
Dennis,

@Dennis OMG, ci sono molti livelli di brillantezza :) vuoi pubblicarlo da solo?
aditsu,

Non penso che una risposta separata sia sufficientemente diversa dalla tua.
Dennis,

17

Pyth - 21 byte

Semplice da fare con la iconversione di base di Pyth . Accetta l'input come PBMnome del file e legge usando il 'comando. Ho dovuto usare !Mper negare neri e bianchi. Tutto il resto è autoesplicativo.

*J17i!MsC_cJrstt.z7 2

Provalo qui online . (L'interprete Web non può leggere i file, quindi viene modificato e accetta i file come input).


60
Non credo che nulla in Pyth sia autoesplicativo. : /
Alex A.

3
Nessuna lingua che conosco può battere questa. Ma poi nessuna delle lingue che conosco sono "fatte per il golf".
Mahesh,

Impossibile aprire il collegamento, il percorso è troppo lungo, dang (Safari 8.1)
Kametrixom,

L'immagine di esempio sembra errata. Intendevi usare P2 anziché P3?
aditsu,

Oh aspetta, non è nemmeno P2, sembra P1 ma invertito
aditsu,

9

Python 2: 133 110 byte

Un primo tentativo in Python usando 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

Grazie ai commentatori utili di seguito


2
dato che usi solo una volta Image.open (input ()) .load e non sembra che tu lo stia modificando, non sarebbe meglio usarlo così com'è, invece di usare var j? sarebbe qualcosa del generefrom 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
Continuando sul punto di @ Katenkyo, puoi anche solo collegarti a/17e a%17nelle posizioni appropriate, e puoi abusare del fatto che 1 è veritiero e 0 è falso. Ecco il risultato di questi cambiamenti, arriverai a 111 byte :)
Kade,

@Kateyenko, purtroppo input()viene chiamato ad ogni iterazione del ciclo con quella modifica. Modifica con altri suggerimenti, grazie.
joc

1
(...<1) --> 0**...può essere?
Sp3000,

7

C #, 199

È stato divertente! Non c'è niente di sbagliato nel ricaricare una bitmap 106 * 17 volte, giusto? L'ho fatto come una funzione per salvare alcuni byte, non sono sicuro che sia legale.

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 è il nome del file di input.

Inoltre, come singola espressione, solo perché si tratta di un'espressione, con ifornito o sottotitolato (167 byte)

(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
La domanda dice "il tuo compito è creare un programma ..."
Sean Latham,

1

Mathematica 69 byte

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

Binarize @ può essere lasciato fuori se l'immagine è in formato monocromatico.

Questa funzione riprodurrà l'immagine:

   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}]]&
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.