Exercise from Visual Studio C# 2010 fourth edition - sentinel

I've working on a C# application that is supposed to input miles driven and gallons used(integers) for each tankful of gas and then the application should calculate and display the miles per gallon obtained for each tankful and display combined miles per gallon obtained for all tankfuls. My issue is that the sentinel controlled aspect "-1" doesnt stop program from running, yet, the IDE kicks out a JIT debugger and I get a Microsoft.NET framework exception MileageDriven.exe[732].
Can I have some assistance, as I dont want to move beyond this exercise as future lessons build upon the last lesson. Thanks in advance. :)
using System;
public class MileagedrivenTest
{
public static void Main(string[] args)
{
Mileage driverMileage = new Mileage("Driver log");
driverMileage.DisplayMessage();
driverMileage.DetermineMileagePerGallon();
} // end main
} // end class MileageDrivenTest
// Fig. 1.1: MileageDriven.cs
// Mileage class that solves mileage per gallon problem
// using sentinel-controlled repetition
using System;
public class Mileage
{
public string Gallons { get; set; }
public Mileage (string name)
{
Gallons = name;
}
public void DisplayMessage()
{
Console.WriteLine("Welcome to the mileage log for\n{0}\n", Gallons);
} // end method DisplayMessage
//determine the average mileage for gallon per tank of gas
public void DetermineMileagePerGallon()
{
int total = 0;
int mileage; // sum of miles driven
int gallons; // sum gallons used
double average;
int mileageCounter = 0;
Console.WriteLine("Enter mileage or -1 to quit: ");
mileage = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter gallons used: ");
gallons = Convert.ToInt32(Console.ReadLine());
while (mileage != -1)
{
mileage = total + mileage;
mileageCounter = mileageCounter + mileage;
Console.Write("Enter next miles driven or -1 to quit: ");
mileage = Convert.ToInt32(Console.ReadLine());
} // end while
if (mileageCounter != 0)
{
average = (double)total / mileageCounter;
Console.WriteLine("\nTotal of the {0} miles driven is {1} per tank is{}", mileageCounter, total);
Console.WriteLine("Average mile per gallon is {0}", average);
}
else
Console.WriteLine("No mileage entered");
}
}

The code you posted throws an exception on this line:
Console.WriteLine("\nTotal of the {0} miles driven is {1} per tank is{}", mileageCounter, total);
The problem is the extra {}. If you remove that the code will run but I don't think that it solves the problem that you're trying to solve. I've modified DetermineMileagePerGallon() based on my interpretation of the problem - hopefully it'll get you closer to a solution:
//determine the average mileage for gallon per tank of gas
public void DetermineMileagePerGallon()
{
int totalTankfuls = 0;
int inputMileage;
int totalMileage = 0; // sum of miles driven
int totalGallons = 0; // sum gallons used
Console.WriteLine("Enter mileage or -1 to quit: ");
while (!Int32.TryParse(Console.ReadLine(), out inputMileage)) ;
while (inputMileage != -1)
{
totalTankfuls++;
if (inputMileage > 0)
totalMileage += inputMileage;
Console.WriteLine("Enter gallons used: ");
int inputGallons;
while (!Int32.TryParse(Console.ReadLine(), out inputGallons)) ;
if (inputGallons > 0)
totalGallons += inputGallons;
Console.WriteLine("Enter mileage or -1 to quit: ");
while (!Int32.TryParse(Console.ReadLine(), out inputMileage)) ;
} // end while
if (totalTankfuls > 0)
{
double averageMpg = (double)totalMileage / totalGallons;
double averageMileagePerTankful = (double)totalMileage / totalTankfuls;
Console.WriteLine("Total of {0} miles driven on {1} tanks of fuel; average is {2} miles per tankful", totalMileage, totalTankfuls, averageMileagePerTankful);
Console.WriteLine("Average mile per gallon across all tankfuls is {0}", averageMpg);
}
else
Console.WriteLine("No mileage entered");
}

Related

C# How to generate random high or low numbers, and have each succeeding number be based off of the last randomly generated number

