Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import std.stdio, std.random, std.algorithm, std.conv, std.range,
|
||||
std.traits, std.typecons;
|
||||
|
||||
auto bestShuffle(S)(in S orig) if (isSomeString!S) {
|
||||
auto bestShuffle(S)(in S orig) @safe if (isSomeString!S) {
|
||||
static if (isNarrowString!S)
|
||||
immutable o = orig.dtext;
|
||||
else
|
||||
|
|
@ -32,9 +32,9 @@ auto bestShuffle(S)(in S orig) if (isSomeString!S) {
|
|||
assert("".bestShuffle[1] == 0);
|
||||
}
|
||||
|
||||
void main(in string[] args) {
|
||||
void main(in string[] args) @safe {
|
||||
if (args.length > 1) {
|
||||
immutable entry = args.dropOne.join(" ");
|
||||
immutable entry = args.dropOne.join(' ');
|
||||
const res = entry.bestShuffle;
|
||||
writefln("%s : %s (%d)", entry, res[]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ extern(C) pure nothrow void* alloca(in size_t size);
|
|||
void bestShuffle(in char[] txt, ref char[] result) pure nothrow {
|
||||
// Assume alloca to be pure.
|
||||
//extern(C) pure nothrow void* alloca(in size_t size);
|
||||
enum size_t NCHAR = cast(size_t)char.max + 1;
|
||||
enum size_t NCHAR = size_t(char.max + 1);
|
||||
enum size_t MAX_VLA_SIZE = 1024;
|
||||
immutable size_t len = txt.length;
|
||||
if (len == 0)
|
||||
|
|
@ -19,7 +19,7 @@ void bestShuffle(in char[] txt, ref char[] result) pure nothrow {
|
|||
// how many of each character?
|
||||
size_t[NCHAR] counts;
|
||||
size_t fmax = 0;
|
||||
foreach (char c; txt) {
|
||||
foreach (immutable char c; txt) {
|
||||
counts[c]++;
|
||||
if (fmax < counts[c])
|
||||
fmax = counts[c];
|
||||
|
|
@ -38,7 +38,7 @@ void bestShuffle(in char[] txt, ref char[] result) pure nothrow {
|
|||
}
|
||||
{
|
||||
int pos = 0;
|
||||
foreach (size_t ch; 0 .. NCHAR)
|
||||
foreach (immutable size_t ch; 0 .. NCHAR)
|
||||
if (counts[ch])
|
||||
foreach (j, char c; txt)
|
||||
if (c == ch) {
|
||||
|
|
@ -57,7 +57,7 @@ void bestShuffle(in char[] txt, ref char[] result) pure nothrow {
|
|||
}
|
||||
{
|
||||
size_t n, m;
|
||||
foreach (size_t i; 0 .. len) {
|
||||
foreach (immutable size_t i; 0 .. len) {
|
||||
ndx2[i] = ndx1[n];
|
||||
n += fmax;
|
||||
if (n >= len) {
|
||||
|
|
@ -67,27 +67,27 @@ void bestShuffle(in char[] txt, ref char[] result) pure nothrow {
|
|||
}
|
||||
}
|
||||
|
||||
// how long can our cyclic groups be?
|
||||
// How long can our cyclic groups be?
|
||||
immutable size_t grp = 1 + (len - 1) / fmax;
|
||||
|
||||
// how many of them are full length?
|
||||
// How many of them are full length?
|
||||
immutable size_t lng = 1 + (len - 1) % fmax;
|
||||
|
||||
// rotate each group
|
||||
// Rotate each group.
|
||||
{
|
||||
size_t j;
|
||||
foreach (size_t i; 0 .. fmax) {
|
||||
foreach (immutable size_t i; 0 .. fmax) {
|
||||
immutable size_t first = ndx2[j];
|
||||
immutable size_t glen = grp - (i < lng ? 0 : 1);
|
||||
foreach (size_t k; 1 .. glen)
|
||||
foreach (immutable size_t k; 1 .. glen)
|
||||
ndx1[j + k - 1] = ndx2[j + k];
|
||||
ndx1[j + glen - 1] = first;
|
||||
j += glen;
|
||||
}
|
||||
}
|
||||
|
||||
// result is original permuted according to our cyclic groups
|
||||
foreach (size_t i; 0 .. len)
|
||||
// Result is original permuted according to our cyclic groups.
|
||||
foreach (immutable size_t i; 0 .. len)
|
||||
result[ndx2[i]] = txt[ndx1[i]];
|
||||
}
|
||||
|
||||
|
|
@ -97,7 +97,7 @@ void main() {
|
|||
foreach (txt; data) {
|
||||
auto result = txt.dup;
|
||||
bestShuffle(txt, result);
|
||||
immutable nEqual = zip(txt, result).count!q{a[0] == a[1]}();
|
||||
immutable nEqual = zip(txt, result).count!q{ a[0] == a[1] };
|
||||
writefln("%s, %s, (%d)", txt, result, nEqual);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,27 @@
|
|||
#define system.
|
||||
#define system'routines.
|
||||
#define extensions.
|
||||
|
||||
// --- shuffle ---
|
||||
|
||||
#symbol shuffle = (:aLiteral)
|
||||
[
|
||||
#var aLength := aLiteral length.
|
||||
#var aShuffled := literalControl toArray:aLiteral.
|
||||
|
||||
control from:0 &till:aLength &do: i
|
||||
control forrange &int:0 &int::(aLength-1) &do: (&int:i)
|
||||
[
|
||||
#var aChar := aLiteral@i.
|
||||
(aChar == (aShuffled@i)) ?
|
||||
[
|
||||
control from:0 &till:aLength &do: j
|
||||
control forrange &int:0 &int::(aLength-1) &do: (&int:j)
|
||||
[
|
||||
#var anAltChar := aShuffled@j.
|
||||
(anAltChar != aChar)and:[ anAltChar != (aLiteral@i) ]and:[aChar != (aLiteral@j)] ?
|
||||
[
|
||||
arrayControl exchange:i &with:j &in:aShuffled.
|
||||
|
||||
#break nil.
|
||||
#break.
|
||||
].
|
||||
].
|
||||
].
|
||||
|
|
@ -27,24 +30,27 @@
|
|||
^ Summing new:(String new) foreach:aShuffled literal.
|
||||
].
|
||||
|
||||
// --- ShuffleScore ---
|
||||
|
||||
#symbol scoreShuffle = (:anOriginal:aShuffled)
|
||||
[
|
||||
#var aScore := Integer new.
|
||||
|
||||
control from:0 &till:(anOriginal length) &do: i
|
||||
control forrange &int:0 &int:(anOriginal length - 1) &do: (&int:i)
|
||||
[ (anOriginal @ i) == (aShuffled @ i) ? [ aScore += 1. ]. ].
|
||||
|
||||
^ aScore number.
|
||||
^ aScore value.
|
||||
].
|
||||
|
||||
// --- Program ---
|
||||
|
||||
#symbol program =
|
||||
[
|
||||
control foreach:("abracadabra", "seesaw", "grrrrrr", "pop", "up", "a") &do: aWord
|
||||
[
|
||||
#var aShuffled := shuffle:aWord.
|
||||
|
||||
console write:"The best shuffle of " write:aWord write:" is " write:aShuffled write:"("
|
||||
write:(scoreShuffle:aWord:aShuffled) writeLine:")".
|
||||
consoleEx writeLine:"The best shuffle of ":aWord:" is ":aShuffled:"(":(scoreShuffle:aWord:aShuffled):")".
|
||||
].
|
||||
|
||||
console readChar.
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ func main() {
|
|||
t[i] = s[r]
|
||||
}
|
||||
// algorithm of Icon solution
|
||||
for i := 0; i < len(s); i++ {
|
||||
for j := 0; j < len(s); j++ {
|
||||
for i := range t {
|
||||
for j := range t {
|
||||
if i != j && t[i] != s[j] && t[j] != s[i] {
|
||||
t[i], t[j] = t[j], t[i]
|
||||
break
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import java.util.*;
|
||||
import java.util.Random;
|
||||
|
||||
public class BestShuffle {
|
||||
|
||||
|
|
@ -10,7 +10,7 @@ public class BestShuffle {
|
|||
|
||||
public static String bestShuffle(final String s1) {
|
||||
char[] s2 = s1.toCharArray();
|
||||
Collections.shuffle(Arrays.asList(s2));
|
||||
shuffle(s2);
|
||||
for (int i = 0; i < s2.length; i++) {
|
||||
if (s2[i] != s1.charAt(i))
|
||||
continue;
|
||||
|
|
@ -26,6 +26,16 @@ public class BestShuffle {
|
|||
return s1 + " " + new String(s2) + " (" + count(s1, s2) + ")";
|
||||
}
|
||||
|
||||
public static void shuffle(char[] text) {
|
||||
Random rand = new Random();
|
||||
for (int i = text.length - 1; i > 0; i--) {
|
||||
int r = rand.nextInt(i + 1);
|
||||
char tmp = text[i];
|
||||
text[i] = text[r];
|
||||
text[r] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
private static int count(final String s1, final char[] s2) {
|
||||
int count = 0;
|
||||
for (int i = 0; i < s2.length; i++)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ def best_shuffle(s):
|
|||
# Add character to list. Remove it from supply.
|
||||
r.append(best)
|
||||
count[best] -= 1
|
||||
if count[best] == 0: del count[best]
|
||||
if count[best] >= 0: del count[best]
|
||||
|
||||
# If the final letter became stuck (as "ababcd" became "bacabd",
|
||||
# and the final "d" became stuck), then fix it.
|
||||
|
|
|
|||
|
|
@ -3,19 +3,18 @@ def best_shuffle(s)
|
|||
# that we want to fill them.
|
||||
pos = []
|
||||
# g["a"] = [2, 4] implies that s[2] == s[4] == "a"
|
||||
g = (0...s.length).group_by { |i| s[i] }
|
||||
g = s.length.times.group_by { |i| s[i] }
|
||||
|
||||
# k sorts letters from low to high count
|
||||
k = g.sort_by { |k, v| v.length }.map! { |k, v| k }
|
||||
k = g.sort_by { |k, v| v.length }.map { |k, v| k }
|
||||
|
||||
until g.empty?
|
||||
k.each { |letter|
|
||||
k.each do |letter|
|
||||
g[letter] or next
|
||||
pos.push(g[letter].pop)
|
||||
g[letter].empty? and g.delete letter
|
||||
}
|
||||
end
|
||||
end
|
||||
pos.reverse!
|
||||
|
||||
# Now fill in _new_ with _letters_ according to each position
|
||||
# in _pos_, but skip ahead in _letters_ if we can avoid
|
||||
|
|
@ -23,7 +22,7 @@ def best_shuffle(s)
|
|||
letters = s.dup
|
||||
new = "?" * s.length
|
||||
until letters.empty?
|
||||
i, p = 0, pos.shift
|
||||
i, p = 0, pos.pop
|
||||
i += 1 while letters[i] == s[p] and i < (letters.length - 1)
|
||||
new[p] = letters.slice! i
|
||||
end
|
||||
|
|
@ -32,6 +31,6 @@ def best_shuffle(s)
|
|||
[new, score]
|
||||
end
|
||||
|
||||
%w(abracadabra seesaw elk grrrrrr up a).each { |word|
|
||||
printf "%s, %s, (%d)\n", word, *best_shuffle(word)
|
||||
}
|
||||
%w(abracadabra seesaw elk grrrrrr up a).each do |word|
|
||||
puts "%s, %s, (%d)" % [word, *best_shuffle(word)]
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue