Excuse my ignorance, but I ran into a problem that turned out to be challenging for my current knowledge in programming with Processing, even though the idea is quite simple. You see, I need to add 1 unit to a variable every 10 seconds. This is the code:
int i = 0;
void setup()
{
frameRate(60);
}
void draw()
{
int time = (millis() % 10000) / 1000;
if (time == 9)
{
i++;
} else {}
System.out.println("-------------------------------\n" +
"Timer: " + time + "\n"
+ "Adding 1 every 10 seconds: : " + i + "\n"
+ "-------------------------------");
}
The problem is that because draw() loops 60 times per second, as soon as time reaches 9 the second it last makes the if statement to be executed 60 times and it ends adding 60 to i every 10 seconds and I just need to be adding 1.
I tried to apply some kind of algorithm that subtracts the unnecessary numbers as they increase like so:
int i = 1;
int toSubstract = 0; //Variable for algorithm
void setup()
{
frameRate(60);
}
void draw()
{
int time = (millis() % 10000) / 1000;
if (time == 9)
{
i++;
algToSubstract();
} else {}
System.out.println("-------------------------------\n" +
"Timer: " + time + "\n"
+ "Adding 1 every 10 seconds: : " + i + "\n"
+ "-------------------------------");
}
void algToSubstract() //<--- This is the algorithm
{
i = i - toSubstract;
toSubstract++;
if (toSubstract > 59)
{
toSubstract = 0;
} else {}
}
...but I couldn't make it work. The idea was something like this:
time reaches 9, if statement executes, i = 1 and toSubstract = 0.
i increases 1 so i = 2.
i = i - toSusbract (i = 2 - 0 so i = 2).
toSusbract increases 1 so toSusbract = 1.
i increases 1 so i = 3.
i = i - toSusbract (i = 3 - 1 so i = 2).
toSusbract increases 1 so toSusbract = 2.
... Process continues...
toSubstract gets bigger than 59 so it is restarted to 0.
time stops being 9.
The other answers are fine general approaches, but they don't take advantage of the features that Processing provides for you.
For example, you could use the frameCount variable to check how many frames have elapsed. Since draw() is called 60 times per second, 10 seconds is 600 frames. Something like this:
void draw(){
if(frameCount % 600 == 0){
// 10 seconds has elapsed
}
}
Another way to do this is to store the last time 10 seconds elapsed, and then check that against the current time to see if 10 seconds has elapsed since then. Something like this:
int previousTime = 0;
void draw(){
if(millis() > previousTime + 10*1000){
// 10 seconds has elapsed
previousTime = millis();
}
}
More info can be found in the reference.
Ringo has a solution that's perfectly fine.
Another way you can do this easily is:
bool addOnce = false;
void draw()
{
int time = (millis() % 10000) / 1000;
if (time == 9)
{
if(!addOnce) {
addOnce = true;
i++;
}
} else { addOnce = false; }
}
As long as time == 9, we'll only get through if(!addOnce) one time.
After it changes, we reset the flag.
You could store the last number of seconds in a static (or global) variable, and only increment i when the current number of seconds is higher than the oldsecs
void draw() {
static int oldsecs = 0;
int secs = millis() / 1000;
if (secs > oldsecs) {
i++;
oldsecs = secs;
}
...
Assuming the language is C, and the int type is not overflowed by the number of seconds.
Related
I am working on an Arduino stopwatch, where it needs a start, stop, and reset button. To reset it, I am using a variable called starttime that is updated to equal to millis(), and then take the difference to display time. However, past thirty seconds, the starttime does not update correctly, and the resulting difference between starttime and millis() is equivalent to 65 seconds. Can someone explain why this is happening?
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const int start = 8;
const int stp = 9;
const int reset = 10;
int seconds;
int minutes;
int timedif;
int starttime = -1;
int timestall = 0;
bool onoff = true;
void setup()
{
pinMode(start, INPUT);
pinMode(stp, INPUT);
pinMode(reset, INPUT);
lcd.begin(16, 2); //Initialize the 16x2 LCD
lcd.clear(); //Clear any old data displayed on the LCD
Serial.begin(9600);
}
void loop()
{
int bsta = digitalRead(start);//sees if start switch is pressed
int bstp = digitalRead(stp);//records if stop switch is pressed
int bres = digitalRead(reset);//records if reset switch is pressed
lcd.setCursor(0,0);
lcd.print("Stopwatch");//prints stopwatch top row
lcd.setCursor(0,1);
if (starttime == -1) { //if running first time, time dif is initiated
starttime = millis();
}
timedif = (millis() - starttime )/1000 + timestall; //will get difference in terms of seconds
minutes = floor(timedif/60); // divides by sixty, drops decimal
seconds = timedif%60; //gets remainder of divided by 60
lcd.print(minutes);
lcd.print(":");
lcd.print(seconds);
if (seconds < 10) {
lcd.setCursor(3,1);
lcd.print(' ');
}
if (bstp == HIGH) {
onoff = false;
while(onoff == false) {
if (digitalRead(start) == HIGH) {
onoff = true;
}
}
timestall = timedif;
starttime = millis();
}
if (bres == HIGH) {
delay(100);
timestall = 0;
starttime = millis();
timedif = 0;
lcd.clear();
Serial.println("stall:");
Serial.println(timestall);
Serial.println("dif");
Serial.println(timedif);
Serial.println("start");
Serial.println(millis() - starttime);
}
}
You should use long or unsigned long instead if int to declare variables that hold time values.
A int variable can only hold 32,767 millisecond hence the 32 sec. where a long variable can hold 2,147,483,647 millisecond which is something like 48 days. A unsigned long can hold double of that but can not hold a negative value.
First, sorry for my bad English.
Special numbers are numbers that the sum of the digits is divisible to the number of the digit.
Example: 135 is a special number because the sum of the digits is 1+3+5 = 9, the number of the digit is 3, and 9 is divisible to 3 because 9 % 3 == 0. 2,3,9,13,17,15,225, 14825 are also special numbers.
Requirement:
Write a program that read the number n (n <= 10^6) from a file named SNUMS.INP (SNUMS.INP can contain up to 10^6 numbers) and print the result out into the file SNUMS.OUT. Number n is the order of the special number and the result will be that special number in n order (sorry I don't know how to express it).
Example: n = 3 means you have to print out the 3rd special number which is 3, n = 10 you have to print out 10th special number which is 11, n = 13 you have to print out 13th special number which is 17, n = 15 you have to print out 15th special number which is 20.
The example bellow will demonstrate the file SNUMS.INP and SNUMS.OUT (Remember: SNUMS.INP can contain up to 10^6 numbers)
SNUMS.INP:
2
14
17
22
SNUMS.OUT:
2
19
24
35
I have my own alogrithm but the the running time exceeds 1 second (my SNUMS.INP has 10^6 numbers). So I need the optimal alogrithm so that the running time will be less than or equal 1s.
Guys I decide to post my own code which is written in Java, it always take more than 4 seconds to run. Could you guys please suggest some ideas to improve or how to make it run faster
import java.util.Scanner;
import java.io.*;
public class Test
{
public static void main(String[]args) throws IOException
{
File file = new File("SNUMS.INP");
Scanner inputFile = new Scanner(file);
int order = 1;
int i = 1;
int[] special = new int[1000000+1];
// Write all 10^6 special numbers into an array named "special"
while (order <= 1000000)
{
if (specialNumber(i) == true)
{
special[order] = i;
order++;
}
i++;
}
// Write the result to file
PrintWriter outputFile = new PrintWriter("SNUMS.OUT");
outputFile.println(special[inputFile.nextInt()]);
while (inputFile.hasNext())
outputFile.println(special[inputFile.nextInt()]);
outputFile.close();
}
public static boolean specialNumber(int i)
{
// This method check whether the number is a special number
boolean specialNumber = false;
byte count=0;
long sum=0;
while (i != 0)
{
sum = sum + (i % 10);
count++;
i = i / 10;
}
if (sum % count == 0) return true;
else return false;
}
}
This is file SNUMS.INP (sample) contains 10^6 numbers if you guys want to test.
https://drive.google.com/file/d/0BwOJpa2dAZlUNkE3YmMwZmlBOTg/view?usp=sharing
I've managed to solve it in 0.6 seconds on C# 6.0 (.Net 4.6 IA-64) at Core i7 3.2 GHz with HDD 7200 rpc; hope that precompution will be fast enough at your workstation:
// Precompute beautiful numbers
private static int[] BeautifulNumbers(int length) {
int[] result = new int[length];
int index = 0;
for (int i = 1; ; ++i) {
int sum = 0;
int count = 0;
for (int v = i; v > 0; sum += v % 10, ++count, v /= 10)
;
if (sum % count == 0) {
result[index] = i;
if (++index >= result.Length)
return result;
}
}
}
...
// Test file with 1e6 items
File.WriteAllLines(#"D:\SNUMS.INP", Enumerable
.Range(1, 1000000)
.Select(index => index.ToString()));
...
Stopwatch sw = new Stopwatch();
sw.Start();
// Precomputed numbers (about 0.3 seconds to be created)
int[] data = BeautifulNumbers(1000000);
// File (about 0.3 seconds for both reading and writing)
var result = File
.ReadLines(#"D:\SNUMS.INP")
.Select(line => data[int.Parse(line) - 1].ToString());
File.WriteAllLines(#"D:\SNUMS.OUT", result);
sw.Stop();
Console.Write("Elapsed time {0}", sw.ElapsedMilliseconds);
The output vary from
Elapsed time 516
to
Elapsed time 660
with average elapsed time at about 580 milliseconds
Now that you have the metaphor of abacus implemented below, here are some hints
instead of just incrementing with 1 inside a cycle, can we incremente more aggressively? Indeed we can, but with an extra bit of care.
first, how much aggressive we can be? Looking to 11 (first special with 2 digits), it doesn't pay to just increment by 1, we can increment it by 2. Looking to 102 (special with 3 digits), we can increment it by 3. Is it natural to think we should use increments equal with the number of digits?
now the "extra bit of care" - whenever the "increment by the number of digits" causes a "carry", the naive increment breaks. Because the carry will add 1 to the sum of digits, so that we may need to subtract that one from something to keep the sum of digits well behaved.
one of the issues in the above is that we jumped quite happily at "first special with N digits", but the computer is not us to see it at a glance. Fortunately, the "first special with N digits" is easy to compute: it is 10^(N-1)+(N-1) - 10^(N-1) brings an 1 and the rest is zero, and N-1 brings the rest to make the sum of digits be the first divisible with N. Of course, this will break down if N > 10, but fortunately the problem is limited to 10^6 special numbers, which will require at most 7 digits (the millionth specual number is 6806035 - 7 digits);
so, we can detect the "first special number with N digits" and we know we should try with care to increment it by N. Can we look now better into that "extra care"?.
The code - twice as speedy as the previous one and totally "orthodox" in obtaining the data (via getters instead of direct access to data members).
Feel free to inline:
import java.util.ArrayList;
import java.util.Arrays;
public class Abacus {
static protected int pow10[]=
{1,10,100,1000, 10000, 100000, 1000000, 10000000, 100000000}
;
// the value stored for line[i] corresponds to digit[i]*pow10[i]
protected int lineValues[];
protected int sumDigits;
protected int representedNumber;
public Abacus() {
this.lineValues=new int[0];
this.sumDigits=0;
this.representedNumber=0;
}
public int getLineValue(int line) {
return this.lineValues[line];
}
public void clearUnitLine() {
this.sumDigits-=this.lineValues[0];
this.representedNumber-=this.lineValues[0];
this.lineValues[0]=0;
}
// This is how you operate the abacus in real life being asked
// to add a number of units to the line presenting powers of 10
public boolean addWithCarry(int units, int line) {
if(line-1==pow10.length) {
// don't have enough pow10 stored
pow10=Arrays.copyOf(pow10, pow10.length+1);
pow10[line]=pow10[line-1]*10;
}
if(line>=this.lineValues.length) {
// don't have enough lines for the carry
this.lineValues=Arrays.copyOf(this.lineValues, line+1);
}
int digitOnTheLine=this.lineValues[line]/pow10[line];
int carryOnTheNextLine=0;
while(digitOnTheLine+units>=10) {
carryOnTheNextLine++;
units-=10;
}
if(carryOnTheNextLine>0) {
// we have a carry, the sumDigits will be affected
// 1. the next two statememts are equiv with "set a value of zero on the line"
this.sumDigits-=digitOnTheLine;
this.representedNumber-=this.lineValues[line];
// this is the new value of the digit to set on the line
digitOnTheLine+=units;
// 3. set that value and keep all the values synchronized
this.sumDigits+=digitOnTheLine;
this.lineValues[line]=digitOnTheLine*pow10[line];
this.representedNumber+=this.lineValues[line];
// 4. as we had a carry, the next line will be affected as well.
this.addWithCarry(carryOnTheNextLine, line+1);
}
else { // we an simply add the provided value without carry
int delta=units*pow10[line];
this.lineValues[line]+=delta;
this.representedNumber+=delta;
this.sumDigits+=units;
}
return carryOnTheNextLine>0;
}
public int getSumDigits() {
return this.sumDigits;
}
public int getRepresentedNumber() {
return this.representedNumber;
}
public int getLinesCount() {
return this.lineValues.length;
}
static public ArrayList<Integer> specials(int N) {
ArrayList<Integer> ret=new ArrayList<>(N);
Abacus abacus=new Abacus();
ret.add(1);
abacus.addWithCarry(1, 0); // to have something to add to
int increment=abacus.getLinesCount();
while(ret.size()<N) {
boolean hadCarry=abacus.addWithCarry(increment, 0);
if(hadCarry) {
// need to resynch the sum for a perfect number
int newIncrement=abacus.getLinesCount();
abacus.clearUnitLine();
if(newIncrement!=increment) {
// we switched powers of 10
abacus.addWithCarry(newIncrement-1, 0);
increment=newIncrement;
}
else { // simple carry
int digitsSum=abacus.getSumDigits();
// how much we should add to the last digit to make the sumDigits
// divisible again with the increment?
int units=increment-digitsSum % increment;
if(units<increment) {
abacus.addWithCarry(units, 0);
}
}
}
ret.add(abacus.getRepresentedNumber());
}
return ret;
}
// to understand how the addWithCarry works, try the following code
static void add13To90() {
Abacus abacus; // starts with a represented number of 0
// line==1 means units of 10^1
abacus.addWithCary(9, 1); // so this should make the abacus store 90
System.out.println(abacus.getRepresentedNumber());
// line==0 means units of 10^0
abacus.addWithCarry(13, 0);
System.out.println(abacus.getRepresentedNumber()); // 103
}
static public void main(String[] args) {
int count=1000000;
long t1=System.nanoTime();
ArrayList<Integer> s1=Abacus.specials(count);
long t2=System.nanoTime();
System.out.println("t:"+(t2-t1));
}
}
Constructing the numbers from their digits is bound to be faster.
Remember the abacus? Ever used one?
import java.util.ArrayList;
public class Specials {
static public ArrayList<Integer> computeNSpecials(int N) {
ArrayList<Integer> specials = new ArrayList<>();
int abacus[] = new int[0]; // at index i we have the digit for 10^i
// This way, when we don't have enough specials,
// we simply reallocate the array and continue
while (specials.size() < N) {
// see if a carry operation is necessary
int currDigit = 0;
for (; currDigit < abacus.length && abacus[currDigit] == 9; currDigit++) {
abacus[currDigit] = 0; // a carry occurs when adding 1
}
if (currDigit == abacus.length) {
// a carry, but we don't have enough lines on the abacus
abacus = new int[abacus.length + 1];
abacus[currDigit] = 1; // we resolved the carry, all the digits below
// are 0
} else {
abacus[currDigit]++; // we resolve the carry (if there was one),
currDigit = 0; // now it's safe to continue incrementing at 10^0
}
// let's obtain the current number and the sum of the digits
int sumDigits = 0;
for (int i = 0; i<abacus.length; i++) {
sumDigits += abacus[i];
}
// is it special?
if (sumDigits % abacus.length == 0) {
// only now compute the number and collect it as special
int number = 0;
for (int i = abacus.length - 1; i >= 0; i--) {
number = 10 * number + abacus[i];
}
specials.add(number);
}
}
return specials;
}
static public void main(String[] args) {
ArrayList<Integer> specials=Specials.computeNSpecials(100);
for(int i=0; i<specials.size(); i++) {
System.out.println(specials.get(i));
}
}
}
I know that machines find it difficult to make calculations involving very large numbers.
Let's say I want to find square of a million digit number. Will a typical computer give an answer almost instantly? How much time does it take for them to handle million digit calculations?
Also what is the reason for them to be slow in such calculations?
I found some calculator websites which claim that they can do the task instantly. Will a computer become faster if they use the method those websites use?
On my PC it takes more than 21 minutes to draw a square root of a number with 1 million digits. See the details below. It should be possible to achieve faster times, but "almost instantly" is probably not feasible without making use of special hardware (like graphics boards with CUDA support).
I have written a test program in C# to find the runtimes for calculating the square root with Newton's method. It uses the System.Numerics library which features the BigInteger class for arbitrary accuracy arithmetic.
The runtime depends on the initial value assumed for the iterative calculation method. To look for the highest non-zero bit of the number turned out to be faster than simply always using 1 as initial value.
using System;
using System.Diagnostics;
using System.Numerics;
namespace akBigSquareRoot
{
class Program
{
static void Main(string[] args)
{
Stopwatch stopWatch = new Stopwatch();
Console.WriteLine(" nDigits error iterations elapsed ");
Console.WriteLine("-----------------------------------------");
for (int nDigits = 10; nDigits <= 1e6; nDigits *= 10)
{
// create a base number with nDigits/2 digits
BigInteger x = 1;
for (int i = 0; i < nDigits / 2; i++)
{
x *= 10;
}
BigInteger square = x * x;
stopWatch.Restart();
int iterations;
BigInteger root = sqrt(square, out iterations);
stopWatch.Stop();
BigInteger error = x - root;
TimeSpan ts = stopWatch.Elapsed;
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
Console.WriteLine("{0,8} {1,6} {2,6} {3}", nDigits, error, iterations, elapsedTime);
}
Console.WriteLine("\n<end reached>");
Console.ReadKey();
}
public static BigInteger sqrt(BigInteger x, out int iterations)
{
BigInteger div = BigInteger.One << (bitLength(x) / 2);
// BigInteger div = 1;
BigInteger div2 = div;
BigInteger y;
// Loop until we hit the same value twice in a row, or wind
// up alternating.
iterations = 0;
while (true)
{
iterations++;
y = (div + (x / div)) >> 1;
if ((y == div) || (y == div2))
return y;
div2 = div;
div = y;
}
}
private static int bitLength(BigInteger x) {
int len = 0;
do
{
len++;
} while ((x >>= 1) != 0);
return len;
}
}
}
The results on a DELL XPS 8300 with Intel Core i7-2600 CPU 3.40 GHz
nDigits error iterations elapsed
----------------------------------------
10 0 4 00:00:00.00
100 0 7 00:00:00.00
1000 0 10 00:00:00.00
10000 0 14 00:00:00.09
100000 0 17 00:00:09.81
1000000 0 20 00:21:18.38
Increasing the number of digits by a factor of 10 results in three additional iterations in the search procedure. But due to the increased bit-length, the search iterations a slowed down substantially.
The computational complexity of calculating square (and higher degree) roots is discussed in a related post.
I am trying to develop a program that can help me to find the Beats Per Minute of a song by clicking, or tapping a button.
I have worked out that I need a dynamic array that saves the time (in milliseconds) of each tap, adding a new element on to the end of the Arraylist every time.
After a certain amount of elements are added, the BPM is worked out by finding the sum of all elements and dividing that by the amount of elements in the list.
I am not very familiar with Arraylists and was wondering whether somebody could help me implement these steps.
I will be using processing for this program.
something like this?
ArrayList <Integer> diffs = new ArrayList<Integer>();
int last, now, diff;
void setup() {
last = millis();
}
void draw() {
}
void mouseClicked() {
now = millis();
diff = now - last;
last = now;
diffs.add(diff);
int sum = 0;
for (Integer i : diffs) {
sum = sum + i;
}
int average = diffs.size() > 0 ? sum/diffs.size() : 0;
println ("average = " + average);
}
Actually if you don't need to access each entrie, you don't even need an arraylist...
int last, now, diff, entries, sum;
void setup() {
last = millis();
}
void draw() {
}
void mouseClicked() {
now = millis();
diff = now - last;
last = now;
sum = sum + diff;
entries++;
int average = sum/entries ;
println ("average = " + average);
}
I have this method here which renders my players movement. It swaps between 3 images, standing, left leg forward, and right leg forward.
It swaps images very fast so how can I change the speed of the rendering?
public static void renderUpwardWalking() {
ImageIcon[] frames = { CharacterSheet.up, CharacterSheet.upLeftLeg,
CharacterSheet.upRightLeg };
if (Key.up && Character.direction == "up") {
currentFrame++;
if (currentFrame == 3)
currentFrame = 1;
Character.character.setIcon(frames[currentFrame]);
} else if (!Key.up && Character.direction == "up") {
currentFrame = 0;
}
}
This is usually done on timer.
Decide on a frame pattern and a frequency. You seem to have chosen the frame pattern CharacterSheet.up, CharacterSheet.upLeftLeg, CharacterSheet.upRightLeg. Let's say you want to swap frame every 400 ms.
Get the time from a clock with sufficient resolution. System.nanoTime() is usually accurate enough.
long frameTime = 400L * 1000000L; // 400 ms in nanoseconds Edit
currentFrame = (System.nanoTime() / frametime) % frames.length;
You can change the scale of your currentFrame counter, and use its range to control your frame rate:
//Let this go from 1...30
int currentFrameCounter;
.
.
.
currentFrameCounter++;
if(currentFrameCounter == 30) currentFrameCounter = 0;
//Take a fraction of currentframeCounter for frame index ~ 1/10 frame rate
//Note care to avoid integer division
currentFrame = (int) (1.0*currentFrameCounter / 10.0);
Putting it all together in a general model:
int maxCounter = 30; //or some other factor of 3 -- controls speed
int currentFrameCounter;
public static void renderUpwardWalking() {
ImageIcon[] frames = { CharacterSheet.up, CharacterSheet.upLeftLeg,
CharacterSheet.upRightLeg };
if (Key.up && Character.direction == "up") {
currentFrameCounter++; //add
if(currentFrameCounter == maxCounter) currentFrameCounter = 0;
currentFrame = (int) (1.0*currentFrameCounter / (maxCounter/3.0));
Character.character.setIcon(frames[currentFrame]);
} else if (!Key.up && Character.direction == "up") {
currentFrame = 0;
}
}