Java Fitness Function - Scales - java

I have a fitness function as part of a lab and wish to apply it to a set of 'weights' (ArrayList weights). I have created the array and stored some values in it. I have created random binary strings (which have an 'x' at the end in order to generate random values) which I wish to also apply the fitness function to; however, the problem I am having is that the fitness function always returns a value of 0. Am I missing something here?
The fitness function is as follows:
import java.util.*;
public class ScalesSolution{
private static String scasol;
//Creates a new scales solution based on a string parameter
//The string parameter is checked to see if it contains all zeros and ones
//Otherwise the random binary string generator is used (n = length of parameter)
public ScalesSolution(String s)
{
boolean ok = true;
int n = s.length();
for(int i=0;i<n;++i)
{
char si = s.charAt(i);
if (si != '0' && si != '1') ok = false;
}
if (ok)
{
scasol = s;
}
else
{
scasol = RandomBinaryString(n);
}
}
private static String RandomBinaryString(int n)
{
String s = new String();
//Code goes here
//Create a random binary string of just ones and zeros of length n
for(int i = 0; i < n; i++){
int x = CS2004.UI(0,1);
if(x == 0){
System.out.print(s + '0');
}
else if(x == 1){
System.out.print(s + '1');
}
}
return(s);
}
public ScalesSolution(int n)
{
scasol = RandomBinaryString(n);
}
//This is the fitness function for the Scales problem
//This function returns -1 if the number of weights is less than
//the size of the current solution
//EXERCISE 3
public static double ScalesFitness(ArrayList<Double> weights)
{
int n = scasol.length();
double lhs = 0.0, rhs = 0.0;
if (n > weights.size()) return(-1);
for(int i = 0; i < n; i++){
if(scasol.charAt(i) == 0){
lhs += weights.get(i);
}
else{
rhs += weights.get(i);
}
}
//Code goes here
//Check each element of scasol for a 0 (lhs) and 1 (rhs) add the weight wi
//to variables lhs and rhs as appropriate
return(Math.abs(lhs-rhs));
}
//Display the string without a new line
public void print()
{
System.out.print(scasol);
}
//Display the string with a new line
public void println()
{
print();
System.out.println();
}}
Main method (in separate class):
import java.util.ArrayList;
public class Lab8 {
public static void main(String args[])
{
for(int i = 0; i < 10; i++){
ScalesSolution s = new ScalesSolution("10101x");
s.println();
}
ArrayList<Double> weights = new ArrayList<Double>();
weights.add(1.0);
weights.add(2.0);
weights.add(3.0);
weights.add(4.0);
weights.add(10.0);
System.out.println();
System.out.println(weights);
System.out.print("Fitness: ");
double fitness = ScalesSolution.ScalesFitness(weights);
System.out.println(fitness);
}}
CS2004 class:
import java.util.*;
import java.io.*;
//Some useful code that we will probably reuse in later laboratories...
public class CS2004
{
//Shared random object
static private Random rand;
//Create a uniformly distributed random integer between aa and bb inclusive
static public int UI(int aa,int bb)
{
int a = Math.min(aa,bb);
int b = Math.max(aa,bb);
if (rand == null)
{
rand = new Random();
rand.setSeed(System.nanoTime());
}
int d = b - a + 1;
int x = rand.nextInt(d) + a;
return(x);
}
//Create a uniformly distributed random double between a and b inclusive
static public double UR(double a,double b)
{
if (rand == null)
{
rand = new Random();
rand.setSeed(System.nanoTime());
}
return((b-a)*rand.nextDouble()+a);
}
//This method reads in a text file and parses all of the numbers in it
//This code is not very good and can be improved!
//But it should work!!!
//It takes in as input a string filename and returns an array list of Doubles
static public ArrayList<Double> ReadNumberFile(String filename)
{
ArrayList<Double> res = new ArrayList<Double>();
Reader r;
try
{
r = new BufferedReader(new FileReader(filename));
StreamTokenizer stok = new StreamTokenizer(r);
stok.parseNumbers();
stok.nextToken();
while (stok.ttype != StreamTokenizer.TT_EOF)
{
if (stok.ttype == StreamTokenizer.TT_NUMBER)
{
res.add(stok.nval);
}
stok.nextToken();
}
}
catch(Exception E)
{
System.out.println("+++ReadFile: "+E.getMessage());
}
return(res);
}}
Once run, the random binary strings work perfectly well, yet the fitness function fails to change from 0. Here is a sample output:
011100
111010
001110
111011
001000
010101
001010
100011
110100
011001
[1.0, 2.0, 3.0, 4.0, 10.0]
Fitness: 0.0
Thank you all so much for your time.
Stefanos.

