Wolfram Elementary Cellular Automata Using Processing - java

I'm using a piece of code taken from the website The Nature of Code - https://natureofcode.com/book/chapter-7-cellular-automata/ - the portion I used was from example 7.1. I'm trying to create a one-dimensional cellular automaton using the Processing IDE, but I keep getting an error saying that brackets are missing from particular locations.
Errors:
-Missing curlry bracket "}", line 32
-Syntax error on "}", delete this, line 40
I've gone over it multiple times, but I can't see how this is wrong. Though I did try changing them as it says, only to get more errors. I thought maybe they were just in the wrong place, but I also can't see how that's the case. They seem to be correct as far as I can tell, but maybe I'm missing something. This is my first time using Processing, and it's been a long time since I last used Java. So maybe I'm mistaken.
class CA {
int[] cells;
int[] ruleset;
int w = 10;
// The CA should keep track of how
// many generations.
int generation = 0;
CA() {
cells = new int[width/w];
ruleset = new int[]{0,1,0,1,1,0,1,0};
cells[cells.length/2] = 1;
}
// Function to compute the next generation
void generate() {
int[] nextgen = new int[cells.length];
for (int i = 1; i < cells.length-1; i++) {
int left = cells[i-1];
int me = cells[i];
int right = cells[i+1];
nextgen[i] = rules(left, me, right);
}
cells = nextgen;
// Increment the generation counter.
generation++;
}
int rules(int a, int b, int c) {
String s = "" + a + b + c;
int index = Integer.parseInt(s,2);
return ruleset[index];
}
for (int i = 0; i < cells.length; i++) {
if (cells[i] == 1) fill(0);
else fill(255);
// Set the y-location according to the generation.
rect(i*w, generation*w, w, w);
}
}
The program is supposed to print each generation of the one-dimensional CA on top of the next.

The for-loop in the end of the CA class is not supposed to be there. That is why you get the error: the parser expects either a method declaration or the end of the class, hence a curly bracket.
It looks like this loop is actually drawing the CA state, so you can try to wrap it in a void draw(){} method. Then it should be syntactically correct, not sure though whether it works as expected. Alternatively move the for-loop outside of the class and call fill based on the the cells state of an instance of the CA class.
In any case, will need some additional code that creates the CA instance and invokes the generate function.

Related

Recursive backtracking in Java for solving a crossword

