Printing A String at the end of array - java

Sorry; I wasn't sure how to title this, so the question is a little shoddy.
I'm finishing up a small program for an extra credit assignment, and there are two very small details that are ruining it.
The purpose of the program is to read some data, divide it into a customer number and a flight number, then determine if the flight is suitable. I have an image screenshot of the file here, because it's a bit of a hassle to explain in short detail. Sorry for having to send a link.
Here is my code:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class prog475a {
static Scanner inFile = null;
public static void main(String[] args) {
// make the flight plan array
boolean[][] flightPlan = new boolean[7][7];
// fill the true
flightPlan[1][2]=true;
flightPlan[1][3]=true;
flightPlan[1][6]=true;
flightPlan[2][1]=true;
flightPlan[2][3]=true;
flightPlan[2][6]=true;
flightPlan[3][4]=true;
flightPlan[4][2]=true;
flightPlan[4][5]=true;
flightPlan[4][6]=true;
flightPlan[5][2]=true;
flightPlan[5][4]=true;
flightPlan[6][2]=true;
flightPlan[6][5]=true;
// read for file
try {
// create scanner to read file
inFile = new Scanner(new File ("prog475a.dat"));
} catch (FileNotFoundException e) {
System.out.println("File not found!");
System.exit(0);
}
/*
* read customer number
* method to translate flight plan into coordinates
*
*/
int customer = 0;
int flight = 0;
while (inFile.hasNext()) {
customer = inFile.nextInt();
flight = inFile.nextInt();
translator(customer, flight, flightPlan);
}
}
public static void translator(int c, int f, boolean[][] fl) {
System.out.println("Customer Number " + c + "\tFlight Plan " + f);
// change int f into individual numbers?
int[] coo = new int[6];
int a = 10000;
// boolean ok = true;
for (int x = 0; x < coo.length - 1; x ++) {
coo[x] = (f / a) % 10;
a /= 10;
}
// test if your array has all the right numbers
// for (int x = 0; x < coo.length - 1; x++) {
//
// System.out.println(coo[x]);
//
// }
// instantiate variables to act as parameters to navigate boolean
int n = 0; // the actual coordinate
int p = 0; // placeholders
int q = 0;
while (q < coo.length) { // q has to end when it equals length of coo
p = coo[n];
q = coo[n + 1];
if (fl[p][q]) {
System.out.println(p + "\t" + q + "\t" + "Available");
n++;
} else {
System.out.println(p + "\t" + q + "\t" + "Unavailable\t Flight Plan invalid");
break; // if unavailable, break
}
}
System.out.println("");
}
}
Here is the data:
10123 13426
11305 62000
13427 42320
18211 34212
19006 65426
20831 52500
21475 32000
22138 13424
24105 65231
24216 34250
25009 43621
The issue I am having is very simple-- my program works perfectly fine, except I've tried various different ways to print "Flight Plan is Valid" at the end of the program to no avail. I've honestly done everything; I've added an extra if/else statement to account for when q = coo[coo.length - 1], tried to append it on the outside of the while-loop. I just can't get it to work.
Another issue I'm having is, for flight 34212, an extra line is arbitrarily printed out, indicating a flight from 2 to 0, which doesn't exist in the number at all. It's the only flight that's having this problem.
I'm really not sure what I'm doing wrong, and I hope that someone can give some advice on how to fix my code to make sure these errors are dealt with somewhat. Again, thank you for your time. I'm a bit of an arse, so I've spent a really long time trying to figure out what I was doing wrong, and I feel a bit frustrated.