scasol appears to be empty when ScalesFitness is called. In the RandomBinaryString method, you never actually construct s, but rather, just print it out. Instead of System.out.print(s+'0') and the other line, you should have s += '0';.
Since this appears to be an exercise, I'll leave the rest to you, but here is a tip for next time: don't have a function do more than it's supposed to (such as printing out its results), otherwise, it might look like the set of functions is actually working, when in reality it isn't.
In this case, it looked like everything was working fine since it appeared like the s.println() function what actually printing out scasol, but in reality, scasol was empty and the RandomBinaryString method was actually doing the printing.

Related

ArrayList with even or odd

I would like to checking if an element is even or odd. What is wrong with my code?
bad operand types for binary operator '%' first type: java.lang.String second type: int, line 16
incompatible types: java.util.ArrayDeque cannot be converted to java.util.ArrayList, line 44
class ArrayExample{
public void printMethod(ArrayList<String> theList){
String value = null;
for (int n=0; n < theList.size(); n++){
value = theList.get(n);
//checking if an element is even or odd
if (value.length % 2 == 0){
System.out.println("even");
System.out.println(value);
} else {
System.out.println("odd");
System.out.println(value);
}}}}
class Calc {
public static void main(String[] args) {
ArrayDeque<String> storeQueue = new ArrayDeque<String>();
for (int i = 0; i < 40; i++) {
Random rand = new Random();
int value = rand.nextInt((40 - 1) + 1) + 1;
String z = new String(new char[value]).replace("\0", "z");
storeQueue.add(z);
System.out.println(storeQueue);
}
ArrayExample samp = new ArrayExample();
samp.printMethod(storeQueue);
}}
I think you can simply using ArrayList instead of ArrayDeque unless you want to perform FIFO operation. Also you might realised that your array is consisted of String, mod operation here should take input as integer. So you can use this random:
Random random = new Random();
int randomInteger = random.nextInt();
Here are the 2 changes required to make the program work:
Change the operands of % operator to Integer (Use value.length in place of value)
Change the argument to printMethod from ArrayDeque type to 'ArrayList' type.
Here is the working solution, with these 2 changes:
// File name: Calc.java
import java.util.*;
class ArrayExample{
public void printMethod(ArrayList<String> theList) {
String value = null;
for (int n=0; n < theList.size(); n++){
value = theList.get(n);
//checking if an element is even or odd
if ((value.length()) % 2 == 0) {
System.out.println("even - " + value);
} else {
System.out.println("odd - " + value);
}
}
}
}
public class Calc {
public static void main(String[] args) {
ArrayDeque<String> storeQueue = new ArrayDeque<String>();
for (int i = 0; i < 40; i++) {
Random rand = new Random();
int value = rand.nextInt((40 - 1) + 1) + 1;
String z = new String(new char[value]).replace("\0", "z");
storeQueue.add(z);
System.out.println(storeQueue);
}
ArrayExample samp = new ArrayExample();
samp.printMethod(new ArrayList<String>(storeQueue));
}
}
Output:
> javac Calc.java
> java Calc
[zzzzzzzzzzzzzzzzzzzz]
[zzzzzzzzzzzzzzzzzzzz, zzzzzz]
[zzzzzzzzzzzzzzzzzzzz, zzzzzz, zzzzzzzzzzzzzzzzzzz]
[zzzzzzzzzzzzzzzzzzzz, zzzzzz, zzzzzzzzzzzzzzzzzzz, zzzzzzzzzzzzzzzzzzzzzzzzzzzz]
...
...
...
even - zzzzzzzzzzzzzzzzzzzz
even - zzzzzz
odd - zzzzzzzzzzzzzzzzzzz
even - zzzzzzzzzzzzzzzzzzzzzzzzzzzz
even - zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
odd - zzzzzzzzzzzzzzzzz
even - zzzzzzzzzzzzzzzz
odd - zzzzzzzzzzzzzzz
odd - zzzzzzzzz
odd - zzzzzzzzzzz
even - zzzzzzzzzzzzzz
even - zzzzzzzzzzzzzzzzzzzzzz
odd - zzzzz
even - zzzz
even - zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
In your class ArrayExample method printMethod expect ArrayList as parameter, but in main method you try to pass ArrayDeque which is not compatible with ArrayList.
To resolve this problem you should change parameter declaration in printMethod to ArrayDeque, but still there is a problem becouse ArrayDeque dont have .get method.
I propose to change body of method to foreach loop.
And another bug in this code is you try modulo on String but you need do it on its length. You cannot modulo on text, rather you should use it on text length.
class ArrayExample {
public void printMethod(ArrayDeque<String> theList) {
String value = null;
for (String s : theList) {
if (s.length() % 2 == 0) {
System.out.println("even");
System.out.println(value);
} else {
System.out.println("odd");
System.out.println(value);
}
}
}
}
And you main class can stay the same as you write.
It works - #Gopinath
// File name: Calc.java
import java.util.*;
class ArrayExample{
public void printMethod(ArrayList<String> theList) {
String value = null;
for (int n=0; n < theList.size(); n++){
value = theList.get(n);
//checking if an element is even or odd
if ((value.length()) % 2 == 0) {
System.out.println("even - " + value);
} else {
System.out.println("odd - " + value);
}
}
}
}
public class Calc {
public static void main(String[] args) {
ArrayDeque<String> storeQueue = new ArrayDeque<String>();
for (int i = 0; i < 40; i++) {
Random rand = new Random();
int value = rand.nextInt((40 - 1) + 1) + 1;
String z = new String(new char[value]).replace("\0", "z");
storeQueue.add(z);
System.out.println(storeQueue);
}
ArrayExample samp = new ArrayExample();
samp.printMethod(new ArrayList<String>(storeQueue));
}
}

