Потратив некоторое время на Stack Exchange, я могу узнать большинство сайтов в Hot Network Questions по их маленькому значку (который также является их значком ), но, конечно, не по всем. Давайте напишем программу, которая может! Вам нужно написать код, который определяет сайт, учитывая один из (в настоящее время) 132 значка, включая переполнение стека на японском языке (которое все еще находится в закрытой бета-версии):
Я загрузил ZIP-файл со всеми этими изображениями в формате PNG на GitHub . Нажмите кнопку «Сырье», чтобы загрузить его. Порядок вышеупомянутых значков является алфавитным порядком имен файлов в zip.
Соответствующие имена сайтов (в этом порядке):
Примечания:
- Я удалил
®
изLEGO® Answers
иExpressionEngine® Answers
, так что вам не нужно беспокоиться о Юникоде. - Я использовал английские имена для переполнения стека на японском и португальском языках по той же причине.
- Иконы наук о Земле и испанского языка неразличимы. Следовательно, с учетом одного из этих значков ваш код может возвращать любой из этих сайтов (по вашему выбору). То же самое касается Magento и боевых искусств .
правила
Вы можете написать программу или функцию, которая
- получает (локальное) имя файла изображения через STDIN, аргумент командной строки или аргумент функции или получает содержимое файла изображения через STDIN
- возвращает или печатает в STDOUT название сайта, как указано выше.
Ваш код должен правильно распознавать все 132 сайта (за исключением упомянутых выше).
Вы не можете делать какие-либо предположения относительно имени файла (например, как оно называется codegolf.png
). Вы можете предположить, что изображение имеет размеры 16x16, и что оно действительно будет одним из 132 изображений выше. Все изображения выше являются PNG, но вы можете использовать любой другой удобный формат растровой графики, но вам придется конвертировать изображения самостоятельно. Вы не должны делать никаких предположений о фактическом потоке байтов файла изображения, кроме того, что это допустимое изображение в любом формате, который вы выбрали. В частности, если существует несколько способов кодирования одного и того же изображения в вашем формате (например, путем добавления не относящихся к делу полей в раздел заголовка), ваш код должен работать для всех них. Короче говоря, ваш код должен полагаться только на сами значения пикселей, а не на детали файла, кодирующего его.
Как обычно, вы не можете получать какие-либо данные из Интернета. Вы должны определить сайт только по изображению.
Вы можете использовать встроенные или сторонние функции для чтения файла изображения и получения списка значений цвета, но вы не должны использовать какие-либо другие существующие функции обработки изображения.
Это код гольф, поэтому самый короткий ответ (в байтах) выигрывает.
источник
pngcrush
не будет.Ответы:
Python 3.x + Подушка,
230118941878 байтИдея состоит в том, чтобы хешировать изображение и найти соответствующую строку из словаря (как и другие ответы).
Код ключа это:
Мы открываем файл, а затем преобразуем его в 1024-байтовую строку значений RGBA. Немного поэкспериментировав, мы обнаружили, что контрольная сумма ADLER-32 каждого шестого байта этой строки байтов уникальна для этих 132 изображений. А затем дальнейшее тестирование показывает, что, взяв модуль 2003 контрольной суммы, мы получаем наименьший словарь.
Оригинальный словарь выглядит так:
Мы заметили, что все названия сайтов не содержат цифр. Поэтому мы можем объединить весь словарь в одну строку:
А затем используйте регулярное выражение, например,
1969(\D+)
чтобы извлечь имя сайта. Затем эта огромная строка сжимается для экономии места (пусть механизм сжатия замечает множественные вхождения "Language") и, наконец, кодируется в формате base-85.Поскольку теперь он также помечен как сложность по Колмогорову , здесь решение размером 2394 байта, которое не использует сжатие (zlib все еще импортируется для adler32).
источник
.tobytes()
получает данные о пикселях (16 × 16 × 4 = 1024), поэтому он опирается на изображение. Файл должен быть в RGBA.C #, 2760 байт
Мое решение не использует хеширование, оно на самом деле исследует отдельные пиксели изображения и принимает решение на основе этого. Я обнаружил, что этого достаточно, чтобы исследовать синий компонент изображения по модулю 9. Идея состоит в том, чтобы многократно разбивать на основе значения pixel.B% 9, примерно так:
Используя скрипт, я сгенерировал следующую чудовищную программу (5197 байт), которая решает проблему с помощью бинарного дерева решений:
Некоторые люди использовали встроенные функции сжатия в своих решениях. Я сделал свой собственный, написав скрипт, который идентифицирует общие подстроки и заменяет их односимвольными сокращениями. Код сжимается до следующей строки 2502:
Словарь, необходимый для распаковки, составляет всего 108 байт:
Словарь использует точки с запятой в качестве разделителя и содержит одиночные символы, за которыми следует декомпрессия. Таким образом, чтобы распаковать, ":" сначала будет заменен на "&", затем "<" на "%!", "|" по ic и так далее. Декомпрессия строки c может быть выражена довольно кратко:
Затем, после распаковки, я использую черную магию отражения, чтобы скомпилировать код на лету и запустить его:
Обратите внимание, что примеры, используемые здесь для объяснения, немного отличаются от примера, используемого в 2876-байтовом решении.
источник
Node.js,
3178313026672608 байтВычисляет хэш SHA1 для данных изображения каждого файла и, используя байты с 16 по 19 шестнадцатеричного дайджеста, индексирует имена сайтов.
Используя байты с 12 по 16 шестнадцатеричного дайджеста хэша SHA1 каждого файла, индексирует имена сайтов. Может быть более короткая комбинация, использующая только 3 байта шестнадцатеричного дайджеста.источник
h="17352368".match(/.{4}/g)
(4-х символьные хэши, разделенные на массив),s="MathOverflow;StackOverflow in Portuguese".split(";")
(имена, разделенные символом ;), а затем снова сложите все вместе:t={}h.forEach(function(k,i){t[k]=s[i]})
(приводит к тому же объекту, что и ваш код). Это 132 точки с запятой, поэтому даже если вы переключитесь на двухбайтовый символ (OP говорит, что в именах сайтов не должно быть Unicode), вы сэкономите место. Кроме того, вы можете добавить оптимизацию @manatwork в дополнение к этой дополнительной экономии.split()
s: us одну строку, например "1234Site; 5678Other". Затем, предположим, что между хеш-фрагментами и именами сайтов не будет столкновения, этоmatch()
сделает один:function $(e){r=require;return"8d4fAcademia;3a6dAndroid Enthusiasts;5caeAnime & Manga;804cAsk Different;bef3Arduino".match(r("crypto").createHash("sha1").update(r("fs").readFileSync(e)).digest("hex").slice(12,16)+"([^;]+)")[1]}
Python 2.7,
19061889 байтЭто решение использует CRC32 для данных пикселей для создания уникального двузначного базового идентификатора 95. Индекс идентификатора затем используется для поиска строки ответа.
Сложнее было найти комбинацию функций в стиле хеш-функции, которая привела бы к 132 (или 131) небольшим, но уникальным меткам. Я попробовал несколько вариантов, прежде чем остановиться на этом. Кажется, довольно компактно.
Программа использует Python PIL для чтения данных пикселей из файла.
Python 2.7 2150 байт
Это версия без использования библиотек сжатия или кодирования. Список обмена стека сжимается простым методом обмена. Символы, которые не используются в тексте:
используются для хранения общих строковых сегментов. Текст несжатый со
for k,v in [(v[0],v[1:]) for v in K.split('|')]:T=T.replace(k,v)
строкой. Таблица двухсимвольного индексирования такая же, как в приведенной выше программе.источник
C #, 2672 байта
Таблица (строка) меток и частичных хэшей SHA сжимается для сохранения нескольких байтов. Оригинальный словарь выглядит так:
источник
var
должен сохранить пару байтов. 2) Что за струнный строитель? Я не вижу его использованным. 3)StreamReader.ReadToEnd
может немного помочь.