Okay there are a lot of logical errors in the translator function, so I'll just list them and then provide some fixed code. However since this sounds like this is for a course, DO NOT JUST COPY AND PASTE. I think actually walking through some of the errors in your program would be highly beneficial.
The length of coo is 6. This may be intentional, but is unnecessary.
When you fill coo. You only fill 5 out of the 6 spots.
You never change the ok variable.
You never use the n variable.
I think in the first part of the while loop, comparing with q is a typo/logical mistake, I think you meant to compare with n.
Using both a check in the while loop for ok, and a break statement is redundant.
You didn't add in an if to do run code depending on the state of ok.
With all these errors, I think that you should definitely ask your teacher or whatever with help, because this is a lot to change in one post. Either way, I hope you don't misuse this code ;). Here's the new translate function:
public static void translator(int c, int f, boolean[][] fl) {
System.out.println("Customer Number " + c + " Flight Plan " + f);
int[] coo = new int[5];
int a = 10000;
for (int x = 0; x < coo.length; x++) {
coo[x] = (f / a) % 10;
a /= 10;
}
for (int x = 0; x < coo.length - 1; x++) {
int p = coo[x];
int q = coo[x + 1];
if (fl[p][q]) {
System.out.print(p + "\t" + q + "\tAvailable");
if (x == coo.length - 2) {
System.out.print("\tFlight Plan is Valid");
}
System.out.println();
}
else {
System.out.println(p + "\t" + q + "\tUnavailable\tFlight Plan is Invalid");
break;
}
}
}
Explanation: I used basically the same code until the last for loop except that I changed the length of coo to 5 and made the first for loop run 5 times. You will also notice that I removed ok because it was redundant. This is because once I have a bad flight, I just print the invalid flight message and then break. There's no need of a variable in there. For the last loop you can see, I use a for loop instead of a while loop. Why did I do this? Pretty much just cause of taste. I typically use a for loop when I know how many times I am going to loop, and a while when the number isn't clear cut. Also, in this case, since you were using a counting variable n anyways, that's just the kind of thing a for loop is good for (haha). The rest of the code is pretty self-explanatory. If the flight is valid, you do the print for that. And if it's the last loop, hence if (x == coo.length - 2) (this checks that its the last loop), then you print that the flight plan is valid. Otherwise you print it's not valid and you break. I have done a little testing with this code, and it works so far. I hope this helps you!

Related

Good fix for this algorithmic puzzle code (USACO)?