I need to solve a crossword given the initial grid and the words (words can be used more than once or not at all).
The initial grid looks like that:
++_+++
+____+
___+__
+_++_+
+____+
++_+++
Here is an example word list:
pain
nice
pal
id
The task is to fill the placeholders (horizontal or vertical having length > 1) like that:
++p+++
+pain+
pal+id
+i++c+
+nice+
++d+++
Any correct solution is acceptable, and it's guaranteed that there's a solution.
In order to start to solve the problem, I store the grid in 2-dim. char array and I store the words by their length in the list of sets: List<Set<String>> words, so that e.g. the words of length 4 could be accessed by words.get(4)
Then I extract the location of all placeholders from the grid and add them to the list (stack) of placeholders:
class Placeholder {
int x, y; //coordinates
int l; // the length
boolean h; //horizontal or not
public Placeholder(int x, int y, int l, boolean h) {
this.x = x;
this.y = y;
this.l = l;
this.h = h;
}
}
The main part of the algorithm is the solve() method:
char[][] solve (char[][] c, Stack<Placeholder> placeholders) {
if (placeholders.isEmpty())
return c;
Placeholder pl = placeholders.pop();
for (String word : words.get(pl.l)) {
char[][] possibleC = fill(c, word, pl); // description below
if (possibleC != null) {
char[][] ret = solve(possibleC, placeholders);
if (ret != null)
return ret;
}
}
return null;
}
Function fill(c, word, pl) just returns a new crossword with the current word written on the current placeholder pl. If word is incompatible with pl, then function returns null.
char[][] fill (char[][] c, String word, Placeholder pl) {
if (pl.h) {
for (int i = pl.x; i < pl.x + pl.l; i++)
if (c[pl.y][i] != '_' && c[pl.y][i] != word.charAt(i - pl.x))
return null;
for (int i = pl.x; i < pl.x + pl.l; i++)
c[pl.y][i] = word.charAt(i - pl.x);
return c;
} else {
for (int i = pl.y; i < pl.y + pl.l; i++)
if (c[i][pl.x] != '_' && c[i][pl.x] != word.charAt(i - pl.y))
return null;
for (int i = pl.y; i < pl.y + pl.l; i++)
c[i][pl.x] = word.charAt(i - pl.y);
return c;
}
}
Here is the full code on Rextester.
The problem is that my backtracking algorithm doesn't work well. Let's say this is my initial grid:
++++++
+____+
++++_+
++++_+
++++_+
++++++
And this is the list of words:
pain
nice
My algorithm will put the word pain vertically, but then when realizing that it was a wrong choice it will backtrack, but by that time the initial grid will be already changed and the number of placeholders will be reduced. How do you think the algorithm can be fixed?
This can be solved in 2 ways:
Create a deep copy of the matrix at the start of fill, modify and return that (leaving the original intact).
Given that you already pass around the matrix, this wouldn't require any other changes.
This is simple but fairly inefficient as it requires copying the matrix every time you try to fill in a word.
Create an unfill method, which reverts the changes made in fill, to be called at the end of each for loop iteration.
for (String word : words.get(pl.l)) {
if (fill(c, word, pl)) {
...
unfill(c, word, pl);
}
}
Note: I changed fill a bit as per my note below.
Of course just trying to erase all letter may erase letters of other placed words. To fix this, we can keep a count of how many words each letter is a part of.
More specifically, have a int[][] counts (which will also need to be passed around or be otherwise accessible) and whenever you update c[x][y], also increment counts[x][y]. To revert a placement, decrease the count of each letter in that placement by 1 and only remove letters with a count of 0.
This is somewhat more complex, but much more efficient than the above approach.
In terms of code, you might put something like this in fill:
(in the first part, the second is similar)
for (int i = pl.x; i < pl.x + pl.l; i++)
counts[pl.y][i]++;
And unfill would look something like this: (again for just the first part)
for (int i = pl.x; i < pl.x + pl.l; i++)
counts[pl.y][i]--;
for (int i = pl.x; i < pl.x + pl.l; i++)
if (counts[pl.y][i] == 0)
c[pl.y][i] = '_';
// can also just use a single loop with "if (--counts[pl.y][i] == 0)"
Note that, if going for the second approach above, it might make more sense to simply have fill return a boolean (true if successful) and just pass c down to the recursive call of solve. unfill can return void, since it can't fail, unless you have a bug.
There is only a single array that you're passing around in your code, all you're doing is changing its name.
See also Is Java "pass-by-reference" or "pass-by-value"?
You identified it yourself:
it will backtrack, but by that time the initial grid will be already
changed
That grid should be a local matrix, not a global one. That way, when you back up with a return of null, the grid from the parent call is still intact, ready to try the next word in the for loop.
Your termination logic is correct: when you find a solution, immediately pass that grid back up the stack.

How to draw a triangle in a 2D array (Java)

