Calling random functions - java

public static GetRandomFunc() {
switch((int)(Math.random()*NUM_FUNCTIONS) {
case 0:
functionA();
break;
case 1:
functionB();
break;
case 2:
functionC();
break;
// ...
}
}
I want to call GetRandomFunc() in main randomly until each function has been called once and then it ends. How do I make sure a function would be called once only, and not called again.

It would be easier to store values in an collection, and draw them out randomly until the collection is empty. Or better yet, shuffle the collection and then walk over it sequentially.
The values in the collection could be integers, or they could be objects of different classes (with a common superclass or interface), which provide different implementations of a call() method.
For example:
import java.util.*;
import java.util.concurrent.*;
List<Runnable> functions = new ArrayList<Runnable>();
functions.add(new Runnable() {
public void run() { /* do something */ }
});
functions.add(new Runnable() {
public void run() { /* do something else */ }
});
Collections.shuffle(functions);
for(Runnable function : functions)
function.run();
The other posts on this thread show other potential solutions, but all of them are more complex and error-prone than this one, and most of them would be very slow if the number of functions is large. (The one from #AndersLinden is an exception -- it would still be fast even if there are thousands of functions to call.)

Bit fields to record whether a function has been called and an if statement to not call the function if it's bit is already set - keep looping until all of the bits are set.
(or as Alex D says, create a collection of numbers to use up front)
Either way the trick is to make sure you generate each number once and once only - if you screw this bit up you can end up in an infinite loop (e.g. waiting to get numbers 1, 2 and 3, but your random function is generating 0, 1 and 2)

You could create an array to keep track of which functions have already been used.
For example:
boolean[] usedFunctions = new boolean[NUM_FUNCTIONS];
public static GetRandomFunc() {
switch((int) (Math.random() * NUM_FUNCTIONS) {
case 0:
if(!usedFunctions[0]) {
functionA();
usedFunctions[0] = true;
}
break;
case 1:
if(!usedFunctions[1]) {
functionB();
usedFunctions[1] = true;
}
break;
// etc.
}
}
Then all you need to do is repeatedly call GetRandomFunc() until all elements in usedFunctions are true.

You keep an array of integers that tells which indexes that are still not used.
When you have used an integer, you fill it in the hole with the last index in the list and treat it as a list with one item shorter.
int indexes[] = new int[3];
for (int i = 0; i < 3; i++)
indexes[i] = i;
for (int i = 0; i < 3; i++)
{
int index = (int)(Math.random()*(3 - i));
switch (indexes[index])
{
case 0:
functionA();
break;
case 1:
functionB();
break;
case 2:
functionC();
break;
}
indexes[index] = indexes[2 - i];
}

Related

How can I allow programmable key inputs in Processing?

I am writing a Processing script and want to detect whether a key (using the key variable) is one of a set of keys chosen by the user ahead of time (say, in a settings JSON file or some other method). I used a switch/case statement to set this up, but it turns out I cannot use variables as case expressions.
I have used the final keyword to mark them as constants, and this works for those defined as direct variables, but not those stored inside an array.
Is there a way of doing this to avoid either using a long if/elseif statement or splitting the array into multiple variables?
In case that's not clear (pun not intended), this is my current code:
// constants
final char[] teamHotkeys = {'b', 'y', 'p', 'o', 'r'};
final char animationHotkey = ' ';
final char doAllHotkey = 'a';
...
// keyPressed handler
void keyPressed(){
float[] chartArea = {gridSizeHeight * 2, gridSizeHeight * 22, gridSizeWidth * 1, gridSizeWidth * 23};
// check which key has been pressed
switch (key){
case teamHotkeys[0]:
drawBar(0, chartArea);
break;
case teamHotkeys[1]:
drawBar(1, chartArea);
break;
case teamHotkeys[2]:
drawBar(2, chartArea);
break;
case teamHotkeys[3]:
drawBar(3, chartArea);
break;
case teamHotkeys[4]:
drawBar(4, chartArea);
break;
case animationHotkey:
runAnimation();
break;
case doAllHotkey:
showFinalScores();
break;
}
}
The compiler can access animationHotkey and doAllHotkey fine, now they are constants, but it can't access the indices of teamHotkeys[] as only the array is a constant, but its members could technically have changed, but the compiler doesnt' know that they never change.
I would just use if statements. Sometimes the dumbest code is the best. It's the easiest to understand, and once it's written you can put it in a function somewhere and not really look at it very much.
But if you really want to avoid if statements, one approach you might take is to create a HashMap that maps character keys to runnable actions. Here's a very basic example:
HashMap<Character, Runnable> keyRunnableMap = new HashMap<Character, Runnable>();
void setup() {
Runnable aRunnable = new Runnable() {
public void run() {
println("A pressed.");
}
};
Runnable bRunnable = new Runnable() {
public void run() {
println("B pressed.");
}
};
keyRunnableMap.put('a', aRunnable);
keyRunnableMap.put('b', bRunnable);
}
void draw() {
}
void keyPressed() {
if (keyRunnableMap.containsKey(key)) {
keyRunnableMap.get(key).run();
}
}
This allows you to keep your keyPressed() logic very short, but it takes more code to set up. You could shorten this a little bit with Java 8 lambdas, but that won't work if you're using the current version of the Processing editor. I don't actually recommend this approach. Just stick with if statements.
Edit: You could also rely on the fact that behind the scenes, the key variable is a char type, which is actually a number. Lower-case 'a' is the number 97. More info here. Here's an example:
Runnable[] runnableArray = new Runnable[2];
void setup() {
Runnable aRunnable = new Runnable() {
public void run() {
println("A pressed.");
}
};
Runnable bRunnable = new Runnable() {
public void run() {
println("B pressed.");
}
};
runnableArray[0] = aRunnable;
runnableArray[1] = bRunnable;
}
void draw() {
}
void keyPressed() {
// a = 97, b = 98
if(key >= 'a' && key <= 'b'){
int index = key - 97;
runnableArray[index].run();
}
}
Again, I don't actually recommend this approach, as it's not any more readable than if statements.
Well, in C# a long switch is basically a HashMap, but in Java it is just... many if/else's, so I usually prefer HashMap when I can use it.
If you only want to know if your key is into a group (let's say, "teamHotkeys") you could use a HashMap<Character, String> or HashMap<Character, KeyType> (with KeyType as an enum), to map multiple keys to a same action. It still will be O(n) in the worst case, but since the keys are grouped it should be better than a lot of if/else's.
HashMap<Character, KeyType> keyTypePairs = new HashMap<Character, KeyType>();
switch(keyTypePairs.get(key)) {
case teamHotkeys:
// ...
break;
}
enum KeyType { teamHotkeys, otherType1, otherType2 }
And that's all, it should work if I did understand the question.
EDIT: With a quick test I can say the space ocuppied by the HashMap is between 2.3 and 3.5 kilobytes in the worst case. About 300 entries = null reserved space, 120 (int)keys and KeyType (each enum uses an 4 or 8 byte address depending on the CPU). Is not THAT much, but I'll take it in acount if I was you. Also, I say 300 as an aproximation; I don't have 120 keys so it could be much less or much more.

How to disable some enum and keep the enum value?

I wrote a library
This library accept the limited options and print the related string.
public class Lib {
public enum Num {
ZERO,
ONE,
TWO,
THREE
}
public static void main(String[] args) {
Lib obj = new Lib();
obj.print(Num.ONE);
}
public void print(Num num) {
switch (num) {
case ZERO:
System.out.println("ZERO is "+Num.ZERO.ordinal());
break;
case ONE:
System.out.println("ONE is "+Num.ONE.ordinal());
break;
case TWO:
System.out.println("TWO is "+Num.TWO.ordinal());
break;
case THREE:
System.out.println("THREE is "+Num.THREE.ordinal());
break;
default:
break;
}
}
}
In the new version, I will disable option ONE and TWO
public enum Num {
ZERO,
//ONE,
//TWO,
THREE
}
How can I keep the correct values after I disabled the options?
It is not clear what you are asking. If you change any piece of code and thereby "remove" "names" that formerly existed ... than of course, any "reference" to any of the deleted elements is ... first of all: broken.
In case of an enum, you might prefer to not rely on build-in ordinals; instead you could go for this:
enum Whatever {
ONE(1), TWO(2);
private final int value;
private Whatever(value) {
this.value = value;
}
public int getValue() { return value }
But you have to be really careful here. For example, if you are persisting enum objects (into some sort of database for example) then any such change (adding or removing enum "values") will lead to incompatibilities!
I am not sure of what you want to do, but for example you can do this:
public enum Num {
ZERO,
ONE,
TWO,
THREE
}
switch (num) {
case ZERO:
System.out.println("ZERO is "+Num.ZERO.ordinal());
break;
case THREE:
System.out.println("ZERO is "+Num.THREE.ordinal());
break;
case One:
case Two:
default:
break;
You might be disable some of enum now onward and keep stored as it is. To support both the things, you should have a method that returns list of enum that will populate on UI. I.E. List getPopulatedOnUi(). That contains those enum list that you needed.
Don't remove from definition itself. keep as it is. because that will throw error for existing as it might be stored into database.
You can modify the print() method as below: Instead of switch, you can use for loop and make the code little bit generic. Now, even when your enum values changes, you need not to make any changes in this code.
It will handle the case , If you disable some enum values in future.
public void print(Num num) {
for(Num n : Num.values()) {
if(n == num) {
System.out.println(n.name()+ " is " + n.ordinal());
break;
}
}
}

Get Random Functions from Main

public static GetRandomFunc() {
switch((int)(Math.random()*NUM_FUNCTIONS) {
case 0:
functionA();
break;
case 1:
functionB();
break;
case 2:
functionC();
break;
// ...
}
}
I want to call GetRandomFunc() in main randomly until each function has been called once and then it ends. How do I make sure a function would be called once only, and if all has been called, it prints out System.out.println("All done")
create a list containing 0,1 and 2. shuffle it and iterate over it to call each function once but in random order.
List<Integer> integers = Arrays.asList(0,1,2);
Collections.shuffle(integers)
for (Integer i: integers){
GetRandomFunc(i)
}
and your function will be
public static GetRandomFunc(int index) {
switch(index) {
case 0:
functionA();
break;
case 1:
functionB();
break;
case 2:
functionC();
break;
// ...
}
}
Use a list of Runnables (or of Integers mapping to each function, as you did in your code), shuffle it, then iterate through the list and call each function.
http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#shuffle%28java.util.List%29
Make a list of the functions and take from it at random. When it's empty, you can be sure you used every function exactly once.
public interface Function { void execute(); }
public static runFunctionsRandomly(List<Function> functions) {
while (!functions.isEmpty()) {
int index = Math.random() * functions.size();
Function f = functions.get(index);
f.execute();
functions.remove(index);
}
}
class ExampleFunction implements Function {
void execute() {
System.out.println("Hello world!");
}
}
...

Having trouble understanding how to maintain state using classes

I'm new to using OOP, I typically just put all my code in a single class and use methods. But I want to maintain state information and think classes are the best fit but I'm having trouble wrapping my head around it.
Say I have a list of items and I want to stop when the total sum of all previous items in the list equals X(in this case 10 so it takes item 1 + 2, then 2+3.etc..until it hits the threshold 10), I can use a method to calculate it but it involves me doing the entire process all over again when all I really need to do is increment by the last item and then see if my data exceeds the threshold. Here's my code so far but I know its not good because although it works its really just using the class as an independent method and recalculating on every loop. My goal is to,using this structure, reduce loops if not necessary to check thresholds.
Any suggestions?
Code:
public class LearningClassesCounter {
public static void main(String[] args) {
int[] list = new int[]{1,2,3,4,5,6,7,8,9,10};
int[] data_list = new int[list.length];
for (int current_location = 0; current_location<list.length;current_location++) {
//can only put commands in here. Nothing above.
Counter checker = new Counter(data_list);
System.out.println(checker.check_data(current_location));
for (int i =0; i<100; i++){
if (checker.check_data(current_location) == false) {
break;
}
data_list[current_location] = (list[current_location]+1); //this is just a random function, it could be any math function I just put it in here to show that some work is being done.
}
}
//its done now lets print the results
for (Integer item : data_list) {
System.out.println(item);
}
}
}
class Counter {
private int[] data_list;
private int total_so_far;
// create a new counter with the given parameters
public Counter(int[] data_list) {
this.data_list = data_list;
this.total_so_far = 0;
}
public boolean check_data(int current_location) {
// TODO Auto-generated method stub
int total_so_far = 0;
//System.out.println(total_so_far);
for (int item : data_list) {
total_so_far = item + total_so_far;
if (total_so_far >= 10) {
break;
}
}
if (total_so_far>=10) {
return false;
} else {
return true;
}
}
}
I don't need anyone to fix my code or anything(I want to do it myself, the code is just to give an idea of what I'm doing). I'm more interested in the flaw in my logic and maybe a way for me to better think about designing classes so I can apply them to my own situations better.
So the solution is that you do not update the data_list directly. Instead have a setter method in the Counter class that takes the index and value to update. It updates the value in the array and also updates a count value.
Something like this:
class Counter{
private final int[] list;
private count = 0;
private final maxCount = 10;
public Counter(int[] list){
this.list = list;
}
public boolean updateValueAndCheckPastMax(int index, int value){
list[index] = value;
count += value;
return count >= maxCount;
}
}
You are way over thinking this, and a counter class is not really necessary in this case.
I'm also interested as to why you'd be doing this line:
data_list[current_location] = (list[current_location]+1);
Do you want your data_list to be the same as list, but each value is incremented by 1?
If you are merely trying to return a sub-array of the values that are < 10, i would suggest just doing this in a for loop, and using an int as a counter.

Shorten lines of code in case statements inside switch block

I have 10 cases in my switch statement. Each of them does the same thing with the other except that the assignments are different. If I have to change 1 line of code (during development) in one case block then I have to change all other 9 cases manually.
Here are the scenarios of each case statements:
Each case contains long lines of code with many function calls and assignments.
Only variable assignments, function arguments, and if statement conditions vary.
There is no pattern/sequence in the assignment of variables and function arguments.
Adding helper functions and calling them on each case statements is almost impossible for some reason.
How do I optimize or shorten this?
To illustrate:
final int CONSTANT_A = 0;
final int CONSTANT_B = 1;
...
final int CONSTANT_J = 10;
int varA = 0;
int varB = 1;
...
int varJ = 10;
int anothervarA = 0;
int anothervarB = 1;
...
int anothervarJ = 10;
int action = 0;
switch(something) {
case 1:
... long lines of code here
// If I have to change the variables below
// then I have to update all other variables in
// other cases below
varA = CONSTANT_J;
anothervarA = CONSTANT_B;
... another long lines of code here
int ret = someObject.foo(varA);
... do something with ret.
action = 5;
break;
case 2:
... long lines of code here
varB = CONSTANT_I;
anothervarB = CONSTANT_C
... another long lines of code here
int ret = someObject.foo(varA);
... do something with ret.
action = 100;
break;
...
...
case 9:
... long lines of code here
varI = CONSTANT_B;
anothervarI = CONSTANT_A;
... another long lines of code here
int ret = someObject.foo(varA);
... do something with ret.
action = 100;
break;
case 10:
... long lines of code here
varK = CONSTANT_A;
anothervarJ = CONSTANT_F;
... another long lines of code here
int ret = someObject.foo(varA);
... do something with ret.
action = 4;
break;
}
Nothing obvious jumps out, except maybe to factor all that code into a set of classes (or an enum), and rely on polymorphism instead of switch to call the right one. So for instance, load your cases into a Map<Integer,Foo> -- or even a List<Foo> if it's not a sparse array -- and then replace the switch with myFoos.get(something).whatever();.
As for assigning the variables when you're done, if they're member variables you could have the Foos set them directly; if this is always called in a single-threaded environment, you could have foo.whatever() set up state and then have getters. If it's in a multi-threaded environment, you could have whatever() return back a new object with those getters. Something like:
FooResult result = myFoos().get(something).getResult(whatever, args);
varA = result.getA();
action = result.getAction();
etc
Given your criteria, I don't think there is much you can do. If there is no pattern in what you are calling or assigning then it's going to be pretty hard to optimize this. It looks like there is some code that is common that could be pulled out into helper methods but then you say:
Adding helper functions and calling them on each case statements is
almost impossible for some reason.
I'm not really sure what this means but if you cannot create helper methods for some reason, I don't think there is anything you can do.
You could put the shared code outside the switch statement, and separate the switch statement into multiple switches so the shared code can go in between:
// declare & initialize variables
//... long lines of code here
// first switch: only assign values
switch(something) {
case 1:
varA = CONSTANT_J;
anothervarA = CONSTANT_B;
break;
// more cases...
}
//... another long lines of code here
// second switch: only call the method someObject.foo(???);
switch(something) {
case 1:
int ret = someObject.foo(varA);
break;
// more cases...
}
//... do something with ret.
// third switch: assign the action value
switch(something) {
case 1:
action = 5;
break;
// more cases...
}
This lets you write the repeated code only once at the cost of having multiple switch statements, which add lots of extra case and break lines.
Depending on the situation, you might be able to use arrays to completely get rid of the switch statements. For example, you could make an array of all the action values and then assign action the element at index something - 1:
int[] actionValues = { 5, 100, \*...,*\ 100, 4};
action = acionValues[something - 1];
This could also be applied to the variable initialization, although it would be tricky. You'd have to store all the variables and constants in arrays, and either find a mathematical pattern or hardcode a set of rules for each case (each rule contains the index of a constant and the index of a variable to assign it to). To still access the variables and constants by their name (as opposed to index), you could make getters and setters:
int getVarA() { return varArray[0]; }
void setVarA(int val) { varArray[0] = val; }
int getVarB() { return varArray[1]; }
void setVarB(int val) { varArray[1] = val; }
int CONSTANT_A() { return constArray[0]; } // no need for a setter
For the first case, the rules might be
assign constant at index 9 (CONSTANT_J) to variable at index 0 (varA)
assign constant at index 1 (CONSTANT_B) to variable at index 26 (anothervarA)
You can store these rules in an array, and store the rule-arrays for each case in an array of arrays:
int[][] rules = {
/* rules for case 1 */
{ 9, 0, 1, 26 }, /* interpret as: const9 -> var0, const1 -> var26 */
/* rules for other cases */
};
To 'execute' the rules for the case:
int c = something - 1; // give the case a short name to save typing
varArray[ rules[c][1] ] = constArray[ rules[c][0] ];
varArray[ rules[c][3] ] = constArray[ rules[c][2] ];

Categories