I'm a first-year computer science student and I am currently dabbling in some algorithmic competitions. The code below that I made has a flaw that I'm not sure how to fix
Here is the problem statement:
http://www.usaco.org/index.php?page=viewproblem2&cpid=811
In the statement, I missed where it said that Farmer John could only switch boots on tiles that both boots can stand on. I tried adding constraints in different places but none seemed to address the problem fully. I don't really see a way to do it without butchering the code
Basically, the problem is that John keeps switching boots on tiles where the new boots can't stand on, and I can't seem to fix it
Here is my code (sorry for the one letter variables):
import java.io.*;
import java.util.*;
public class snowboots {
static int n,k;
static int[] field,a,b; //a,b --> strength, distance
static int pos;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("snowboots.in"));
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter("snowboots.out")));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
k = Integer.parseInt(st.nextToken());
st = new StringTokenizer(br.readLine());
field = new int[n];
a = new int[k];
b = new int[k];
for (int i = 0; i < n; i++)
field[i] = Integer.parseInt(st.nextToken());
for (int i = 0; i < k; i++) {
st = new StringTokenizer(br.readLine());
a[i] = Integer.parseInt(st.nextToken());
b[i] = Integer.parseInt(st.nextToken());
}
pw.println(solve());
pw.close();
}
static int solve() {
pos = 0;
int i = 0; //which boot are we on?
while(pos < n-1) {
while(move(i)); //move with boot i as far as possible
i++; //use the next boot
}
i--;
return i;
}
static boolean move(int c) {
for (int i = pos+b[c]; i > pos; i--) {
if (i < n && field[i] <= a[c]) { //snow has to be less than boot strength
pos = i;
return true;
}
}
return false;
}
}
I tried adding a constraint in the "move" method, and one when updating I, but they both are too strict and activate at unwanted times
Is it salvageable?
Yes, it's possible to salvage your solution, by adding an extra for-loop.
What you need to do is, if you find that your previous pair of boots can get you all the way to a tile that's too deep in snow for your next pair, then you need to try "backtracking" to the latest tile that's not too deep. This ends up giving a solution in worst-case O(N·B) time and O(1) extra space.
It may not be obvious why it's OK to backtrack to that tile — after all, just because you can reach a given tile, that doesn't necessarily mean that you were able to reach all the tiles before it — so let me explain a bit why it is OK.
Let maxReachableTileNum be the number (between 1 and N) of the last tile that you were able to reach with your previous boots, and let lastTileNumThatsNotTooDeep be the number (between 1 and N) of the last tile on or before maxReachableTileNum that's not too deeply snow-covered for your next pair. (We know that there is such a tile, because tile #1 has no snow at all, so if nothing else we know that we can backtrack to the very beginning.) Now, since we were able to get to maxReachableTileNum, then some previous boot must have either stepped on lastTileNumThatsNotTooDeep (in which case, no problem, it's reachable) or skipped over it to some later tile (on or before maxReachableTileNum). But that later tile must be deeper than lastTileNumThatsNotTooDeep (because that later tile's depth is greater than scurrentBootNum, which is at least at great as the depth of lastTileNumThatsNotTooDeep), which means that the boot that skipped over lastTileNumThatsNotTooDeep certainly could have stepped on lastTileNumThatsNotTooDeep instead: it would have meant taking a shorter step (OK) onto a less-deeply-covered tile (OK) than what it actually did. So, either way, we know that lastTileNumThatsNotTooDeep was reachable. So it's safe for us to try backtracking to lastTileNumThatsNotTooDeep. (Note: the below code uses the name reachableTileNum instead of lastTileNumThatsNotTooDeep, because it continues to use the reachableTileNum variable for searching forward to find reachable tiles.)
However, we still have to hold onto the previous maxReachableTileNum: backtracking might turn out not to be helpful (because it may not let us make any further forward progress than we already have), in which case we'll just discard these boots, and move on to the next pair, with maxReachableTileNum at its previous value.
So, overall, we have this:
public static int solve(
final int[] tileSnowDepths, // tileSnowDepths[0] is f_1
final int[] bootAllowedDepths, // bootAllowedDepths[0] is s_1
final int[] bootAllowedTilesPerStep // bootAllowedTilesPerStep[0] is d_1
) {
final int numTiles = tileSnowDepths.length;
final int numBoots = bootAllowedDepths.length;
assert numBoots == bootAllowedTilesPerStep.length;
int maxReachableTileNum = 1; // can reach tile #1 even without boots
for (int bootNum = 1; bootNum <= numBoots; ++bootNum) {
final int allowedDepth = bootAllowedDepths[bootNum-1];
final int allowedTilesPerStep = bootAllowedTilesPerStep[bootNum-1];
// Find the starting-point for this boot -- ideally the last tile
// reachable so far, but may need to "backtrack" if that tile is too
// deep; see explanation above of why it's safe to assume that we
// can backtrack to the latest not-too-deep tile:
int reachableTileNum = maxReachableTileNum;
while (tileSnowDepths[reachableTileNum-1] > allowedDepth) {
--reachableTileNum;
}
// Now see how far we can go, updating both maxReachableTileNum and
// reachableTileNum when we successfully reach new tiles:
for (int tileNumToTry = maxReachableTileNum + 1;
tileNumToTry <= numTiles
&& tileNumToTry <= reachableTileNum + allowedTilesPerStep;
++tileNumToTry
) {
if (tileSnowDepths[tileNumToTry-1] <= allowedDepth) {
maxReachableTileNum = reachableTileNum = tileNumToTry;
}
}
// If we've made it to the last tile, then yay, we're done:
if (maxReachableTileNum == numTiles) {
return bootNum - 1; // had to discard this many boots to get here
}
}
throw new IllegalArgumentException("Couldn't reach last tile with any boot");
}
(I tested this on USACO's example data, and it returned 2, as expected.)
This can potentially be optimized further, e.g. with logic to skip pairs of boots that clearly aren't helpful (because they're neither stronger nor more agile than the previous successful pair), or with an extra data structure to keep track of the positions of latest minima (to optimize the backtracking process), or with logic to avoid backtracking further than is conceivably useful; but given that N·B ≤ 2502 = 62,500, I don't think any such optimizations are warranted.
Edited to add (2019-02-23): I've thought about this further, and it occurs to me that it's actually possible to write a solution in worst-case O(N + B log N) time (which is asymptotically better than O(N·B)) and O(N) extra space. But it's much more complicated; it involves three extra data-structures (one to keep track of the positions of latest minima, to allow backtracking in O(log N) time; one to keep track of the positions of future minima, to allow checking in O(log N) time if the backtracking is actually helpful (and if so to move forward to the relevant minimum); and one to maintain the necessary forward-looking information in order to let the second one be maintained in amortized O(1) time). It's also complicated to explain why that solution is guaranteed to be within O(N + B log N) time (because it involves a lot of amortized analysis, and making a minor change that might seem like an optimization — e.g., replacing a linear search with a binary search — can break the analysis and actually increase the worst-case time complexity. Since N and B are both known to be at most 250, I don't think all the complication is worth it.
You can solve this problem by Dynamic Programming. You can see the concept in this link (Just read the Computer programming part).
It has following two steps.
First solve the problem recursively.
Memoize the states.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mx 100005
#define mod 1000000007
int n, b;
int f[333], s[333], d[333];
int dp[251][251];
int rec(int snowPos, int bootPos)
{
if(snowPos == n-1){
return 0;
int &ret = dp[snowPos][bootPos];
if(ret != -1) return ret;
ret = 1000000007;
for(int i = bootPos+1; i<b; i++)
{
if(s[i] >= f[snowPos]){
ret = min(ret, i - bootPos + rec(snowPos, i));
}
}
for(int i = 1; i<=d[bootPos] && snowPos+i < n; i++){
if(f[snowPos + i] <= s[bootPos]){
ret = min(ret, rec(snowPos+i, bootPos));
}
}
return ret;
}
int main()
{
freopen("snowboots.in", "r", stdin);
freopen("snowboots.out", "w", stdout);
scanf("%d %d", &n, &b);
for(int i = 0; i<n; i++)
scanf("%d", &f[i]);
for(int i = 0; i<b; i++){
scanf("%d %d", &s[i], &d[i]);
}
memset(dp, -1, sizeof dp);
printf("%d\n", rec(0, 0));
return 0;
}
This is my solution to this problem (in C++).
This is just a recursion. As problem says,
you can change boot, Or
you can do a jump by current boot.
Memoization part is done by the 2-Dimensional array dp[][].
One way which to solve it using BFS. You may refer below code for details. Hope this helps.
import java.util.*;
import java.io.*;
public class SnowBoots {
public static int n;
public static int[] deep;
public static int nBoots;
public static Boot[] boots;
public static void main(String[] args) throws Exception {
// Read the grid.
Scanner stdin = new Scanner(new File("snowboots.in"));
// Read in all of the input.
n = stdin.nextInt();
nBoots = stdin.nextInt();
deep = new int[n];
for (int i = 0; i < n; ++i) {
deep[i] = stdin.nextInt();
}
boots = new Boot[nBoots];
for (int i = 0; i < nBoots; ++i) {
int d = stdin.nextInt();
int s = stdin.nextInt();
boots[i] = new boot(d, s);
}
PrintWriter out = new PrintWriter(new FileWriter("snowboots.out"));
out.println(bfs());
out.close();
stdin.close();
}
// Breadth First Search Algorithm [https://en.wikipedia.org/wiki/Breadth-first_search]
public static int bfs() {
// These are all valid states.
boolean[][] used = new boolean[n][nBoots];
Arrays.fill(used[0], true);
// Put each of these states into the queue.
LinkedList<Integer> q = new LinkedList<Integer>();
for (int i = 0; i < nBoots; ++i) {
q.offer(i);
}
// Usual bfs.
while (q.size() > 0) {
int cur = q.poll();
int step = cur / nBoots;
int bNum = cur % nBoots;
// Try stepping with this boot...
for (int i = 1; ((step + i) < n) && (i <= boots[bNum].maxStep); ++i) {
if ((deep[step+i] <= boots[bNum].depth) && !used[step+i][bNum]) {
q.offer(nBoots * (step + i) + bNum);
used[step + i][bNum] = true;
}
}
// Try switching to another boot.
for (int i = bNum + 1; i < nBoots; ++i) {
if ((boots[i].depth >= deep[step]) && !used[step][i]) {
q.offer(nBoots * step + i);
used[step][i] = true;
}
}
}
// Find the earliest boot that got us here.
for (int i = 0; i < nBoots; ++i) {
if (used[n - 1][i]) {
return i;
}
}
// Should never get here.
return -1;
}
}
class Boot {
public int depth;
public int maxStep;
public Boot(int depth, int maxStep) {
this.depth = depth;
this.maxStep = maxStep;
}
}

Turning a iteration into a recursion

Good day!
I just wrote a code as an iteration which is supposed to sum up even numbers in between 0 and y.
I've been sitting now on my desk for about two hours thinking on how to write the same code in a recursion - without any progress so far.
The only explanations I find on the internet explain it for one simple repeat of one specific change - unlike my code which includes two. ("result = result + x;" and "x = x + 2;" )
Could someone please explain to me how I turn this kind of iteration into a recursion? Thanks in advance!
public class Sum {
static int method(int y) {
int result = 0;
for (int x = 2; x<=y;)
{
result = result + x;
x = x + 2;
}
return result;
}
public static void main(String[ ] args) {
int result = method(35);
System.out.println("Sum of even numbers between 0-35: " +result);
}
}
The total of the numbers is the total of this number plus the total of the number minus 2. Written in code:
int method(int y) {
if (y <= 0) {
return 0;
} else {
return y + method(y - 2);
}
}
Needless to say that recursion in this form is not necessary, and will create a StackoverflowException when y is a really large number. Some languages allow you to write a recursive function and indicate it is a tail recursion so that the compiler actually transforms it to an iteration.

Checksums - ISBN program

This problem has me puzzled. I tried using a loop like this: Basically I tried to get the first digit from the input and do the formula but it doesn't seem to work. It looks so simple but I can't figure it out. Could you help me? Thanks.
public static int ISBN(String ninedigitNum) {
number = 9;
while (number > 0) {
int nextDigit = ninedigitNum.substring(0,1);
...
}
Checksums (Source: Princeton University). The International Standard
Book Number (ISBN) is a 10 digit code that uniquely specifies a book.
The rightmost digit is a checksum digit which can be uniquely
determined from the other 9 digits from the condition that d1 + 2d2 +
3d3 + ... + 10d10 must be a multiple of 11 (here di denotes the ith
digit from the right). The checksum digit d1 can be any value from 0
to 10: the ISBN convention is to use the value X to denote 10.
Example: the checksum digit corresponding to 020131452 is 5 since is
the only value of d1 between 0 and and 10 for which d1 + 2*2 + 3*5 +
4*4 + 5*1 + 6*3 + 7*1 + 8*0 + 9*2 + 10*0 is a multiple of 11. Create a
Java method ISBN() that takes a 9-digit integer as input, computes the
checksum, and returns the 10-digit ISBN number. Create 3 JUnit test
cases to test your method.
I got it, thanks a lot everyone!
What about it isn't working? Either way, I believe what you're missing is that you're continually getting the same substring, which will be the first number of the string: int nextDigit = ninedigitNum.substring(0,1);. In addition, you're going to want to use an int, not a String; you can technically convert from String to int if desired, but the problem itself calls for an int.
There are two ways to do this that jump to mind. I would do this by realizing that mod in powers of 10 will give you the respective digit of an integer, but the easier way is to convert to a char array and then access directly. Note that there's no error checking here; you'll have to add that yourself. In addition, there are a LOT of 'magic numbers' here: good code typically has very, very few. I would recommend learning more data structures before attempting problems like these; to be honest there's very few things you can do without at least arrays and linked lists.
char[] ISBN = ninedigitNum.toCharArray();
//Process each number
int total = 0;
for(int i=0; i<9; i++){
int current_int = Integer.parseInt(ISBN[i]);
total += current_int * (10 - i)
}
//Find value of d1
for(int i=0; i<9; i++){
if(((total + i) % 11) == 0){
total += i*100000000;
break;
}
}
return total;
In general: Use print outs with System.out.println(x); or use your compiler's debugger to see what's going on during processing.
So,
This is the piece of code that I wrote. I still think it could be made more efficient.
public class Problem3 {
public static String ISBN(String x)
{
char[]temp = x.toCharArray();
int counter = 2;
int sum = 0;
int j=0;
for(int i=8;i>=0;i--)
{
sum+= counter*Integer.parseInt(""+temp[i]);
counter+=1;
}
for(j=0;j<10;j++)
{
if((sum+j)%11==0)
{
break;
}
}
return x+""+j;
}
public static void main(String args[])
{
String a = "020131452";
System.out.println(ISBN(a));
}
}
Hope this helps.
This works:
public static int ISBN(String nineDigitNum){
int sum = 0;
for(int i = 0; i<nineDigitNum.length(); i++){
sum += Integer.parseInt(""+nineDigitNum.charAt(i))*(10-i);
}
return (sum%11);
}
Also I believe if the checksum is == to 10, it should return an X, so you could either change the return type and add an if statement somewhere, or just put the if statement outside wherever you are using this method.
Here is a short one without loops that uses only substring(), charAt() and length():
public static String ISBN(String nineDigits) {
int chkD = 11 - checkDigit(nineDigits, 0);
return nineDigits + ((chkD == 10) ? "X" : chkD);
}
public static int checkDigit(String nDsub, int chkD) {
if (nDsub.length() == 0)
return 0;
chkD = ((nDsub.charAt(0) - '0') * (nDsub.length() + 1));
return (chkD + checkDigit(nDsub.substring(1), chkD)) % 11;
}
Output:
> ISBN("123456789")
"123456789X"
> ISBN("123456780")
"1234567806"

Java Program taking up too much memory

This is my Problem for which i made the program
Ali baba did a trick on the forty thieves and was able to trap them
inside a big cave which was the home of wild wolves. The thieves are
without any weapons, only the chief of the thieves has knife. With no
weapons they will not be able to fight with the wolves, so they decide
to kill themselves rather than being eaten alive.
They all decide that they will stand in a circle and they every third
person will kill himself but the chief of the thieves does not like
this idea and has no intention of killing himself. He calculates where
should he stand so that he is the last one left.
HackerMan wants to build a game based on this story, but instead of
killing he decides that the participant will leave the game, and
instead of every 3rd position it will be every 2nd position. Of course
the number of participants will be much more than 40 in this game.
Input
The first line of input is an integer N (1 <= N <= 1000) that
specifies the number of test cases. After that every line contains an
integer X (5 <= X <= 100000000) which is the number of participants in
the game.
Output
For each test case generate a line containing the position of the
participant who survives. Assume that the participants have serial
numbers from 1 to n and that the counting starts with person 1, i.e.,
the first person leaving is the one with number 2.
Sample Input
3 5 11 45
Sample Output
3 7 27
Here is my Solution Program
class SurvivalStrategy {
public int next;
public int value;
public boolean alive;
SurvivalStrategy(int n, int v)
{
this.next = n;
this.value = v;
this.alive = true;
}
public int getNext(){
return this.next;
}
public void kill(){
this.alive = false;
}
public void changeNext(int n){
this.next = n;
}
public static void main(String[] args) throws IOException {
System.out.println("Enter the number of cases");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = br.readLine();
int N = Integer.parseInt(line);
int[] array = new int[N];
for(int a = 0; a < N; a++)
{
System.out.println("Enter No. of theives in case " + (a + 1));
array[a] = Integer.parseInt(br.readLine());
}
for(int b = 0; b < N; b++)
{
try{
int theives = 0;
theives = array[b];
SurvivalStrategy[] people = new SurvivalStrategy[theives];
int i = 0;
int nextctr = 2;
for(i = 0; i < people.length; i++)
{
people[i] = new SurvivalStrategy(nextctr, i + 1);
if(nextctr > people.length)
{
people[i] = new SurvivalStrategy(1, i + 1);
}
nextctr++;
}
int k = 0;
int nextguy = 0;
int survivers = people.length;
boolean CarryOnJatta = true;
int lastSurviver = 0;
while(CarryOnJatta)
{
if(k >= people.length)
{
k = 0;
k = k + 2;
}
if(people[k].alive)
{
//System.out.println(people[k].value + " is Alive");
nextguy = people[k].getNext();
if(people[nextguy - 1].alive)
{
people[nextguy - 1].kill();
people[k].changeNext(people[nextguy - 1].next);
lastSurviver = people[k].value;
survivers--;
}else{
k = k + 2;
}
k = k + 2;
}else{
k = k + 2;
}
if (survivers == 1)
{
CarryOnJatta = false;
System.out.println("" + lastSurviver);
}
}
} catch(Exception e)
{
e.printStackTrace();
}
}
}
}
My program is giving an output for small values but not for large ones.
if i try it with the input(23987443) i get java heap size exceeded error.
is there any way i can improve the space as well as time complexity of this program.
i am open for other algorithms also if they are generating the desired output.
You are allocating at least 23987443 * sizeof(SurvivalStrategy) memory on the heap - that would be around 300MB per single case, and that is only before this line of code:
SurvivalStrategy[] people = new SurvivalStrategy[theives];
I guess the challenge was designed to teach you with merits of efficient memory handling - so instead of allocating the whole memory at once, you need to process your items one by one, so that you allocate only a few items at a time, letting the no-longer-needed ones to be collected by GC.
You could try to assign more memory to the JVM, there's a recent post about this:
Java Heap Space error from command line
you could use a circular LinkedList. Add your nodes to the list, and use the counting algorithm to traverse the list. Everytime someone loses, simply call a remove on that person, which will mark it eligible for garbage collection (assuming the list contains the only ref to your node).
Better yet, no need to add everyone all at once on the first cycle through the list. You can simply not add someone if they are a multiple of V iterations. This should chop your memory usage up quite a bit.
This will save space on your heap, since you are maintaining a max size of N, but will have more allocation / deallocation overhead. Still, linkedList.remove offers O(1) complexity. I think it would clean your code up a lot to and make it easier to understand

Algorithm that takes an integer and returns all possible format of addition

I need to write an algorithm that takes an integer and returns all possible format of addition
e.g.
If I eneter: 6
it would return the following String:
0+6=6
1+1+1+1+1+1=6
1+1+1+1+2=6
1+1+1+3=6
1+1+4=6
1+5=6
2+1+1+1+1=6
2+1+1+2=6
2+1+3=6
2+4=6
3+1+1+1=6
3+1+2=6
3+3=6
4+1+1=6
4+2=6
5+1=6
6+0=6
Here is my try:
import java.util.*;
public class Test
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.print("Enter an integer? ");
int num = in.nextInt();
System.out.println();
calculate(num);
}
private static void calculate(int n)
{
int[] arInt = new int[n];
for(int i = 0; i <= n; i++)
{
for(int j = 0; j <= n; j++)
{
arInt[j] = i;
}
// ...
}
}
}
I agree with Brad. The best way to complete this would probably be through recursion. In fact, I was working on something related to this last night. I solved my problem using a recursive backtracking algorithm. Check out the Wikipedia page: Backtracking
Now, I make no guarantees that there aren't better, less complex ways to solve this. However, with recursive backtracking you will find all the solutions.
One thing to watch out for though, that 0. You can throw any amount of zeros into an addition/subtraction and it will come out the same.
If you asked the question, you are probably stuck... so i give you a hint :
Usually, in this kind of problem, you do not consider the same combinations with different permutations as different counts, and you do not consider addtion by 0: see Partition.
However, in your example, you seem to be distinguishing different permutations and counting 0. I am pertty much sure that you are not supposed to include 0 because that will give you infinitely many examples to any n. (By the way the answer you gave does not include all counts.) So I assume that you distinguish different permutations but not allow segment into 0. That actually makes the problem much easier.
Suppose you have n = 6.
O O O O O O
^ ^ ^ ^ ^
Think about the n - 1 = 5 positions between the six objects above. For each position, you can decide to either segment at the point or not. For example,
O|O O O|O O
^ ^ ^ ^ ^
is one possible segmentation. Interpret this as: 1+3+2, taking the consecutive objects not segmented by '|'. You should be able to get all possible ways in this way. Namely, for n-1 positions, either segment it or not. For any n, your list should be of 2^(n-1) examples.
E.g. for n = 3:
1+1+1, 2+1, 1+2, 3 => 4 different ways = 2^(3-1)
for n = 6, you should have 2^(6-1) = 32 examples, but you only have 17, which immediately tells that your list is not complete.
Finally note that, as I wrote at the beginning, your question is different from the partion question which is much more standard.
It looks like a homework, so I won't try to write it for you. But I will give you a hint about the solution. You have fixed quantity, imagine e.g. marbles. You are trying to find all possible numbers that add up to that quantity. This means you have to divide the marbles into groups somehow. If you know basic combinatorics, you can easily count the possibilities and enumerate them using an algorithm. Good luck!
Possible solution in Java using recursion:
public void run(int n)
{
List<StringBuilder> combos = showAdditionsFor(n);
for (StringBuilder s : combos)
{
if (s.indexOf("+") < 0)
{
System.out.println(s + " + 0 = " + n);
System.out.println("0 + " + s + " = " + n);
}
else
{
System.out.println(s + " = " + n);
}
}
}
List<StringBuilder> showAdditionsFor(int n)
{
List<StringBuilder> list = new ArrayList<StringBuilder>();
if (n == 0)
list.add(new StringBuilder(""));
else if (n == 1)
list.add(new StringBuilder(String.valueOf(1)));
else
{
for (int i = 1; i <=n; i++)
{
//get n-i list
List<StringBuilder> tempList = showAdditionsFor(n-i);
appendToEachListElement(String.valueOf(i),tempList);
list.addAll(tempList);
}
}
return list;
}
private void appendToEachListElement(String x, List<StringBuilder>l)
{
for (StringBuilder s : l)
{
if (s.length() == 0)
s.append(x);
else
s.append("+" + x);
}
}

Categories

Resources