Java > Array-2 > twoTwo - java

problem
Given an array of ints, return true if every 2 that appears in the array is next to another 2.
twoTwo({4, 2, 2, 3}) → true
twoTwo({2, 2, 4}) → true
twoTwo({2, 2, 4, 2}) → false
my code is only mising this case
twoTwo({2, 2, 7, 2, 1}) → false; but returns true;
my code
public boolean twoTwo(int[] nums) {
int notFound = 0;
int i = 0;
boolean found = false;
if (nums.length == 0) {
return true;
}
if (nums.length == 1 && (nums[0] != 2)) {
return true;
}
for (i = 0; i < nums.length - 1; i++) {
if ((nums[i] == 2 && nums[i + 1] == 2)) {
found = true;
}
if (nums[nums.length - 1] == 2 && nums[nums.length - 2] != 2) {
return false;
}
if (nums[i] != 2) {
notFound++;
}
}
if (nums[i] != 2) {
notFound++;
}
if (notFound == nums.length) {
return true;
}
return found;
}

There is never a "wrong" way to code a working solution, but there are bad ways. In your solution, I think you try to handle every individual case in chaotic ways instead of tackling the overarching problem. You have floating variables all over the place and hard coded numbers that are very specific to each case. You have unnecessary and excessive returns.
My suggestion is to work on solving your own question "Return true if all 2's are next to another 2" - instead of trying to code for each specific case. You aren't REALLY solving a problem if you are hard coding to work on a specific subset of that problem.
Just my critique; keep working at it.
Consider refactoring your for loop with this as a starting point, see if you can figure out the logic (semi pseudo code):
for(int i = 1; i < nums.length-1; i++) { // Why do I start i at 1?
if(nums[i]==2) {
if(nums[i-1] == 2 || nums[i+1] == 2) // What does this if check?
do something; // What to do here? Look up the 'continue' keyword.
else
return false;
}
}
return true;
You will find this for loop is JUST a starting point. There will be more needed to add, but hopefully a good jumping point for you.
Best of luck!

public boolean twoTwo(int[] nums)
{
if (nums.length == 1 && nums[0] == 2)
return false;
for (int i = 0; i < nums.length - 1; i++)
if (nums[i] == 2)
if (nums[i + 1] != 2 && (i > 0 && nums[i - 1] != 2))
return false;
return true;
}
Basically this goes through each number in the list, and if it finds a 2, it checks it against the previous and next numbers. That's all it does.

Related

Shortest path algorithm on an integer matrix grid does not return the expected value

I have an assignment to submit and I need help I will appreciate it a lot!!
I need to write a method that gets an integer matrix grid with numbers from 0 and above. 1 value in the matrix is different and contains -1. the function also gets the starting x and y in the matrix.
I need to write a recursive function that finds the shortest path from the starting x, y to the -1 value.
you can "jump" to the left' right' up and down. the condition to "jump" from one index to another is if the absolute value between the subtraction of the the 2 pairing is either 0, 1 or 2
The shortest path is 4
I cannot use while and for loops, and global variables
The function signature should be: public static int shortestPath(int[][] drm, int i, int j)
Thanks a lot!
Here is my try:
package assignment1;
import java.util.*;
public class run {
static Scanner reader = new Scanner(System.in);
public static int shortestPath(int[][] drm, int i, int j) {
if (drm.length == 0 || i >= drm.length || j >= drm.length || i < 0 || j < 0)
return 0;
if (i > 0 && j > 0 && i < drm.length - 1 && j < drm[i].length - 1) {
if (drm[i][j - 1] == -1) {
System.out.print("Got it! the target is on the left");
return 2;
}
if (drm[i][j + 1] == -1) {
System.out.print("Got it! the target is on the right");
return 2;
}
if (drm[i - 1][j] == -1) {
System.out.print("Got it! the target is up");
return 2;
}
if (drm[i + 1][j] == -1) {
System.out.print("Got it! the target is down");
return 2;
}
}
int temp = drm[i][j];
int left = Integer.MAX_VALUE, right = Integer.MAX_VALUE, up = Integer.MAX_VALUE, down = Integer.MAX_VALUE;
if (isValidJump(drm, i, j, i + 1, j)) {
System.out.print("down ");
drm[i][j] = Integer.MIN_VALUE;
down = shortestPath(drm, i + 1, j) + 1;
}
if (isValidJump(drm, i, j, i, j + 1)) {
System.out.print("right ");
drm[i][j] = Integer.MIN_VALUE;
right = shortestPath(drm, i, j + 1) + 1;
}
if (isValidJump(drm, i, j, i, j - 1)) {
System.out.print("left ");
drm[i][j] = Integer.MIN_VALUE;
left = shortestPath(drm, i, j - 1) + 1;
}
if (isValidJump(drm, i, j, i - 1, j)) {
System.out.print("up ");
drm[i][j] = Integer.MIN_VALUE;
up = shortestPath(drm, i - 1, j) + 1;
}
drm[i][j] = temp;
return Math.min(Math.min(Math.min(up, down), left), right);
}
public static boolean isValidJump(int[][] drm, int i, int j, int m, int n) {
if (m < drm.length && m >= 0 && n < drm.length && n >= 0 && drm[m][n] != Integer.MIN_VALUE) {
int jump = drm[m][n] - drm[i][j];
if (jump == 0 || jump == 1 || jump == -1 || jump == -2) {
return true;
}
}
return false;
}
public static void main(String[] args) {
int[][] drm = { { 2, 0, 1, 2, 3 }, { 2, 3, 5, 5, 4 }, { 8, -1, 6, 8, 7 }, { 3, 4, 7, 2, 4 },
{ 2, 4, 3, 1, 2 } };
System.out.println(shortestPath(drm, 0, 0));
}
}
It supposed to return 4 (shortest path)
Given this is for a class I advise you to notify your professor that you received assistance from this post on stack overflow. Neglecting to do this would be considered academic dishonestly at most universities.
Second thing is as David suggested this is a good opportunity for you to learn how to use a debugger. This is a skill that will be incredibly valuable in your academic career and in a engineering role.
Your Code
Now looking at your code it does give the solution "4" for the case you presented which is correct. Problem is if you change the inputs the output may not give the correct answer.
This is because your code as written gives the FIRST path it finds and not the SHORTEST path.
Your logic as far as the recursion is sound and based on this code it looks like you understand the basics of recursion. Your problem is a minor logical flaw with how your are masking your data when you call your function recursively.
You should have everything you need to solve this. If you are still having problems please try to use a debugger and examine the area where you make your recursive calls.
Solution
I advise you to try to figure this out yourself before looking at the spoilers below.
In the code where you make your recursive calls you mask by setting drm[i][j] = Integer.MIN_VALUE. The problem is after each of your recursive calls return you do not set it back to the previous value with drm[i][j] = temp before doing the tests for your next recursive call.
What is happening is when you next call isValidJump() it will always return false because drm[i][j] will always be Integer.MIN_VALUE after your have made your first recursive call on this iteration.
How to fix:
Put drm[i][j] = temp immediately after each recursive call to shortestPath().

