Это проблема со ссылками на себя


49

Самореференциальная формула Таппера (скопировано из Википедии)

Самореференциальная формула Таппера - это формула, определенная Джеффом Таппером, которая, будучи построенной в двух измерениях в очень специфическом месте на плоскости, может быть «запрограммирована» для визуального воспроизведения самой формулы. Он используется в различных курсах математики и информатики как упражнение в построении графиков.

Самореференциальная формула Таппера

Где пол эта функция пола?

Позвольте kбыть следующим 543-значным числом: 960939379918958884971672962127852754715004339660129306651505519271702802395266424689642842174350718121267153782770623355993237280874144307891325963941337723487857735749823926629715517173716995165232890538221612403238855866184013235585136048828693337902491454229288667081096184496091705183454067827731551705405381627380967602565625016981482083418783163849115590225610003652351370343874461848378737238198224849863465033159410054974700593138339226497249461751545728366702369745461014655997933798537483143786841806593422227898388722980000748404719

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

Результат самореферентной формулы Таппера

И что?

Интересной особенностью этой формулы является то, что ее можно использовать для построения графиков любого возможного черно-белого изображения размером 106x17. Теперь, на самом деле поиск в поиске был бы чрезвычайно утомительным, поэтому есть способ выяснить значение k, в котором появляется ваше изображение. Процесс довольно прост:

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

Какая у меня работа?

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

  1. Все изображения будут ровно 106х17
  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

Проверьте этот Гист для точных решений.

Это , поэтому выигрывает наименьшее количество байтов.


Полезные ссылки

Википедия

Wolfram Mathworld


Могу ли я принять в PPM?
Maltysen

РЕДАКТИРОВАТЬ: Да, формат 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базовым преобразованием пита . Принимает ввод как PBMимя файла и читает, используя 'команду. Я должен был использовать, !Mчтобы отрицать черных и белых. Все остальное самоочевидно.

*J17i!MsC_cJrstt.z7 2

Попробуйте здесь онлайн . (Веб-интерпретатор не может читать файлы, поэтому изменяется и принимает файл в качестве входных данных).


60
Я не думаю, что что- то в Pyth говорит само за себя. : /
Алекс А.

3
Ни один язык, который я знаю, не может победить этот. Но с другой стороны, ни один из языков, которые я знаю, не «сделан для игры в гольф».
Махеш

Невозможно открыть ссылку, путь слишком длинный, черт (Safari 8.1)
Kametrixom

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

Ой, подождите, это даже не P2, это похоже на P1, но перевернутый
aditsu

9

Python 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 ()). load, и он не выглядит так, как будто вы его модифицируете, не лучше ли будет использовать его как есть, вместо использования переменной 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 байт :)
Kade

@Kateyenko, к сожалению, вызывается input()на каждой итерации цикла с этой модификацией. Редактирование с другими советами, хотя, спасибо.
Joc

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

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