Best shuffle: Difference between revisions

→‎{{header|AWK}}: Add translation from Icon; this is simpler than the translation from Perl 6.
(Improved D version)
(→‎{{header|AWK}}: Add translation from Icon; this is simpler than the translation from Perl 6.)
Line 6:
 
=={{header|AWK}}==
=== {{trans|Perl 6Icon}} ===
The Icon and Unicon program uses a simple algorithm of swapping. This is relatively easy to translate to Awk.
 
<lang awk>{
Awk is a poor choice for this task, because Awk provides no array functions, except for split(). This Awk program uses its own code
scram = best_shuffle($0)
print $0 " -> " scram " (" unchanged($0, scram) ")"
}
 
function best_shuffle(s, c, i, j, len, r, t) {
len = split(s, t, "")
 
# Swap elements of t[] to get a best shuffle.
for (i = 1; i <= len; i++) {
for (j = 1; j <= len; j++) {
# Swap t[i] and t[j] if they will not match
# the original characters from s.
if (i != j &&
t[i] != substr(s, j, 1) &&
substr(s, i, 1) != t[j]) {
c = t[i]
t[i] = t[j]
t[j] = c
break
}
}
}
 
# Join t[] into one string.
r = ""
for (i = 1; i <= len; i++)
r = r t[i]
return r
}
 
function unchanged(s1, s2, count, len) {
count = 0
len = length(s1)
for (i = 1; i <= len; i++) {
if (substr(s1, i, 1) == substr(s2, i, 1))
count++
}
return count
}</lang>
 
This program has the same output as the Icon and Unicon program.
 
=== {{trans|Perl 6}} ===
AwkThe isPerl a6 poorprogram choice(and forthe thisequivalent task,Ruby becauseprogram) use several built-in array functions. Awk provides no array functions, except for split(). This Awk program, a translation from Perl 6, uses its own code
 
* to sort an array,
Line 16 ⟶ 61:
* to join the elements of an array into a string.
 
TheIf equivalent programs for [[#Perl 6|Perl 6]] and for [[#Ruby|Ruby]] use severalthose built-in array functions. But if those array functions seem strange to you, and if you can understand this bunch ofthese for loops, then you might prefer this Awk program. This algorithm counts the letters in the string, sorts the positions, and fills the positions in order.
 
This algorithm calculates an order of positions, then fills a new string in this order, by moving each letter from the original string. It will never replace an old letter with an identical letter, unless the remainder of the original string has only this letter. The next position to fill is always the position of the old letter with the most occurrences among the remaining old letters. This special order can always change every old letter, unless some old letter occurs in more than half of the original string.
 
<lang awk># out["string"] = best shuffle of string _s_
Line 66 ⟶ 109:
# Now fill in _new_ with _letters_ according to each position
# in pos[slen], ..., pos[1], but skip ahead in _letters_
# if we can avoid matching characteerscharacters that way.
rlen = split(s, letters, "")
for (i = slen; i >= 1; i--) {
Line 110 ⟶ 153:
a, a, (1)</lang>
 
The output might change if the <tt>for (c in set)</tt> loop iterates the array in a different order. (Awk specifies not an order of iteration.)
 
=={{header|C}}==
Anonymous user