How can I change my code below to avoid the unexpected type error (required : variable; found: value)?

1.The fifth line of my code below returns an unexpected type error where a variable is required but a value found.
2.The code is a to check if a number n is Prime or not using a while loop.
public boolean primeNumberCheck(int n)
{
int divisionNumber = 2;
boolean primeCheck = true;
while (divisionNumber < n)
{
if (n%divisionNumber = 0)
{
primeCheck = true;
divisionNumber = n;
}
else
{
primeCheck = false;
}
divisionNumber++;
}
return primeCheck;
}
= is the assignment operator. n%divisionNumber returns a value, and you cannot assign a value to another value. So you get that error.
You need to compare the values using the == operator. So, you should do:
if (n%divisionNumber == 0)
Apart from the answers here , one more tip which I follow is doing :
if (0 == n%divisionNumber) rather than if (n%divisionNumber = 0).
this ensures that I haven't missed one "=" sign.
This is not an answer, just a more optimized algorithm based on Primality test on WikiPedia
public boolean primeNumberCheck(int n) {
// exclude numbers with divisor 2 or 3
if (n % 2 == 0) {
return false;
}
if (n % 3 == 0) {
return false;
}
// all integers can be expressed as (6k + i) for some integer k and
// for i = −1, 0, 1, 2, 3, or 4;
// 2 divides (6k + 0), (6k + 2), (6k + 4); and 3 divides (6k + 3).
// so we only have to test numbers of the form 6k +- 1
int k = 1;
int i = -1;
// we only need to check candidates up to SQRT(n)
double sqrtN = Math.Sqrt(n);
int candidateDivisor = getCandidateDivisor(k, i);
while (candidateDivisor < sqrtN) {
if (n % candidateDivisor == 0) {
return false;
}
// flip i between -1 and 1
i = -i;
// when i flips back to -1, increment k
if (i < 0) {
k++;
}
candidateDivisor = getCandidateDivisor(k, i);
}
return true;
}
private int getCandidateDivisor(k, i) {
return (6 * k) + i;
}
DISCLAIMER: I have not tested this code

How do I make make my code repeat itself?

