# 涂一根棍子需要多长时间？

12

（基于此Math.SE问题，该问题还提供了一些图形）

``````------
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
``````

Kendall Frey 2014年

3

### GolfScript，82 72 67个字符

``````.,n*{:c,,{[).2\$1<*\c>+1\$.,,{).2\$<\3\$<=},,.@>@@>]}%\;{~S)}%\$0+0=}:S~
``````

``````> hyghgy
4

> pbgbrgrp
5
``````

• 忽略左侧所有已经具有所需颜色的部分。再次为其补漆将无法提供更好的答案。
• 如果完整的摇杆已经具有所需的颜色，则返回0步。
• 否则，获取当前最左边部分的目标颜色（即第一个不是所需颜色的部分）。

• 用目标颜色绘制1个零件并递归。
• 用此颜色绘制2个零件并递归。

...

• 用这种颜色涂满整个剩余的棍子，然后递归。

取所有这些数字中的最小值并加1（对于当前步骤）。将其作为最佳步骤数返回。

``````.,n*         # prepare the initial situation (target stick, unpainted stick)
# used n instead of '-' for the unpainted parts, because it is shorter
{            # Define the operator S which does t c S -> n
#   - t: the desired target colors
#   - c: the stick as it is colored currently
#   - n: minimum number of steps required to go from c to t
:c         # Assign the current configuration to the variable c
,,{[       # Map the list [0 1 2 .. L-1]
# We will build a list of all possible configurations if we paint
# the stick with the 0th part's color (either 1 or 2 or 3 or ... parts)
).       # Increase the number, i.e. we paint 1, 2, 3, ... L parts, copy
2\$1<     # Take the first color of the target configuration
*        # ...paint as many parts
\c>+     # ...and keep the rest as with the current stick
1\$       # take the target configuration
# Top of stack now e.g. reads
#    h----- hyghgy (for i=0)
#    hh---- hyghgy (for i=1)
# Next, we strip the common leading characters from both strings:
.,,      # Make list [0 1 2 ... L-1]
{        # Filter {}, all the numbers for which the first j+1 parts are the same
).     # incr j
2\$<    # take leftmost j parts of stick A
\3\$<   # take leftmost j parts of stick B
=      # are they equal?
},,      # The length of the result is the number of common parts.
.@>      # cut parts from A
@@>      # cut parts from B
]}%
\;         # Remove the target from the stack (not needed anymore)
# We now have a list of possible paintings where 1, 2, ..., L parts were
# painted from the left with the same color.
# All configurations were reduced by the common parts (they won't be
# painted over anyways)
{~S)}%     # Call the method S recursively on the previously prepared configurations
\$0+0=      # \$0= -> sort and take first, i.e. take the minimum, 0+ is a workaround
# if the list was empty (i.e. the operator was called with a stick of length 0).
}:S
~            # Execute S
``````

+1为“最左边的颜色错误”算法。但是，这似乎是`n!`步骤；）（但这可能是真正的复杂性，我不知道）。

2

JavaScript：187字节

``````function p(w){var j,l,s=-1,i,m=i=w.length;if(m<2)return m;for(;i--;){l = 1;for(var k=-1;(j=k)!=m;){if((k=w.indexOf(w[i],++j))==-1)k=m;l+=p(w.substring(j,k));}if(s==-1||l<s)s=l;}return s;}
``````

``````function p(w){var j,l,s=-1,i,m=i=w.length;if(m<2)return m;for(;i--;s<0|l<s?s=l:1)for(l=1,j=0;~j;)l+=p(w.substring(j,(j=w.indexOf(w[i],j))<0?m:j++));return s}
``````

135个字节我意识到输入的长度是一个上限，我现在不需要分别处理琐碎的情况。

``````function p(w){var j,l,s,i,m=s=i=w.length;for(;i--;l<s?s=l:1)for(l=1,j=0;~j;)l+=p(w.substring(j,~(j=w.indexOf(w[i],j))?j++:m));return s}
``````

``````p("YRYGR")
4
p("grG")
3
p("GyRyGyG")
4
p("pbgbrgrp")
5
p("hyghgy")
4
``````

