C #, 660 바이트
using System.Linq;using System;class P{int p=1,x,y,r;P l;static void Main(){var Q="$&.$'7$(@$*R$'/$(8$)A'(A('A$+S$(0$)9'(9('9$*B$,T$*2$+;$,D$.V*,V,*V";var I=Console.ReadLine().Split(',').Select(int.Parse).ToList();int i=0,t,s=7,u,v,w,p=I[3]*I[2];for(var D=new[]{new P{r=Math.Abs(I[3]),l=new P{r=Math.Abs(I[2]),x=I[0],y=I[1],p=3}}}.ToList();i>=0;){P c=D[i++],l=c.l;for(;(l=l?.l)!=null&&(s=(t=c.x-l.x)*t+(t=c.y-l.y)*t-(t=c.r+l.r)*t)>0;);if(s==0&&l.p>2&p*c.p<0)for(i=-1;c.l.p<3;c=c.l)Console.WriteLine(c.x+","+c.y+","+c.r);for(t=0;s>0&t<66;t++)for(u=Q[t++]-36,v=Q[t++]-36,s=1;s++<5&Q[t]%9==c.r;w=u,u=v,v=-w,D.Add(new P{l=c,r=Q[t]/9-4,x=c.x+u,y=c.y+v,p=-c.p}));}}}
온라인 시도
이것은 많은 재미이었다!! 완전한 프로그램, STDIN의 입력을 받아 STDOUT으로 출력. 출력은 끝에서 시작까지 순서대로 기어입니다. 용법:
간단한 너비 우선 검색을 수행하여 1 초 이내에 4 단 문제를 해결합니다. 분기 요소는 실제로 그렇게 크지 않으므로 상당히 더 많은 것이 좋습니다 (실제 테스트하지는 않음). 슬프게도 Linq를 사용합니다.
Q
문자열이 허용 된 모든 장비의 연결의 테이블 (AN을 즉 r=3
와 연결할 r=1
경우 dx=4
와 dy=0
) 후 다른 사람을 찾기 위해 회전 사분면에. 3 바이트의 각 세트는이다 dx
, dy
법적 연결하고, 반경 정보를 제공합니다. (
오프셋으로 의 선택 은 매우 신중했습니다. 부과 된 ASCII 문자에 대한 멋진 속성을 필사적으로 찾으려고하는 대신 멋진 속성에 대해 ASCII 문자를 선택하는 것이 재미있었습니다.
아마 입력을 더 잘 읽을 수는 있지만 Linq가 목록의 필요성에 의해 지불되기 때문에 아직 운이 없었습니다. 또한 회전 코드에 매우 실망합니다. 이는 훨씬 적은 바이트로 수행 될 수 있다고 생각합니다.
Q
생성기를 사용한 형식화 및 주석 처리 된 코드 :
using System.Linq; // seems to pay today
using System;
class P
{
static void GenQ()
{
int t, k = 0, m = 0;
Func<P, P, int> C = (P c, P l) => (t = c.x - l.x) * t + (t = c.y - l.y) * t - (t = c.r + l.r) * t; // ==0 -> touching, <0 -> not touching, >0 -> overlap
string str = "";
string T(int i) => "" + (char)('$' + i); // $ is zero, '$' == 36, so we can mod and div by 9, and greater than " so we don't have to escape it
foreach (int r in new[] { 1, 2, 3, 5 }) // at 0,0 (current gear)
foreach (int s in new[] { 1, 2, 3, 5 }) // gear to place
for (int i = 0; i <= r + s; i++) // x
for (int j = 1; j <= r + s; j++, m++) // y
if (C(new P { r = r }, new P { r = s, x = i, y = j }) == 0) //
{
str += T(i) + T(j) + T(r + s * 9);
k++;
}
System.Console.WriteLine("K : " + k);
System.Console.WriteLine("M : " + m);
System.Console.WriteLine(str);
System.Console.ReadKey(true);
return;
}
int p=1, // parity
x, // x
y, // y
r; // radias (TODO: store radias^2 ?)
P l; // previous in search list
static void Main()
{
//GenQ();
// '$' == 36 (4*9)
// 3char blocks: x,y,r+9*s
var Q="$&.$'7$(@$*R$'/$(8$)A'(A('A$+S$(0$)9'(9('9$*B$,T$*2$+;$,D$.V*,V,*V"; // quarter table
// primative read ints
var I=Console.ReadLine().Split(',').Select(int.Parse).ToList();
int i=0, // position in Due
t, // check differential cache, position in Q
s=7, // check cache, rotation counter (>0)
u, // rotation x
v, // rotation y
w, // rotation x cache
p=I[3]*I[2]; // parity (>0 -> same, even ; <0 -> different, odd)
// due (not point using a queue, the search space grows exponentially)
for(var D=new[]{
new P{r=Math.Abs(I[3]), // start (p==1)
l=new P{r=Math.Abs(I[2]),x=I[0],y=I[1],p=3} // terminal (detect with p==3)
}}.ToList();
i>=0;) // infinite number of configurations, no bounds, i is escape term
{
P c=D[i++], // current
l=c.l; // check, initially the one before the previous (we know we are touching last already)
// 'checks' c against l
//Func<int>C=()=>(t=c.x-l.x)*t+(t=c.y-l.y)*t-(t=c.r+l.r)*t; // ==0 -> touching, >0 -> not touching, <0 -> overlap
// check we arn't touching any before us (last thing we check is terminal)
for(;(l=l?.l)!=null&& // for each before us (skipping the first one)
(s=(t=c.x-l.x)*t+(t=c.y-l.y)*t-(t=c.r+l.r)*t)>0;); // check c against l and cache in s, ==0 -> touching, >0 -> not touching, <0 -> overlap
if(s==0&& // touching last checked?
l.p>2& // stopped on terminal?
p*c.p<0) // correct parity? -> win
for(i=-1; // escape
c.l.p<3;c=c.l) // for each that wasn't the first
Console.WriteLine(c.x+","+c.y+","+c.r);
// enumerate possible additions, and queue them in due
for(t=0;
s>0& // not touching or overlapping anything (including terminal)
t<66;t++) // 66 = Q.Length
for(
u=Q[t++]-36, // '$'
v=Q[t++]-36,
s=1;s++<5& // rotate 4 times
Q[t]%9==c.r; // our raidus matches
w=u, // chache y value
u=v, // rotate
v=-w,
D.Add(new P // add
{
l=c,
r=Q[t]/9-4, // radius
x=c.x+u,
y=c.y+v,
p=-c.p // flip parity
}));
}
}
}