RosettaCodeData/Task/Topswops/D/topswops-2.d

53 lines
1.3 KiB
D
Raw Permalink Normal View History

2015-02-20 00:35:01 -05:00
import std.stdio, std.typecons;
2013-04-11 01:07:29 -07:00
__gshared uint[32] best;
2015-02-20 00:35:01 -05:00
uint topswops(size_t n)() nothrow @nogc {
2013-04-11 01:07:29 -07:00
static assert(n > 0 && n < best.length);
size_t d = 0;
alias T = byte;
alias Deck = T[n];
2015-02-20 00:35:01 -05:00
void trySwaps(in ref Deck deck, in uint f) nothrow @nogc {
2013-04-11 01:07:29 -07:00
if (d > best[n])
best[n] = d;
2015-02-20 00:35:01 -05:00
foreach_reverse (immutable i; staticIota!(0, n)) {
2013-04-11 01:07:29 -07:00
if ((deck[i] == i || (deck[i] == -1 && !(f & (1U << i))))
&& (d + best[i] >= best[n] || deck[i] == -1))
break;
if (d + best[i] <= best[n])
return;
}
Deck deck2 = void;
2015-02-20 00:35:01 -05:00
foreach (immutable i; staticIota!(0, n)) // Copy.
2013-04-11 01:07:29 -07:00
deck2[i] = deck[i];
d++;
2015-02-20 00:35:01 -05:00
foreach (immutable i; staticIota!(1, n)) {
2013-04-11 01:07:29 -07:00
enum uint k = 1U << i;
if (deck[i] != i && (deck[i] != -1 || (f & k)))
continue;
2015-02-20 00:35:01 -05:00
deck2[0] = T(i);
foreach_reverse (immutable j; staticIota!(0, i))
2013-04-11 01:07:29 -07:00
deck2[i - j] = deck[j]; // Reverse copy.
trySwaps(deck2, f | k);
}
d--;
}
best[n] = 0;
Deck deck0 = -1;
deck0[0] = 0;
trySwaps(deck0, 1);
return best[n];
}
void main() {
2015-02-20 00:35:01 -05:00
foreach (immutable i; staticIota!(1, 14))
2013-04-11 01:07:29 -07:00
writefln("%2d: %d", i, topswops!i());
}