Checking to see if an integer has distinct numbers java - java

I'm having a difficult time with my program! For this method I have to check to see if all the numbers are distinct and I can't figure out for the life of me what I am doing wrong. I don't know if using an array is the best way to go. I must call the getDigit method.
for (int i = 0; i <= numDigits(number); i++) {
int digit = getDigit(number,i);
if (digit == getDigit(number,i)) {
return false;
}
}
return true;

You can first get each digit from the number and add them to a HashSet, then compare the size of HashSet with the number of digits present in the number
You can try this code:
public static void main(String[] args) {
int val = 123554;
Set<Integer> set = new HashSet<Integer>(); // HashSet contains only unique elements
int count = 0; // keeps track of number of digits encountered in the number
// code to get each digit from the number
while (val > 0) {
int tempVal = val % 10;
set.add(tempVal); // add each digit to the hash set
// you can have a boolean check like if(!set.add(tempVal)) return false; because add() returns false if the element is already present in the set.
val = val / 10;
count++;
}
if (count == set.size()) {
System.out.println("duplicate digit not present");
} else {
System.out.println("duplicate digit present");
}
}

Splitting Int into single digits:
Use something similar to this:
Code to print the numbers in the correct order:
int number; // = and int
LinkedList<Integer> stack = new LinkedList<Integer>();
while (number > 0) {
stack.push( number % 10 );
number = number / 10;
}
while (!stack.isEmpty()) {
print(stack.pop());
}
Source
Checking for Duplicates:
Again, something similar to this:
public static boolean duplicates (int [] x, int numElementsInX ) {
Set<Integer> set = new HashSet<Integer>();
for ( int i = 0; i < numElementsInX; ++i ) {
if ( set.contains( x[i])) {
return true;
}
else {
set.add(x[i]);
}
}
return false;
}
Source
Alternative
If you can split the array, an alternative could be to use:
int[] numbers = { 1, 5, 23, 2, 1, 6, 3, 1, 8, 12, 3 };
Arrays.sort(numbers);
for(int i = 1; i < numbers.length; i++) {
if(numbers[i] == numbers[i - 1]) {
System.out.println("Duplicate: " + numbers[i]);
}
}

i suppose that you want to compare for example the number 12345 with 23145, and prompt out a false, and if they are the same (digit by digit, prompt a true) , am i right?.
If you want to do this, you should make 2 arrays and you have to make sure to compare each position of both so you can compare digit by digit.
Hope it helps you

public boolean unique(int theNumber) {
String number = new Integer(theNumber).toString();
Set<Character> set = new LinkedHashSet<Character>();
for(char c:number.toCharArray()) {
set.add(Character.valueOf(c));
}
return number.length() == set.size();
}

Related

*First* Longest Increasing Subsequence

