ArrayShuffle.tu
Author |
Message |
Jorbalax
|
Posted: Tue Jun 21, 2005 3:52 pm Post subject: ArrayShuffle.tu |
|
|
I posted this earlier, guess it was lost in the "roll-back".
Takes an array and shuffles it's values. I added a new command, ArrayShuffle.Set (arrayupper : int). This presets the random values to be used by the other procedures, so you can shuffle arrays with the same corresponding values (if they are the same length, of course). See the example below to help clarify.
Commands
-------------
ArrayShuffle.Set (var arrayupper : int)
- Sets random values
ArrayShuffle.Int (var inputarray : array 1..* of int)
- Shuffles an array of integers.
ArrayShuffle.String (var inputarray : array 1..* of string)
- Shuffles an array of strings.
ArrayShuffle.Real (var inputarray : array 1..* of real)
- Shuffles an array of real numbers.
Example Program
code: |
%Draws 3 circles on the on the screen, with color names corresponding to their colors (red, blue or green).
%Import ArrayShuffle.tu
import ArrayShuffle
View.Set ("graphics:max;max, nocursor, nobuttonbar")
%Variable declaration.
var array1 : array 1..3 of string := init ("Red", "Green", "Blue")
var array2 : array 1..3 of int := init (brightred, brightgreen, brightblue)
var x, y : int
%Main Loop
loop
y := maxy div 2
x := (maxx div 2) - 100
%Set the random number values, using the upper of one of the arrays to be shuffled.
ArrayShuffle.Set (upper (array1))
%Shuffle the arrays.
ArrayShuffle.String (array1)
ArrayShuffle.Int (array2)
%Draw a circle with the color, and output the corresponding name.
for i:1..upper (array1)
locatexy (x, y + 100)
put array1 (i)
Draw.FillOval (x, y, 50, 50, array2 (i))
x+=100
end for
Input.Pause
end loop
|
Feel free to use this in your programs (credit me if you're nice!).
Description: |
Takes an array and shuffles its values. |
|
Download |
Filename: |
ArrayShuffle.tu |
Filesize: |
1.87 KB |
Downloaded: |
213 Time(s) |
|
|
|
|
|
|
Sponsor Sponsor
|
|
|
Delos
|
Posted: Thu Jun 23, 2005 8:14 pm Post subject: (No subject) |
|
|
Good concept. A couple of pointers:
- Press F2!
- Line 15 (or so)
code: |
new randomarray, upper (randomarray) - upper (randomarray)
|
Wouldn't this be easier as simply:
Turing: |
new randomarray, 0
|
- I don't like the idea of having to 'Set' the upper bound of the temporary array. Think of a way to make this implicit. For example, if you have an array of ints, the call to 'ArrayShuffle.Int()' will call a procedure within your module that will extract the upper bound of the said array, and deal with your temporary array accordingly.
- You may want to look into replacing your procedures with functions. Since each of them return a set series of values, you could simply 'result temparray'...you should be able to get away with it even with dynamic bounds.
|
|
|
|
|
|
Cervantes
|
Posted: Thu Jun 23, 2005 8:55 pm Post subject: (No subject) |
|
|
Delos wrote: ...you should be able to get away with it even with dynamic bounds.
Is it going to be some wacky roundabout way? I couldn't figure it out using basic methods. Mind giving it a stab?
|
|
|
|
|
|
Delos
|
Posted: Fri Jun 24, 2005 9:20 am Post subject: (No subject) |
|
|
Bah. Apparently dynamic bounds in a functions result are not applicable...which is strange seeing as dynamic bounds within the parameters are allowed! Anyway, my primary qualm was with the fact that you had to 'Set' the upper bound before you called your shuffle. Here, I've made it so that you just need to call the shuffle command and not an explicit set command.
Turing: |
% Shuffling arrays:
setscreen ("text")
module arrShuff
export Int, String, Real
procedure Int (var inArr : array 1 .. * of int)
var tempArr : array 1 .. upper (inArr ) of string
var outArr : flexible array 1 .. 0 of int
var xCount : int := 0
for i : 1 .. upper (tempArr )
tempArr (i ) := intstr (inArr (i ))
end for
loop
for i : 1 .. upper (tempArr )
var temp : int := Rand.Int (1, upper (tempArr ))
if tempArr (temp ) not= "x" then
new outArr, upper (outArr ) + 1
outArr (upper (outArr )) := strint (tempArr (temp ))
tempArr (temp ) := "x"
xCount + = 1
end if
end for
exit when xCount = upper (tempArr )
end loop
for i : 1 .. upper (outArr )
inArr (i ) := outArr (i )
end for
end Int
procedure String (var inArr : array 1 .. * of string)
end String
procedure Real (var inArra : array 1 .. * of real)
end Real
end arrShuff
var myArr : array 1 .. 10 of int
for i : 1 .. upper (myArr )
myArr (i ) := Rand.Int (1, 100)
put myArr (i )
end for
put ""
arrShuff.Int (myArr )
put ""
for i : 1 .. upper (myArr )
put myArr (i )
end for
|
If you want to test it, use an int array of sequential terms (such as 50 - 100, or 1 - 1000), shuffle it, then sort it using your favourite sort algorithm.
I've got a feeling it might slow down a tad once the number of elements in the array reaches a large number...though I've tested it at 1000 elements and it still works fine.
Yes, I'm aware that only one of the procedures is complete. The other two stubs are for you to figure out. My method of comparison gets a little tricky with the strings, since there's always a chance that your null-key (in this case 'x') would appear normally in the array. For that I'd probably randomly generate a key, and then do a check to make sure its not an existing element.
|
|
|
|
|
|
Jorbalax
|
Posted: Fri Jun 24, 2005 11:41 am Post subject: (No subject) |
|
|
Try this with your version of ArrayShuffle
code: |
var myArr : array 1 .. 10 of int
for i : 1 .. upper (myArr)
myArr (i) := i
put myArr (i)
end for
put ""
var myArr2 : array 1 .. 10 of int
for i : 1..upper (myArr)
myArr2 (i) := i
put myArr2 (i)
end for
put ""
arrShuff.Int (myArr)
arrShuff.Int (myArr2)
put ""
for i : 1 .. upper (myArr)
put myArr (i)
end for
put ""
for i : 1 .. upper (myArr2)
put myArr2 (i)
end for
|
Great, works fine and dandy, right? But what if you want myArr and myArr2 to have the same random values?
See, originally, I had it like that, but the problem with that is that each time you call ArrayShuffle.whatevertype, you'd get a different set of random numbers. Having ArrayShuffle.Set allows you to shuffle multiple arrays with the same random values, so you can have the arrays correspond to each other if you want (like in my example program, red is always with the red circle, and so on.)
Haha, I had actually tried making them into functions at first. I ran into the same problem .
Anyways...
I'm going to attempt two-dimensional array shuffling.
var examplearray : array 1..10, 1..10 of int
One command would allow the user to shuffle just the first dimension of the array.
Another would allow them to shuffle just the second dimension.
Last one would call both of those, shuffling the array entirely.
The problem is, though, that I'll have to make a whole list of procedures for each individual type, which means lots of excessive code. Is there a way to have a procedure with a parameter that has a dynamic type?
ex proc Example (var examplearray : array 1..* of (type input))
BTW
I like your comparison method, it's much faster than the one I have set up.
(I ran them in an array that was composed of 5000 numbers, results;
Mine - 13.286
Yours - 7.157)
|
|
|
|
|
|
Delos
|
Posted: Fri Jun 24, 2005 1:45 pm Post subject: (No subject) |
|
|
There is no 'universal' type that I'm aware of, but you *might* want to look into 'anyclass'. I'm not garanteeing anything - I've never used it myself. It seems that if you use a class system you might be able to get away with this...
I'm not entirely sure why you'd want two seperate arrays to have the same set of random, shuffled values...
Anyhow, if you wanted to do that with my programme, you'd just need to be creative! Create an int array the same lenght as your two arrays that you want, and shuffle it. Then, assign your arrays using the corresponding numbers generated from the shuffled array.
See! No need to have any excessive 'Set' commands . But of course it is your proggie, and if you feel that having Set is more efficient for you, then by all means go ahead.
|
|
|
|
|
|
Cervantes
|
Posted: Fri Jun 24, 2005 4:54 pm Post subject: (No subject) |
|
|
Of course, the other alternative is to join those two arrays at the hip, via records:
code: |
var twoArrays :
record
effectiveArray1 : int
effectiveArray2 : int
end record
|
But, that's not always going to be what you want.
|
|
|
|
|
|
|
|