Copying Object in Java

So I've been tasked to work on an algorithm based on Random Mutation Hill Climbing. I have a method RMHC that takes in an ArrayList of weights and two ints, one for number of weights and another for iterations. My instructions tell me to create an initial solution, copy it and then apply a mutation method SmallChange() to the initial solution. I was also instructed on how to copy the solution with the GetSol() method in my ScalesSolution class. The mutation takes in a binary String value (i.e 11101) and changes a random substring in the binary to either 0 or 1 so I may be met with an output such as 10101 if the 2nd substring is mutated.
My issue is that when I make the SmallChange() to my solution, it makes the change to the original solution also.
I've already tried adding a copy constructor as what was suggested in another question I'd found, but it did not work.
Main Method
public class Worksheet9 {
public static void main(String[] args) {
ArrayList<Double> myArray = new ArrayList<Double>();
myArray.add(1.0);
myArray.add(2.0);
myArray.add(3.0);
myArray.add(4.0);
myArray.add(10.0);
RMHC(myArray, 5, 2);
}
RMHC Method
public static ScalesSolution RMHC(ArrayList<Double> weights,int n,int iter)
{
ScalesSolution oldsol = new ScalesSolution(n);
ScalesSolution newsol = new ScalesSolution(oldsol.GetSol());
//Attempting Copy Constructor
ScalesSolution newsol = new ScalesSolution(oldsol);
double origfitness = oldsol.ScalesFitness(weights);
System.out.println("Original Fitness: " + origfitness);
double origfitness1 = newsol.ScalesFitness(weights);
System.out.println("Cloned Original Fitness: " + origfitness1);
newsol.SmallChange();
double origfitness2 = newsol.ScalesFitness(weights);
System.out.println("Changed Fitness: " + origfitness2);
double origfitness3 = oldsol.ScalesFitness(weights);
System.out.println("Cloned Original Fitness: " + origfitness3);
return(oldsol);
}
}
ScalesSolution Class
import java.util.ArrayList;
import java.util.Random;
public class ScalesSolution
{
private static String scasol;
//Creates a new scales solution based on a string parameter
//The string parameter is checked to see if it contains all zeros and ones
//Otherwise the random binary string generator is used (n = length of parameter)
#
public ScalesSolution(ScalesSolution another) {
this.scasol = another.scasol; // you can access
}
public void SmallChange() {
int n = scasol.length();
String s = scasol;
Random rand = new Random();
int p = (rand.nextInt(n));
String x;
x = scasol.substring(0, p);
if (scasol.charAt(p) == '0') {
x += '1';
} else {
x += '0';
}
x += scasol.substring(p + 1, n);
scasol = x;
}
public String GetSol()
{
return(scasol);
}
public ScalesSolution(String s)
{
boolean ok = true;
int n = s.length();
for(int i=0;i<n;++i)
{
char si = s.charAt(i);
if (si != '0' && si != '1') ok = false;
}
if (ok)
{
scasol = s;
}
else
{
scasol = RandomBinaryString(n);
}
}
private static String RandomBinaryString(int n)
{
String s = new String();
//Code goes here
//Create a random binary string of just ones and zeros of length n
for(int i = 0; i < n; i++){
int x = CS2004.UI(0, 1);
if(x == 0){
s += '0';
} else if (x == 1) {
s += '1';
}
}
return(s);
}
public ScalesSolution(int n)
{
scasol = RandomBinaryString(n);
}
//This is the fitness function for the Scales problem
//This function returns -1 if the number of weights is less than
//the size of the current solution
public static double ScalesFitness(ArrayList<Double> weights)
{
if (scasol.length() > weights.size()) return(-1);
double lhs = 0.0,rhs = 0.0;
int n = scasol.length();
for(int i = 0; i < n; i++){
if (scasol.charAt(i) == '0') {
lhs += weights.get(i);
}
else {
rhs += weights.get(i);
}
}
//Code goes here
//Check each element of scasol for a 0 (lhs) and 1 (rhs) add the weight wi
//to variables lhs and rhs as appropriate
return(Math.abs(lhs-rhs));
}
//Display the string without a new line
public void print()
{
System.out.print(scasol);
}
//Display the string with a new line
public void println()
{
print();
System.out.println();
}
}
When I call the RMHC function in the main method, I get an output like this:
Original Fitness: 16.0
Cloned Original Fitness: 16.0
Changed Fitness: 14.0
Cloned Original Fitness: 14.0
The 2nd Cloned Original Fitness should also be value 16.0 in this example. Once I figure out this initial issue, I will implement the code into a for loop to include the iterations. Thanks.
Assuming this is where you try to copy your data:
ScalesSolution oldsol = new ScalesSolution(n);
ScalesSolution newsol = new ScalesSolution(oldsol.GetSol());
This doesn't work because the variable is static:
public class ScalesSolution
{
private static String scasol;
//...
public String GetSol()
{
return(scasol);
}
Since all you do is assign the value to the static string scasol, no actual change or copy is made.

Trying to solve the derivative of a given equation from the user using ArrayList

As part of my AP computer science project, I decided to get a polynomial from a user and it will be able to find the derivative of the equation using the power rule.
For example, if the user enters 2X^3+5x^2 it should output 6x^2+10x^1, so the coefficient and degree multiplied together and then the degree is just minus one. This is what I have so far but it's giving me a lot of errors, and tried following the code but don't see anything wrong with it. Thanks for your help.
import java.util.ArrayList;
import java.util.Scanner;
public class Practice {
public static void main(String[] args) {
//input of polynomial
System.out.println("Enter polynomial:");
Scanner sc = new Scanner(System.in);
String polynomialEquation = sc.nextLine();
//A string array list is created with the polynomial
ArrayList<String> equationArr = new ArrayList<String>();
for (int i = 0; i<polynomialEquation.length(); i++) {
equationArr.add(polynomialEquation.substring(i, i+1));
}
ArrayList<String> intStrings = new ArrayList<String>();
//separate the numbers from the list
for(int i =0; i<equationArr.size(); i++) {
if (equationArr.get(i).equals("1") || equationArr.get(i).equals("2") || equationArr.get(i).equals("3") ||equationArr.get(i).equals("4") ||equationArr.get(i).equals("5") ||
equationArr.get(i).equals("6") || equationArr.get(i).equals("7") || equationArr.get(i).equals("8") || equationArr.get(i).equals("9") || equationArr.get(i).equals("0"))
{
String addVal = equationArr.get(i);
intStrings.add(addVal);
equationArr.remove(i);
}
}
//convert string integers to integers
ArrayList<Integer> deriveInt = new ArrayList<Integer>(intStrings.size());
for (String myInt : intStrings)
{
deriveInt.add(Integer.valueOf(myInt));
}
//derive coefficiants
for (int i = 0; i<deriveInt.size()-1;i +=2) {
deriveInt.set(i, deriveInt.get(i)*deriveInt.get(i+1));
}
//derive exponent
for(int i = 1; i< deriveInt.size(); i +=2) {
deriveInt.set(i,deriveInt.get(i)-1);
}
//convert integer back to string
ArrayList<String> stringDerive = new ArrayList<String>();
for (Integer myInt2 : deriveInt)
{
stringDerive.add(String.valueOf(myInt2));
}
//get the signs from the original equation
ArrayList<String> sign = new ArrayList<String>();
for(int i =0; i<equationArr.size(); i++) {
if(equationArr.get(i).equals("+") || equationArr.get(i).equals("-")) {
sign.add(equationArr.get(i));
}
}
int totalSize = stringDerive.size() * 2 + equationArr.size();
for (int i = 0; i<totalSize-1; i=+2) {
int countSign= 0;
System.out.print(stringDerive.get(i));
System.out.print("x^");
System.out.print(stringDerive.get(i+1));
System.out.print(equationArr.get(countSign));
}
}
}
Polynomials are composed of monomials. In your example these are 2X^3 and 5x^2. One of approach to solving your problem is writing the Monom class and Polynom class. I'll give you a skeleton so you can practice.
public class Helper {
private class Monom{
private int coefficient;
private int degree;
public Monom(int coefficient, int degree){
this.coefficient = coefficient;
this.degree = degree;
}
public Monom(String input){
//TODO parse input. E.g Monom("6x^2) --> this.coefficient = 6...
//TODO validate input
}
public Monom derivate(final Monom monom){
return new Monom(monom.getCoefficient() * monom.getDegree(), monom.getDegree() - 1);
}
public int getCoefficient() {
return coefficient;
}
public int getDegree() {
return degree;
}
#Override
public String toString(){
return this.coefficient + "x^" + this.degree;
}
}
//skeleton
private class Polynom{
private List<Monom> polynom; //holder of monoms
//TODO rest of code including constructors, validate, derivate...
public Polynom(List<Monom> monoms){
this.polynom = monoms;
}
public Polynom derivate(Polynom input){
List<Monom> temp = new ArrayList<>();
for (Monom monom: polynom){
temp.add(monom.derivate(monom));
}
return new Polynom(temp);
}
}
public static void main(String[] args) {
//TODO test code
List<Monom> monoms = new ArrayList<>();
//TODO rest of code like:
// Polynom myPolynom = new Polynom(List<Monom> monoms);
//...
}
}
Like I said, this is just a code you have to upgrade... Good luck.
welcome to Stack Overflow and the wonderful world of programming! On a personal note, I started coding in high school with APCS too :)
Your question is arguably a bit too broad for this site. For example, you mentioned the code is "giving me a lot of errors": a better question would include the inputs you've tried and the specific output you're seeing and what you expected instead. I still want to help you though, so I'll give you some feedback and we can work through a few revisions.
First, I see that you've divided your program into sections using comments. This is a great instinct! You've decomposed the larger problem into smaller problems in a way that communicates your intent.
input of polynomial
A string array list is created with the polynomial
separate the numbers from the list
convert string integers to integers
derive coefficiants
derive exponent
convert integer back to string
get the signs from the original equation
However, it still leaves us with the problem of having a large main method to understand. So for your next revision, you should fix that by breaking it up into smaller methods. You can start by moving each of these "steps" into its own method, then call each of them from main. To help you get started, here's what it would look like with your first "step" extracted:
public class Practice {
public static String readPolynomial() {
System.out.println("Enter polynomial:");
Scanner sc = new Scanner(System.in);
String polynomialEquation = sc.nextLine();
return polynomialEquation;
}
public static void main(String[] args) {
String polynomialEquation = readPolynomial();
//A string array list is created with the polynomial
...
}
}
I think you'll find that this really improves your understanding of both your code and the problem you're trying to solve. Don't be afraid to change the steps based on that new understanding. It's no coincidence that the buggy or unfocused areas of your code are the areas you'll struggle the most to name. Try to focus on the problem, rather than your implementation. For instance, my first step would probably be a combination of your first few. Things like parsing the input String and then converting from Strings to Integer don't have much to do with polynomials or derivatives. So for readPolynomial I would prefer:
public static ArrayList<Integer> readPolynomial() {
The other big benefit of this refactor is that it will be much easier for you to test that each step is working the way you want it to. It gives you much more fine-grained control because you can test each method individually, rather than only being able to test by running the entire program. It will be much easier to isolate, understand, and fix each individual bug.
Another big thing: please provide some more sample inputs! Not only will this help clarify requirements, but we can use them as test cases later.
Here's some functioning code to help you, please don't just take it for granted but read it and understand what is happening. If you have any questions on it please ask. It could use some cleanup but hopefully it's still understandable.
One minor thing to note is that sign is attached to the expressions (as it kinda should be) so you could just + all the expressions together and it would be valid. But if you want to avoid having an answer like 6x^2 + -10y^4 and would rather have 6x^2 - 10y^4 then you'd have to check if the expressions are negative when building the answer with them.
public class Test {
public static void main(String[] args) {
// input requires all constants to be fully resolved
// eg. no '3^2^1^3', instead it should be '9'
// eg. no '5*2x', instead it should be '10x'
// mess around with the input to test
String s = "2x^3+5x^2";
List<DerivableExpression> list = parseDeriveableExpressions(s);
List<DerivableExpression> derivatives = new ArrayList<>();
for(DerivableExpression de : list)
derivatives.add(de.getDerivative());
System.out.println(String.join("+", derivatives)); // 6x^2+10x^1
}
private static List<DerivableExpression> parseDeriveableExpressions(String s) {
// remove all spaces and lowercase everything
s = s.replace(" ", "");
List<DerivableExpression> list = new ArrayList<>();
char var = ' ';
StringBuilder constBuff = new StringBuilder();
StringBuilder powerBuff = new StringBuilder();
boolean parsingPower = false;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '+' || c == '-') {
if (parsingPower && powerBuff.length() == 0) {
// at the start of the power expression
if (c == '-')
powerBuff.append(c);
} else {
// either not parsing a power or not at the start of the power
// this is a +/- after the power, terminating the expression
parsingPower = false;
int constant = 1;
if (constBuff.length() > 0) {
constant = Integer.parseInt(constBuff.toString());
constBuff.setLength(0);
}
if (var != ' ' && constant != 0) {
int power = 1;
if (powerBuff.length() > 0)
power = Integer.parseInt(powerBuff.toString());
list.add(new VariableExpression(constant, var, power));
} else {
list.add(new ConstantExpression(constant));
}
powerBuff.setLength(0);
var = ' ';
// append the sign for the next expression
if (c == '-')
constBuff.append(c);
}
} else if ('0' <= c && c <= '9') {
if (parsingPower)
powerBuff.append(c);
else
constBuff.append(c);
} else if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')) {
if (constBuff.length() == 0 ||
(constBuff.length() == 1 && constBuff.charAt(0) == '-'))
constBuff.append("1");
var = c;
} else if (c == '^') {
parsingPower = true;
}
}
// add the last expression
int constant = 1;
if (constBuff.length() > 0) {
constant = Integer.parseInt(constBuff.toString());
constBuff.setLength(0);
}
if (var != ' ') {
int power = 1;
if (powerBuff.length() > 0) {
power = Integer.parseInt(powerBuff.toString());
powerBuff.setLength(0);
}
list.add(new VariableExpression(constant, var, power));
var = ' ';
} else {
list.add(new ConstantExpression(constant));
}
return list;
}
private static interface DerivableExpression {
public abstract DerivableExpression getDerivative();
}
private static class VariableExpression implements DerivableExpression {
private final int constant;
private final char variable;
private final int power;
public VariableExpression(int constant, char variable, int power) {
this.constant = constant;
this.variable = variable;
this.power = power;
}
#Override public VariableExpression getDerivative() {
return new VariableExpression(constant * power, variable, power - 1);
}
#Override public String toString() { return constant + "" + variable + "^" + power; }
}
private static class ConstantExpression implements DerivableExpression {
private final int constant;
public ConstantExpression(int constant) {
this.constant = constant;
}
#Override public DerivableExpression getDerivative() { return this; }
#Override public String toString() { return Integer.toString(constant); }
}
}

