I'm practicing for a contest by doing some of the older problems, and I was wondering if there are more efficient ways of doing this or if I'm not following any coding conventions. Most importantly, I would like to know if I am using ArrayList correctly in this code, since I learned how to use it off of a brief tutorial on another website.

Problem S2: Bridge transport

A train of railway cars attempts to cross a bridge. The length of each car is 10m but their weights can differ. The bridge is 40m long. The cars are numbered starting at 1, going up to N, and they cross the bridge in that order. Your job is to find the largest number of railway cars that can safely cross the bridge.

Sample Input

100

6

50

30

10

10

40

50

Sample Output

5

Explanation for input/output

The first number indicates the maximum weight that the bridge can hold (100), the second number tells us how many railway cars there are in total (6), and the next N (6) lines are the weights of those respective railway cars (in order, so car 1 has a weight of 50 and so on). The first four railway cars have total weight of 100, which is not greater than what the bridge can hold. When the first railway car leaves, and the next comes on, we have a total weight of $$30 + 10 + 10 + 40 = 90$$ This is also fine because it's not greater than what the bridge can hold. The last four cars would cause the bridge to break, since $$10 + 10 + 40 + 50 = 110$$ which is greater than the bridge can hold. Therefore, to get the maximum number of railway cars, you would need to disengage the last car, and let the first five go.

My solution:

public class BridgeTransport {

public static void main(String args[]) {

    try {
        BufferedReader input = new BufferedReader(new InputStreamReader(
                System.in));

        int maxWeight = Integer.parseInt(input.readLine());
        int totalCars = Integer.parseInt(input.readLine());
        int crossedCars = 0;
        int massOnBridge = 0;

        ArrayList<Integer> cars = new ArrayList<Integer>();
        ArrayList<Integer> carsOnBridge = new ArrayList<Integer>();

        // to get a list of all the weights of cars
        for (int i = 0; i < totalCars; i++) {
            cars.add(Integer.parseInt(input.readLine()));
        }

        for (int i = 0; i < totalCars; i++) {

            // put the cars on the bridge one by one, if there are more than 4
            // cars, then remove the first car
            carsOnBridge.add(cars.get(i));
            if (carsOnBridge.size() > 4) {
                carsOnBridge.remove(0);
            }

            // gets the sum of the masses on the bridge
            for (int j = 0; j < carsOnBridge.size(); j++) {
                massOnBridge += carsOnBridge.get(j);
            }

            // if the masses are less than the max weight for the bridge,
            // then they can successfully cross
            if (massOnBridge <= maxWeight) {
                crossedCars++;
            } else {
                break;
            }

            //reset the sum of the masses on the bridge back to zero
            massOnBridge = 0;

        }

        System.out.println(crossedCars);

    } catch (IOException e) {
        e.printStackTrace();
    }
}
}
  1. Am I using ArrayList correctly here?

  2. Are there better ways to accomplish this task?

  3. I feel guilty for resetting the mass on the bridge to 0 each iteration. Is that okay, or is there a better way to do it?

up vote 1 down vote accepted
  1. Instead of resetting the massOnBridge, you can declare it inside the body of the for loop:

    for (int i = 0; i < totalCars; i++) {
        int massOnBridge = 0;
        ...
    

    It is a good practice to keep a scope of a variable as narrow as possible.

  2. There are a lot of comments in your code that tell what the code does. Instead, you should try to write a self-documenting code. You can increase modularity and clarity of your code by using separate methods for separate tasks. For instance,

    // gets the sum of the masses on the bridge
    for (int j = 0; j < carsOnBridge.size(); j++) {
         massOnBridge += carsOnBridge.get(j);
    }
    

    looks like a very good candidate for a separate method:

    /**
      * Computes the sum of elements of {@code aList}.
      * @param aList A list of integers. Must not contain {@code null} elements.
      *              Must be non-{@code null}.
      * @return The sum of elements of the given list.
      */
    private static int getSum(List<Integer> aList) {
        int sum = 0;
        for (int value : aList) {
             sum += value;
        }
        return sum;
     }
    

    Having one long method(main in your case) that does everything is a bad practice.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.