I have a text file that I'm continuously checking the last line to see if it's changed. I only want Processing to update the drawing when the last line of the file has changed, but I can't think of how to do it.
This is what I have so far, where lastLine checks the last line of the file:
String last = lastLine(file);
String previous = null;
float r = random(0,255);
float g = random(0, 255);
float b = random(0, 255);
public void settings() {
size(500, 500);
}
public void setup() {
frameRate(60);
stroke(155, 0, 0);
textSize(30);
}
void draw() {
if (last != previous) {
background(r+(random(0,100)), g+(random(0,100)), b+(random(0,100)));
previous = last;
}
if (last == previous) {
text(lastLine(file), 255, 255);
}
}
Right now this updates the text as the file changes, but the background remains the same.
How do I go about this?
When comparing String values, don't use the == operator. Use the equals() method:
if (last.equals(previous)) {
To check that they're not equal, use the ! operator:
if (!last.equals(previous)) {
From the reference:
To compare the contents of two Strings, use the equals() method, as in if (a.equals(b)), instead of if (a == b). A String is an Object, so comparing them with the == operator only compares whether both Strings are stored in the same memory location. Using the equals() method will ensure that the actual contents are compared. (The troubleshooting reference has a longer explanation.)
Related
This operator will receive a string with the format "x,y."
x represents an x coordinate and y represents a y coordinate. If the
coordinates are valid (that is within the valid range of the chess
board) then the appropriate variables should be set with these
variables. If the coordinates are invalid,
then nothing should happen.
operator<<: It also prints out (with a new line at the end), a message in the
following format:
b rook at [0,0]
The side is printed first, then the piece type followed by the coordinates at the end.
``This message must be sent to the output variable.
Piece::Piece(){
}
Piece::Piece(Piece *newPiece){
*newPiece = Piece;
}
Piece::Piece(string pType, char side, int x, int y){
//string pT = pType;
//char s = side;
}
Piece::~Piece(){
}
char Piece::getSide(){
return side;
}
string Piece::getPieceType(){
return PieceType;
}
int Piece::getX(){
return xPos;
}
int Piece::getY(){
return yPos;
}
void Piece::setX(int x){
xPos = x;
}
void Piece::setY(int y){
yPos = y;
}
void Piece::operator[](int pos){
cin>>pos;
if(pos != 0 || pos != 1){
cout<<"Invalid Index"<<endl;
}
else{
if(pos == 0 ){
cout<<"x coord"<<xPos;
}
if(pos == 1){
cout<<"y cord"<<yPos;
}
}
}
//Everything above compiled
Piece& Piece::operator+(string move){
if(xPos<=side && yPos<=side){
move = xPos;",";yPos;
return move;
}
return 0;
}
ostream& Piece::operator<<(ostream& output,const Piece& t ){
t = Piece;
output = side + PieceType + pos;
cout<<output;
}
There is no reason to call new inside the constructor.
Since you're calling new Piece in the constructor of Piece, you will end up in an infinite loop. The expression new Piece again invokes the constructor of Piece, which again calls new Piece, which invokes the constructor, ...
Also, think a second about what's happening here: *newPiece = new Piece; is constructing a new Piece object and assigning the result to the local pointer value newPiece. After the constructor ends (which in your case, it never does, because of the infinite loop), that local variable goes out of scope and your new Piece is lost.
Imagine I gave you a set of line segments in the form [(x1, y1), (x2, y2)]. We've got two points that define a line segment. For our purposes this segment will always be horizontal or vertical. I want to find the largest area of any rectangle enclosed by the line segments.
For example when given the set of the following line segments the result should be the area of the green shaded area:
So far the only solution I can think of is brute force - every pair of horizontal segments (O(N^2)) being checked with every pair of vertical segments (O(N^2)) for an O(N^4) runtime. Obviously we can optimize this by precomputing which segments can be put together, but that will still keep the time complexity at O(N^4).
I'm looking for ideally an O(N^2) solution but if you have anything less than O(N^4) please share!
You can use the line-sweep algorithm with this problem.
In this case, the vertical lines are added or removed from the set of lines to take into account when moving up. Both start & end points o the lines are added to the sweepset and the horizontal lines are added in order to a list.
step 1: line is added to activeVertical
step 2: second line added to activeVertical
step 3: third line added to activeVertical (note: they are in order of X).
step 4a: fourth line added to activeVertical
step 4b: Horizontal line found, time to create a rectangle which does not
have any height
step 5: second horizontal line found, time to check finish previous rectangle
etc.
Below the code (C#). Yuo can find more details on line sweep algorithm here: https://en.wikipedia.org/wiki/Sweep_line_algorithm
using System;
using System.Collections.Generic;
using System.Linq;
namespace tt
{
public class Point
{
public Point(double X, double Y)
{
this.X = X;
this.Y = Y;
}
public double X { get; set; }
public double Y { get; set; }
}
public class Line
{
public Point Start { get; set; }
public Point End { get; set; }
}
public class Rectangle
{
public Rectangle()
{ }
public Rectangle(Point BottomLeft, Point TopRight)
{
this.BottomLeft = BottomLeft;
this.TopRight = TopRight;
}
public Point BottomLeft { get; set; }
public Point TopRight { get; set; }
}
public class XComparer : IComparer<Line>
{
public int Compare(Line x, Line y)
{
return x.Start.X.CompareTo(y.Start.X);
}
}
public class Program
{
public static int GetMinIndex(List<Line> Lines, Line Horizontal)
{
var xComp = new XComparer();
int minIndex = Lines.BinarySearch(Horizontal, xComp);
if (minIndex < 0) minIndex = ~minIndex;
return minIndex;
}
public static int GetMaxIndex(List<Line> Lines, Line Horizontal)
{
var xComp = new XComparer();
int maxIndex = Lines.BinarySearch(new Line() { Start = Horizontal.End }, xComp);
if (maxIndex < 0) maxIndex = ~maxIndex - 1;
return maxIndex;
}
public static void Main()
{
List<Line> lines = new List<Line>();
lines.Add(new Line() { Start = new Point(0.5, 12.5), End = new Point(10, 12.5) });
lines.Add(new Line() { Start = new Point(2.5, 9.5), End = new Point(15.8, 9.5) });
lines.Add(new Line() { Start = new Point(6, 8.5), End = new Point(16.3, 8.5) });
lines.Add(new Line() { Start = new Point(3.5, 8.5), End = new Point(3.5, 12.5) });
lines.Add(new Line() { Start = new Point(7, 4.2), End = new Point(7, 13.8) });
lines.Add(new Line() { Start = new Point(10, 5.8), End = new Point(10, 14.2) });
lines.Add(new Line() { Start = new Point(15.6, 0), End = new Point(15.6, 16) });
lines.Add(new Line() { Start = new Point(1.6, 20), End = new Point(15.6, 20) });
var activeVertical = new List<Line>();
SortedList<double, List<Line>> sweepSet = new SortedList<double, List<Line>>();
foreach (Line oneLine in lines.Where(x => x.Start.X == x.End.X))
{
if (!sweepSet.ContainsKey(oneLine.Start.Y)) sweepSet.Add(oneLine.Start.Y, new List<Line>());
sweepSet[oneLine.Start.Y].Add(oneLine);
if (!sweepSet.ContainsKey(oneLine.End.Y)) sweepSet.Add(oneLine.End.Y, new List<Line>());
sweepSet[oneLine.End.Y].Add(oneLine);
}
var linesHorizontal = lines.Where(x => x.Start.Y == x.End.Y).OrderBy(x => x.Start.Y).ToList();
List<Rectangle> rectangles = new List<Rectangle>();
List<Rectangle> completedRectangles = new List<Rectangle>();
var xComp = new XComparer();
int horIndex = 0;
int sweepIndex = 0;
while (sweepIndex < sweepSet.Count)
{
double y = Math.Min(sweepSet.Keys[sweepIndex], linesHorizontal[horIndex].Start.Y);
double verValue = linesHorizontal[horIndex].Start.Y;
//add lines which are influencing
if (sweepSet.ContainsKey(y))
{
foreach (Line oneLine in sweepSet[y].Where(x => x.Start.Y == y))
{
int index = activeVertical.BinarySearch(oneLine, xComp);
if (index < 0) index = ~index;
activeVertical.Insert(index, oneLine);
}
}
if (y == verValue)
{
int minIndex = GetMinIndex(activeVertical, linesHorizontal[horIndex]);
int maxIndex = GetMaxIndex(activeVertical, linesHorizontal[horIndex]);
if (minIndex != maxIndex && minIndex < activeVertical.Count && maxIndex < activeVertical.Count)
{
double minX = activeVertical[minIndex].Start.X;
double maxX = activeVertical[maxIndex].Start.X;
foreach (Rectangle oneRec in rectangles)
{
if (minX > oneRec.BottomLeft.X) oneRec.BottomLeft.X = minX;
if (maxX < oneRec.TopRight.X) oneRec.TopRight.X = maxX;
oneRec.TopRight.Y = verValue;
}
completedRectangles.AddRange(rectangles);
rectangles.Clear();
rectangles.Add(new Rectangle(new Point(activeVertical[minIndex].Start.X, verValue), new Point(activeVertical[maxIndex].Start.X, verValue)));
}
else rectangles.Clear();
}
//Cleanup lines which end
if (sweepSet.ContainsKey(y))
{
foreach (Line oneLine in sweepSet[y].Where(x => x.End.Y == y))
{
activeVertical.Remove(oneLine);
}
}
if (y >= verValue)
{
horIndex++;
if (horIndex == linesHorizontal.Count) break;
if (y == sweepSet.Keys[sweepIndex]) sweepIndex++;
}
else
{
sweepIndex++;
}
}
}
}
}
You can find all intersections between vertical lines and horizontal lines with scan. Work through all lines in order of increasing y. Maintain a buffer containing all vertical lines including the current value of y. Keep the buffer sorted on the x value for each vertical line. As you come to each horizontal line, check to see if it intersects any of the lines in the buffer. The worst case cost of this is when there are O(N^2) intersections.
Now you have a list of intersections, and a list, for each line, of where it is intersected. For each horizontal line we will be interested, for each intersection, in how far down you can go following the vertical line at that intersection. Store these values in an array. Divide these values up into pairs and store the maximum of each pair in the array. Repeat the process for each maximum, and so on. This builds a tree of values where the leaves are the original values, in the original order, and each node carries the maximum value found in any descendant. The total cost of this is linear in the number of intersections.
Now take every intersection and assume it is the bottom left corner of a rectangle. For each intersection above it on its vertical line look at the intersecting horizontal line and find the rightmost point on this line where you can go down at least as far as the intersection. You have built a tree that allows you to find this in time logarithmic in the number of intersections on that line: start from the top of the tree and go right if the value at that child is at least as far as you need to go, else go left. Finding this gives you the largest rectangle using that bottom left and that horizontal line, so checking this for each horizontal line gives you the largest rectangle including that intersection as bottom left, and repeating this for each intersection gives you the overall largest rectangle.
If the lines form an N x N grid then for each intersection you check O(N) horizontal lines above it at cost O(log N) so the total cost of this stage is O(N^3log(N)) in the worst case.
The example you provided:
actually simplifies to something like this once we extract and merge only the rectangles formed by intersections:
---------------------
| |
| |
| |
| |
--------- ------------------
| |
|____________________________|
Then the problem becomes finding the largest rectangle in a rectilinear (aka orthogonal) polygon, for which there is a bunch of literature out there.
I'm working on making a matrix text rain effect in Processing 3.3 as a simple starter project for learning the processing library and Java. My code so far:
class Symbol {
int x, y;
int switchInterval = round(random(2, 50));
float speed;
char value;
Symbol(int x, int y, float speed) {
this.x = x;
this.y = y;
this.speed = speed;
}
//Sets to random symbol based on the Katakana Unicode block
void setToRandomSymbol() {
if(frameCount % switchInterval == 0) {
value = char((int) random(0x30A0, 0x3100));
}
}
//rains the characters down the screen and loops them to the top when they
// reach the bottom of the screen
void rain() {
if(y <= height) {
y += speed;
}else {
y = 0;
}
}
}
Symbol symbol;
class Stream {
int totalSymbols = round(random(5, 30));
Symbol[] symbols = new Symbol[500];
float speed = random(5, 20);
//generates the symbols and adds them to the array, each symbol one symbol
//height above the one previous
void generateSymbols() {
int y = 0;
int x = width / 2;
for (int i = 0; i <= totalSymbols; i++) {
symbols[i] = new Symbol(x, y, speed);
symbols[i].setToRandomSymbol();
y -= symbolSize;
}
}
void render() {
for(Symbol s : symbols) {
fill(0, 255, 70);
s.setToRandomSymbol();
text(s.value, s.x, s.y);
s.rain();
}
}
}
Ok, so that was a lot of code, Let me explain my dilemma. The issue I'm having is that when I run the code I get a NullpointerException at the s.setToRandomSymbol(); method call in the for each loop in the render function. The weird part about this NullPointerException error and the part I'm not understanding is that it's being thrown on a method that doesn't take in any arguments that could be coming back empty, and the method itself is void, so it shouldn't be returning anything, right? Why is this returning Null and what did I do wrong to have it return this way?
First you come up with a random number betwen 5 and 30:
int totalSymbols = round(random(5, 30));
Then you create an array that holds 500 instances of your Symbol class:
Symbol[] symbols = new Symbol[500];
Note that this array holds 500 null values at this point.
Then you add a maximum of 30 instances of Symbol to your array:
for (int i = 0; i <= totalSymbols; i++) {
symbols[i] = new Symbol(x, y, speed);
Note that this array now holds at least 470 null values at this point.
Then you iterate over all 500 indexes:
for(Symbol s : symbols) {
s.setToRandomSymbol();
But remember that at least 470 of these indexes are null, which is why you're getting a NullPointerException.
Some basic debugging would have told you all of this. I would have started by adding a basic println() statement just before you get the error:
for(Symbol s : symbols) {
println("s: " + s);
s.setToRandomSymbol();
This would have showed you that you're iterating over null values.
Anyway, to fix your problem you need to stop iterating over your entire array, or you need to stop making room for indexes you never use.
In the future, please try to narrow your problem down to a MCVE before posting. Note that this much smaller example program shows your error:
String[] array = new String[10];
array[0] = "test";
for(String s : array){
println(s.length());
}
I've create a code for a "generative" logo {Like this http://ebologna.it/ } (it's at the start so is not complete), and I want that while pressing one time the BACKSPACE I can go back just for one shape. Now like I have my code, when I press Backspace it delete all.
Below is the code:
import controlP5.*;
ControlP5 cp5;
String textValue = "";
String val;
void setup() {
size(700,800);
PFont font = createFont("arial",20);
cp5 = new ControlP5(this);
cp5.addTextfield("INPUT")
.setPosition(width/2-100,600)
.setSize(200,40)
.setFont(font)
.setFocus(true)
.setColor(color(255,255,255))
;
textFont(font);
background(0);
noStroke();
}
void draw() {
if (keyPressed) {
if (key == 'o' || key == 'O') {
fill(205, 152, 59, 100);
ellipse(width/2, height/2, 50, 50);
}
if (key == 'b' || key == 'B') {
fill(20, 84, 42, 100);
rectMode(CENTER);
rect(width/2, height/2, 50, 50);
}
}
if (key == BACKSPACE) { //This reset all, I want to reset just the last one shape
background (0);
}
val = cp5.get(Textfield.class,"INPUT").getText();
println(val.length());
}
Thanks !
Another option is to use a for loop to go through each character of the text String and draw the corresponding shape.
A for loop may look complicated because of it's syntax but it's not too bad if you look at it as a way of repeating a set of instructions for a given number of times/steps. The syntax roughly like so:
for( intial step ; condition to stop ; incrementation ){
//something to repeat while the condition to stop is still false
}
think of walking 10 steps, one step a time:
for(int step = 0 ; step < 10 ; step = step+1){
println("step index: " + i);
}
If you can do one step at a time, you can also hop:
for(int step = 0 ; step < 10 ; step = step+2){
println("step index: " + i);
}
Going back to your challenge, you can use a for loop to go through each character of the text. For example:
String text = "go";
for(int letterIndex = 0 ; letterIndex < text.length(); letterIndex = letterIndex + 1){
//get the character
char letter = text.charAt(letterIndex);
println(letter);
}
The snippet above uses String's length() function to retrieve the number of characters and the charAt() to retrieve a character by it's index in the String
Applied to your code:
import controlP5.*;
ControlP5 cp5;
void setup() {
size(700,800);
PFont font = createFont("arial",20);
cp5 = new ControlP5(this);
cp5.addTextfield("INPUT")
.setPosition(width/2-100,600)
.setSize(200,40)
.setFont(font)
.setFocus(true)
.setColor(color(255,255,255));
textFont(font);
background(0);
noStroke();
}
void draw() {
background (0);
//get the text string
String text = cp5.get(Textfield.class,"INPUT").getText();
//loop through each character
for(int letterIndex = 0 ; letterIndex < text.length(); letterIndex = letterIndex + 1){
//get the character
char letter = text.charAt(letterIndex);
//draw the coresponding shape
if (letter == 'o' || letter == 'O') {
fill(205, 152, 59, 100);
ellipse(width/2, height/2, 50, 50);
}
if (letter == 'b' || letter == 'B') {
fill(20, 84, 42, 100);
rectMode(CENTER);
rect(width/2, height/2, 50, 50);
}
}
}
If you want to be able to change what's been drawn to the screen, you're going to have to take this approach:
Step 1: Store everything you need to draw to the screen in a data structure. For you, this might be an ArrayList that holds instances of a Circle class that you create.
Step 2: Every single time draw() is called, clear the previous frames by calling the background() function, and then draw everything in the data structure to the screen.
Step 3: To modify what's on the screen, just modify what's in the data structure. For you, you might remove the Circle in the last position of the ArrayList.
I found this to be asked as an interview question. While it is fairly trivial to solve using bit masking and loops, any idea on how this can be done without loops? While I'm looking for an algorithm, any code would be appreciated as well.
The options I see for solving the problem without loops are bit hacks, recursion and loop unrolling.
Solving this with bit hacks seems quite difficult - most likely something only the most skilled bit hackers would be able to figure out in the time limit of an interview, or really figure out at all, but it's possible that that's who they were looking for.
Loop unrolling is just a silly solution.
So that leaves recursion.
Below is a recursive solution in Java.
It basically maintains the current count of consecutive zeros and also the best count, checks the last digit (i.e. checks the number modulo 10), sets these values appropriately and recurses on the number without the last digit (i.e. divided by 10).
I assumed we're talking about zeros in the decimal representation of the number, but converting this to use the binary representation is trivial (just change 10 to 2).
public static int countMaxConsecutiveZeros(int number)
{
return countMaxConsecutiveZeros(number, 0, 0);
}
private static int countMaxConsecutiveZeros(int number, int currentCount, int bestCount)
{
if (number == 0)
return bestCount;
if (number % 10 == 0)
currentCount++;
else
{
bestCount = Math.max(bestCount, currentCount);
currentCount = 0;
}
return countMaxConsecutiveZeros(number / 10, currentCount, bestCount);
}
public static void main(String[] args)
{
System.out.println(countMaxConsecutiveZeros(40040001)); // prints 3
}
Here's a roughly equivalent loop-based solution, which should provide a better understanding of the recursive solution:
private static int countMaxConsecutiveZerosWithLoop(int number)
{
int currentCount = 0, bestCount = 0;
while (number > 0)
{
if (number % 10 == 0)
currentCount++;
else
{
bestCount = Math.max(bestCount, currentCount);
currentCount = 0;
}
number /= 10;
}
return bestCount;
}
I don't know if this is what they were looking for, but here is a recursive solution.
I used two recursions, one comparing the current string of zeros to the record, and another recursion calculating the current string of zeros.
public class countconsecutivezeros{
public static void main(String[] Args){
int number = 40040001; // whatever the number is
System.out.println(consecutivezeros(number, 0));
}
public static int consecutivezeros(int number, int max){
if (number != 0){
if (max < zerosfrompoint(number)) max = zerosfrompoint(number);
return consecutivezeros(number/10, max);
}
return max;
}
public static int zerosfrompoint(int number){
int zeros = 0;
if ((number != 0) && ((number/10)*10 == number)){
zeros++;
System.out.println(zeros);
return zeros + zerosfrompoint(number/10);
}
return zeros;
}
}