Implementation of Radix sort in Java using Nodes instead of integers

I have a final project for my Data Structures class that I can't figure out how to do. I need to implement Radix sort and I understand the concept for the most part. But all the implementations I found online so far are using it strictly with integers and I need to use it with the other Type that I have created called Note which is a string with ID parameter.
Here is what I have so far but unfortunately it does not pass any JUnit test.
package edu.drew.note;
public class RadixSort implements SortInterface {
public static void Radix(Note[] note){
// Largest place for a 32-bit int is the 1 billion's place
for(int place=1; place <= 1000000000; place *= 10){
// Use counting sort at each digit's place
note = countingSort(note, place);
}
//return note;
}
private static Note[] countingSort(Note[] note, long place){ //Where the sorting actually happens
Note[] output = new Note[note.length]; //Creating a new note that would be our output.
int[] count = new int[10]; //Creating a counter
for(int i=0; i < note.length; i++){ //For loop that calculates
int digit = getDigit(note[i].getID(), place);
count[digit] += 1;
}
for(int i=1; i < count.length; i++){
count[i] += count[i-1];
}
for(int i = note.length-1; i >= 0; i--){
int digit = getDigit((note[i].getID()), place);
output[count[digit]-1] = note[i];
count[digit]--;
}
return output;
}
private static int getDigit(long value, long digitPlace){ //Takes value of Note[i] and i. Returns digit.
return (int) ((value/digitPlace ) % 10);
}
public Note[] sort(Note[] s) { //
Radix(s);
return s;
}
//Main Method
public static void main(String[] args) {
// make an array of notes
Note q = new Note(" ", " ");
Note n = new Note("CSCI 230 Project Plan",
"Each person will number their top 5 choices.\n" +
"By next week, Dr. Hill will assign which piece\n" +
"everyone will work on.\n");
n.tag("CSCI 230");
n.tag("final project");
Note[] Note = {q,n};
//print out not id's
System.out.println(Note + " Worked");
//call radix
Radix(Note);
System.out.println(Note);
//print out note_id's
}
}
Instead of
public Note[] sort(Note[] s) { //
Radix(s);
return s;
}
I should have used
public Note[] sort(Note[] s) { //
s = Radix(s);
return s;
}
and change the variable type of Radix from void to Note[].

