moar better A*

This commit is contained in:
Hackerpilot 2015-02-18 18:31:41 -08:00
parent a886dc5cd0
commit 7dea7ea962
1 changed files with 34 additions and 38 deletions

View File

@ -1159,42 +1159,52 @@ struct State
size_t breakIndex = 0; size_t breakIndex = 0;
size_t i; size_t i;
bool s = true; bool s = true;
do if (breaks.length == 0)
{ {
immutable size_t j = breakIndex < breaks.length ? breaks[breakIndex] : tokens.length; _cost = int.max;
ll += tokens[i .. j].map!(a => tokenLength(a)).sum(); s = false;
writeln("ll = ", ll, " i = ", i, " j = ", j); }
if (ll > formatterConfig.columnSoftLimit) else
{ {
s = false; do
break; {
} immutable size_t j = breakIndex < breaks.length ? breaks[breakIndex] : tokens.length;
i = j; ll += tokens[i .. j].map!(a => tokenLength(a)).sum();
ll = (indentLevel + 1) * formatterConfig.indentSize; if (ll > formatterConfig.columnSoftLimit)
writeln("ll2 = ", ll); {
breakIndex++; s = false;
break;
}
i = j;
ll = (indentLevel + 1) * formatterConfig.indentSize;
breakIndex++;
}
while (i + 1 < tokens.length);
} }
while (i + 1 < tokens.length);
this._solved = s; this._solved = s;
writeln("breaks = ", breaks, " solved = ", this._solved);
} }
int cost() const @property { return _cost; } int cost() const pure nothrow @safe @property { return _cost; }
int depth() const @property { return _depth; } int depth() const pure nothrow @safe @property { return _depth; }
int solved() const @property { return _solved; } int solved() const pure nothrow @safe @property { return _solved; }
int opCmp(ref const State other) const int opCmp(ref const State other) const pure nothrow @safe
{ {
if (other.cost < cost) if (cost < other.cost || (_solved && !other.solved))
return -1; return -1;
return other.cost > cost; return other.cost > _cost;
} }
bool opEquals(ref const State other) const bool opEquals(ref const State other) const pure nothrow @safe
{ {
return other.breaks == breaks; return other.breaks == breaks;
} }
size_t toHash() const nothrow @safe
{
return typeid(breaks).getHash(&breaks);
}
size_t[] breaks; size_t[] breaks;
private: private:
int _cost; int _cost;
@ -1205,38 +1215,25 @@ private:
size_t[] chooseLineBreakTokens(const Token[] tokens, size_t[] chooseLineBreakTokens(const Token[] tokens,
const FormatterConfig* formatterConfig, int currentLineLength, int indentLevel) const FormatterConfig* formatterConfig, int currentLineLength, int indentLevel)
{ {
import std.typecons : Tuple, tuple;
import std.container.rbtree : RedBlackTree; import std.container.rbtree : RedBlackTree;
import std.algorithm : map;
int depth = 0; int depth = 0;
auto open = new RedBlackTree!State; auto open = new RedBlackTree!State;
auto closed = new RedBlackTree!(State, "a.breaks < b.breaks");
open.insert(State(cast(size_t[])[], tokens, depth, formatterConfig, open.insert(State(cast(size_t[])[], tokens, depth, formatterConfig,
currentLineLength, indentLevel)); currentLineLength, indentLevel));
while (!open.empty) while (!open.empty)
{ {
State current = open.front(); State current = open.front();
writeln("open = ", open[].map!(a => tuple(a.cost, a.solved)));
open.removeFront(); open.removeFront();
closed.insert(current);
if (current.solved) if (current.solved)
return current.breaks; return current.breaks;
foreach (next; validMoves(tokens, current, formatterConfig, foreach (next; validMoves(tokens, current, formatterConfig,
currentLineLength, indentLevel, depth)) currentLineLength, indentLevel, depth))
{ {
auto r = closed.equalRange(next);
if (!r.empty)
{
if (current.cost > r.front.cost)
continue;
closed.remove(r);
}
open.insert(next); open.insert(next);
} }
} }
writeln("No solution found"); return open.empty ? [] : open.front().breaks;
return open.front().breaks;
} }
State[] validMoves(const Token[] tokens, ref const State current, State[] validMoves(const Token[] tokens, ref const State current,
@ -1258,7 +1255,6 @@ State[] validMoves(const Token[] tokens, ref const State current,
states ~= State(breaks, tokens, depth + 1, formatterConfig, states ~= State(breaks, tokens, depth + 1, formatterConfig,
currentLineLength, indentLevel); currentLineLength, indentLevel);
} }
writeln(states);
return states; return states;
} }
@ -1271,5 +1267,5 @@ unittest
StringCache cache = StringCache(StringCache.defaultBucketCount); StringCache cache = StringCache(StringCache.defaultBucketCount);
auto tokens = byToken(cast(ubyte[]) sourceCode, config, &cache).array(); auto tokens = byToken(cast(ubyte[]) sourceCode, config, &cache).array();
FormatterConfig formatterConfig; FormatterConfig formatterConfig;
writeln(chooseLineBreakTokens(tokens, &formatterConfig, 0, 0)); assert ([15] == chooseLineBreakTokens(tokens, &formatterConfig, 0, 0));
} }