(Na podstawie tego problemu Math.SE , który zapewnia również grafikę)
Mam patyk, który wygląda trochę tak:
Chcę, żeby wyglądało to tak:
Nie jestem jednak specjalistą od malowania, więc zanim rozpocznę tak ambitny projekt DIY, chcę się upewnić, że nie będę się nad tym zastanawiać.
Twój program powinien mi powiedzieć, ile kroków wymaga malowanie tego kija. Każdy krok polega na pomalowaniu ciągłego obszaru jednolitym kolorem, który zakrywa poprzednie warstwy farby. W powyższym przykładzie mogłem pomalować lewą połowę koloru niebieskiego, prawą połówkę koloru czerwonego, a następnie dwa osobne zielone obszary w sumie 4 kroki (kolor zielony nie jest stale malowany).
Oto w ASCII:
------
bbb---
bbbrrr
bgbrrr
bgbrgr
Istnieje kilka różnych sposobów na pomalowanie tego kija i uzyskanie tego samego rezultatu. Interesuje mnie jednak tylko szacunkowy czas, który składa się z czterech kroków.
Cel
Twój program powinien wypisać minimalną liczbę kroków potrzebnych do namalowania kija o danym schemacie kolorów. Schemat malowania będzie miał postać ciągu znaków, a wynikiem będzie liczba. To jest kod golfowy. Najkrótszy program wygrywa.
Wejście
Twój program otrzyma schemat kolorowania kija w postaci ciągu liter. Każda unikalna litera (wielkość liter ma znaczenie) reprezentuje unikalny kolor.
YRYGR
grG
GyRyGyG
pbgbrgrp
hyghgy
Wynik
Te liczby to najmniejsza liczba kroków potrzebnych do pomalowania patyczków.
4
3
4
5
4
Objaśnienia
Tak doszedłem do powyższych liczb. Twój program nie musi generować tego:
-----
YYY--
YRY--
YRYG-
YRYGR
---
g--
gr-
grG
-------
GGGGGGG
GyyyGGG
GyRyGGG
GyRyGyG
--------
pppppppp
pbbbpppp
pbbbrrrp
pbgbrrrp
pbgbrgrp
------
-yyyyy
-ygggy
hygggy
hyghgy
Edycja: Dodam więcej przypadków testowych, jeśli okażą się trudniejsze.
Odpowiedzi:
GolfScript,
827267 znakówDość szybko jak na program GolfScript, przykłady:
Zastosowany algorytm działa rekurencyjnie w kolorach od lewej do prawej, zgodnie z następującymi instrukcjami:
W przeciwnym razie wybierz kolor docelowy najbardziej wysuniętej w lewo części (tj. Pierwszej nie w pożądanym kolorze).
...
Weź minimum wszystkich tych liczb i dodaj 1 (dla bieżącego kroku). Zwróć to jako optymalną liczbę kroków.
Ten algorytm działa, ponieważ i tak najbardziej lewa część musi być pomalowana jednocześnie, więc dlaczego nie zrobić tego natychmiast - w jakikolwiek możliwy sposób.
źródło
n!
kroki;) (ale może to jest prawdziwa złożoność, nie wiem).JavaScript:
187bajtówZakładając, że możemy mieć tylko wejście i wyjście do funkcji (proszę)!
157 bajtów, wykonując dalszą brzydką optymalizację (co jest częścią tego, i znalazłem niesamowitą zabawę):135 Bajtów Zdałem sobie sprawę, że długość danych wejściowych jest górną granicą i nie muszę teraz osobno obsługiwać trywialnych przypadków.
Przypadki testowe:
Wersja rozszerzona:
Dla każdego znaku wejściowego oblicz długość wzoru, jeśli najpierw pomalujemy ten kolor. Odbywa się to przez udawanie, że malujemy ten kolor, a następnie tworzenie podsekcji z bitów, które nie są w tym kolorze, i rekurencyjne wywoływanie na nich metody malowania. Zwracana jest najkrótsza ścieżka.
Przykład (
YRYGR
):Początkowo spróbuj
R
. To daje nam podgrupyY
iYG
.Y
jest trywialnie pomalowany za jednym razem.Dla
YG
: SpróbujG
,Y
jest banalna, długość2
. SpróbujY
,G
jest trywialne, długość 2.YG
jest zatem długością2
.Malowanie jako
R
pierwsze daje nam zatem1 + 1 + 2 = 4
Więc spróbuj
G
. To daje nam podgrupyYRY
iR
.R
jest banalny.Dla
YRY
:Spróbuj
Y
:R
jest banalna, długość2
. SpróbujR
:Y
iY
są dwie grupy, długość3
.YRY
jest długością2
.Malarstwo
G
najpierw daje1 + 1 + 2 = 4
Więc spróbuj
Y
. To daje podgrupomR
iGR
.R
banalna,GR
to długość2
.Y
jest długością4
Ta implementacja sprawdzi następnie R i Y ponownie, aby zmniejszyć długość kodu. Wynik
YRYGR
jest zatem4
.źródło
m
gdzieś zgubiła var ."abcacba"
.m
był skrótem odword.length
:) @Howard Masz rację, będę musiał to przemyśleć.Python, 149 znaków
Używam
?
do zaznaczania obszaru, który może być dowolnego koloru.D
wybiera ciągły obszar sztyftu, który zawiera tylko jeden kolor (plus może trochę?
s), kolory tego regionu trwają, zastępuje ten obszar?
s, i powraca, aby znaleźć wszystkie poprzednie kroki.Wykładniczy czas działania. Tylko ledwo wystarczająco szybko, aby wykonać przykłady w rozsądnym czasie (kilka minut). Założę się, że z zapamiętywaniem może być znacznie szybciej.
źródło
Python 3 - 122
Wydaje się, że działa, ale wciąż nie jestem w 100% pewien, że ta metoda zawsze znajdzie minimalną liczbę kroków.
źródło
CoffeeScript -
183 247 224 215207Demo na JSFiddle.net
Wersja bez golfa, w tym kod debugowania i komentarze:
źródło
hyghgy
. Mówi 5, ale powinno być 4. (zwraca jednak poprawny wynik 4 dlahyghgyh
).Haskell, 143 znaki
Spróbuje wszystkich możliwych przepisań do długości łańcucha i przechodzi do znalezienia takiego, który konstruuje wzorzec wejściowy. Nie trzeba dodawać, że wykładniczy czas (a potem trochę).
źródło
Proste pierwsze wyszukiwanie. Nie umieszcza niczego w kolejce, która już była widoczna. Działa w niecałą sekundę dla wszystkich przykładów, ale „pbgbrgrp”, co w rzeczywistości zajmuje pełną minutę :(
Teraz, gdy mam coś, co działa , będę pracować nad znalezieniem czegoś szybszego i krótszego.
Python -
300296źródło
Haskell,
11886 znakówPrzebiegi testowe:
Ta metoda nie jest wcale taka nieefektywna!
źródło