intelliJ IDEA run class with command line argument - java

I'm going through the Algorithms book by Sedgewick and I can't seem to make my IDE run their programs. The program starts but won't take the passed argument. Specifically I want it to open the tiny.txt file, which I set in Program arguments section but it's just ignored...
import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdOut;
public class Selection
{
public static void sort(Comparable[] a)
{ // Sort a[] into increasing order.
int N = a.length; // array length
for (int i = 0; i < N; i++)
{ // Exchange a[i] with smallest entry in a[i+1...N).
int min = i; // index of minimal entr.
for (int j = i+1; j < N; j++)
if (less(a[j], a[min])) min = j;
exch(a, i, min);
} }
// See page 245 for less(), exch(), isSorted(), and main().
private static boolean less(Comparable v, Comparable w)
{ return v.compareTo(w) < 0; }
private static void exch(Comparable[] a, int i, int j)
{ Comparable t = a[i]; a[i] = a[j]; a[j] = t; }
private static void show(Comparable[] a)
{ // Print the array, on a single line.
for (int i = 0; i < a.length; i++)
StdOut.print(a[i] + " ");
StdOut.println();
}
public static boolean isSorted(Comparable[] a)
{ // Test whether the array entries are in order.
for (int i = 1; i < a.length; i++)
if (less(a[i], a[i-1])) return false;
return true;
}
public static void main(String[ ] args)
{ // Read strings from standard input, sort them, and print.
String[] a = In.readStrings();
sort(a);
assert isSorted(a);
show(a);
}
}

You seem to want standard input redirection. Unfortunately, IntelliJ doesn't support that.
When you supply a command-line argument, all that does is that each word from the argument is passed as a string in the args argument of the main method. You can then write some code in main to open a BufferedReader on that file.
The alternative is to open a terminal window (or Command Prompt window) and type the command line java package.name.ClassName < filename.ext. The command processor or shell interprets the < character as a request to redirect standard input to the supplied file.

Alright this is what needs to be done if you want to use Algorithms code from within intelliJ IDEA on mac OS Sierra:
1, make sure to get and run algs4.app from their website
2, use intelliJ terminal to navigate to algorithms2/out/production/algorithms2 where the .class files reside
3, type in terminal: $ java-algs4 Selection < /Users/mistakeNot/Desktop/Java/algorithms2/tiny.txt

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

Java: array methods

This code supposedly checks an array of integers for 9's and returns it's frequency but the method is not being recognized. Any help please to make this code work.
public static int arrayCount9(int[] nums) {
int count = 0;
for (int i=0; i<nums.length; i++) {
if (nums[i] == 9) {
count++;
}
}
return count;
};
public static void main(String[]args){
System.out.println(arrayCount9({1,2,9}));
}
Change your method call to the following:
System.out.println(arrayCount9(new int[]{1,2,9}));
Alternatively:
int[] a = {1,2,9};
System.out.println(arrayCount9(a));
The shortcut syntax {1,2,9} can only be used when initializing an array type. If you pass this notation to a method, it will not be interpreted it as an array by the compiler.

Having trouble looping arguments with multiples of three. (newb)

The goal of this program is to run arguments such as "K6V3 20.2 17.4" and use the Weather class to calculate the windchill based on the last 2 numeric arguments and use the first argument as the shorthand name for the area. Im running into a problem when the program is given args in multiples of three, such as "K6V3 20.2 17.4 KCHO 40.0 10.0" Im not sure how to get the loop to restart after the third arg. My program will take the first three args and display the correct information, but it will just repeat that information for the second three args. Here is my code so far, HELP!?!?!
public class ChillMapper {
public static void main(String args[]) {
double ICAO;
double t;
double v;
double windChill;
for (int i = 0; i < args.length / 3; i++) {
if (args.length % 3 == 0) {
ICAO = Text.toDouble(args[0]);
t = Text.toDouble(args[1]);
v = Text.toDouble(args[2]);
windChill = Weather.windChillNA(t, v);
Map.setTemperature(args[i], windChill);
}
}
}
}
It is probably simpler to write the loop this way:
for (int i = 0; i < args.length; i+=3)
{
ICAO = Text.toDouble(args[i+0]);
t = Text.toDouble(args[i+1]);
v = Text.toDouble(args[i+2]);
windChill = Weather.windChillNA(t,v);
Map.setTemperature(ICAO,windChill);
}
Instead of checking every time if i%3==0, you jump by steps of 3. (You better have some checks that the argument length itself is multiple of 3, I leave that to you as an exercise). Then you take the arguments at index i, i+1, i+2 respectively.
You have the array indexes hardcoded. Use variable 'i' instead:
public class ChillMapper
{
public static void main(String args[])
{
double ICAO;
double t;
double v;
double windChill;
int i = 0;
if (args.length % 3 == 0)
{
while (i < args.length)
{
ICAO = Text.toDouble(args[i]);
t = Text.toDouble(args[++i]);
v = Text.toDouble(args[++i]);
windChill = Weather.windChillNA(t,v);
Map.setTemperature(args[i],windChill);
}
}
}
}