public Action getMove(CritterInfo info) {
count++;
Direction d = info.getDirection();
if (count < 100) {
if (info.getFront() == Neighbor.OTHER) {
return Action.INFECT;
} else {
return Action.RIGHT;
}
}
if (count >= 100) {
if (info.getFront() == Neighbor.OTHER) {
return Action.INFECT;
} else if (count / 100.0 < 2.0 && count / 100.0 >= 1.0 && !(d == Direction.EAST)) {
return Action.LEFT;
} else if (count / 100.0 < 3.0 && count / 100.0 >= 2.0 && !(d == Direction.WEST)) {
return Action.RIGHT;
} else {
return Action.HOP;
}
}
return Action.INFECT;
}
Right now I have this code that is part of my critter and i'm having problems are the if (count >= 100) part of the code. I can't get my go east and go west code to repeat itself because when I divide count by 100.0, it only works up until 299 then it just stays going west running into the wall. I've tried to set an else if statement after my go west code stating
} else if (count == 299) {
count = 0;
}
but this didn't solve my problem either. Any ideas? I just want my critter to sweep east and west over and over again.
Just use variables instead of your numbers, and change them each time their numbers are reached.Then you can create a method that changes the direction each time the number reaches 100+(100*n).
So, if you reach 200, it will check that the condition I set above is true and will therefore change directions for the next 100 numbers.
Was this what you were looking for , or did I misunderstand what you wanted?
You can use some kind of "cyclic" function like modulo (%) instead of the absolute value of count. E.g.
public Action getMove(CritterInfo info) {
count++;
Direction d = info.getDirection();
if (count < 100) {
if (info.getFront() == Neighbor.OTHER) {
return Action.INFECT;
} else {
return Action.RIGHT;
}
}
else {
int choiceOfAction = (count - 100)%200;
if (0 <= choiceOfDir && choiceOfDir < 100 && !(d == Direction.EAST)) {
return Action.LEFT;
} else if (100 <= choiceOfDir && choiceOfDir < 200 && !(d == Direction.WEST)) {
return Action.RIGHT;
} else {
return Action.HOP;
}
}
}
The line int choiceOfAction = (count - 100)%200; will yield a value of choiceOfAction with:
if count is in [100, 200[ : choiceOfAction is in [0, 100[
if count is in [200, 300[ : choiceOfAction is in [100, 200[
if count is in [300, 400[ : choiceOfAction is in [0, 100[
etc.
Note that I removed the last return in your method that was never reached, and also, that in the case above you will HOP only when you reach the limit and change direction.

Project Euler #7 Java code not working

I've been working on Project Euler #7, and can't figure out why my program is not working. The problem is as follows:
By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.
What is the 10 001st prime number?
This is my program so far:
public class Euler7 {
public static void main (String[] args) {
long count = 1;
long primes = 0;
while (primes <= 10001) {
if (isPrime(count)){
primes++;
if (primes == 10001) {
System.out.println(count);
}
}
count++;
}
}
public static boolean isPrime (long i) {
if (i <= 1) return false;
else if (i == 2 || i == 3) return true;
else if (i % 2 == 0 || i % 3 == 0) return false;
else {
for (int n = 3; n < Math.sqrt(i); n+=2) {
if (i % n == 0) {
return false;
}
}
return true;
}
}
}
EDIT: To be clear, it returns the value 104033, but WolframAlpha says the 10001st prime is 104743
Your code incorrectly believes that some full squares of primes are prime as well. In particular, your isPrime(25) returns true.
This should be enough to figure out a fix (ok, one more hint: all you need is adding a single character).

Naive Primality Testing Optimization

I have an algorithm to test for primality, which uses the naive implementation as listed here http://en.wikipedia.org/wiki/Primality_test#Naive_methods
static boolean check(int n)
{
if(n == 2 || n == 3)
{
return true;
}
if(n < 2 || n % 2 == 0 || n % 3 == 0)
{
return false;
}
for(int i = 6; i * i <= n; i += 6)
{
if(n % (i - 1) == 0 || n % (i + 1) == 0)
{
return false;
}
}
return true;
}
I got all the way to the 6k+1 section, but after that, I'm lost. How else can I further optimize this for speed?
If you want to stick with the naive method, then your next step is to use the next property listed in the wikipedia page you link to:
So all prime numbers are of the form 30k + i for i = 1, 7, 11, 13, 17,
19, 23, 29 (i.e. for i < 30 such that gcd(i,30) = 1).
Except you might pick slightly different / more primes than 2.3.5
You would replace the 6 stepping loop with a 30 stepping loop, (and check with all primes less than 30 by hand )
The code might look like this:
static boolean check(int n)
{
if(n<30)
{
return n==2 || n==3 || n==5 || n==7 || ...
}
for(int i = 30; i * i <= n; i += 30)
{
if (n % (i + 1))==0 return false;
if (n % (i + 7))==0 return false;
if (n % (i + 11))==0 return false;
if (n % (i + 13))==0 return false;
if (n % (i + 17))==0 return false;
if (n % (i + 19))==0 return false;
if (n % (i + 23))==0 return false;
if (n % (i + 29))==0 return false;
}
return true;
}
However you'll note that this scans 8/30 (=27%) numbers, while the 6 stepping loop scans 2/6
(=33%) So it scans about 20% less numbers, so you'd expect a speed up of at best 20%. As you add more primes to the list you get diminishing returns.
Really if you need fast prime checking then you need to move away from the naive methods. And there's been plenty of questions about those on stack overflow previously.

Categories