The longest increasing subsequence is the well known problem and I have a solution with the patience algorithm.
Problem is, my solution gives me the "Best longest increasing sequence" instead of the First longest increasing sequence that appears.
The difference is that some of the members of the sequence are larger numbers in the first(but the sequence length is exactly the same).
Getting the first sequence is turning out to be quite harder than expected, because having the best sequence doesn't easily translate into having the first sequence.
I've thought of doing my algorithm then finding the first sequence of length N, but not sure how to.
So, how would you find the First longest increasing subsequence from a sequence of random integers?
My code snippet:
public static void main (String[] args) throws java.lang.Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int inputInt;
int[] intArr;
try {
String input = br.readLine().trim();
inputInt = Integer.parseInt(input);
String inputArr = br.readLine().trim();
intArr = Arrays.stream(inputArr.split(" ")).mapToInt(Integer::parseInt).toArray();
} catch (NumberFormatException e) {
System.out.println("Could not parse integers.");
return;
}
if(inputInt != intArr.length) {
System.out.println("Invalid number of arguments.");
return;
}
ArrayList<ArrayList<Integer>> sequences = new ArrayList<ArrayList<Integer>>();
int sequenceCount = 1;
sequences.add(new ArrayList<Integer>());
sequences.get(0).add(0);
for(int i = 1; i < intArr.length; i++) {
for(int j = 0; j < sequenceCount; j++) {
if(intArr[i] <= intArr[sequences.get(j).get(sequences.get(j).size() - 1)]) {
sequences.get(j).remove(sequences.get(j).size() - 1);
sequences.get(j).add(i);
break;
} else if (j + 1 == sequenceCount) {
sequences.add(new ArrayList<Integer>(sequences.get(j)));
sequences.get(j + 1).add(i);
sequenceCount++;
break; //increasing sequenceCount causes infinite loop
} else if(intArr[i] < intArr[sequences.get(j + 1).get(sequences.get(j + 1).size() - 1)]) {
sequences.set(j+ 1, new ArrayList<Integer>(sequences.get(j)));
sequences.get(j+ 1).add(i);
break;
}
}
}
int bestSequenceLength = sequenceCount;
ArrayList<Integer> bestIndexes = new ArrayList<Integer>(sequences.get(bestSequenceLength - 1));
//build bestSequence, then after it I'm supposed to find the first one instead
int[] bestSequence = Arrays.stream(bestIndexes.toArray()).mapToInt(x -> intArr[(int) x]).toArray();
StringBuilder output = new StringBuilder("");
for(Integer x : bestSequence) {
output.append(x + " ");
}
System.out.println(output.toString().trim());
}
I'm storing indexes instead in preparation for having to access the original array again. Since it's easier to go from indexes to values than vice versa.
Example:
3 6 1 2 8
My code returns: 1 2 8
First sequence is: 3 6 8
Another Example:
1 5 2 3
My code correctly returns: 1 2 3
Basically, my code works as long as the first longest sequence is the same as the best longest sequence. But when you have a bunch of longest sequences of the same length, it grabs the best one not the first one.
Code is self-explanatory. (Have added comments, let me know if you need something extra).
public class Solution {
public static void main(String[] args) {
int[] arr = {3,6,1,2,8};
System.out.println(solve(arr).toString());
}
private static List<Integer> solve(int[] arr){
int[][] data = new int[arr.length][2];
int max_length = 0;
// first location for previous element index (for backtracing to print list) and second for longest series length for the element
for(int i=0;i<arr.length;++i){
data[i][0] = -1; //none should point to anything at first
data[i][1] = 1;
for(int j=i-1;j>=0;--j){
if(arr[i] > arr[j]){
if(data[i][1] <= data[j][1] + 1){ // <= instead of < because we are aiming for the first longest sequence
data[i][1] = data[j][1] + 1;
data[i][0] = j;
}
}
}
max_length = Math.max(max_length,data[i][1]);
}
List<Integer> ans = new ArrayList<>();
for(int i=0;i<arr.length;++i){
if(data[i][1] == max_length){
int curr = i;
while(curr != -1){
ans.add(arr[curr]);
curr = data[curr][0];
}
break;
}
}
Collections.reverse(ans);// since there were added in reverse order in the above while loop
return ans;
}
}
Output:
[3, 6, 8]

How to swap digits in number?

