[JavaScript(Node.js)]、1220バイト
f=r=>{var a=[{n:0,d:[[0,-1,"0000000101011"],[1,-1,"0011111111111"],[0,0,"0111101111111"],[1,0,"1100010000000"]],e:[2,-1,1]},{n:0,d:[[-1,-1,"1001111111111"],[0,-1,"0000010010110"],[-1,0,"0110000100000"],[0,0,"1101111011111"]],e:[-2,-1,3]},{n:1,d:[[0,0,"0011101111111"]],e:[1,0,1]},{n:1,d:[[0,0,"1001111011111"]],e:[-1,0,3]},{n:2,d:[[0,0,"1111101011111"]],e:[0,-1,0]}],e=r=>{var a=r.d,e=r.e,n=[];return a.forEach(r=>{var a=r[2];n.push([-r[1],r[0],""+a[10]+a[5]+a[0]+a[8]+a[3]+a[11]+a[6]+a[1]+a[9]+a[4]+a[12]+a[7]+a[2]])}),{d:n,e:[-e[1],e[0],e[2]]}};i=((r,a)=>{for(var n=0;n<r.d;n++,a=e(a));var p=!1;return a.d.forEach(a=>{var e=r[`${r.p.x+a[0]},${r.p.y+a[1]}`];void 0===e&&(e="00000000000000");for(var n="",d=0;d<13;d++)"1"===e[d]&&"1"===a[2][d]&&(p=!0),n+=e[d]===a[2][d]?e[d]:"1";r[`${r.p.x+a[0]},${r.p.y+a[1]}`]=n}),r.p.x+=a.e[0],r.p.y+=a.e[1],r.d=(r.d+a.e[2])%4,!p});var n=[],p=(r,e)=>{a.forEach(a=>{var d=Object.assign({},r);if(d.p=Object.assign({},r.p),!(e[a.n]<=0)&&i(d,a)){if(d.ps+=a.n,0==d.p.x&&0==d.p.y&&0==d.d)return void n.push(d);var s=Object.assign([],e);s[a.n]-=1,p(d,s)}})};p({p:{x:0,y:0},d:0,ps:""},Object.assign([],r));var d=0;n.forEach(r=>{r.ps.length>d&&(d=r.ps.length)}),console.log(r[0]+r[1]+r[2]-d)};
オンラインでお試しください!
注:入力は、実際には開始時の変数qです。[2,6,4]も最適化なしのブルートフォースソリューションであるため、かなり時間がかかります。
実際にこれを行ったのは、1年以上にわたって回答が得られていないためです。可能であれば、ちょっと興味がありました。
元のコード:
var q = [4, 2, 4];
var t = [
{
n: 0,
d: [
[0, -1, "0000000101011"],
[1, -1, "0011111111111"],
[0, 0, "0111101111111"],
[1, 0, "1100010000000"]
],
e: [2, -1, 1],
},
{
n: 0,
d: [
[-1, -1, "1001111111111"],
[0, -1, "0000010010110"],
[-1, 0, "0110000100000"],
[0, 0, "1101111011111"]
],
e: [-2, -1, 3]
},
{
n: 1,
d: [
[0, 0, "0011101111111"]
],
e: [1, 0, 1]
},
{
n: 1,
d: [
[0, 0, "1001111011111"]
],
e: [-1, 0, 3]
},
{
n: 2,
d: [
[0, 0, "1111101011111"]
],
e: [0, -1, 0]
},
];
r = (p) => {
var d = p.d; var e = p.e; var o = [];
d.forEach(i => {
var d = i[2];
o.push([-i[1], i[0], "" + d[10] + d[5] + d[0] + d[8] + d[3] + d[11] + d[6] + d[1] + d[9] + d[4] + d[12] + d[7] + d[2]])
});
return { d: o, e: [-e[1], e[0], e[2]] };
};
i = (g, p) => {
//console.log(g.p, g.d);
for (var i = 0; i < g.d; i++ , p = r(p));
var c = false;
p.d.forEach(d => {
var v = g[`${g.p.x + d[0]},${g.p.y + d[1]}`];
if (v === undefined) v = "00000000000000";
var o = "";
for (var i = 0; i < 13; i++) {
if (v[i] === '1' && d[2][i] === '1')
c = true;
o += (v[i] === d[2][i]) ? v[i] : '1';
}
//console.log(o);
g[`${g.p.x + d[0]},${g.p.y + d[1]}`] = o;
});
g.p.x += p.e[0];
g.p.y += p.e[1];
g.d = (g.d + p.e[2]) % 4;
return !c;
};
var l = [];
var re = (g, p) => {
t.forEach(piece => {
var gr = Object.assign({}, g);
gr.p = Object.assign({}, g.p);
if (p[piece.n] <= 0)
return;
if (i(gr, piece)) {
gr.ps += piece.n;
if (gr.p.x == 0 && gr.p.y == 0 && gr.d == 0) {
l.push(gr);
return;
}
var ti = Object.assign([], p);
ti[piece.n] -= 1;
re(gr, ti);
}
});
};
var gr = { p: { x: 0, y: 0 }, d: 0, ps: "" };
re(gr, Object.assign([], q));
var c = 0;
var lo = 0;
l.forEach(g => {
if (g.ps.length > lo) {
require("./draw.js")(g, `outs/out${c++}.png`)
lo = g.ps.length;
}
});
console.log(q[0] + q[1] + q[2] - lo);
最初に、使用したタイルのグラフィックを含める必要があります。
The sections of this tile were given a number and
used for comparison and overlap handling later.
So there first thing is the array t at the start.
This is a collection of track pieces that contain
n[ame]: the index of the input array.
d[ata]: the offset from the current tile and the Tile bit values.
e[nd]: the relative offset and rotation that the piece provides.
function r[otate] ( p[iece] )
this outputs a piece that is rotated by 90 degrees
by rearranging the tile bits and the end offset
function i[nsert] ( g[rid], p[iece] )
this modifies the passed in grid trying to place down each tile of the piece.
if it hits a point where 2 tiles intersect it sets a flag c[ollision]
it then adjusts the current p[osition] and and d[irection] stored in the grid.
then it returns !c[ollision]
function re[peat] ( g[rid], p[eices] )
this iterates across all nodes which
creates a copy of the g[rid] as gr[id].
checks if the piece is available if not continue
if the peice is added without a collision
add piece name to gr[id].ps[piece string];
it checks if its back at the start
add gr[id] to l[ist]
return as no more pieces can be added without a collision.
clone peices remove the used peice ti[nput]
call re[peate] (gr[id], ti[nput])
call re[peate] with empty grid
search l[ist] for longest piece string
and output input added together minus the length of the longest string.
書き込みが読みにくい場合は申し訳ありませんが、コードの動作を説明するのに慣れていません。
PS私は実際に、PNGにマップを描画するためのいくつかの関数も作成しましたが、もちろんそれらは少なくともいくらかのスペースを節約するために削除されました。
[5,0,0]
またはの出力[0,5,0]
はになります1
。あれは正しいですか?そのようなテストケースを追加してもらえますか?