(На основе этой проблемы Math.SE , которая также предоставляет некоторую графику)
У меня есть палка, которая выглядит примерно так:
Я хочу, чтобы это выглядело примерно так:
Однако я не опытный художник, поэтому, прежде чем я начну такой амбициозный проект «Сделай сам», я хочу убедиться, что я не над головой.
Ваша программа должна сказать мне, сколько этапов задействовано в рисовании этой флешки. Каждый шаг включает в себя рисование сплошной области сплошным цветом, который покрывает предыдущие слои краски. Для приведенного выше примера я мог бы нарисовать левую половину синим, правую половину красным, а затем две отдельные зеленые области в общей сложности на 4 шага (зеленый не непрерывно окрашивается).
Вот это в ASCII:
------
bbb---
bbbrrr
bgbrrr
bgbrgr
Есть пара разных способов покрасить эту палку и в итоге получить тот же результат. Однако меня интересует только оценка времени, которая составляет четыре шага.
Цель
Ваша программа должна вывести минимальное количество шагов, необходимых для рисования флешки с заданной цветовой схемой. Схема рисования будет иметь вид строки символов, а на выходе будет число. Это код гольф. Кратчайшая программа выигрывает.
вход
Ваша программа получит схему раскраски палки в виде цепочки букв. Каждая уникальная буква (с учетом регистра) представляет уникальный цвет.
YRYGR
grG
GyRyGyG
pbgbrgrp
hyghgy
Выход
Эти цифры являются наименьшим количеством шагов, необходимых для рисования палочек.
4
3
4
5
4
Пояснения
Вот так я и пришел к вышеприведенным цифрам. Ваша программа не должна выводить это:
-----
YYY--
YRY--
YRYG-
YRYGR
---
g--
gr-
grG
-------
GGGGGGG
GyyyGGG
GyRyGGG
GyRyGyG
--------
pppppppp
pbbbpppp
pbbbrrrp
pbgbrrrp
pbgbrgrp
------
-yyyyy
-ygggy
hygggy
hyghgy
Изменить: я добавлю больше тестов, если они окажутся более сложными.
Ответы:
GolfScript,
827267 символовРазумно быстро для программы GolfScript, примеры:
Используемый алгоритм рекурсивно обрабатывает цвета слева направо в соответствии со следующими утверждениями:
В противном случае возьмите целевой цвет самой левой части (т. Е. Первую, не нужного цвета).
...
Возьмите минимум всех этих чисел и добавьте 1 (для текущего шага). Верните это как оптимальное количество шагов.
Этот алгоритм работает, потому что крайняя левая часть в любом случае должна быть нарисована одновременно, так почему бы не сделать это немедленно - любым возможным способом.
источник
n!
шаги;) (но, возможно, это реальная сложность, я не знаю).JavaScript:
187байтПредполагая, что нам разрешено иметь только вход и выход для функции (пожалуйста)!
157 байт, выполняя дальнейшую уродливую оптимизацию (что является частью вопроса, и я нашел невероятно забавным):135 байт. Я понял, что длина входных данных является верхней границей, и теперь мне не нужно обрабатывать тривиальные случаи отдельно.
Тестовые случаи:
Расширенная версия:
Для каждого символа ввода вычислите длину шаблона, если мы сначала закрасим этот цвет. Это делается, притворяясь, что мы рисуем этот цвет, а затем делая подразделы из битов, которые не того цвета, и рекурсивно вызывая метод рисования для них. Кратчайший путь возвращается.
Пример (
YRYGR
):Изначально попробуйте
R
. Это дает нам подгруппыY
иYG
.Y
тривиально нарисован за один раз.Для
YG
: попробуйG
,Y
банально, длина2
. ПопробуйтеY
,G
тривиально, длина 2.YG
следовательно, длина2
.Картина
R
первая поэтому дает нам1 + 1 + 2 = 4
Тогда попробуй
G
. Это дает нам подгруппыYRY
иR
.R
тривиальноДля
YRY
:Попробуйте
Y
:R
тривиально, длина2
. ПопробуйтеR
:Y
иY
две группы, длина3
.YRY
это длина2
.Картина
G
сначала дает1 + 1 + 2 = 4
Тогда попробуй
Y
. Это дает подгруппыR
иGR
.R
тривиально,GR
это длина2
.Y
длина4
Эта реализация будет затем проверять R и Y снова, чтобы уменьшить длину кода. Результат для
YRYGR
поэтому4
.источник
m
где-то потеряла вар ."abcacba"
.m
был просто стенографиейword.length
:) @Howard Вы правы, мне придется переосмыслить это.Питон, 149 символов
Я использую,
?
чтобы отметить область, которая может быть любого цвета.D
выбирает непрерывную область флешки, которая содержит только один цвет (плюс, может быть, несколько?
s), цвета, которые последняя в этой области, заменяет эту область на?
s и рекурсивно находит все предыдущие шаги.Экспоненциальное время работы. Просто достаточно быстро, чтобы сделать примеры за разумное время (несколько минут). Бьюсь об заклад, с запоминанием это может быть намного быстрее.
источник
Питон 3 - 122
Кажется, это работает, но я все еще не уверен на 100%, что этот метод всегда найдет минимальное количество шагов.
источник
CoffeeScript -
183 247 224 215207Демо на JSFiddle.net
Ungolfed версия, включая отладочный код и комментарии:
источник
hyghgy
. Это говорит 5, но это должно быть 4. (однако, это возвращает правильный результат 4 дляhyghgyh
).Haskell, 143 символа
Это пробует все возможные перезаписи вплоть до длины строки и продолжается до тех пор, пока не найдет тот, который создает шаблон ввода. Излишне говорить, экспоненциальное время (а затем и некоторые).
источник
Простой поиск в ширину. Это не помещает ничего в очередь, которая уже была замечена. Он работает менее чем за секунду для всех примеров, но 'pbgbrgrp', что на самом деле занимает целую минуту :(
Теперь, когда у меня есть что-то, что работает, я буду искать что-то быстрее и короче.
Питон -
300296источник
Хаскелл,
11886 персонажейТестовые прогоны:
Этот метод даже не настолько неэффективен!
источник