For a class project we need to be able to draw a triangle in a 2D array of chars. Algorithmically I can't work out how to do it.
My current code is this (but it does not work):
public void fill() {
for (int i = 0; i < h; i++) {
double x=h;
while(x<=0){
drawing.setPoint(i, x, myChar);
x=Math.ceil(x/2);
}
}
}
I want the output to look something like this:
....*....
...***...
..*****..
.*******.
*********
We can't use any pre-existing methods or classes that relate to drawing.
Thanks for your help
Based on your drawing, you need 9 columns for 5 rows. So,
int height = 5;
int width = 2*height - 1;
Even though I'm not sure what drawing.setPoint(i, x, myChar); does, I think this example will get you going. I will build a String based on chars.
char fill = '*';
char blank = '.';
I'll start the rows at 0 but the columns at 1 to make the math a little clearer.
For row = 0, ....*.... you need one star in column = 5.
For row = 1, ...***... you need three stars in column = 4,5,6.
For row = 3, .*******. you need seven stars in column = 2,3,4,5,6,7,8.
Notice that for row i you need a star in column j if the distance between the height = 5 and the column j is less than or equal to i. That is, when | height - column | <= row
for (int row = 0; row < height; row ++) {
StringBuilder line = new StringBuilder(width);
for (int column = 1; column <= width; column ++) {
char out = Math.abs(column - height) <= row ? fill : blank;
line.append(out);
}
System.out.println(line);
}
This yields
....*....
...***...
..*****..
.*******.
*********
I assume you can use Math.abs since your example has Math.ceil. If not, you can convert Math.abs to an if statement.
There are lots of ways to tackle this, and you've already seen one answer which draws the picture row-by-row.
I'm going to assume that you've already got routines to create char[][] and to print the characters in that array of arrays to the screen. It looks as if you already have a setPoint() method too, to poke a point into the structure.
As a beginner, I don't think it helps you to be given a solution. You need to be pointed in the right direction to solve it yourself.
Lots of experienced coders now use Test Driven Design, and you could learn from this: start with a simple case, create a test for that, make that test pass, repeat with more tests until there are no more tests to write.
Eventually you should learn a test framework like jUnit, but for now you can "test" by just running your program. So the first test is, does it work for height == 1?
You can pass this test (for now that means, run the program and see that the output looks right) with:
public void drawTriangle(int height) {
drawing.setPoint(0,5,'*')
}
Job done.
Now to make it work for height==2:
public void drawTriangle(int height) {
drawing.setPoint(0,5,'*');
if(height == 2) {
drawing.setPoint(1,4,'*');
drawing.setPoint(1,5,'*');
drawing.setPoint(1,6,'*');
}
}
This still works for height == 1, but also works for height == 2.
But you can immediately see an opportunity for a loop to replace those three commands for the second row. So:
public void drawTriangle(int height) {
drawing.setPoint(0,5,'*');
if(height == 2) {
for(int 4; i<7; i++) {
drawing.setPoint(1,i,'*');
}
}
}
... and you can pull that out into a method:
public void drawTriangle(int height) {
drawing.setPoint(0,5,'*');
if(height == 2) {
drawRow2();
}
}
private void drawRow2() {
for(int 4; i<7; i++) {
drawing.setPoint(1,i,'*');
}
}
This is called refactoring -- writing something that works, but isn't written the best way, testing it to ensure it works, then changing the way it's written one step at a time, so it still works, but in a tidier way.
Hopefully you can see where this is going. You can modify drawRow2() to be more general -- drawRow(int rowNumber), and gradually replace the literal numbers in there with variables derived from rowNumber. Then you can use drawRow(0) to draw the first row, and drawRow(1) to draw the second. Then you can draw a three row triangle by adding drawRow(2), and then you can improve that by using a loop instead.

Java Android trying to place a 10*10 grid over a bitmap to see how much of a colour is in each grid section

to describe my issue I must first discuss what I am trying to do, http://i.imgur.com/rcHwze5.png here is an image of a letter with a 10*10 grid over it. For every box in the grid if 1/3 of the pixels are colored a 1 is added to the ArrayList, otherwise a 0 is added. Here is my 3 methods that I have created to do this: https://gist.github.com/VincentMc/7ddf3c282e80bbff7835 BoundBM is a bitmap object with the letter drawn onto it.
Here is an image of my desired output http://i.imgur.com/B0QnUW8.png
Here is an image of my actual output http://i.imgur.com/WgRVXLv.png
It seems once a 1 is added on a row it is constantly added until it reaches the next row, but I can't seem to see why??
Any help would be greatly appreciated I have been at this quite a while, Thanks!
do it in two step:
1: sort each string:
public String sortString(String s1){
char[] chars = s1.toCharArray();
Arrays.sort(chars);
String sorted = new String(chars);
return sorted;
}
2: put each of your string in an array and use:
Arrays.sort(stringArray);
Out of the Code-Segmet you offered, i cant see an obvious mistake. But your design is inviting mistakes. To avoid these you may try:
Don't use count as a classwide variable, thou its not relevant for the hole class but only for the method. So make it an return statement, that you dont loose control over it, that it may be set anywhere or is only changed locally in a method.
totalp should not be calculated in every countPixel() method call, because it is a fixed value for your BoundBM. Initialize it in your constructor maybe, or with loading the bitmap.
At last, you know how large your output array is supposed to be, it doesnt make much sense for me, to keep it a list and to add it. Create an 2D array, and write it directly.
Hope it will help
reineke
EDIT: found the mistake!
in code line 27 you set x to 0 and not to the initial value of the input x, so you continue at the wrong position!!
Here is what i would do:
final int GRID=10;
totalp = boundBM.getWidth()/GRID * boundBM.getHeight()/GRID;
//this method now does not need to read boundBM, so it is more opject-oriented
public int countPixels(int x, int y, int h, int w){
count = 0;
for (i=x; i<x+w; i++){
for(k =y; k<y+h; k++){
if(c != boundBM.getPixel(i, k)) count++;
}
}
//funny thing
return (count>totalp/3) ? 1 : 0;
}
public void createNeuralInput(){
int h = boundBM.getHeight()/GRID;
int w = boundBM.getWidth()/GRID;
int[][] array= new int[GRID][GRID];
for(int i = 0; i < GRID; i++) {
for(int j = 0; j < GRID ; j++) {
n1.add(countPixels(i*h, j*w, h, w));
//i would prefer:
//array[i][j]=countPixels(i*h, j*w);
}
}
}