``````function paint(word) {
var smallest = -1;
if(word.length < 2) return word.length;
for(var i = word.length; i-->0;) {
var length = 1;
for(var left, right = -1;(left = right) != m;) {
if((right = word.indexOf(word[i],++left)) == -1) right = word.length;
if(left != right) length += paint(word.substring(left , right));
}
if(smallest == -1 || length < smallest) smallest = l;
}
return smallest;
}
``````

`YG`：尝试`G``Y`琐碎，长短`2`。尝试`Y``G`琐碎，长度2。`YG`因此是长度`2`

`R`因此绘画首先给我们`1 + 1 + 2 = 4`

`YRY`是长度`2`

Hasturkun 2014年

2014年

@Hasturkun `m`只是它的简写`word.length`：) @Howard你是对的，我必须重新考虑一下。
meiamsome 2014年

1

## Python，149个字符

``````D=lambda s:0 if s=='?'*len(s)else min(1+D(s[:i]+'?'*(j-i)+s[j:])for i in range(len(s))for j in range(i+1,len(s)+1)if set(s[i:j])-set('?')==set(s[i]))
``````

`?`用来标记可能是任何颜色的区域。 `D`选择一个只包含单一颜色（加上一些`?`s）的棍子的连续区域，该区域最后的颜色，用`?`s 替换该区域，然后递归查找所有先前的步骤。

1

## Python 3-122

``````def r(s,a):c=s[0];z=c in a;return s[1:]and min([1+r(s[1:],a+c)]+[r(s[1:],a[:a.rfind(c)+1])]*z)or(1-z)
print(r(input(),''))
``````

1

## 的CoffeeScript - 183 247 224 215 207

``````x=(s,c='')->return 0if !s[0]?;return x s[1..],c if s[0]is c;l=s.length;return x s[1...l],c if s[l-1]is c;i=s.lastIndexOf s[0];1+(x s[1...i],s[0])+x s[i+1..],c
y=(z)->z=z.split "";Math.min (x z),x z.reverse()
``````

``````paintSubstring = (substring, color = '####') ->
console.log 'Substring and color', substring, color, substring[0]
# no need to color here
if !substring[0]?
return 0
# no need to recolor the first part
if substring[0] is color
return paintSubstring (substring[1..]), color
l = substring.length
# no need to recolor the last part
if substring[l-1] is color
return paintSubstring substring[0...l], color
# cover as much as possible
index = substring.lastIndexOf substring[0]
part1 = substring[1...index]
part2 = substring[index+1..]
console.log 'Part 1:', part1
console.log 'Part 2:', part2
# color the rest of the first half
p1 = paintSubstring part1, substring[0]
# color the rest of the second half, note that the color did not change!
p2 = paintSubstring part2, color
# sum up the cost of the substick + this color action
return p1+p2+1
paintSubstringX=(x)->Math.min (paintSubstring x.split("")), paintSubstring x.split("").reverse()
console.clear()
input = """YRYGR
grG
GyRyGyG
pbgbrgrp
aaaaaaaa
hyghgy""".split /\n/
for stick in input
console.log paintSubstringX stick
``````

PhiNotPi 2014年

@PhiNotPi神，这把我推回超过60个字符:(试图用另一种语言重写本，睡午觉后
TimWolla

0

``````f s=g(r n ' ')0where{r=replicate;n=length s;g p l=minimum\$n:[0|p==s]++[1+g(take i p++r(j-i)(s!!i)++drop j p)(l+1)|l<n,i<-[0..n-1],j<-[i+1..n]]}
``````

0

``````def f(c):
k=len(c);q=['0'*99];m={};m[q[0]]=1
while q:
u=q.pop(0)
for x in ['0'*j+h*i+'0'*(k-j-i) for h in set(c) for j in range(1+k) for i in range(1,1+k-j)]:
n=''.join([r if r!='0' else l for l,r in zip(u,x)])
if n == c:
return m[u]
if not n in m:
m[n]=m[u]+1;q.append(n)
``````

@霍华德修复。我不知道昨晚在想什么。
TrevorM 2014年

0

``````p""=0
p(a:s)=1+minimum(map(sum.map p.words)\$sequence\$map(a%)s)
a%b|a==b=b:" "|1<3=[b]
``````

``````λ: p "YRYGR"
4

λ: p "grG"
3

λ: p "GyRyGyG"
4

λ: p "pbgbrgrp"
5

λ: p "hyghgy"
4

λ: p "abcacba"
4
``````