Uva's 3n+1 problem

I'm solving Uva's 3n+1 problem and I don't get why the judge is rejecting my answer. The time limit hasn't been exceeded and the all test cases I've tried have run correctly so far.
import java.io.*;
public class NewClass{
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
int maxCounter= 0;
int input;
int lowerBound;
int upperBound;
int counter;
int numberOfCycles;
int maxCycles= 0;
int lowerInt;
BufferedReader consoleInput = new BufferedReader(new InputStreamReader(System.in));
String line = consoleInput.readLine();
String [] splitted = line.split(" ");
lowerBound = Integer.parseInt(splitted[0]);
upperBound = Integer.parseInt(splitted[1]);
int [] recentlyused = new int[1000001];
if (lowerBound > upperBound )
{
int h = upperBound;
upperBound = lowerBound;
lowerBound = h;
}
lowerInt = lowerBound;
while (lowerBound <= upperBound)
{
counter = lowerBound;
numberOfCycles = 0;
if (recentlyused[counter] == 0)
{
while ( counter != 1 )
{
if (recentlyused[counter] != 0)
{
numberOfCycles = recentlyused[counter] + numberOfCycles;
counter = 1;
}
else
{
if (counter % 2 == 0)
{
counter = counter /2;
}
else
{
counter = 3*counter + 1;
}
numberOfCycles++;
}
}
}
else
{
numberOfCycles = recentlyused[counter] + numberOfCycles;
counter = 1;
}
recentlyused[lowerBound] = numberOfCycles;
if (numberOfCycles > maxCycles)
{
maxCycles = numberOfCycles;
}
lowerBound++;
}
System.out.println(lowerInt +" "+ upperBound+ " "+ (maxCycles+1));
}
}
Are you making sure to accept the entire input? It looks like your program terminates after reading only one line, and then processing one line. You need to be able to accept the entire sample input at once.
I faced the same problem. The following changes worked for me:
Changed the class name to Main.
Removed the public modifier from the class name.
The following code gave a compilation error:
public class Optimal_Parking_11364 {
public static void main(String[] args) {
...
}
}
Whereas after the changes, the following code was accepted:
class Main {
public static void main(String[] args) {
...
}
}
This was a very very simple program. Hopefully, the same trick will also work for more complex programs.
If I understand correctly you are using a memoizing approach. You create a table where you store full results for all the elements you have already calculated so that you do not need to re-calculate results that you already know (calculated before).
The approach itself is not wrong, but there are a couple of things you must take into account. First, the input consists of a list of pairs, you are only processing the first pair. Then, you must take care of your memoizing table limits. You are assuming that all numbers you will hit fall in the range [1...1000001), but that is not true. For the input number 999999 (first odd number below the upper limit) the first operation will turn it into 3*n+1, which is way beyond the upper limit of the memoization table.
Some other things you may want to consider are halving the memoization table and only memorize odd numbers, since you can implement the divide by two operation almost free with bit operations (and checking for even-ness is also just one bit operation).
Did you make sure that the output was in the same order specified in the input. I see where you are swapping the input if the first input was higher than the second, but you also need to make sure that you don't alter the order it appears in the input when you print the results out.
ex.
Input
10 1
Output
10 1 20
If possible Please use this Java specification : to read input lines
http://online-judge.uva.es/problemset/data/p100.java.html
I think the most important thing in UVA judge is 1) Get the output Exactly same , No Extra Lines at the end or anywhere . 2) I am assuming , Never throw exception just return or break with No output for Outside boundary parameters.
3)Output is case sensitive 4)Output Parameters should Maintain Space as shown in problem
One possible solution based on above patterns is here
https://gist.github.com/4676999
/*
Problem URL: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=36
Home>Online Judge > submission Specifications
Sample code to read input is from : http://online-judge.uva.es/problemset/data/p100.java.html
Runtime : 1.068
*/
import java.io.*;
import java.util.*;
class Main
{
static String ReadLn (int maxLg) // utility function to read from stdin
{
byte lin[] = new byte [maxLg];
int lg = 0, car = -1;
String line = "";
try
{
while (lg < maxLg)
{
car = System.in.read();
if ((car < 0) || (car == '\n')) break;
lin [lg++] += car;
}
}
catch (IOException e)
{
return (null);
}
if ((car < 0) && (lg == 0)) return (null); // eof
return (new String (lin, 0, lg));
}
public static void main (String args[]) // entry point from OS
{
Main myWork = new Main(); // create a dinamic instance
myWork.Begin(); // the true entry point
}
void Begin()
{
String input;
StringTokenizer idata;
int a, b,max;
while ((input = Main.ReadLn (255)) != null)
{
idata = new StringTokenizer (input);
a = Integer.parseInt (idata.nextToken());
b = Integer.parseInt (idata.nextToken());
if (a<b){
max=work(a,b);
}else{
max=work(b,a);
}
System.out.println (a + " " + b + " " +max);
}
}
int work( int a , int b){
int max=0;
for ( int i=a;i<=b;i++){
int temp=process(i);
if (temp>max) max=temp;
}
return max;
}
int process (long n){
int count=1;
while(n!=1){
count++;
if (n%2==1){
n=n*3+1;
}else{
n=n>>1;
}
}
return count;
}
}
Please consider that the integers i and j must appear in the output in the same order in which they appeared in the input, so for:
10 1
You should print
10 1 20
package pandarium.java.preparing2topcoder;/*
* Main.java
* java program model for www.programming-challenges.com
*/
import java.io.*;
import java.util.*;
class Main implements Runnable{
static String ReadLn(int maxLg){ // utility function to read from stdin,
// Provided by Programming-challenges, edit for style only
byte lin[] = new byte [maxLg];
int lg = 0, car = -1;
String line = "";
try
{
while (lg < maxLg)
{
car = System.in.read();
if ((car < 0) || (car == '\n')) break;
lin [lg++] += car;
}
}
catch (IOException e)
{
return (null);
}
if ((car < 0) && (lg == 0)) return (null); // eof
return (new String (lin, 0, lg));
}
public static void main(String args[]) // entry point from OS
{
Main myWork = new Main(); // Construct the bootloader
myWork.run(); // execute
}
public void run() {
new myStuff().run();
}
}
class myStuff implements Runnable{
private String input;
private StringTokenizer idata;
private List<Integer> maxes;
public void run(){
String input;
StringTokenizer idata;
int a, b,max=Integer.MIN_VALUE;
while ((input = Main.ReadLn (255)) != null)
{
max=Integer.MIN_VALUE;
maxes=new ArrayList<Integer>();
idata = new StringTokenizer (input);
a = Integer.parseInt (idata.nextToken());
b = Integer.parseInt (idata.nextToken());
System.out.println(a + " " + b + " "+max);
}
}
private static int getCyclesCount(long counter){
int cyclesCount=0;
while (counter!=1)
{
if(counter%2==0)
counter=counter>>1;
else
counter=counter*3+1;
cyclesCount++;
}
cyclesCount++;
return cyclesCount;
}
// You can insert more classes here if you want.
}
This solution gets accepted within 0.5s. I had to remove the package modifier.
import java.util.*;
public class Main {
static Map<Integer, Integer> map = new HashMap<>();
private static int f(int N) {
if (N == 1) {
return 1;
}
if (map.containsKey(N)) {
return map.get(N);
}
if (N % 2 == 0) {
N >>= 1;
map.put(N, f(N));
return 1 + map.get(N);
} else {
N = 3*N + 1;
map.put(N, f(N) );
return 1 + map.get(N);
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
while(scanner.hasNextLine()) {
int i = scanner.nextInt();
int j = scanner.nextInt();
int maxx = 0;
if (i <= j) {
for(int m = i; m <= j; m++) {
maxx = Math.max(Main.f(m), maxx);
}
} else {
for(int m = j; m <= i; m++) {
maxx = Math.max(Main.f(m), maxx);
}
}
System.out.println(i + " " + j + " " + maxx);
}
System.exit(0);
} catch (Exception e) {
}
}
}

Categories

Resources