I've got an assignment I can't figure out, any pointers will be much appreciated, it goes like so:
There's a series of light bulbs represented as an array of true/false, there's a switch for every light bulb, by clicking it for any light bulb, you toggle it as well as 2 adjacent ones (1 from left & another 1 from right; if clicked switch's bulb on edge -- only 1 adjacent toggled of course).
What is needed to accomplish is a method that accepts an array of a series of turned on/off light bulbs and another one representing another state of supposedly the 1st array after some switches have been clicked..!
So recursion must be used to find out whether there's a combination of switch clicks that will transform array 1 to array 2.
Here's the signature of the method:
public static boolean disco(boolean[] init, boolean[] target)
Will return true if array init can be transformed to target, false otherwise.
Method must be static and not use loops & any other static and global variables, only local.
Example:
boolean[] init = {true, false, true, false, true, false};
boolean[] target = {false, true, false, true, false, true};
For above 2 arrays, disco(init, target) will return true because toggling the 1st and 4th bulbs would yield the target state (remember adjacent bulbs being toggled as well).
new version
public static boolean disco(boolean[] init, boolean[] target)
{
return recurse(init,boolean,0);
}
public static boolean recurse(boolean[] init, boolean[] target, int min)
{
if (min == init.length)
if (init == target)
return true;
else
return false;
boolean[] temp = "init with a change at min";
boolean a = recurse(init, target, min+1);
boolean b = recurse(temp, target, min+1);
return a||b;
}
new new version
I've broken it down to three cases:
Case 1: length %3 = 0
By changing the first bulb and the second bulb, you can affect a change on only the 3rd.
Then a change to 4 and 5 will make the 6th the only one changed. We see that we can change every bulb with index divisible by 3.
Working backwards (starting at the end) we can do the same but this time it shows us we can change bulbs with indices (i+1) divisible by 3.
Combining the two, we see that if we want to change an index 0,1 mod 3 we can. But then to change a 2, we simply have to change a neighboring 0,1 pair and then do a change on the middle one. So in all cases these are solvable.
Case 2: length %3 = 1
Just like the first case, but we can affect single changes at 0,2 mod 3, and thus squeeze the 1 mod 3 cases.
Case 3: length %3 = 2
Working forward and backwards only yields cases 0 mod 3. The only remaining moves we have make two changes to the bulbs (since we can ignore any changes to positions 0). Changing a 1 or 2 will reverse the position surrounded by two 0's whereas changing a 0 will swap the parity in adjacent blocks of 1,2 which have a 0 between them (it's easier if you draw it). But what I've shown so far is that the 0's can all be corrected and in any adjacent 1,2 you can fix both if they are wrong without changing anything else. If one is wrong then you propagate a change to an adjacent pair of 1,2. This change can be moved if necessary. What this means is that any even number of errors in 1,2 positions can be fixed, but an odd number cannot. All errors at position 0's can be fixed.
public static boolean disco(boolean[] init, boolean[] target)
{
if (init.length%3 == 0 || init.length%3 == 1)
return true;
return recurse(init,target,0, true);
}
public static boolean recurse(boolean[] init, boolean[] target, int index, boolean even)
{
if (index = init.length)
return even;
if (init[index] != target[index] && index%3 != 0)
even = !even;
return recurse(init, target, index+1, even);
}
So here's in words how I would do it:
If there are just less than or equal 3 bulbs left, it's quite easy to check wether they can be switched so that it's correct.
If there are more than three bulbs, do the following:
Check, if the first bulb is correct. If so, go on recursively with the subarray beginning at the second bulb.
If the first bulb is not correct, switch the second bulb (switching the first bulb won't work because previous bulbs are switched back then). Now, the first bulb is correct. Go on with the subarray beginning at the second bulb.
Hint: Let a1, a2, ..., ak, ..., an be the input and b1, b2, ..., bk, ..., bn be the desired output.
You can recursively test the left and right sides and then combine the result. The tricky part is combining the result.
Start with the left side.
Test a1, a2, ..., ak, true to b1, b2, ..., bk, true.
if true, then test a1, a2, ..., ak to b1, b2, ..., bk.
if true then the solution from a1, a2, ..., ak to b1, b2, ..., bk can not include toggling the kth switch
if false then the solution from a1, a2, ..., ak to b1, b2, ..., !bk must include toggling the kth switch
if false, then test a1, a2,...,ak to b1, b2,...,bk
if true then the solution from a1,a2, ..., ak to b1, b2 ,.., bk must include toggling the kth switch
if false, then the soluation from a1,a2,...,ak to b1, b2,...,!bk can not include toggling the kth switch
After two tests on the left side, you can perform similar tests on the right side. You will be able to combine the values of the test, because you will know whether the kth switch was toggled or not.
Thanks all for your help, this is what I came up with:
public static boolean disco(boolean[] init, boolean[] target)
{
if (java.util.Arrays.equals(init, target)) {
return true;
} else {
return disco(init, target, 0);
}
}
private static boolean disco(boolean[] init, boolean[] target, int i)
{
if (i > init.length-1) {
return false;
}
disco(init, target, i+1);
boolean t = false;
if (init[i] != target[i]) {
switchBulb(init, target, i);
}
if (java.util.Arrays.equals(init, target)) {
t = true;
}
return t;
}
private static void switchBulb(boolean[] init, boolean[] target, int i)
{
if ( (i > 1) && (init[i-1] != target[i-1]) && (init[i-2] != target[i-2]) ) {
// If there's a series of 3 opposite-to-target bulbs, switch the middle one & from both sides
init[i-1] = !init[i-1];
init[i] = !init[i];
init[i-2] = !init[i-2];
} else if (i > 0 && i < init.length-1) {
// There's only 1 bulb or 2 adjacent bulbs that are opposite of target.
if (i == 1 && (init[0] != target[0]) ) {
// First 2 bulbs are opposite of target's, so switch the 1st one.
init[i-1] = !init[i-1];
init[i] = !init[i];
} else if ( (i == init.length-2) && (init[i+1] != target[i+1]) ) {
init[i+1] = !init[i+1];
init[i] = !init[i];
} else {
init[i] = !init[i];
init[i-1] = !init[i-1];
init[i+1] = !init[i+1];
}
} else {
// First bulb or last bulb.
init[i] = !init[i];
if (i == 0) {
init[i+1] = !init[i+1];
} else {
init[i-1] = !init[i-1];
}
}
}
I feel my use of recursion here is minimal, could be much cleaner if recursion was used properly. Any thoughts?
I'm talking about the switchBulb function, it could be swapped with a little bit more sophisticated recursion logic, or am I wrong?
As in, if you simply iterate over the bulbs one by one and compare to the target array, you won't necessary get it right for ALL combinations of bulbs (see example), so how do you mimic random bulb switching with recursion? Or is there a pattern? There must be, if not, how would it know when to stop?
I think I got the solution, will post later if anyone's interested...
Related
I have a 2d array that generates terrain using perlin noise, and then places a (3D) block at a specific height - Before you click away, all I need help with is the 2D array that generates the "height-map". I am trying to figure out whether or not the block next to it is at the same elevation (if it is "neighboring" or not) by checking the values directly up, down, left, and right in the 2D array. If they are equal, then they are at the same elevation, and therefore "neighbors". if the problem that I am running into is that the check is always returning true for all the neighbors, even if the block has no neighbors.
A small example of the perlin noise height map
151514141312121111
151414131313121211
141414131312121211
141313131312121211
131313121212121111
131312121212111111
121212121111111111
111111111110101111
111111111010101111
111111111010101010
111111111010101010
101011101010101010
101010101099109999
991010109999988889
999109999888888999
and here is the checking code, you will have to see the entire file, linked below for context
if (terrain[x][leftColumn] == terrain[x][z]) {
neighbors[2] = true; // left side
}
if (terrain[x][rightColumn] == terrain[x][z]) {
neighbors[3] = true; //right side
}
if (terrain[belowRow][z] == terrain[x][z]) {
neighbors[4] = true; // front side (below)
}
if (terrain[aboveRow][z] == terrain[x][z]) {
neighbors[5] = true; // back side (above)
}
Pastebin: https://www.pastiebin.com/5d5c5416391ec
any help is appreciated, Asher
Move this static variable initialization
boolean[] neighbors = new boolean[]{false, false, false, false, false, false};
inside the inner loop, where you check each block's neighbors, to instantiate a new neighbors array for each individual block. Right now neighbors is a static variable. You never reset the values on the neighbors array so it remains true after each iteration.
edit:
Also
if (belowRow > 1) {
belowRowExists = false;
belowRow = 0;
}
if (rightColumn > - 1) {
rightColumnExists = false;
rightColumn = 0;
}
is wrong, you want to check if the column or row is out of bounds right? Then you want to see if they are >= chunkSize.
my problem is that this is sound logic but the execution is incorrect (the submit server won't take it). So I'm trying to check if my hand of 5 cards has a straight (that's 2, 3, 4, ,5 6, etc. numbers in consecutive order) and then if the fifth card is an ace i want it to evaluate as the value 10 so it'd be like 6 7 8 9 A(A has a card value of 1) and this is my current code
public static boolean hasStraight(Card [] cards) {
boolean isTrue = false;
for(int atPos =0; atPos<cards.length-1; atPos++){
Card ogCard = cards[atPos];
Card notOgCard = cards[atPos+1];
if (ogCard.getValue() == (notOgCard.getValue()-1)){
if ((cards[3]).getValue()==9){
if (cards[4].getValue() ==1);
isTrue = true; //accounting for ace in last position
}
else if(ogCard.getValue() == (notOgCard.getValue()-1)){
isTrue = true; //accounting for ace not in first position
}
}
}
return isTrue;
}
this is what I have so far not sure what's next.
Your code seems to be going the wrong way.
First you set isTrue to false, but then set it to true any time the array is in strictly increasing order. Thus, it will resolve as true if just the first two are 1,2.
I would set it to true in the beginning, then make it false if they array is ever not in increasing order.
Your constructions of ifs and else ifs are also...interesting.
The if ((cards[3]).getValue()==9){ line will most likely never run as you want it to, as ogCard.getValue() == (notOgCard.getValue()-1) will not be true (and thus the second if statement will never run) when the ace is in the last position. I would just remove the wrapping if statement, as it doesn't really test anything useful.
Your described method also doesn't handle valid aces not in the last position.
My recommendation would look something like this:
public static boolean hasStraight(Card [] cards) {
boolean isTrue = true;
for(int atPos =0; atPos<cards.length-1; atPos++){
Card ogCard = cards[atPos];
Card notOgCard = cards[atPos+1];
if (! (ogCard.getValue() == (notOgCard.getValue()-1) || (ogCard.getValue()==9&¬OgCard.getValue()==1) ) ) {
isTrue=false;
}
}
return isTrue;
}
So I'm currently making a game where the instructions are to move left or right within an array using the integer stored at a marked index (circle in this case) until we can get the circle to the last index of the array. The last integer of the array is always 0.
For example,
[4] 1 2 3 1 0, here we start at the circle 0 (index)
We move 4 to the right, 4 1 2 3 [1] 0
Then 1 time to the right, 4 1 2 3 1 [0]. Here the game stops and we win.
My code is as follows for a recursive method:
public static boolean rightWing (int circle, int[] game, List<Integer> checkerList){
int last = game.length-1;
if (circle == last){ // base case for recursion
return true;
}
if (circle < 0){ // if we go out of bounds on the left
return false;
}
if (circle > last){ // if we go out of bounds on the right
return false;
}
if (checkerList.contains(circle)){ // check for the impossible case
return false;
}
checkerList.add(circle); // adds the circle value for the last check to checkerList so we can check for the impossible case
int moveRight = circle + game[circle]; // these two integers help the game move according to the value of the int at circle
int moveLeft = circle - game[circle];
return rightWing( moveRight, game, checkerList) || rightWing(moveLeft, game,checkerList);
}
This works great, but the only problem is it's recursive and slow. I'm trying to redesign it using loops and stacks/queues to make it more efficient, but I'm stuck after writing this (in pseudo):
Boolean rightWing (int circle, List<int> game, List<int> checkerList)
Int lastPlace = game.size() - 1
For int i <- 0 to game.size() - 1 do
If i equals lastPlace then // returns true when i is at the last position of the game
Return true
Any input on how to go forward would be appreciated!
The most important bit: when debugging app for the slowness, you should collect some performance data first to identify where your app is spending the most of its time. Otherwise fixing performance is inefficient. You can use jvisualvm it's bundled with jdk.
Data structures rule the world of performance
One thing why it can be slow is because of this:
if (checkerList.contains(circle)){ // check for the impossible case
return false;
}
The more items you have in the list, the slower it becomes. List has linear complexity for the contains method. You can make it constant complexity if you'll use HashSet. E.g. if you have list with 100 elements, this part will be around slower 100 times with List than with HashSet.
Another thing which might be taking some time is boxing/unboxing: each time you put element to the list, int is being wrapped into new Integer object - this is called boxing. You might want to use IntSet to avoid boxing/unboxing and save on the GC time.
Converting to the iterative form
I won't expect this to affect your application speed, but just for the sake of completeness of the answer.
Converting recursive app to iterative form is pretty simple: each of the method parameters under the cover is stored on a hidden stack on each call of your (or others function). During conversion you just create your own stack and manage it manually
public static boolean rightWingRecursive(int circle, int[] game) {
Set<Integer> checkerList = new HashSet<Integer>();
Deque<Integer> statesToExplore = new LinkedList<>();
int last = game.length - 1;
statesToExplore.push(circle);
while (!statesToExplore.isEmpty()) {
int circleState = statesToExplore.pop();
if (circleState == last) { // base case for recursion
return true;
}
if (circleState < 0) { // if we go out of bounds on the left
continue;
}
if (circleState > last) { // if we go out of bounds on the right
continue;
}
if (checkerList.contains(circle)) { // check for the impossible case
continue;
}
checkerList.add(circle); // adds the circle value for the last check to
// checkerList so we can check for the
// impossible case
int moveRight = circle + game[circle]; // these two integers help the
// game move according to the
// value of the int at circle
int moveLeft = circle - game[circle];
statesToExplore.push(moveRight);
statesToExplore.push(moveLeft);
}
return false;
}
I am making a simple app where you have to toggle buttons/booleans trying to guess the correct combination. I was wondering the simplest way to compare the toggles booleans against the "right" combination. For example if user has:
boolean 1: true
boolean 2: false
Boolean 3: true
but the correct combination is:
boolean 1: true
boolean 2: true
Boolean 3: true
I want the user to see a message that says you have 2 out of 3 correct. I have
public void go(View view){
if (bool1 == true && boo12 == true && bool3 == true) {
// do this
} else {
// display the correct amount of booleans the user has correct.
}
}
Create a BitSet for the correct combination (set the bits that correspond to "true", clear the bits that correspond to "false").
When you want to check the user's input, create a BitSet from the buttons that are pressed (set "true", clear "false").
Correctness can be checked with correctValue.equals(usersAttempt).
A count can be obtained by doing usersAttempt.xor(correctValue) then usersAttempt.cardinality() will return the number of incorrect values.
This requires a bare minimal amount of coding. For your example:
// Correct: [true,true,true]
BitSet correct = new BitSet(3);
correct.set(0); // <= true
correct.set(1); // <= true
correct.set(2); // <= true
// User's attempt (buttonN.isChecked() is just placeholder, drop in whatever
// code you actually use to get the state of your buttons):
BitSet attempt = new BitSet(3);
attempt.set(0, button0.isChecked()); // <= true in your example
attempt.set(1, button1.isChecked()); // <= false in your example
attempt.set(2, button2.isChecked()); // <= true in your example
// Check answer (produces false in your example):
boolean matchIsPerfect = attempt.equals(correct);
// Get the count (produces 1 in your example):
attempt.xor(correct);
int incorrectCount = attempt.cardinality();
// To get the correct count just subtract 'incorrectCount' from total.
// Another way to check if attempt is correct is 'if (incorrectCount == 0)'.
// Note that the remaining bits set in 'attempt' after the above xor()
// will correspond to the individual inputs that weren't correct.
This will let you support any size, the code is clear and you don't need to do any of the logic on your own. Note that you can simplify the button -> user's attempt setup if you have an array of buttons or can access user input given an index.
If the conditions are not always to be true, say bool3 needs to be false, you can use something like this maybe. Otherwise, as the other answers mentioned, an array would work best probably.
int correctCount = 0;
if (bool1) correctCount++;
if (bool2) correctCount++;
if (!bool3) correctCount++;
if (correctCount == 3) {
// do this
} else {
Toast.makeText(context, String.valueOf(correctCount) + " out of 3 correct", Toast.LENGTH_LONG).show();
}
Assuming that your "right" combination will include both true and false values, the following method will return the number of matches, or -1 if the array lengths don't match:
private int getMatches(boolean[] toggleValues, boolean[] matchPattern)
{
if(toggleValues.length != matchPattern.length)
return -1;
int matches = 0;
for (int j = 0; j < toggleValues.length; j++)
{
if(toggleValues[j] == matchPattern[j])
{
matches++;
}
}
return matches;
}
As an example, if you have 3 ToggleButtons, tb1, tb2, and tb3, the following will return 2:
tb1.setChecked(true);
tb2.setChecked(false);
tb3.setChecked(false);
final boolean[] matchPattern = {true, false, true};
final boolean[] toggleValues = {tb1.isChecked(), tb2.isChecked(), tb3.isChecked()};
int matches = getMatches(toggleValues, matchPattern);
This method will allow you to easily change the matching pattern without changing code, e.g by reading stored values into the matchPattern array from a file or SharedPreferences.
you can do it, as the number of boolean values can be more than 3. you may want to use for loop (easy way) and iterate it for the end of the value and return the number of counts to the value k. here k-> number of true boolean values and b is an array containing the array of boolean values.
public void go(View view){
boolean b[]={bool1,bool2,bool3,bool4,bool5,bool6,bool7,bool8,bool9,bool10};
int k=0;
for(int i=0;i<b.length;i++)
{
if(b[i]==true)
{
k++;
}
}
if(k==b.length)
{
do task
}
else
{
Toast.makeText(getApplicationContext(), k+ "out of "+b.length+ "correct",Toast.LENGTH_LONG).show();
}
}
I'm training code problems like UvA and I have this one in which I have to, given a set of n exams and k students enrolled in the exams, find whether it is possible to schedule all exams in two time slots.
Input
Several test cases. Each one starts with a line containing 1 < n < 200 of different examinations to be scheduled.
The 2nd line has the number of cases k in which there exist at least 1 student enrolled in 2 examinations. Then, k lines will follow, each containing 2 numbers that specify the pair of examinations for each case above.
(An input with n = 0 will means end of the input and is not to be processed).
Output:
You have to decide whether the examination plan is possible or not for 2 time slots.
Example:
Input:
3
3
0 1
1 2
2 0
9
8
0 1
0 2
0 3
0 4
0 5
0 6
0 7
0 8
0
Ouput:
NOT POSSIBLE.
POSSIBLE.
I think the general approach is graph colouring, but I'm really a newb and I may confess that I had some trouble understanding the problem.
Anyway, I'm trying to do it and then submit it.
Could someone please help me doing some code for this problem?
I will have to handle and understand this algo now in order to use it later, over and over.
I prefer C or C++, but if you want, Java is fine to me ;)
Thanks in advance
You are correct that this is a graph coloring problem. Specifically, you need to determine if the graph is 2-colorable. This is trivial: do a DFS on the graph, coloring alternating black and white nodes. If you find a conflict, then the graph is not 2-colorable, and the scheduling is impossible.
possible = true
for all vertex V
color[V] = UNKNOWN
for all vertex V
if color[V] == UNKNOWN
colorify(V, BLACK, WHITE)
procedure colorify(V, C1, C2)
color[V] = C1
for all edge (V, V2)
if color[V2] == C1
possible = false
if color[V2] == UNKNOWN
colorify(V2, C2, C1)
This runs in O(|V| + |E|) with adjacency list.
in practice the question is if you can partition the n examinations into two subsets A and B (two timeslots) such that for every pair in the list of k examination pairs, either a belongs to A and b belongs to B, or a belongs to B and b belongs to A.
You are right that it is a 2-coloring problem; it's a graph with n vertices and there's an undirected arc between vertices a and b iff the pair or appears in the list. Then the question is about the graph's 2-colorability, the two colors denoting the partition to timeslots A and B.
A 2-colorable graph is a "bipartite graph". You can test for bipartiteness easily, see http://en.wikipedia.org/wiki/Bipartite_graph.
I've translated the polygenelubricant's pseudocode to JAVA code, in order to provide a solution for my problem. We have a submission platform (like uva/ACM contests), so I know it passed even in the problem with more and hardest cases.
Here it is:
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Scanner;
/**
*
* #author newba
*/
public class GraphProblem {
class Edge {
int v1;
int v2;
public Edge(int v1, int v2) {
this.v1 = v1;
this.v2 = v2;
}
}
public GraphProblem () {
Scanner cin = new Scanner(System.in);
while (cin.hasNext()) {
int num_exams = cin.nextInt();
if (num_exams == 0)
break;
int k = cin.nextInt();
Hashtable<Integer,String> exams = new Hashtable<Integer, String>();
ArrayList<Edge> edges = new ArrayList<Edge>();
for (int i = 0; i < k; i++) {
int v1 = cin.nextInt();
int v2 = cin.nextInt();
exams.put(v1,"UNKNOWN");
exams.put(v2,"UNKNOWN");
//add the edge from A->B and B->A
edges.add(new Edge(v1, v2));
edges.add(new Edge(v2, v1));
}
boolean possible = true;
for (Integer key: exams.keySet()){
if (exams.get(key).equals("UNKNOWN")){
if (!colorify(edges, exams,key, "BLACK", "WHITE")){
possible = false;
break;
}
}
}
if (possible)
System.out.println("POSSIBLE.");
else
System.out.println("NOT POSSIBLE.");
}
}
public boolean colorify (ArrayList<Edge> edges,Hashtable<Integer,String> verticesHash,Integer node, String color1, String color2){
verticesHash.put(node,color1);
for (Edge edge : edges){
if (edge.v1 == (int) node) {
if (verticesHash.get(edge.v2).equals(color1)){
return false;
}
if (verticesHash.get(edge.v2).equals("UNKNOWN")){
colorify(edges, verticesHash, edge.v2, color2, color1);
}
}
}
return true;
}
public static void main(String[] args) {
new GraphProblem();
}
}
I didn't optimized yet, I don't have the time right new, but if you want, you/we can discuss it here.
Hope you enjoy it! ;)