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.