I have an assignment to calculate the amount of carbon dioxide produced in a year from
a household and compare how recycling can reduce its CO2 Footprint.
There are two classes in the program, CO2FromWaste, and CO2FromWasteTester.
The first class, CO2FromWaste is:
public class CO2FromWaste
{
//declaration of private instance variables
private int numPeople;
private boolean Paper, Plastic, Glass, Cans;
private double grossWasteEmission, wasteReduction, netWasteReduction;
//constructor
CO2FromWaste(int people, boolean paper, boolean plastic, boolean glass, boolean cans){
numPeople = people;
Paper = paper;
Plastic = plastic;
Glass = glass;
Cans = cans;
grossWasteEmission = 0.0;
wasteReduction = 0.0;
netWasteReduction = 0.0;
}
public void calcGrossWasteEmission(){
grossWasteEmission = numPeople * 1018;
}
public double getGrossWasteEmission(){
return grossWasteEmission;
}
public void calcWasteReduction(){
if (Paper == true){
wasteReduction = numPeople * 184;
}
if (Plastic == true){
wasteReduction += (numPeople * 25.6);
}
if (Glass == true){
wasteReduction+= (numPeople*46.6);
}
if (Cans == true){
wasteReduction+=(numPeople*165.8);
}
}
public double getWasteReduction()
{
return wasteReduction;
}
public void calcNetWasteReduction(){
netWasteReduction = grossWasteEmission = wasteReduction;
}
public double getNetWasteReduction(){
return netWasteReduction;
}
public int getNumPeople(){
return numPeople;
}
public boolean getPaper(){
return Paper;
}
public boolean getPlastic(){
return Plastic;
}
public boolean getGlass(){
return Glass;
}
public boolean getCans(){
return Cans;
}
}
The second class, CO2FromWasteTester is:
import java.util.ArrayList;
public class CO2FromWasteTester
{
public static void main(String[]args){
ArrayList<CO2FromWaste> waste = new ArrayList<CO2FromWaste>();
waste.add(new CO2FromWaste(1, true, true, true, true));
waste.add(new CO2FromWaste(3, true, false, true, true));
waste.add(new CO2FromWaste(4, false, false, false, false));
waste.add(new CO2FromWaste(1, true, true, true, true));
waste.add(new CO2FromWaste(1, true, true, true, true));
CO2FromWaste wasteRecord;
for (int index = 0; index < waste.size(); index++){
wasteRecord = waste.get(index);
wasteRecord.calcGrossWasteEmission();
wasteRecord.calcWasteReduction();
wasteRecord.calcNetWasteReduction();
}
System.out.println(" Household Waste Recycled Total Pounds of CO2 Net");
System.out.println(" Index People Paper Plastic Glass Cans Emission Reduction Emission ");
for (int index = 0; index < waste.size(); index ++)
{
wasteRecord = waste.get(index);
System.out.printf("%3d %9d %10s %10s %10s %10s %12.2f %10.2f %10.2f%n",index,wasteRecord.getNumPeople(),wasteRecord.getPaper(), wasteRecord.getPlastic(), wasteRecord.getGlass(),wasteRecord.getCans(),wasteRecord.getGrossWasteEmission(),wasteRecord.getWasteReduction(),wasteRecord.getNetWasteReduction());
}
}
}
The output should read like a table, with the correct data under the headers.
For the first line, the output should be
0 1 true true true true 1018.00 422.00 596.00
but it reads
0 1 true true true true 422.00 422.00 422.00
There is something wrong starting the the gross emission part, and that part should be fairly simple because all it needs to do is to multiply the number of people given by 1018.
I am not sure what to do from here and would appreciate some help.
This is the problem:
public void calcNetWasteReduction(){
netWasteReduction = grossWasteEmission = wasteReduction;
}
That's equivalent to:
public void calcNetWasteReduction(){
grossWasteEmission = wasteReduction;
netWasteReduction = grossWasteEmission;
}
In other words, it's modifying grossWasteEmission when it shouldn't be. I suspect you wanted:
public void calcNetWasteReduction(){
netWasteReduction = grossWasteEmission - wasteReduction;
}
In other words, making the second = a - instead.
It's not clear why you have the three separate methods at all, to be honest - why not perform the calculations in the constructor? Or in the getter methods (removing the intermediate fields altogether)?
Additionally, consider making an enum of waste reduction types (PAPER, GLASS, PLASTIC) and taking an EnumSet of them. If you do keep them as individual parameters, I would strongly advise you to change the names to be more conventional Java (paper instead of Paper etc) and use if (paper) rather than if (paper == true) etc. In general, avoid explicit checking against Boolean constants.
The problem is here:
for (int index = 0; index < waste.size(); index++){
wasteRecord = waste.get(index);
wasteRecord.calcGrossWasteEmission();
wasteRecord.calcWasteReduction();
wasteRecord.calcNetWasteReduction(); // <== netWasteReduction = grossWasteEmission = wasteReduction;
}
You just need to replace the '=' sign below. Its because of this line that you are getting all the three values equal. :-)
public void calcNetWasteReduction(){
netWasteReduction = grossWasteEmission = wasteReduction;
Hope this helps
Related
As I know, the order of code running is top down. So when call 2 method book.ship(), chemistrySet.ship() at the bottom, I think the 1st one should be called first. So why the result shows as below:
High value item!
Shipping
Shipping cost: 1.75
Order not ready
For the book instance, the cost = 9.99, but it still shows High value item!. How can I figure this out?
public class Order {
boolean isFilled; //true
double billAmount; //9.99
String shipping; //Express
public Order(boolean filled, double cost, String shippingMethod) {
if (cost > 24.00) {
System.out.println("High value item!");
}
isFilled = filled;
billAmount = cost;
shipping = shippingMethod;
}
public void ship() {
if (isFilled) {
System.out.println("Shipping");
System.out.println("Shipping cost: " + calculateShipping());
} else {
System.out.println("Order not ready");
}
}
public double calculateShipping() {
// declare conditional statement here
if (shipping.equals("Regular")) {
return 0;
} else if (shipping.equals("Express")){
return 1.75;
} else {return .50;}
}
public static void main(String[] args) {
// do not alter the main method!
Order book = new Order(true, 9.99, "Express");
Order chemistrySet = new Order(false, 72.50, "Regular");
book.ship();
chemistrySet.ship();
}
}
The first thing happening here is the main() method, which is where the program starts:
public static void main(String[] args) {
// do not alter the main method!
Order book = new Order(true, 9.99, "Express"); //(1)
Order chemistrySet = new Order(false, 72.50, "Regular"); //(2)
book.ship(); //(3)
chemistrySet.ship(); //(4)
}
You call the constructor method of the class for "book":
public Order(boolean filled, double cost, String shippingMethod) {
if (cost > 24.00) {
System.out.println("High value item!");
}
isFilled = filled;
billAmount = cost;
shipping = shippingMethod;
}
And nothing is printed because cost < 24.00.
Now you call the constructor again for "chemistrySet", but this time it prints "High value item!" because its cost > 24.00
You call book.ship() and, since filled == true, it prints: Shipping and Shipping cost: 1.75
Now you call chemistrySet.ship(), but this time isFilled equals false, so it prints Order not ready
I am still beginner in programming. This is my first year.
I have some problem with my code. I hope you guys can help me with it.
This is my main (VehicleApp.java)
public static void main(String[] args) {
// TODO code application logic here
int acc, brake;
String type, powerTrain;
Scanner sc = new Scanner(System.in);
Vehicle vehicle = new Vehicle("Car", "Manual", "Electric");
//input
System.out.println("Type of vehicle? [Car, SUV, MPV, Lorry]: ");
type = sc.nextLine();
vehicle.setType(type);
if(type.equals("Lorry")){
System.out.println("Enter Accelerate: ");
acc = sc.nextInt();
vehicle.autoAccelerate(acc);
System.out.println("Enter Brake: ");
brake = sc.nextInt();
vehicle.autobrake(brake);
//output
System.out.println("===========================================\n");
System.out.println(vehicle.getPowertrain()+" "+vehicle.getType()+".");
System.out.println("\nAccelerate:\nCurrent Speed = "+vehicle.autoAccelerate(acc)+" kmh");
System.out.println("\nBrake:\nCurrent Speed = "+vehicle.autobrake(brake)+" kmh");
System.out.println("\nPrice: RM "+vehicle.getRoadtaxPrice());
}
else{
System.out.println("Type of powertrain? [Gasoline, Hybrid, Electric]: ");
powerTrain = sc.nextLine();
vehicle.setPowertrain(powerTrain);
System.out.println("Enter Accelerate: ");
acc = sc.nextInt();
vehicle.autoAccelerate(acc);
System.out.println("Enter Brake: ");
brake = sc.nextInt();
vehicle.autobrake(brake);
//output
System.out.println("===========================================\n");
System.out.println(vehicle.getPowertrain()+" "+vehicle.getType()+".");
System.out.println("\nAccelerate:\nCurrent Speed = "+vehicle.autoAccelerate(acc)+" kmh");
System.out.println("\nBrake:\nCurrent Speed = "+vehicle.autobrake(brake)+" kmh");
System.out.println("\nPrice: RM "+vehicle.getRoadtaxPrice());
}
}
This is my class (Vehicle.java)
public class Vehicle {
private String typeVehicle, transmissionVehicle, powertrainVehicle;
private int speedVehicle;
public Vehicle(String type, String transmission, String powertrain){
this.typeVehicle = type;
this.transmissionVehicle = transmission;
this.powertrainVehicle = powertrain;
speedVehicle = 60;
}
public int accelerate(){
return speedVehicle+=10;
}
public int brake(){
return speedVehicle-=5;
}
//Getter
public String getType(){
return typeVehicle;
}
//Setter
public void setType(String type){
//type = this.typeVehicle;
this.typeVehicle = type;
}
//Lab3 Start
public int autoAccelerate(int accelerate){
for(int i = 0; i < accelerate; i++){
speedVehicle += 10;
}
return speedVehicle;
}
public int autobrake(int brake){
for(int i = 0; i < brake; i++){
speedVehicle -= 5;
if(speedVehicle <= 0){
speedVehicle = 0;
}
}
return speedVehicle;
}
public double getRoadtaxPrice(){
double price = 0;
if (typeVehicle == "Car"){
if (powertrainVehicle == "Gasoline"){
price = 200;
}
else if (powertrainVehicle == "Hybrid"){
price = 100;
}
else if (powertrainVehicle == "Electric"){
price = 50;
}
else{
price = 0;
}
}
else if (typeVehicle == "SUV" || typeVehicle == "MPV"){
if (powertrainVehicle == "Gasoline"){
price = 300;
}
else if (powertrainVehicle == "Hybrid"){
price = 150;
}
else if (powertrainVehicle == "Electric"){
price = 100;
}
else{
price = 0;
}
}
else if (typeVehicle == "Lorry"){
powertrainVehicle = "All";
price = 400;
}
return price;
}
//Lab3 End
//Getter
public String getTransmission(){
return transmissionVehicle;
}
//Setter
public void setTransmission(String transmission){
transmission = this.transmissionVehicle;
}
//Getter
public String getPowertrain(){
return powertrainVehicle;
}
//Setter
public void setPowertrain(String powertrain){
powertrain = this.powertrainVehicle;
}
public void output(){
System.out.println("Type of vehicle: "+getType());
}
}
My input:
Type of vehicle? [Car, SUV, MPV, Lorry]:
MPV
Type of powertrain? [Gasoline, Hybrid, Electric]:
Hybrid
Enter Accelerate:
2
Enter Brake:
2
My output:
===========================================
Electric MPV.
Accelerate:
Current Speed = 90 kmh
Brake:
Current Speed = 80 kmh
Price: RM 0.0
The output should be like this:
===========================================
Hybrid MPV.
Accelerate:
Current Speed = 90 kmh
Brake:
Current Speed = 80 kmh
Price: RM 150.0
There are problems with the Price and Powertrain.
Please help me!
Thank you.
My first thought is that vehicle.typeVehicle or vehicle.powertrainVehicle have an extra space at the end of them you aren't accounting for. But we can't know that just from your code. I'd suggest you learn to step through your code using your IDE's debugger. Then watch how it goes through the code as well as exactly what values each variable and property are getting.
That was going to be my comment, then I looked at the code a little harder and found the mistake. And you have more than one. Stepping through your code with an IDE's debugger should help you solve this kind of problem, which is why I'm leaving that part in.
Your setPowertrain and setTransmission methods have the same bug. You are setting the parameter to the value of the existing property, instead of the other way around. You are doing it correctly in your constructor and setType, though.
public void setPowertrain(String powertrain){
// powertrain = this.powertrainVehicle;
this.powertrainVehicle = powertrain;
}
public void setTransmission(String transmission){
// transmission = this.transmissionVehicle;
this.transmissionVehicle = transmission;
}
Everyone misses things at times, which is why having a 2nd set of eyes on code is so great. There's even a semi-official idea of "rubber ducking", where people keep something like a rubber duck at their desk. Then whenever they run into a problem, they start explaining it to the duck as if they were showing someone else the problem. This helps puts your brain into a different mode and you can hopefully see your problems/issues/bugs/blocks/whatever with sort of a new set of eyes.
I have a list of objects, each has two fields, name and weight. I need to populate and calculate the weights from those list that will fulfill a parameter of an object in list of other objects, however it must create this new objects only when the sum of weight doesn't exceed the maximum, then it moves on, calculates another weight from the first list until maximum and then create an object with a needed parameter for the other list, this is what it looks like in a code.
This is the first list:
[Item{name='building tools', weight=2000}, Item{name='building tools', weight=2000}, Item{name='building tools', weight=2000}, Item{name='building tools', weight=5000}, Item{name='building tools', weight=5000}, Item{name='building tools', weight=2000}, Item{name='building tools', weight=1000}, Item{name='building tools', weight=5000}, Item{name='building tools', weight=6000}, Item{name='shelter equipment', weight=5000}, Item{name='construction equipment', weight=5000}, Item{name='plants', weight=1000}, Item{name='steel', weight=8000}, Item{name='books', weight=1000}, Item{name='water', weight=5000}]
Now I am creating a loop that takes the weights into separate variable until its less than 8000, then I need to populate other list of objects, where one of the paramether is the weight of those items and it cannot be greater than 8000, this is how it looks like in a code:
public List<Rocket> loadU1(List<Item> items) {
List<Rocket> u1Rockets = new ArrayList<>();
for (int i = 0; i < items.size(); i++) {
if ( testWeight + items.get(i).getWeight() <= 8000) {
testWeight += items.get(i).getWeight();
} else {
u1Rockets.add(new U1(120, 10000, 18000, testWeight));
testWeight = 0;
}
}
return u1Rockets;
}
testWeight is the calculation variable its a global int variable in the class. The constructor for a new u1Rocket has everything static except the last parameter which is the weight which cannot exceed 8000. When I run loadU1, this is however how it looks populated:
[U1{cost=120, weight=10000, maxWeight=18000, weightOfCargo=6000}, U1{cost=120, weight=10000, maxWeight=18000, weightOfCargo=8000}, U1{cost=120, weight=10000, maxWeight=18000, weightOfCargo=6000}, U1{cost=120, weight=10000, maxWeight=18000, weightOfCargo=6000}]
It works just fine until i=3, then it of course sets testWeight to 0, so it could calculate it over but then doesn't creates a new rocket object with 5000 as it should because the one after 5000 (i = 4) is also 5000 which exceeds the limit so it should create separate Rocket with 5000 for this one and then of course go on... I am trying to debug it but cannot find out where is the exact logical problem from my side, thanks.
So this is my Rocket class,
public class Rocket implements Spaceship {
private int price;
private int weight;
private int weightOfCrago;
private int maxWeight;
public Rocket(int price, int weight, int weightOfCrago, int maxWeight) {
this.price = price;
this.weight = weight;
this.weightOfCrago = weightOfCrago;
this.maxWeight = maxWeight;
}
public Rocket() {
}
#Override
public boolean launch() {
return true;
}
#Override
public boolean land() {
return true;
}
#Override
public boolean canCarry(Item item) {
if ((item.getWeight() + weightOfCrago) <= (maxWeight - weight)){
return true;
}else {
return false;
}
}
#Override
public void carry(Item item) {
maxWeight += item.getWeight();
}
Couldn't for example somehow the canCarry method be used before creation in the loop I have posted before to prevent from creating a new Rocket object that exceeds the limit ? The U1 is a child of a Rocket.
The problem is that your code simply skips the currently checked item when the rocket is already full.
The fastest way to solve this would be to return to the skipped position whenever a rocket is created (thus i--). But you also always skip the last bucket, so you must still add it. See:
for (int i = 0; i < items.size(); i++) {
if (testWeight + items.get(i).getWeight() <= 8000) {
testWeight += items.get(i).getWeight();
} else {
u1Rockets.add(new U1(120, 10000, 18000, testWeight));
testWeight = 0;
// re-check the skipped item
i--;
}
}
// add the last rocket
u1Rockets.add(new U1(120, 10000, 18000, testWeight));
Note that you have a variation of the bin packing problem on your hands here, an NP-complete problem.
I'm trying to store 5 different boolean answers (true or false) in 5 different array positions after each loop and then make a method to display the questions which were 'true'.
For example, a test run would go like this:
Question1: Content1 ~ (True or False?) False
Question2: Content2 ~ (True or False?) True
Question3: Content3 ~ (True or False?) False
(loop finished)
Question2: Content2
(exit)
And here is my code so far.
import javax.swing.*;
class booleanTest {
public static void main(String [] params) {
String[] data = {"Test1", "Test2", "Test3", "Test4", "Test5"};
boolean[] user = new boolean[5];
array_input(data, user);
System.out.println(user); // to see if it works atm
System.exit(0);
}
public static String array_input(String[] a, boolean[] b) {
String x = "";
for (int i=0; i<a.length; i++) {
x = JOptionPane.showInputDialog("Data: " + a[i]);
if(x.equals("yes")) {
b[i] = true;
}
else {
b[i] = false;
}
}
return x;
}
//public static String array_print() {
// print the boolean + question here
//}
}
It doesn't work, I understand that the b[i] = true part must be wrong, I should do something else?
If the value at an index of the boolean array is true, print out the value in the String array at that index.
public static void printTrue(boolean[] answers, String[] questions) {
// checking both indices to avoid ArrayIndexOutOfBoundsException
for (int i = 0; i < answers.length && i < questions.length; i++) {
// if the answer is true
if (answers[i]) {
System.out.println(questions[i] + ": " + true);
}
}
}
When you say System.out.println(user); prints something like [Z#3b9187c7, this is because the toString() implementation for Object returns class name + # + hex hashCode().
The Arrays#toString method creates a more readable result:
[false, false, false, true, true]
You only have to return values in a method when you have no other way of accessing the data. If you look at your code you see that you're not even using the returned value, and the last values for x will never be useful anyway. In that kind of case, you can make it a void method. Void methods are used when you want it to perform some kind of operation, but don't need it to return any values. Your code works because an array is an Object and the changes done to it can be seen even outside the method.
Here's more or less how I would implement it. Notice the variable names are a little more descriptive.
import javax.swing.*;
public class Main {
public static void main(String[] args) {
String[] questions = {"Test1", "Test2", "Test3", "Test4", "Test5"};
boolean[] responses = getUserResponses(questions);
}
public static boolean[] getUserResponses(String[] questions) {
boolean[] responses = new boolean[questions.length]; //use the length of the other array. Don't count on it always being 5
for (int i = 0; i< questions.length; i++) {
String x = JOptionPane.showInputDialog("Data: " + questions[i]);
if(x.equals("yes")) {
responses[i] = true;
}
else {
responses[i] = false;
}
}
return responses;
}
}
In general, it's better not to modify parameter Objects and to instead return new ones. Sometimes it is much more useful or necessary to do it that way, but in your case it was not.
It looks like you're on the correct path.
Array creation and element assignment:
Your code for this looks fine. You create the array using the new operator, as you would any object, but must specify an array size, as you did. Element assignment is done using an index, either an integer literal or an integer variable (in the case of your code above). Array indices range from 0 to size-1. It looks like you also got that part right.
Printing the results:
In your scenario, you only want to some of the results, where the array value is true. A simple loop with an if(user[i]) would do the trick.
for (int i = 0; i < user.length; i++) {
if (user[i]) {
System.out.println(data[i] + " = " + true);
}
}
I was recently in a job interview for a position as Java Developer. I was given a task: To think about a good way to represent an electric circuit (such as the one in the figure below) in Java.
A circuit is a combination of logic gates XOR, AND, OR etc.. Each gate has two input ports and an output port. Each output is connected to an input of another gate, which goes all the way to a higher gate (as in the picture). Make the system simple, no cycles are allowed (although real life circuits can have them).
I was asked to think about a good way to represent this model in Java, using the following guidelines:
I am given a circuit and a list of values which should be provided to its inputs.
I need to create a model to represent the circuit in Java, i.e., I need to define classes and an API that could be used to represent the circuit.
According to the input values and how the gates are connected, I need to calculate the output that the represented circuit would produce.
I need to think about a way to represent the board, use abstract classes or interfaces, and show understanding of the model (and if needed to use pattern design).
I chose to design the system as a tree and the interviewer told me it was a good choice. Then I build those classes:
Node
public class gate_node {
gate_node right_c,left_c;
Oprtator op;
int value;
int right_v,left_v;
public gate_node(gate_node right,gate_node left,Oprtator op){
this.left_c=left;
this.right_c=right;
this.op=op;
right_v=left_v=0;
}
}
Tree
public class tree {
gate_node head;
tree(gate_node head) {
this.head = head;
}
void go_right() {
head = head.right_c;
}
void go_left() {
head = head.left_c;
}
static int arr[] = { 0, 0, 1, 0 };
static int counter=0;
static int compute(gate_node head) {
if ((head.left_c == null) && (head.right_c == null))
{
int ret=(head.op.calc(arr[counter], arr[counter+1]));
counter++;
counter++;
return ret;
}
return (head.op.calc(compute(head.left_c), compute(head.right_c)));
}
public static void main(String[] args) {
tree t = new tree(new gate_node(null, null, new and()));
t.head.left_c = new gate_node(null, null, new and());
t.head.right_c = new gate_node(null, null, new or());
System.out.println(tree.compute(t.head));
}
}
Oprtator class:
public abstract class Oprtator {
abstract int calc(int x, int y);
}
OR gate:
public class or extends Oprtator {
public int calc(int x, int y){
return (x|y);
}
}
In the above code, I implemented the board as a tree with its a current head (which can go down to the left/right children). Every node has 2 children (also node type), 2 entries (0/1), a value and an operator (abstract class, could be extended by OR/AND..).
I used a counter and an array to insert the values to the appropriate leafs of the tree (as mentioned in the code).
It works but still I got a feeling that my interviewer wanted something more. Is my code is correct? Does anyone have a better way of represent this electrical board and how to give a good output (in terms of complexity or using better connection from one class to another, design patterns, something else?)
It's not a "perfect" answer, but you can solve this using a few classes to hold the logical connection/evaluation and then recursively evaluate the circuit.
Create a base class LogicalNode and give it a list of inputs to manage. Give it a base class function to evaluate all the inputs and return an output. This gets overridden in derived classes. Each type of node (INPUT, NOT, AND, OR) gets a derived class with a special "ComputOutput" overridden version. If you compute the output at the output node, it should recurse up the tree, computing all inputs of inputs of inputs, etc., till it reaches the "INPUT" nodes, which are fixed/logical inputs to the system.
You can create new types fairly quickly (see code). Not a lot of comments here, but it should be somewhat self explanatory.
Something like this (in C#):
public class LogicalNode
{
private List<LogicalNode> _inputs = new List<LogicalNode>();
private String _name = "Not Set";
public override string ToString()
{
return String.Format("Node {0}", _name);
}
public void Reset()
{
_inputs.Clear();
}
public void SetName(String name)
{
_name = name;
}
protected List<LogicalNode> GetInputs()
{
return _inputs;
}
public void AddInput(LogicalNode node)
{
_inputs.Add(node);
}
protected virtual bool ComputeOutputInternal()
{
return false;
}
public bool ComputeOutput()
{
// Console.WriteLine("Computing output on {0}.", _name);
return ComputeOutputInternal();
}
}
public class LogicalInput : LogicalNode
{
private bool _state = true;
public void SetState(bool state)
{
_state = state;
}
public bool GetState() { return _state; }
protected override bool ComputeOutputInternal()
{
return _state;
}
}
public class LogicalAND : LogicalNode
{
protected override bool ComputeOutputInternal()
{
List<LogicalNode> inputs = GetInputs();
bool result = true;
for (Int32 idx = 0; idx < inputs.Count && result; idx++)
{
result = result && inputs[idx].ComputeOutput();
}
return result;
}
}
public class LogicalOR : LogicalNode
{
protected override bool ComputeOutputInternal()
{
List<LogicalNode> inputs = GetInputs();
bool result = false;
for (Int32 idx = 0; idx < inputs.Count; idx++)
{
result = inputs[idx].ComputeOutput();
if (result)
// If we get one true, that is enough.
break;
}
return result;
}
}
public class LogicalNOT : LogicalNode
{
protected override bool ComputeOutputInternal()
{
List<LogicalNode> inputs = GetInputs();
if (inputs.Count > 0)
{ // NOTE: This is not an optimal design for
// handling distinct different kinds of circuits.
//
// It it demonstrative only!!!!
return !inputs[0].ComputeOutput();
}
return false;
}
And then to (quickly) test it:
static void Main(string[] args)
{
// The test circuit
// !((A&&B) || C)
// A B C Out
// 1 1 1 0
// 1 1 0 0
// 1 0 1 0
// 1 0 0 1
// 0 1 1 0
// 0 1 0 1
// 0 0 1 0
// 0 0 0 1
//
//
//
/* ------- -------
* A - | | | |
* | AND |-----| | -------
* B - | (D) | | | | |
* ------- | OR |----| NOT |----
* | (E) | | (F) |
* C --------------| | | |
* ------- -------
*/
LogicalInput A = new LogicalInput();
LogicalInput B = new LogicalInput();
LogicalInput C = new LogicalInput();
LogicalAND D = new LogicalAND();
LogicalOR E = new LogicalOR();
LogicalNOT F = new LogicalNOT();
A.SetName("A");
B.SetName("B");
C.SetName("C");
D.SetName("D");
E.SetName("E");
F.SetName("F");
D.AddInput(A);
D.AddInput(B);
E.AddInput(D);
E.AddInput(C);
F.AddInput(E);
// Truth Table
bool[] states = new bool[]{ true, false };
for(int idxA = 0; idxA < 2; idxA++)
{
for(int idxB = 0; idxB < 2; idxB++)
{
for(int idxC = 0; idxC < 2; idxC++)
{
A.SetState(states[idxA]);
B.SetState(states[idxB]);
C.SetState(states[idxC]);
bool result = F.ComputeOutput();
Console.WriteLine("A = {0}, B = {1}, C = {2}, Output = {3}",
A.GetState(), B.GetState(), C.GetState(), result.ToString());
}
}
}
}
}
With output:
A = True, B = True, C = True, Output = False
A = True, B = True, C = False, Output = False
A = True, B = False, C = True, Output = False
A = True, B = False, C = False, Output = True
A = False, B = True, C = True, Output = False
A = False, B = True, C = False, Output = True
A = False, B = False, C = True, Output = False
A = False, B = False, C = False, Output = True
Was this helpful?
While I obviously can't say exactly what the interviewer was looking for, if I were interviewing you I would probably press you to make your compute method a non-static member of your gate_node class. This way, your networks do not have to be "balanced" (they can be deeper, have more inputs) on one side or the other.
Put another way, looking at your compute code, I do not believe it would work for general circuits.
Perhaps something like the following (in gate_node):
int compute() {
/* The following use of a static sInputCounter assumes that the static/global
* input array is ordered from left to right, irrespective of "depth". */
final int left = (null != left_c ? left_c.compute() : sInput[sInputCounter++]);
final int right = (null != right_c ? right_c.compute() : sInput[sInputCounter++]);
return op.calc(left, right);
}
This way, the "tree" can just be represented by the head/root gate_node (although you still probably want a class like your tree class -- I might call it "network" just to avoid confusion, with static methods for constructing the tree, setting up the inputs, etc.) and you trigger the network evaluation by calling head.compute().
Of course, you are still left with the non-trivial problem of constructing a network from some external specification. I imagine that another issue for the interviewer could have been that this aspect was not well-specified in your solution. (Nor in mine here either, I'm sorry.)