I need to write function that gets 3 params(int num, int k, int nDigit).
The function get number and replace the digit inside the number in k index by nDigit.
for example:
int num = 5498
int k = 2
int nDigit= 3
the result is num = 5398
My question is how can I implement it?I undastand that the best way to convert the num to string and then just replace char on specific index by nDigit char.
But is there any way to implement it?Without
public int changeDigit(int num, int k, int nDigit){
k = pow(10,k);
double saved = num%k; // Save digits after
num = num - (num%(k*10)); //Get what's before k
return ((int) (num + (nDigit*k) + saved));
}
I won't do your homework for you, but here's some hints:
Convert integer to string:
String s = Integer.toString(1234);
Enumerating a string:
for (i = 0; i < s.length; i++)
{
char c = s.charAt(i);
}
String building (a little less efficient without the StringBuilder class)
char c = '1';
String s = "3";
String j = "";
j = j + c;
j = j + s; // j is now equal to "13"
String back to integer:
int val = Integer.parseInt("42");
You can use a StringBuilder. It's easier to see what you're doing and you don't need to perform mathematics, only adjust the characters in their positions. Then convert it back to int.
public class Main {
static int swapParams(int num, int k, int nDigit) {
StringBuilder myName = new StringBuilder(Integer.toString(num));
myName.setCharAt(k-1, Integer.toString(nDigit).charAt(0));
return Integer.parseInt(myName.toString());
}
public static void main(String[] args) {
System.out.println(swapParams(5498, 2, 3));
}
}
http://ideone.com/e4MF6m
You can do it like this:
public int func(int num, int k, int nDigit) {
String number = String.valueOf(num);
return Integer.parseInt(number.substring(0, k - 1) + nDigit + number.substring(k, number.length()));
}
This function takes the first characters of the number without the k'th number and adds the nDigit to it. Then it adds the last part of the number and returns it as an integer number.
This is my javascript solution.
const solution = numbers => { //declare a variable that will hold
the array el that is not strictly ascending let flawedIndex;
//declare a boolean variable to actually check if there is a flawed array el in the given array let flawed = false;
//iterate through the given array for(let i=0; i<numbers.length; i++) {
//check if current array el is greater than the next
if(numbers[i] > numbers[i+1])
{
//check if we already set flawed to true once.
//if flawed==true, then return that this array cannot be sorted
//strictly ascending even if we swap one elements digits
if(flawed) {
return false;
}
//if flawed is false, then set it to true and store the index of the flawed array el
else {
flawed = true;
flawedIndex = i;
}
}
}
//if flawed is still false after the end of the for loop, return true //where true = the array is sctrictly ascending if(flawed ==
false) return true;
//if flawed==true, that is there is an array el that is flawed if(flawed){
//store the result of calling the swap function on the digits of the flawed array el
let swapResult = swap(flawedIndex,numbers);
//if the swapresult is true, then return that it is ascending
if (swapResult == true) return true; }
//else return that its false return false; }
const swap = (flawIndex, numbers) => {
let num = numbers[flawIndex];
//convert the given array el to a string, and split the string based on '' let numToString = num.toString().split('');
//iterate through every digit from index 0 for(let i=0;
i<numToString.length; i++) {
//iterate from every digit from index 1
for(let j=i+1; j<numToString.length; j++) {
//swap the first index digit with every other index digit
let temp = numToString[i];
numToString[i] = numToString[j]
numToString[j] = temp;
console.log(numToString)
//check if the swapped number is lesser than the next number in the main array
//AND if it is greater than the previous el in the array. if yes, return true
let swappedNum = Number(numToString.join(''));
if(swappedNum < numbers[flawIndex + 1] && swappedNum > numbers[flawIndex-])
{
return true;
}
} } //else return false return false; }
console.log("the solution is ",solution([1, 3, 900, 10]))

Java: check if arraylist is part of fibonacci sequence