100 doors task: for loop won't work, otherwise fine

public class OneHundredDoors
{
static OneHundredDoors.Door[] doors = new OneHundredDoors.Door[100];
static public class Door
{
public int doorClosed = 0;
public void open ()
{
this.doorClosed = 0;
}
public void close ()
{
this.doorClosed = 1;
}
private void printStatus (int address)
{
if (this.doorClosed == 0)
{
System.out.println("Door: " + address + " is Open!");
}
}
public void printStatusOfAll ()
{
for (int i = 0; i < doors.length; i++)
{
doors[i].printStatus(i);
}
}
public void passDoor (int increment)
{
for (int k = 0; k < doors.length; k += increment)
{
if (doors[k].doorClosed == 0)
{
doors[k].close();
}
else
{
doors[k].close();
}
}
}
}
public static void main (String [] args)
{
for (int i = 0; i < doors.length; i++)
{
doors[i] = new OneHundredDoors.Door ();
}
for (int j = 0; j < doors.length; j++)
{
doors[5].passDoor(j);
}
doors[5].printStatusOfAll();
}
}
My problem here is that the loop for doors[5].passDoor(j) simply does not work at all. No errors come up, neither at runtime or at compile time. Nothing happens. Leaving the program for a while and coming back to it does nothing, signifying that it is not doing anything in the background. Now this code solves the problem if you simply say doors[5].passDoor(2) then 3, then 4 up to 100. The problem is that that's a wasteful thing to do, and hence I instead want to do it with a for loop.
About the static array of objects: sorry about that, I'm doing that to make things easier in the testing stage, and will fix things when I've got it up and running (by making the array private to the class Door).
I'm only really posting this here because I'm at a complete loss for why this is happening. No errors to search for on the internet, no freezes so I know it's probably not an infinite (or long) loop, and no one seems to have similar problems with 100 doors (albeit this may be because they have not taken an object-oriented approach to it as I have done). Also, the code works completely fine if you type it 100 times as I have said (or at least, it APPEARS that it would do so had I the patience to actually type it out 100 times).
Note finally, that the loop here does not work for ANY value of x where j < x. (What I'm missing here must be something obvious and simple therefore).
The reason passDoor won't work is that you pass an increment of 0 to:
for (int k = 0; k < doors.length; k += increment) {
so the values of k never increment causing an infinite loop.

I don't understand the program

I wanted a program which could list all the contents available in a directory. I found a nice code in java2's.com,
http://www.java2s.com/Code/Java/File-Input-Output/ListingtheDirectoryContents.htm
And here is the code,
import java.io.File;
import java.util.Arrays;
public class Dir {
static int indentLevel = -1;
static void listPath(File path) {
File files[];
indentLevel++;
files = path.listFiles();
Arrays.sort(files);
for (int i = 0, n = files.length; i < n; i++) {
for (int indent = 0; indent < indentLevel; indent++) {
System.out.print(" ");
}
System.out.println(files[i].toString());
if (files[i].isDirectory()) {
listPath(files[i]);
}
}
indentLevel--;
}
public static void main(String args[]) {
listPath(new File(".\\code"));
}
}
What I don't understand is the variable n in the first for loop. If it is not defined anywhere, then why is the program not showing any error?
int i, n;
would declare two ints.
In the code
int i = 0, n = files.length;
declares and initialises them.
It's declared right there, as an int. The comma separates the multiple variable declarations.
n is defined in the for loop in the same way as i.
int x,y;
Would define two variables x and y both as ints. the comma in the for with assignments just looks more complex.

Categories

Resources