Це проблема самореференції


49

Самореференційна формула Тіппера (скопійовано з Вікіпедії)

Самореференційна формула Тіппера - це формула, визначена Джеффом Тюппером, яка, схопившись на два виміри в дуже конкретному місці в площині, може бути «запрограмована» для візуального відтворення самої формули. Він використовується в різних курсах з математики та інформатики як вправа в графічних формулах.

Самореференційна формула Туппера

Де підлогу функція підлоги.

Нехай це kбуде наступний 543-значний номер: 960939379918958884971672962127852754715004339660129306651505519271702802395266424689642842174350718121267153782770623355993237280874144307891325963941337723487857735749823926629715517173716995165232890538221612403238855866184013235585136048828693337902491454229288667081096184496091705183454067827731551705405381627380967602565625016981482083418783163849115590225610003652351370343874461848378737238198224849863465033159410054974700593138339226497249461751545728366702369745461014655997933798537483143786841806593422227898388722980000748404719

Якщо один графік містить набір точок (x, y)у 0 <= x < 106та k <= y < k + 17задовольняє наведену вище нерівність, то отриманий графік виглядає приблизно так (зауважте, що осі на цій ділянці були перевернуті, інакше малюнок виходить догори дном):

Результат формули самореференції Туппера

І що?

Цікавим у цій формулі є те, що за її допомогою можна графікувати будь-яке можливе чорно-біле зображення 106х17. Тепер насправді пошук за допомогою пошуку був би вкрай стомлюючим, тому існує спосіб визначити значення k, де відображається ваше зображення. Процес досить простий:

  1. Почніть з нижнього пікселя першого стовпця вашого зображення.
  2. Якщо піксель білий, до значення k додається 0. Якщо він чорний, додайте 1.
  3. Перемістіть стовпчик вгору, повторивши крок 2.
  4. Опинившись в кінці стовпця, перейдіть до наступного стовпчика і починайте знизу, дотримуючись того самого процесу.
  5. Після аналізу кожного пікселя перетворіть цей двійковий рядок у десятковий і помножте на 17, щоб отримати k-значення.

Яка моя робота?

Ваше завдання - створити програму, яка може приймати будь-яке зображення 106x17, і виводити її відповідне k-значення. Можна зробити наступні припущення:

  1. Усі зображення будуть рівно 106x17
  2. Усі зображення містять лише чорні (# 000000) або білі (#FFFFFF) пікселі, між ними нічого немає.

Існує також кілька правил:

  1. Вихід - це просто k-значення. Він повинен бути в належній базі, але може бути в будь-якому форматі.
  2. Зображення потрібно читати з PNG або PPM.
  3. Немає стандартних лазівки

Тестові зображення

[ Nintendo] має виробляти ~ 1,4946x10 542

[ Велика кількість] має виробляти ~ 7.2355x10 159

[ 2 ^ 1801 * 17] має дати 2 1801 * 17

[ 2 ^ 1802 - 1 * 17] має виробляти (2 1802 -1) * 17

Ознайомтеся з цією історією щодо точного рішення

Це , тому виграє найменше кількість байтів.


Корисні Посилання

Вікіпедія

Вольфрамський математичний світ


Чи можу я взяти в PPM?
Мальтісен

EDIT: Так, формат PPM дозволений. Коли я придумав програму, я мав на меті використовувати PNG, але дозволяючи PPM повинен передбачати більше мов для гри в гольф.
Кейд

3
Коли я читав це запитання, перш ніж перейти до частини "Що моя робота", я був впевнений, що quineдесь побачу це слово .
Яків

Я не буду претендувати на програміста, який може робити подібні речі, натомість я просто поставлю невинне, щире запитання: Так, але чи можна це зробити в зворотному порядку? Тобто подача в розчин і бачення * .png, що генерується як результат?

@NotAsSharpAsYouGuys: якщо у вас є арифметика довільної точності, це тривіально, потрібно просто перевірити результат цієї формули для кожного пікселя і вивести отримане зображення.
Маттео Італія

Відповіді:


12

CJam, 16

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

З великою подякою Деннісу. Спробуйте в Інтернеті

Якщо у вас виникли проблеми з URL-адресою, це тестування, яке я перевірив:

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

Я використовував формат, який GIMP генерував при експорті як ASCII pbm, при цьому коментар видалено.

Пояснення:

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

Я отримав це в URL для вас.
mbomb007

@ mbomb007 дякую, не впевнений, що пішов не так.
aditsu

Якщо вам не доведеться мати справу з коментарями, l;l~\qN-/W%zs:~2b*слід працювати так само добре.
Денніс

@Dennis OMG, є кілька рівнів блиску там :) хочете опублікувати його самостійно?
aditsu

Я не думаю, що окрема відповідь буде досить відмінною від вашої.
Денніс

17

Pyth - 21 байт

З iбазовим перетворенням pyth це просто . Приймає введення як PBMім'я файлу і читає за допомогою 'команди. Мені довелося !Mзаперечувати чорношкірих та білих. Все інше само собою зрозуміле.

*J17i!MsC_cJrstt.z7 2

Спробуйте це онлайн . (Веб-перекладач не може читати файли, тому він змінюється і приймає файл як вхідний).


60
Я не думаю, що нічого в Pyth само собою пояснюється. : /
Алекс А.

3
Жодна мова, яку я знаю, не може перемогти цю. Але знову ж таки жодна з мов, які я знаю, не "зроблена для гольфу".
Махеш

Не вдається відкрити посилання, шлях занадто довгий, завис (Safari 8.1)
Kametrixom

Образ вашого прикладу здається неправильним. Ви мали на увазі використовувати P2, а не P3?
aditsu

О, зачекайте, це навіть не P2, схоже на P1, але перевернуто
aditsu

9

Пітон 2: 133 110 байт

Перша спроба python за допомогою 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

Дякуємо корисним коментаторам нижче


2
як ви використовуєте лише один раз завантаження Image.open (input ()). Це не виглядає так, як ви його модифікуєте, чи не було б краще використовувати його таким, яким він є, замість використання var j? це було б щось подібнеfrom 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
Продовжуючи точку @ Katenkyo, ви також можете просто підключити a/17та a%17у відповідних місцях, і ви можете зловживати тим фактом, що 1 - фальшивий, а 0 - хибний. Ось результат цих змін, ви знизитесь до 111 байт :)
Каде

@Kateyenko, на жаль, input()викликає кожну ітерацію циклу з цією модифікацією. Редагування з іншими порадами, дякую.
Джок

1
(...<1) --> 0**...може бути?
Sp3000

7

C #, 199

Це було весело! Немає нічого поганого в тому, щоб перезавантажити растровий малюнок 106 * 17 разів, правда? Я зробив це як функцію, щоб зберегти кілька байт, не впевнений, що це законно.

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 - це ім'я вхідного файлу.

Крім того, як єдиний вираз, лише тому, що це один вираз, із iнаданим або підрядним (167 байт)

(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
У запитанні сказано: "Ваше завдання - створити програму ..."
Шон Латхем

1

Математика 69 байт

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

Binarize @ можна залишити, якщо зображення монохромного формату.

Ця функція відтворить зображення:

   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}]]&
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.