I'm currently creating a Guess Game via a Udemy course based on C# using Unity Engine. What I'm trying to do is outside the scope of the course.
I got to the point you see below where when I press the "up arrow" or "down arrow" a random number is generated between two numbers: (avg, max) and (avg, min).
As it stand right now the numbers generated are always higher or lower than the 'avg' based on the key that's pressed, but the each number generated after that won't necessarily be higher or lower than the previously generated number.
For example. I could choose lower than 393 (the 'avg') and get 242. But if I press lower again it could be 345. While it's lower than the 'avg' I want to have each randomly generated number be lower than the last randomly generated number (or higher depending on the key press).
I thought maybe assigning a variable to the function was the right thing to do. I have an unused integer 'c' that I was thinking of using.
Not sure how to make this happen....
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NumberWizard : MonoBehaviour
{
int max = 734;
int min = 52;
int avg = 393;
int a;
int b;
int c;
// Use this for initialization
void Start()
{
StartGame();
}
void StartGame()
{
max = 734;
min = 52;
avg = 393;
Debug.Log("Welcome to Number Wizard you filthy son of a bitch.");
Debug.Log("Pick a goddamn number.");
Debug.Log("The highest number is: " + max);
Debug.Log("The lowest number is: " + min);
Debug.Log("Tell me if your number is higher or lower than " + avg);
Debug.Log("Push Up = Higher, Push Down = Lower, Push Enter = Correct!");
max = max + 1;
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.UpArrow))
{
Debug.Log("You chose higher. What is your guess? ");
NextGuess();
}
else if (Input.GetKeyDown(KeyCode.DownArrow))
{
Debug.Log("You chose lower. What is your guess?");
NextGuess2();
}
else if (Input.GetKeyDown(KeyCode.Return))
{
Debug.Log("You are correct.");
StartGame();
}
else if (Input.GetKeyDown(KeyCode.KeypadEnter))
{
Debug.Log("You are correct.");
StartGame();
}
else if (Input.anyKeyDown)
{
Debug.Log("Input invalid. Try again.");
}
}
void NextGuess()
{
a = Random.Range(avg, max);
Debug.Log(a);
}
void NextGuess2()
{
b = Random.Range(avg, min);
Debug.Log(b);
}
}
Try updating the avg on a key down to waht the value is. So with your example
choose lower than 393 (the 'avg') and get 242
now update avg to be 242.
avg = NextGuess2();
public NextGuess2()
{
b = Random.Range(avg, min);
Debug.Log(b);
return b;
}

Special numbers challenge in programming

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));
}
}
}

Dividing B cheese cakes among N classes to minimize maximum no of students per cake