My assignment for school is to implement a method that checks if a given ArrayList is part of the Fibonacci sequence.
The array must not be empty and must be bigger than 3.
I understood that I have to check if one number of the array and the next one are part of the Fibonacci sequence, however I have a lot of trouble with it since you're supposed to accept the array if it's any part of the sequence and not just from the start.
e.g.: 0 1 1 2 3 5 will be accepted as well as 2 3 5 8 13 21.
This is my code so far. I know it's very flawed but i really have no clue how to move on.
public class ArrayCheck {
/**
* Tests if the given array is a part of the Fibonacci sequence.
*
* #param arr array to be tested
* #return true if the elements are part of the fibonacci sequence
*/
public boolean isFibonacci(ArrayList<Integer> arr) {
//check if array exists
if(arr.size() == 0)
return false;
//check if array is bigger than 3
if (arr.size() < 3)
return false;
//check for the startsequence of 0,1,1
else if(arr.get(0) == 0 && arr.get(1) == 1 && arr.get(2) == 1)
return true;
//check every number in array
for(int i = 0; i < arr.size(); i++) {
//check if i >= 2 is fib
if(i >= 2) {
int fibn = i;
int nextfib = i + 1;
int fibnew = (fibn - 1) + (fibn - 2);
int fibnext = (nextfib - 1) + (nextfib - 2);
if (arr.get(i) != fibnew && arr.get(i + 1) != fibnext)
return false;
}
//check if the order is right
if(arr.get(i) > arr.get(i+1))
return false;
}
return true;
}
Any help is greatly appreciated!
Well, you have a few issues with your code. First of all, if you array is at least 3 items, you check if only the first three are the start of the Fibonacci sequence:
//check for the startsequence of 0,1,1
else if(arr.get(0)==0 && arr.get(1)==1 && arr.get(2)==1){
return true;
}
This is bad, as this mean 0 1 1 5 which is not part of the sequence will return true.
What you need to do is split this into two tasks:
Find the first relevant number in the sequence (i.e. if the array starts with 7, you know this isn't a part of the sequence; alternatively, if it starts with 8, you know you need to start checking from 8 onward).
Once you've found the "start", simply check that the rest of the array follows the Fibonacci rule. you'll need to manually verify the first two items.
public boolean isFibonacci(ArrayList<Integer> arr) {
if (arr.size() < 3){
return false;
}
/** find if the first element is part of the sequence: **/
int fib1 = 0;
int fib2 = 1;
while (fib1 < arr.get(0)) {
int tmp = fib1 + fib2;
fib1 = fib2;
fib2 = tmp;
}
if (fib1 != arr.get(0)) {
// first element is not part of Fibonacci sequence
return false;
}
if (fib2 != arr.get(1)) {
// the first two elements are not part of the Fibonacci sequence
return false;
}
/*** now simply verify that the rest of the elements uphold the rule:
each element is the sum of the two previous ones: **/
for(int i=2; i < arr.size(); i++) {
// make sure there are no negatives in the array:
if (arr.get(i) < 0)
return false;
if (arr.get(i) != (arr.get(i-1) + arr.get(i-2)))
return false;
}
//everything checks out okay - return true:
return true;
}
private boolean isFib(final List<Integer> li) {
//check if each int is the sum of the two prior ints
for (int i = 2; i < li.size(); i++) {
if (li.get(i) != li.get(i - 1) + li.get(i - 2)) {
return false;
}
}
//reverse the fibonacci sequence and check if we end up at the correct starting point (0, 1)
int i1 = li.get(0);
int i2 = li.get(1);
while (i1 > 0) {
final int tmp = i1;
i1 = i2 - i1;
i2 = tmp;
}
return i1 == 0 && i2 == 1;
}
I'd suggest a solution which abstracts Fibonacci sequence generator in a separate Iterator<Integer>, then uses it to check if provided list matches any part of the sequence.
Iterator is quite simple and straightforward:
public static class FiboIterator implements Iterator<Integer> {
#Override
public boolean hasNext() { return true; }
int i = -1, j = -1; // previous two items of Fibo sequence
#Override
public Integer next() {
int k = (i < 0) ? (j < 0 ? 0 : 1) : (i + j);
i = j;
j = k;
return k;
}
}
Main checking method:
public static boolean isFibo(List<Integer> seq) {
if (seq.size() < 3)
return false;
final Iterator<Integer> f = new FiboIterator();
int start = seq.get(0), k;
while ((k = f.next()) < start); // roll Fibo to match the starting item in input
if (start != k) // starting item doesn't match
return false;
if (start == 1 && seq.get(1) != 1) // special case: [1, 2, ...]
f.next();
for (int i = 1; i < seq.size(); i++) { // check if other items match
if (seq.get(i) != f.next())
return false;
}
return true;
}
And finally a few unit tests:
#Test
public void testFibo() {
assertTrue(isFibo(Arrays.asList(0, 1, 1, 2)));
assertTrue(isFibo(Arrays.asList(1, 1, 2, 3, 5)));
assertTrue(isFibo(Arrays.asList(1, 2, 3, 5, 8)));
assertTrue(isFibo(Arrays.asList(5, 8, 13, 21, 34)));
assertFalse(isFibo(Arrays.asList(1, 2, 0)));
assertFalse(isFibo(Arrays.asList(1, 0, 1)));
assertFalse(isFibo(Arrays.asList(5, 5, 10, 15)));
}

Sieve of erastothenes primality issue

Set up to print out all false values which are prime numbers however out of 25 it prints. 3, 5, 7, 8, 9, 11, 13, 14, 15, 17, 19, 20, 21, 23, 24, not sure why some of them slip by. Any insight into the matter would be nice.
Or simply pointing me in the write direction.
Why are the non-prime numbers such as 8 being printed?
import java.util.Arrays;
import java.util.Scanner;
class Sieve {
public static void main(String args[]) {
Scanner inputScanner;
inputScanner = new Scanner(System.in);
//determine max value
System.out.println("I will determine all the primality of a set of numbers, enter the max");
int n = Integer.parseInt (inputScanner.nextLine());
boolean[] truedBooleanArray = calcBooleanMax (n);
//call upon function to check primality
boolean [] primeNumbers = calcPrimality (truedBooleanArray);
// call upon function to print out prime numbers
printPrimes(primeNumbers);
}
public static boolean[] calcBooleanMax(int maxNumber) {
boolean [] maxNumberArray = new boolean [maxNumber];
maxNumberArray[0] = false;
maxNumberArray[1] = false;
//asigns 1, 0 to false
//change all boleans within array from false to true!
for(int i=1; i < maxNumber; i++) {
maxNumberArray [i] = true;
}
return maxNumberArray;
}
public static boolean[] calcPrimality(boolean [] truedBooleans) {
for(int i = 2; i <=truedBooleans.length; i++) {
//check every number greater than 1 for primality.
if (truedBooleans[i-1]) {
}
//finds multiples and makes sure they arent stored
for(int j = 2*i; j <= truedBooleans.length; j+= i) {
truedBooleans[j-1] = false;
}
}
return truedBooleans;
}
public static void printPrimes(boolean [] thePrimeNumbers){
System.out.println("The prime numbers are [");
for(int i = 2; i<thePrimeNumbers.length; i++) {
if(thePrimeNumbers[i] == false ) {
System.out.print(i + ", ");
}
}
}
}
You have a few errors.
The array must be one larger than the given max
You are accidentally adding one back to the sieve when initializing
When removing multiples from the sieve, you must first make sure the initial number "i" is still in the sieve
You want to print the items that are still in the sieve, so print when true rather than false
Here is the fixed code
public static boolean[] calcBooleanMax(int maxNumber) {
boolean [] maxNumberArray = new boolean [maxNumber+1];
maxNumberArray[0] = false;
maxNumberArray[1] = false;
//asigns 1, 0 to false
//change all boleans within array from false to true!
for(int i=2;i < maxNumber+1; i++) {
maxNumberArray [i] = true;
}
return maxNumberArray;
}
public static boolean[] calcPrimality(boolean [] truedBooleans){
for(int i = 2; i <truedBooleans.length; i++) {
if(truedBooleans[i]) {
//finds multiples and makes sure they arent stored
for(int j = 2*i; j < truedBooleans.length; j+= i) {
truedBooleans[j] = false;
}
}
}
return truedBooleans;
}
public static void printPrimes(boolean [] thePrimeNumbers){
System.out.println("The prime numbers are [");
for(int i = 2;i<thePrimeNumbers.length;i++) {
if(thePrimeNumbers[i] ) {
System.out.print(i + ", ");
}
}
}
A simpler solution is a less literal interpretation of the algorithm. Rather than keeping a literal list of booleans, you can keep a list of the current primes. This makes the code simpler and easier to read.
Here is an example of a solution (that relies on Java 8 streams):
class Sieve {
private long current = 2;
private final List<Long> primes = new ArrayList<>();
public long nextPrime() {
while (primes.stream().anyMatch(p -> current % p == 0))
current++;
primes.add(current);
return current;
}
}

Maximize sum with a limit

I have to get the highest sum of some numbers which do not exceeded a limit.
For Example with 5, 7, 14 and a limit of 13, I must choose 5 and 7.
This example is with only 3 numbers but I have to be able to do this with a lot more numbers.
Is there a library or a method to do this?
I'm assuming the allowed inputs are positive integers. This will return [7, 5] for the example in your question.
public class Knapsack {
private class State {
State previousState = null;
int value = 0;
}
public List<Integer> solve(List<Integer> list, int limit) {
// validate input
if (limit < 0) {
throw new IllegalArgumentException();
}
if (list == null) {
throw new IllegalArgumentException();
}
for (Integer i: list) {
if (i == null || i.intValue() <= 0) {
throw new IllegalArgumentException();
}
}
// if the limit is 12, then 0 through 12 inclusive are valid amounts
State[] states = new State[limit + 1];
// the state at position x represents a way of achieving a sum of x
// if a state is null it means we can't get that sum, for example in your
// question there's no way to get a sum of 11 with any combination of inputs
// base state -- we can always get a sum of zero if we just take nothing
states[0] = new State();
// build up more states
for (Integer i: list) {
// iterate through the states backwards
// if we iterate forwards we'll encounter any changes we make to the list
// during the iteration, which has the effect of taking the same number
// multiple times
for (int j = limit - i.intValue(); j >= 0; --j) {
if (states[j] != null) {
State newState = new State();
newState.previousState = states[j];
newState.value = i.intValue();
states[i.intValue() + j] = newState;
}
}
}
// find the best state
State s = null;
for (int i = limit; i >= 0; --i) {
if (states[i] != null) {
// if all you care about is the best achievable sum, you can just
// return i here
s = states[i];
break;
}
}
// build the list of numbers
List<Integer> ret = new ArrayList<Integer>();
while (s.previousState != null) {
// this will add them backwards, change to add to the beginning of the list
// to preserve the same order as the input
ret.add(Integer.valueOf(s.value));
s = s.previousState;
}
return ret;
}
public static void main(String[] arg) {
List<Integer> list = new ArrayList<Integer>();
for (int i: new int[] { 5, 7, 9 }) {
list.add(Integer.valueOf(i));
}
int limit = 13;
Knapsack k = new Knapsack();
System.out.println(k.solve(list, limit));
}
}

Categories