Task

Given a jumbled list of the numbers   1   to   9   that are definitely   not   in
ascending order.

Show the list,   and then ask the player how many digits from the
left to reverse.

Reverse those digits,   then ask again,   until all the digits end up in ascending order.



The score is the count of the reversals needed to attain the ascending order.



Note: Assume the player's input does not need extra validation.



Related tasks

   Sorting algorithms/Pancake sort
   Pancake sorting.
   Topswops


% This program uses the random number generator from PCLU's
% 'misc.lib'
 
% Shuffle the given array. Every item ends up in a different place,
% so if given the numbers in ascending order, it is guaranteed that
% they will not still be in ascending order at the end.
jumble = proc [T: type] (a: array[T]) 
    for i: int in int$from_to_by(array[T]$high(a), array[T]$low(a)+1, -1) do
        j: int := array[T]$low(a) + random$next(i - array[T]$low(a))
        x: T := a[i]
        a[i] := a[j]
        a[j] := x
    end
end jumble
 
% Is the array sorted?
win = proc (a: array[int]) returns (bool)
    for i: int in array[int]$indexes(a) do
        if i ~= a[i] then return(false) end
    end
    return(true)
end win
 
% Reverse the first N items of the array
reverse = proc (n: int, a: array[int])
    for i: int in int$from_to(1, n/2) do
        j: int := n-i+1
        x: int := a[j]
        a[j] := a[i]
        a[i] := x
    end
end reverse
 
% Play the game
start_up = proc ()
    po: stream := stream$primary_output()
    pi: stream := stream$primary_input()
    d: date := now()
    random$seed(d.second + 60*(d.minute + 60*d.hour))
    score: int := 0
    nums: array[int] := array[int]$[1,2,3,4,5,6,7,8,9]
    jumble[int](nums)
    while ~win(nums) do
        for i: int in array[int]$elements(nums) do
            stream$puts(po, int$unparse(i))
        end
        stream$puts(po, ": reverse how many? ")
        n: int := int$parse(stream$getl(pi))
        reverse(n, nums)
        score := score + 1
    end
    for i: int in array[int]$elements(nums) do
        stream$puts(po, int$unparse(i))
    end
    stream$putl(po, "\nScore = " || int$unparse(score))
end start_up