There is a school in a village. It has N classes. One fine day, someone donated B blue berry cheese cakes to schools. Now you need to divide these cakes such that:
Each class gets at least 1 cake.
Each class will share the cake(s) among students.
Your aim is to minimize the maximum number of students per cake in any class.
input
contains two space separated integers N and B denoting the number of classes and total number of blue berry cheese cakes, respectively.
Next N lines contain number of students in each class.
Output
For each test case, output the maximum number of students who will share a cake.
Constraints
2 <= N <= 5*10^5
N <= B <= 2*10^6 1 <= number of students in ith class <= 5*10^6
Sample Input - 1 1 2 35 Sample Output - 1 18 Sample Input - 2 2 7 20 50 Sample Output - 2 10
Apply binary search to find minimum number of students/cake.
Take lower limit 'l' as 1 and upper limit 'u' as max number of students in any given class.
Let 'mid' represents current students/cake where mid=(l+u)/2, then,
calculate required number of cakes 'req' for each mid value,
if req<=total number of cakes u=mid-1 else l=mid+1.
Apply the binary search.
Handle the case when n>b separately.
Link to my C++ code for this problem : https://ideone.com/zsTHC5
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
ll n,b;cin>>n>>b;
ll arr[n],ans=0;
for(ll i=0;i<n;i++){cin>>arr[i];ans=max(ans,arr[i]);}
if(n>b)cout<<"-1";
else if(n==b)cout<<ans;
else // binary search to find minimum students/cake
{
ll l=1,r=ans,mid; // mid represents current number of students/cake
while(l<=r)
{
mid=(l+r)/2;
ll ct=0;
for(ll i=0;i<n;i++)
{
ct+=(arr[i]+mid-1)/mid;
}
if(ct<=b)
{
ans=min(ans,mid);
r=mid-1;
}
else
l=mid+1;
}
cout<<ans;
}
return 0;
}
I agree with smartsn123.The solution is pretty simple ,initialize the max heap with each class with one cake and then start distributing cakes one by one.Here following the java implementation of the solution.
import java.util.*;
class Node{
private int nStu ;
private int nCake;
public Node(int nStu , int nCake ){
this.nStu = nStu;
this.nCake = nCake;
}
public int getnStu(){
return nStu;
}
public int getnCake(){
return nCake;
}
public void addCake(){
nCake++;
}
}
class CheeseCake{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
int B = sc.nextInt();
int[] arr = new int[N];
int ext = B - N ;
MyComparator mc = new MyComparator();
PriorityQueue<Node> queue = new PriorityQueue<>(mc);
for(int i = 0 ; i < N ; i++){
//arr[i] = sc.nextInt();
int temp = sc.nextInt();
Node newNode = new Node(temp , 1);
queue.add(newNode);
}
while(ext != 0){
Node new1 = queue.poll();
new1.addCake();
queue.add(new1);
ext--;
}
Node newNode1 = queue.poll();
int fStu = newNode1.getnStu();
int fCake = newNode1.getnCake();
System.out.println((fStu+1)/2);
}
}
class MyComparator implements Comparator<Node>{
#Override
public int compare(Node n1 , Node n2){
/*arranging based on the students per cakes*/
double avg1 = n1.getnStu() / n1.getnCake();
double avg2 = n2.getnStu() / n2.getnCake();
if(avg1 > avg2){
return -1;
}
if(avg1 < avg2){
return 1;
}
return 0;
}
}

Algorithm for seating firefighters in vehicle seats