I used clone, but the original array is still affected

I am trying to write a 3x3 square-shift puzzle solver in Java. However, I'm stuck on the part where I shift the blocks around - I kept ending up with a bunch of new empty spaces with the algorithm I was using. After some testing I determined that it was because, in spite of my use of the clone() command, v's array is still being affected when I change "current". Does anyone know why this is and how I can fix it? I thought that after using clone, I could change the new array without affecting the old one.
if (!rightwall)
{
int[][] current = v.state.clone();
current[x][y] = current[x][y + 1];
current[x][y + 1] = 0;
State w = new State(current);
w.distance = v.distance + 1;
w.path = v;
System.out.println("Right Shift:");
w.print();
q.insert(w);
}
State is a class that represents a two-dimensional array along with some properties - the first part of the code for State is
public class State {
int[][] state = new int[3][3];
int distance = 0;
boolean known = false;
State path = null;
State(int[][] newstate){
state = newstate.clone();
}
v is the state representing the current position. w would then be an "adjacent" position created after switching the empty space with the space next to it.
q is a queue.
In your State class, you need to make sure that all properties are deep copied.

Problem with recursive backtracking

Hey guys, recently posted up about a problem with my algorithm.
Finding the numbers from a set which give the minimum amount of waste
Ive amended the code slightly, so it now backtracks to an extent, however the output is still flawed. Ive debugged this considerablychecking all the variable values and cant seem to find out the issue.
Again advice as opposed to an outright solution would be of great help. I think there is only a couple of problems with my code, but i cant work out where.
//from previous post:
Basically a set is passed to this method below, and a length of a bar is also passed in. The solution should output the numbers from the set which give the minimum amount of waste if certain numbers from the set were removed from the bar length. So, bar length 10, set includes 6,1,4, so the solution is 6 and 4, and the wastage is 0. Im having some trouble with the conditions to backtrack though the set. Ive also tried to use a wastage "global" variable to help with the backtracking aspect but to no avail.
SetInt is a manually made set implementation, which can add, remove, check if the set is empty and return the minimum value from the set.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package recursivebacktracking;
/**
*
* #author User
*/
public class RecBack {
int WASTAGE = 10;
int BESTWASTAGE;
int BARLENGTH = 10;
public void work()
{
int[] nums = {6,1,2,5};
//Order Numbers
SetInt ORDERS = new SetInt(nums.length);
SetInt BESTSET = new SetInt(nums.length);
SetInt SOLUTION = new SetInt(nums.length);
//Set Declarration
for (int item : nums)ORDERS.add(item);
//Populate Set
SetInt result = tryCutting(ORDERS, SOLUTION, BARLENGTH, WASTAGE);
result.printNumbers();
}
public SetInt tryCutting(SetInt possibleOrders, SetInt solution, int lengthleft, int waste)
{
for (int i = 0; i < possibleOrders.numberInSet(); i++) // the repeat
{
int a = possibleOrders.min(); //select next candidate
System.out.println(a);
if (a <= lengthleft) //if accecptable
{
solution.add(a); //record candidate
lengthleft -= a;
WASTAGE = lengthleft;
possibleOrders.remove(a); //remove from original set
if (!possibleOrders.isEmpty()) //solution not complete
{
System.out.println("this time");
tryCutting(possibleOrders, solution, lengthleft, waste);//try recursive call
BESTWASTAGE = WASTAGE;
if ( BESTWASTAGE <= WASTAGE )//if not successfull
{
lengthleft += a;
solution.remove(a);
System.out.println("never happens");
}
} //solution not complete
}
} //for loop
return solution;
}
}
Instead of using backtracking, have you considered using a bitmask algorithm instead? I think it would make your algorithm much simpler.
Here's an outline of how you would do this:
Let N be number of elements in your set. So if the set is {6,1,2,5} then N would be 4. Let max_waste be the maximum waste we can eliminate (10 in your example).
int best = 0; // the best result so far
for (int mask = 1; mask <= (1<<N)-1; ++mask) {
// loop over each bit in the mask to see if it's set and add to the sum
int sm = 0;
for (int j = 0; j < N; ++j) {
if ( ((1<<j)&mask) != 0) {
// the bit is set, add this amount to the total
sm += your_set[j];
// possible optimization: if sm is greater than max waste, then break
// out of loop since there's no need to continue
}
}
// if sm <= max_waste, then see if this result produces a better one
// that our current best, and store accordingly
if (sm <= max_waste) {
best = max(max_waste - sm);
}
}
This algorithm is very similar to backtracking and has similar complexity, it just doesn't use recursion.
The bitmask basically is a binary representation where 1 indicates that we use the item in the set, and 0 means we don't. Since we are looping from 1 to (1<<N)-1, we are considering all possible subsets of the given items.
Note that running time of this algorithm increases very quickly as N gets larger, but with N <= around 20 it should be ok. The same limitation applies with backtracking, by the way. If you need faster performance, you'd need to consider another technique like dynamic programming.
For the backtracking, you just need to keep track of which element in the set you are on, and you either try to use the element or not use it. If you use it, you add it to your total, and if not, you proceeed to the next recursive call without increasing your total. Then, you decrement the total (if you incremented it), which is where the backtracking comes in.
It's very similar to the bitmask approach above, and I provided the bitmask solution to help give you a better understanding of how the backtracking algorithm would work.
EDIT
OK, I didn't realize you were required to use recursion.
Hint1
First, I think you can simplify your code considerably by just using a single recursive function and putting the logic in that function. There's no need to build all the sets ahead of time then process them (I'm not totally sure that's what you're doing but it seems that way from your code). You can just build the sets and then keep track of where you are in the set. When you get to the end of the set, see if your result is better.
Hint2
If you still need more hints, try to think of what your backtracking function should be doing. What are the terminating conditions? When we reach the terminating condition, what do we need to record (e.g. did we get a new best result, etc.)?
Hint3
Spoiler Alert
Below is a C++ implementation to give you some ideas, so stop reading here if you want to work on it some more by yourself.
int bestDiff = 999999999;
int N;
vector< int > cur_items;
int cur_tot = 0;
int items[] = {6,1,2,5};
vector< int > best_items;
int max_waste;
void go(int at) {
if (cur_tot > max_waste)
// we've exceeded max_waste, so no need to continue
return;
if (at == N) {
// we're at the end of the input, see if we got a better result and
// if so, record it
if (max_waste - cur_tot < bestDiff) {
bestDiff = max_waste - cur_tot;
best_items = cur_items;
}
return;
}
// use this item
cur_items.push_back(items[at]);
cur_tot += items[at];
go(at+1);
// here's the backtracking part
cur_tot -= items[at];
cur_items.pop_back();
// don't use this item
go(at+1);
}
int main() {
// 4 items in the set, so N is 4
N=4;
// maximum waste we can eliminiate is 10
max_waste = 10;
// call the backtracking algo
go(0);
// output the results
cout<<"bestDiff = "<<bestDiff<<endl;
cout<<"The items are:"<<endl;
for (int i = 0; i < best_items.size(); ++i) {
cout<<best_items[i]<<" ";
}
return 0;
}

Categories