How to resolve the algorithm Best shuffle step by step in the Picat programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Best shuffle step by step in the Picat programming language

Table of Contents

Problem Statement

Shuffle the characters of a string in such a way that as many of the character values are in a different position as possible. A shuffle that produces a randomized result among the best choices is to be preferred. A deterministic approach that produces the same sequence every time is acceptable as an alternative. Display the result as follows: The score gives the number of positions whose character value did not change.

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Best shuffle step by step in the Picat programming language

Source code in the picat programming language

import cp.

go =>
  Words = ["abracadabra", 
           "seesaw", 
           "elk", 
           "grrrrrr", 
           "up", 
           "a",
           "shuffle",
           "aaaaaaa"
           ], 
  foreach(Word in Words)
     best_shuffle(Word,Best,_Score),
     printf("%s, %s, (%d)\n", Word,Best,diff_word(Word, Best))
  end,
  nl.

best_shuffle(Word,Best,Score) =>
  WordAlpha = Word.map(ord), % convert to integers
  WordAlphaNoDups = WordAlpha.remove_dups(),
  % occurrences of each character in the word
  Occurrences = occurrences(WordAlpha), 
  
  Len = Word.length,
  
  % Decision variables
  WordC = new_list(Len),
  WordC :: WordAlphaNoDups,

  %
  % The constraints
  %
  
  % Ensure that the shuffled word has the same
  % occurrences for each character
  foreach(V in WordAlphaNoDups) 
     count(V, WordC,#=, Occurrences.get(V))
  end,
  
  % The score is the number of characters
  % in the same position as the origin word
  % (to be minimized).
  Score #= sum([WordC[I] #= WordAlpha[I] : I in 1..Len]),

  if var(Score) then
    % We don't have a score yet: minimize Score
    solve([$min(Score),split], WordC)
  else
    % Get a solution for the given Score
    solve([split], WordC)
  end,
  % convert back to alpha
  Best = WordC.map(chr).


diff_word(W1,W2) = Diff =>
  Diff = sum([1 : I in 1..W1.length, W1[I]==W2[I]]).

occurrences(L) = Occ => 
  Occ = new_map(),
  foreach(E in L)
    Occ.put(E, Occ.get(E,0) + 1)
  end.

go2 ?=>
  Words = ["abracadabra", 
           "seesaw", 
           "elk", 
           "grrrrrr", 
           "up", 
           "a",
           "shuffle",
           "aaaaaaa"
           ], 
  member(Word,Words),
  println(word=Word),
  best_shuffle(Word,_Best,Score),
  println(best_score=Score),
  % Find all optimal solutions
  All = findall(Best2,best_shuffle(Word,Best2,Score)),
  Len = All.len,
  println(num_solutions=All.len),
  if Len <= 10 then
    println(solutions=All)
  else
    println("Only showing the first 10 solutions:"),
    println(solutions=All[1..10])
  end,
  nl,
  fail,
  nl.
go2 => true.

  

You may also check:How to resolve the algorithm Primorial numbers step by step in the Racket programming language
You may also check:How to resolve the algorithm Kaprekar numbers step by step in the BASIC programming language
You may also check:How to resolve the algorithm Atomic updates step by step in the C++ programming language
You may also check:How to resolve the algorithm Trigonometric functions step by step in the Arturo programming language
You may also check:How to resolve the algorithm Partial function application step by step in the FunL programming language