I’m doing a project which involves placing volunteer firefighters, in seats when they arrive at the fire station to take the trucks.
Also some firefighters has drivers license some haven’t and some have a team leader education.
So my idea is to follow them by GPS and send the server a integer of distance to fire station and which education types each has.
Then every 5 sec, run the algorithm and based on the new GPS coordinates change their seats, until 1 is close to the station, and then mark is seat as taken.
This should happen until there is no empty seats or not anymore firefighters to call in or all called firefighters has arrived
The tricky thing I want help with (besides if my idea is the optimal), is to seat the firefighters most optimal.
I was thinking to make a prioritization list of possible roles.
And a prioritization list of vehicles which had to leave the station.
Then take the highest prioritized vehicle and the highest prioritized role, and fill it in with the closest firefighter which has the education.
But then if he is a driver but already set to the teamleaders seat, and only 1 more driver is coming, and there were more teamleaders coming, and two vehicles had to leave, it would be a wrong solution as the second vehicle couldn’t leave.
Again if Drivers and not teamleaders is the highest priority, then if the closest is set as driver, but is also the only one coming with a teamleader education, but more drivers are coming, then it would also be wrong.
Any ideas for the algorithm to work? Or does anybody knows an algorithm for this?
You're right, this type of greedy approach won't necessarily give you an optimal solution. Have you looked into/heard of Linear Programming or more specifically Integer programming: http://en.wikipedia.org/wiki/Integer_programming
In short integer programming is one technique for solving these types of scheduling problems. The problem has some objective you wish to maximise or minimise and is subject to various (linear) constraints. Integer because we can't have half a volunteer.
From your description the objective function could be to minimise the number of undeployed trucks and the total wait time. You could have different costs for different trucks to capture the different vehicle priorities.
Constraints would include each vehicle needing at least one driver, at least one team leader and that a volunteer can only be assigned to one vehicle. There might be other constraints you haven't described as well, such as no one can wait at the base for more than 20 minutes.
If you search for integer programming and scheduling you should find some code examples. You'll likely need a solver to assist. Wiki has a fairly comprehensive list, the choice will come down to your programming language preference and budget: http://en.wikipedia.org/wiki/Linear_programming#Solvers_and_scripting_.28programming.29_languages
How about something like this..
as you noticed the only conflicting situation is when you have a firefighter that can be driver and leader.. because the can only occupy one position.. but may be blocking another..
so don't start with them.. first start with the ones that have ether divers license OR Leaders education.. because those already have a predefined seat (the only they can take)..
after those are filled.. assign the ones that can do ether jobs, for the seats that are missing or replace some if they are nearer.
after having a queue of drivers and a queue of leaders.. sort them by distance to the firehouse and assign to trucks in pairs.. then fill the rest of the truck.. removing from a queue by order of ETA..
not sure if it will always give the best solution.. but seems quite optimal.. to to you wish some code? C#?
the question made me curious so. here is the code for what I was talking.. eve if you don't use it
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace FF
{
class Program
{
[Flags]
public enum Skill
{
None = 0,
Driver = 1,
TeamLeader = 2,
}
public class FireFighter : IComparable<FireFighter>
{
public int ID;
public Skill Skills;//the skills that he has
public Skill Assigned;//the one that he will be deployed with
public int ETA;
public override string ToString()
{
return ID + "(" + Skills + ")" + " # " + ETA + " minutes as " + this.Assigned;
}
int IComparable<FireFighter>.CompareTo(FireFighter other)
{
return this.ETA.CompareTo(other.ETA);
}
}
public class Truck
{
public int ID;
public int Capacity;
public List<FireFighter> Crew = new List<FireFighter>();
}
static int TotalStationTrucks = 8;
static List<Truck> Trucks = new List<Truck>();
static List<FireFighter> Team = new List<FireFighter>();
static Random Rnd = new Random();
static void Main(string[] args)
{
//create the sample data
int nAvailableSeats = 0;
for (int i = 0; i < TotalStationTrucks; i++)
{
Truck oTruck = new Truck();
oTruck.ID = i;
nAvailableSeats += oTruck.Capacity = Rnd.Next(4, 7);//seats between 4 - 6
Trucks.Add(oTruck);
}
for (int i = 0; i < nAvailableSeats * 2; i++)//add twice the amount of FF we need for all trucks
{
FireFighter oFireFighter = new FireFighter();
oFireFighter.ID = i;
oFireFighter.ETA = Rnd.Next(Int16.MaxValue);
Team.Add(oFireFighter);
}
for (int i = 0; i < Trucks.Count * 2; i++)//add twice the drivers we need
{
FireFighter oFireFighter = Team[Rnd.Next(Team.Count)];
oFireFighter.Skills |= Skill.Driver;
}
for (int i = 0; i < Trucks.Count * 2; i++)//add twice the leaders we need
{
FireFighter oFireFighter = Team[Rnd.Next(Team.Count)];
oFireFighter.Skills |= Skill.TeamLeader;
}
for (int i = 0; i < Trucks.Count * 2; i++)//add twice the multitaskers we need
{
FireFighter oFireFighter = Team[Rnd.Next(Team.Count)];
oFireFighter.Skills = (Skill.TeamLeader|Skill.Driver);
}
//Truck that are going to be deployed
int nTrucksToDeploy = Rnd.Next(2, Trucks.Count);
// distribute firefighter by ETA to minimize truck deploy
//*******************************************************
//Sort by ETA
Team.Sort();
//get top the ones that can only drive
List<FireFighter> oSelectedDrivers = Team.FindAll(delegate(FireFighter item) { return item.Skills == Skill.Driver; }).GetRange(0, nTrucksToDeploy);
oSelectedDrivers.ForEach(delegate(FireFighter item) { item.Assigned = Skill.Driver; });
//get top the ones that can only lead
List<FireFighter> oSelectedLeaders = Team.FindAll(delegate(FireFighter item) { return item.Skills == Skill.TeamLeader; }).GetRange(0, nTrucksToDeploy);
oSelectedLeaders.ForEach(delegate(FireFighter item) { item.Assigned = Skill.TeamLeader; });
//put them on a list of already assigned
List<FireFighter> oAssigned = new List<FireFighter>();
oAssigned.AddRange(oSelectedDrivers);
oAssigned.AddRange(oSelectedLeaders);
//get the ones that can do ether job
List<FireFighter> oMultitaskers = Team.FindAll(delegate(FireFighter item) { return item.Skills == (Skill.Driver | Skill.TeamLeader); });
//sort by ETA
oMultitaskers.Sort();
oAssigned.Sort();
//put a multitaskers in the queue if he is gonna arrive earlier than the most delayed
while (oMultitaskers[0].ETA < oAssigned[oAssigned.Count - 1].ETA)
{
FireFighter oIsOut = oAssigned[oAssigned.Count - 1];
FireFighter oIsIn = oMultitaskers[0];
//swap tasks
oIsIn.Assigned = oIsOut.Assigned;
oIsOut.Assigned = Skill.None;
//remove from respective queues
oAssigned.RemoveAt(oAssigned.Count - 1);
oMultitaskers.RemoveAt(0);
//Add the multitasker to queue
//and if you are questioning if the could get a better solution by choosing another assignment
//that as no influence.. the optmizing condition is removing the slowest that was on queue
oAssigned.Add(oIsIn);
//the out guy is not added for two reasons
//1st is not a multitasker
//2nd and most importante.. he was the one with the highest ETA, we will NEVER gain by replacing another driver with this one
//oMultitaskers.Add(oIsOut);
oMultitaskers.Sort();
oAssigned.Sort();
}
//start filling the trucks take one of each from top, wich means the first truck will have the earliest departure
for (int i = 0; i < nTrucksToDeploy; i++)
{
int nDriverIndex = oAssigned.FindIndex(delegate(FireFighter item) { return item.Assigned == Skill.Driver; });
Trucks[i].Crew.Add(oAssigned[nDriverIndex]);
oAssigned.RemoveAt(nDriverIndex);
int nLeaderIndex = oAssigned.FindIndex(delegate(FireFighter item) { return item.Assigned == Skill.TeamLeader; });
Trucks[i].Crew.Add(oAssigned[nLeaderIndex]);
oAssigned.RemoveAt(nLeaderIndex);
}
//now fill the rest of the crew.. also ordered by ETA
List<FireFighter> oUnassigned = Team.FindAll(delegate(FireFighter item) { return item.Assigned == Skill.None; });
oUnassigned.Sort();
for (int i = 0; i < nTrucksToDeploy; i++)
{
while (Trucks[i].Crew.Count < Trucks[i].Capacity)
{
Trucks[i].Crew.Add(oUnassigned[0]);
oUnassigned.RemoveAt(0);
}
}
//dump truck data
Trace.WriteLine(String.Format("{0} trucks to be deployed",nTrucksToDeploy));
for (int i = 0; i < nTrucksToDeploy; i++)
{
Trace.WriteLine(new String('-', 20));
Truck oTruck = Trucks[i];
oTruck.Crew.Sort();
Trace.WriteLine(String.Format("truck {0} estimated time of departure: {1}",oTruck.ID,oTruck.Crew[oTruck.Crew.Count-1].ETA));
for (int j = 0; j < oTruck.Crew.Count; j++)
{
FireFighter oFireFighter = oTruck.Crew[j];
Trace.WriteLine(String.Format("{0}({1})\t # {2} minutes as \t{3}", oFireFighter.ID, oFireFighter.Skills, oFireFighter.ETA, oFireFighter.Assigned));
}
}
Trace.WriteLine(new String('#', 20));
//list the team
for (int i = 0; i < Team.Count; i++)
{
FireFighter oFireFighter = Team[i];
Trace.WriteLine(String.Format("{0}({1})\t # {2} minutes as \t{3}", oFireFighter.ID, oFireFighter.Skills, oFireFighter.ETA, oFireFighter.Assigned));
}
}
}
}

Tap BPM code in Processing

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);
}

Resources