111 lines
2.8 KiB
Plaintext
111 lines
2.8 KiB
Plaintext
Structure charInfo
|
|
Char.s
|
|
List Position.i()
|
|
count.i ;number of occurrences of Char
|
|
EndStructure
|
|
|
|
Structure cycleInfo
|
|
Char.s
|
|
Position.i
|
|
EndStructure
|
|
|
|
Structure cycle
|
|
List cycle.cycleInfo()
|
|
EndStructure
|
|
|
|
Procedure.s shuffleWordLetters(word.s)
|
|
Protected i
|
|
Dim originalLetters.s(len(word) - 1)
|
|
For i = 1 To Len(word)
|
|
originalLetters(i - 1) = Mid(word, i, 1)
|
|
Next
|
|
|
|
Dim shuffledLetters.s(0)
|
|
CopyArray(originalLetters(), shuffledLetters())
|
|
|
|
;record original letters and their positions
|
|
Protected curChar.s
|
|
NewList letters.charInfo()
|
|
NewMap *wordInfo.charInfo()
|
|
For i = 0 To ArraySize(originalLetters())
|
|
curChar = originalLetters(i)
|
|
If FindMapElement(*wordInfo(), curChar)
|
|
AddElement(*wordInfo()\position())
|
|
*wordInfo()\position() = i
|
|
Else
|
|
*wordInfo(curChar) = AddElement(letters())
|
|
If *wordInfo()
|
|
*wordInfo()\Char = curChar
|
|
AddElement(*wordInfo()\position())
|
|
*wordInfo()\position() = i
|
|
EndIf
|
|
EndIf
|
|
Next
|
|
|
|
ForEach letters()
|
|
letters()\count = ListSize(letters()\Position())
|
|
Next
|
|
|
|
SortStructuredList(letters(), #PB_Sort_Ascending, OffsetOf(charInfo\Char), #PB_Sort_String) ;extra sort step, not strictly necessary
|
|
SortStructuredList(letters(), #PB_Sort_Descending, OffsetOf(charInfo\count), #PB_Sort_integer)
|
|
|
|
;construct letter cycles
|
|
FirstElement(letters())
|
|
Protected maxLetterCount = letters()\count
|
|
Dim letterCycles.cycle(maxLetterCount - 1)
|
|
|
|
Protected curCycleIndex
|
|
ForEach letters()
|
|
ForEach letters()\Position()
|
|
With letterCycles(curCycleIndex)
|
|
AddElement(\cycle())
|
|
\cycle()\Char = letters()\Char
|
|
\cycle()\Position = letters()\position()
|
|
EndWith
|
|
curCycleIndex = (curCycleIndex + 1) % maxLetterCount
|
|
Next
|
|
Next
|
|
|
|
;rotate letters in each cycle
|
|
Protected isFirst, prevChar.s, pos_1
|
|
For i = 0 To maxLetterCount - 1
|
|
With letterCycles(i)
|
|
isFirst = #True
|
|
ForEach \cycle()
|
|
If Not isFirst
|
|
shuffledLetters(\cycle()\Position) = prevChar
|
|
Else
|
|
pos_1 = \cycle()\Position
|
|
isFirst = #False
|
|
EndIf
|
|
prevChar = \cycle()\Char
|
|
Next
|
|
shuffledLetters(pos_1) = prevChar
|
|
EndWith
|
|
Next
|
|
|
|
;score and display shuffle
|
|
Protected shuffledWord.s, ignored
|
|
For i = 0 To ArraySize(shuffledLetters())
|
|
shuffledWord + shuffledLetters(i)
|
|
If shuffledLetters(i) = originalLetters(i)
|
|
ignored + 1
|
|
EndIf
|
|
Next
|
|
|
|
PrintN(word + ", " + shuffledWord + ", (" + Str(ignored) + ")")
|
|
ProcedureReturn shuffledWord
|
|
EndProcedure
|
|
|
|
If OpenConsole()
|
|
shuffleWordLetters("abracadabra")
|
|
shuffleWordLetters("seesaw")
|
|
shuffleWordLetters("elk")
|
|
shuffleWordLetters("grrrrrr")
|
|
shuffleWordLetters("up")
|
|
shuffleWordLetters("a")
|
|
|
|
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
|
|
CloseConsole()
|
|
EndIf
|