As an exercise I need to make a code that will give the amount of happy numbers* in a given range. As a test I need to insert the code in a program that checks 10 different outcomes, for every good outcome you get 4 points. I want the full 40 points and my teacher said that I need to change only a little bit in my code. So far I have this:
*A happy number is a number which eventually reaches 1 when replaced by the sum of the square of each digit. For instance, 13 is a happy number because 1^2 + 3^2 = 10 and 1^2 + 0^2 = 1
Important to know: When you end up with a 4, it is definitely not a happy number.
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String st1 = scan.nextLine().trim();
String st2 = scan.nextLine().trim();
int min = Integer.parseInt(st1);
int max = Integer.parseInt(st2);
Set<Integer> happyNumbers = getHappyNumbers(min, max);
System.out.println(happyNumbers.size());
}
public static Set<Integer> getHappyNumbers(int min, int max) {
Set<Integer> out = new HashSet<>();
for (int i = min; i < max; i++) {
if (isHappy(i)) {
out.add(i);
}
}
return out;
}
private static boolean isHappy(int i) {
int sum = 0;
while (i != 0) {
sum += Math.pow((i % 10), 2);
i /= 10;
}
if (sum == 4) return false;
else if(sum == 1) return true;
else if (sum !=1) {return isHappy(sum);}
else return true;
}
}
My teacher also said the mistake is in the following part:
if (sum == 4) return false;
else if(sum == 1) return true;
else if (sum !=1) {return isHappy(sum);}
else return true;
Please help :)
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
public class HappyNumbersMain {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("Lower limit (>0): ");
String st1 = scan.nextLine().trim();
System.out.print("Upper limit: ");
String st2 = scan.nextLine().trim();
int min = Integer.parseInt(st1);
int max = Integer.parseInt(st2);
Set<Integer> happyNumbers = getHappyNumbers(min, max);
System.out.println("Happy numbers between " + min + " and " + max + ":" + happyNumbers);
}
public static Set<Integer> getHappyNumbers(int min, int max) {
Set<Integer> out = new TreeSet<>();
for (int i = min; i <= max; i++) {
if (isHappy(i)) {
out.add(i);
}
}
return out;
}
private static boolean isHappy(int i) {
// Stopping conditions
if (i == 4) {
return false;
} else if (i == 1) {
return true;
}
int sum = 0;
while (i > 0) {
sum += Math.pow((i % 10), 2);
i /= 10;
}
return isHappy(sum);
}
}
Above works as expected, some notes:
When doing recursive functions, put stopping conditions as the first thing it checks
Adding some feedback to the user helps in understanding how to use your program
TreeSet will sort values, HashSet does not, better for display purposes
You should always verify user input (I did not do that, but you should)
if (sum == 4)
return false;
else
if(sum == 1)
return true;
else
return isHappy(sum);
Alternative:
switch ( sum ): {
case 4: return false; break;
case 1: return true; break;
default: return isHappy(sum); break;
}
The break isn't needed, since the return in all control paths.
Related
I'm very new to binary search and I attempted a code that would read values from a document and then the user can input a number to search for from the document, and through binary search, the number would be found. I'm having trouble now because the "low" variable that I initialize in the binary search section of my code is not being returned to my main code and there's an error that says "low can not be resolved to a variable".
Here is the code for my binary search:
static public int search (int[]numbers,int target, int count)
{
int high = numbers.length;
int low = -1;
int middle = (high+low)/2;
while(high-low>1)
{
count++;
middle = (high+low)/2;
if(numbers[middle]>target)
{
high = middle;
}
else if(numbers[middle]<target)
{
low = middle;
}
else
{
break;
}
System.out.println(numbers[middle]);
System.out.println(middle);
}
if(low == -1 || numbers[low]!=target)
{
low=-1;
return low;
}
else
{
return low;
}
}
And here is the code from my main code. The part with the if statements is where the error is showing up:
public static void main(String[] args) throws IOException {
DataInputStream input = new DataInputStream(System.in);
int [] numbers = new int [50000];
int target;
int count=0;
try
{
BufferedReader br = new BufferedReader(new FileReader("randNums.txt"));
for(int i=0;i<50000;i++)
{
numbers[i]=Integer.parseInt(br.readLine());
}
br.close();
Arrays.sort(numbers);
System.out.print("Choose a number between 1-100000000 to search for: ");
target = Integer.parseInt(input.readLine());
search(numbers, target,count);
if(low==-1)
{
System.out.println("The number was not on the list.");
}
else
{
System.out.println("The number is at position " + low);
System.out.println("It took " + count + " comparisons to find the number.");
}
}
You have to initialize low in main:
int low=search(numbers, target,count);
I have Already resolved this algorithm.
Try my code :
public static int guessNumber(int number) {
int first = 0;
int last = 1_000_000;
if (verify(first) == 0) {
count++;
return first;
}
if (verify(last) == 0) {
count++;
return last;
}
while (last > first && count <= 50) {
count += 1;
// get the middle of the range
int middle = (first + last) / 2;
if (verify(middle) == 0) {
return middle;
}
if (verify(middle) == 1) {
first = middle + 1;
if (verify(first) == 0) {
return first;
}
}else {
last = middle - 1;
if (verify(last) == 0)
return last;
}
}
return 0;
}
//Function verify(integer) => integer
public static int verify(int guess){
if (numberTobeGuessed > guess ) {
return 1;
}else if (numberTobeGuessed < guess) {
return -1;
}
return 0;
}
I recently found a solution for lazy peoples like me use below code
int position = Arrays.binarySearch(numbers , target);
here no need to sort, and array variable number integer variable target.
As I have already made the code just I have to add the required condition(1000 == 1 ! 0001). Can anybody help me out.
public class ReverseNum {
static void reverseInteger(int n) {
// Write your code here
if (n <= 0) {
System.out.print("-");
reverseInteger(n * -1);
} else if (n < 10) {
System.out.println(n);
}
else {
System.out.print(n % 10);
reverseInteger(n / 10);
}
}
public static void main (String args[]){
Scanner s = new Scanner(System.in);
int num = s.nextInt();
reverseInteger(num);
}
}
Be careful with negative numbers: they need special consideration (and also will break string reversal and parsing).
A solution that works with any int:
public static int reverse(int value) {
if (value < 0) {
// special handling for negative numbers
return 0 - reverse(-value);
}
int reversed = 0;
while (value > 0) {
reversed = reversed * 10 + (value % 10);
value /= 10;
}
return reversed;
}
Test cases:
assertEquals(0, reverse(0));
assertEquals(321, reverse(123));
assertEquals(98765, reverse(567890000));
assertEquals(-91, reverse(-19));
assertEquals(-2, reverse(-20000));
Try this code :
private static int reverseInteger(int n) {
if (n == 0) {
return n;
}
int symbol = n / Math.abs(n);
n = Math.abs(n);
String str = new StringBuilder(String.valueOf(n)).reverse().toString();
return symbol * Integer.parseInt(str);
}
Test cases:
#Test
public void test_reverseInteger() {
assertEquals(0, reverseInteger(0));
assertEquals(321, reverseInteger(123));
assertEquals(98765, reverseInteger(567890000));
assertEquals(-91, reverseInteger(-19));
assertEquals(-2, reverseInteger(-20000));
}
I was trying to build a Java program for finding the LCM of 'N' numbers. but first of all i am stuck at finding the total prime factors of a number including their occurrences. For example (6=2x3) and (8=2x2x2). but the output i get is '2' for (6) and only two '2's for (8). Where are the other? I am even checking the integer 's' to be prime.
package lcm;
import java.util.ArrayList;
import java.util.Scanner;
public class LCM {
public static boolean isPrime(int numero){
for (int i = 2; i <= Math.sqrt(numero); i++) {
if (numero % i == 0) {
return false;
}
}
return true;
}
public static void factor(int x){
int s;
int copy = x;
ArrayList<Integer> al = new ArrayList<>();
for(s=2;s<copy;s++){
if(copy%s==0){
if (isPrime(s)){
al.add(s);
copy/=s;
//used for repetition
s--;
}
}
}
for( int p : al){
System.out.println(p);
}
}
public static void main(String[] args) {
// TODO code application logic here
int j,k;
int temp=0;
System.out.println("Enter no. of numbers");
Scanner cin = new Scanner(System.in);
int i = cin.nextInt();
int []a = new int[i];
int []b=new int[100];
System.out.println("Enter numbers one by one");
for(j=0;j<a.length;j++){
a[j] = cin.nextInt();
}
for(j=0;j<a.length;j++){
temp=a[j];
factor(temp);
}
}
}
The reason is when s=2 and copy also becomes 2 in a case at that time it skips the loop so only two 2's are shown. Try putting <=copy in that place
I think one of the best way to approach this problem is to use recursion since you continuously have to divide in order to find all the prime factors.
package leastcommonmultiple;
import java.util.ArrayList;
import java.util.Scanner;
public class Runner {
private static LeastCommonMultiple lcm;
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
System.out.println("Enter numbers and separate them with a comma: ");
Scanner cin = new Scanner(System.in);
String[] inputs;
String lineInput;
try {
lineInput = cin.nextLine();
while (lineInput.isEmpty()) {
System.out.println("Enter at least 2 numbers separated by a comma ");
lineInput = cin.nextLine();
}
inputs = lineInput.split(",");
int length = inputs.length;
int[] numbers = new int[length];
int temp = 0;
for (int i = 0; i < length; i++) {
if (inputs[i] != null && !inputs[i].isEmpty()) {
if ((temp = Math.abs(Integer.valueOf(inputs[i].trim()))) == 0) {
throw new IllegalArgumentException("No number should be 0");
}
numbers[i] = temp;
}
}
ArrayList<Integer> list = new ArrayList<>();
lcm = new LeastCommonMultiple();
System.out.println("The Least Common Multiple is: " + lcm.getLeastCommonMultipleOfListOfNumbers(numbers));
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}
package leastcommonmultiple;
import java.util.ArrayList;
public class LeastCommonMultiple {
public LeastCommonMultiple() {
}
/**
* #param numbers array of numbers whose LCM should be found.
* #assure numbers.length > 1
* #return LCM of numbers contained in numbers array
*/
public int getLeastCommonMultipleOfListOfNumbers(int[] numbers) throws IllegalArgumentException {
int leastCommonMultiple;
int length = numbers.length;
if ( length <= 1) {
throw new IllegalArgumentException("Please enter at least 2 numbers separated by a comma.");
} else {
leastCommonMultiple = getLeastCommonMultipleOfTwoNumbers(numbers[0], numbers[length-1]);
length = length-1;
for ( int i=1; i<length; i++ ) {
leastCommonMultiple = getLeastCommonMultipleOfTwoNumbers(leastCommonMultiple, numbers[i]);
}
}
return leastCommonMultiple;
}
private int getLeastCommonMultipleOfTwoNumbers(int number1, int number2) {
int leastCommonMultiple = 0;
int maxOfTheTwoNumbers = Math.max(number1, number2);
int minOfTheTwoNumbers = Math.min(number1, number2);
int quotient = 0;
if (number1 % number2 == 0 || number2 % number1 == 0) {
leastCommonMultiple = maxOfTheTwoNumbers;
} else {
ArrayList<Integer> primeFactors = getPrimeFactors(minOfTheTwoNumbers, new ArrayList<>());
for (int primeFactor : primeFactors) {
if (maxOfTheTwoNumbers % primeFactor == 0) {
maxOfTheTwoNumbers = (maxOfTheTwoNumbers / primeFactor);
}
leastCommonMultiple = minOfTheTwoNumbers * maxOfTheTwoNumbers;
}
}
return leastCommonMultiple;
}
// recursive methods that finds all the prime factors for a given number
/**
* #param numero positive number whose prime factors has to be found
* #param primeFactors an empty ArrayList where the prime factors will be
* stored
* #return the ArrayList containing the found prime factors
*/
private static ArrayList<Integer> getPrimeFactors(int numero, ArrayList<Integer> primeFactors) {
int sqrt = (int) Math.sqrt(numero);
int quotient;
if (isPrime(numero)) {
primeFactors.add(numero);
} else {
if (numero % sqrt == 0) {
quotient = numero / sqrt;
if (isPrime(sqrt)) {
primeFactors.add(sqrt);
} else {
primeFactors = getPrimeFactors(sqrt, primeFactors);
}
} else {
quotient = numero / (sqrt - 1);
if (isPrime(sqrt - 1)) {
primeFactors.add(sqrt - 1);
} else {
primeFactors = getPrimeFactors((sqrt - 1), primeFactors);
}
}
if (!isPrime(quotient)) {
primeFactors = getPrimeFactors(quotient, primeFactors);
} else {
primeFactors.add(quotient);
}
}
return primeFactors;
}
// Make sure a number is prime
public static boolean isPrime(int numero) {
int length = (int) Math.sqrt(numero);
for (int i = 2; i <= length; i++) {
if (numero % i == 0) {
return false;
}
}
return true;
}
}
Here's a solution which is faster by using binary splitting on the Euclidean algorithm:
private static int gcd(int a, int b) {
if (a == 0) return b;
if (b == 0) return a;
return gcd(b, a%b);
}
private static int lcm(int a, int b) {
return a / gcd(a, b) * b;
}
public static int LCM(int[] numbers) {
int len = numbers.length;
if (len == 2) return lcm(numbers[0], numbers[1]);
if (len == 1) return numbers[0];
if (len == 0) return 1;
int[] left = Arrays.copyOfRange(numbers, 0, len/2);
int[] right = Arrays.copyOfRange(numbers, len/2+1, len);
return lcm(LCM(left), LCM(right));
}
I am trying to write program to find upside down of all double digit number. Actually I have written this code and it works pretty well too. Any other alternatives to find upside down of an integer. Say 18=81 and 96=69....
List < Integer > al = new ArrayList < Integer > ();
al.add(10);al.add(11);al.add(16);al.add(18);al.add(19);al.add(60);al.add(61);
al.add(66);al.add(69);al.add(80);al.add(81);al.add(86);al.add(88);al.add(91);
al.add(96);al.add(98);al.add(99);
Scanner s = new Scanner(System.in);
Integer n = s.nextInt();
if (((String)"" + n).length() == 2) {
if (al.contains(n))
System.out.println("yes");
else
System.out.println("no");
}
This is a simple, general algorithm analysing an integer w.r.t. digits with vertical symmetry. (It depends on a certain style of writing digits; note that "continental" '1' is not symmetrical.)
private static int[] other = new int[]{0, 1, -1, -1, -1, -1, 9, -1, 8, 6};
public static int invert( int n ){
int units = n % 10;
n /= 10;
int inv = other[units];
if( n == 0 ) return inv;
return inv < 0 ? -1 : invert( n )*10 + inv;
}
If a negative value is returned, the number is not symmetrical.
public static void main(String[] args) throws Exception {
for( int i = 100; i <= 199; ++i ){
int invi = invert( i );
if( invi > 0 ){
System.out.println( i + ": " + invi );
}
}
}
This is a better way of doing it.
It not only prints yes or no, but also the up side down number
public static void main(String[] args) {
List<String> al = new ArrayList<String>();
al.add("0");
al.add("1");
al.add("6");
al.add("8");
al.add("9");
Scanner s = new Scanner(System.in);
Integer n = s.nextInt();
String num = n + "";
if (num.length() == 2) {
if(al.contains(num.charAt(0) + "") && al.contains(num.charAt(1) + "")) {
System.out.println("Yes");
String upSideDownNumber = "";
if(num.charAt(1) == 6) {
upSideDownNumber += 9;
} else if(num.charAt(1) == 9) {
upSideDownNumber += 6;
} else {
upSideDownNumber += num.charAt(1);
}
if(num.charAt(0) == 6) {
upSideDownNumber += 9;
} else if(num.charAt(0) == 9) {
upSideDownNumber += 6;
} else {
upSideDownNumber += num.charAt(0);
}
System.out.println("The up side down number is " + upSideDownNumber);
} else {
System.out.println("No");
}
} else {
System.out.println("No");
}
}
Since only 0,1,6,8,9 look like digits when inverted. You can so below:
public static void main(String[] args) throws IOException {
Set<Integer> upsideDownProperDigits = new TreeSet<>(Arrays.asList(0,1,8,9,6));
Scanner s = new Scanner(System.in);
Integer n = s.nextInt();
boolean found = true;
while( n != 0){
int digit = n % 10;
if(!upsideDownProperDigits.contains(digit)){
found = false;
break;
}
n = n/10;
}
if(found){
System.out.println("yes");
}
else{
System.out.println("no");
}
}
I was asked this question in an interview recently (Java programming que)
Return the sum of all integers from a random String.
Just iterate over the string, handle one digit at a time. This is pretty much exactly what the regex would do anyway:
String testStrings[] = { "-1a2b3c", "123ab!45c", "abcdef", "0123.4",
"dFD$#23+++12##T1234;/.,10" };
for (String testString : testStrings) {
String currentNumber = "";
int sum = 0;
for (int i = 0; i < testString.length(); i++) {
char currentChar = testString.charAt(i);
// Add digits or a leading minus to "currentNumber"
if (Character.isDigit(currentChar)
|| (currentNumber.equals("") && currentChar == '-')) {
currentNumber += currentChar;
} else {
// We've stumbled across a non-digit char.
//Try to parse the "currentNumber" we have so far
if (!currentNumber.equals("") && !currentNumber.equals("-"))
sum += Integer.parseInt(currentNumber);
currentNumber = "";
}
}
// Add the last "currentNumber" in case the string ends with a
// number
if (!currentNumber.equals("") && !currentNumber.equals("-"))
sum += Integer.parseInt(currentNumber);
System.out.println(sum);
}
Output:
4
168
0
127
1279
public class Random {
public int SumofNumbers(String s){
char[] str = s.toCharArray();
String answer="";
int sum = 0;
List<String> al = new ArrayList();
for (int i=0;i< str.length;i++){
if (checkNumber(str[i])){
answer=answer+str[i];
}
else
{
if(!answer.isEmpty()){
al.add(answer);
answer = "";
}
}
if (i == str.length -1 && !answer.isEmpty()) {
al.add(answer);
}
}
for (String a1 : al){
sum = sum + Integer.valueOf(a1);
}
return sum;
}
private boolean checkNumber(char c) {
if ((int)c > 47 && (int)c < 58){
return true;
}else if ((int)c == 45){
return true;
}
return false;
}
public static void main(String [] args){
Random r = new Random();
String test = "123ab!45c";
System.out.println(r.SumofNumbers(test));
}
}
public class StringToIntAddition {
public static void main(String[] args) throws Exception {
String str = "2e40 ssdf 23-9", number="";
int sum=0;
for(int i=0; i<str.length() ;i++){
if(Character.isDigit(str.charAt(i))){
number += str.charAt(i);
}
else if(!number.isEmpty()){
sum += Integer.parseInt(number);
number= "";
}
if (str.charAt(i) == '-'){
number = "-" ;
}
}
if(!number.isEmpty()){
sum += Integer.parseInt(number);
}
System.out.println("number= " + sum);
}
}
I've got a slightly 'cute' way to do this in Java 8: implement it as a Collector
public DigitCollector {
private boolean negative = false;
private int current = 0;
private int total = 0;
public int getTotal() {
if (negative) {
total -= current;
} else {
total += current;
}
current = 0;
negative = false;
return total;
}
public void accept(Character ch) {
if (Character.isDigit(ch)) {
current = 10 * current + Integer.parseInt(ch.toString());
} else if (ch.equals('-')) {
negative = true;
} else {
getTotal();
}
}
}
Now you can collect a stream of characters:
text.chars().map(ch -> new Character((char)ch))
.collect(DigitCollector::new, DigitCollector::accept, null)
.getTotal();
I realise the mapping ch -> new Character((char)ch)) looks strange but .chars() returns a stream of integers instead of characters. See here for reasons why (though pretty much everyone agrees it was a mistake).
This is a slightly longwinded way of doing it but it's pretty flexible: you could take a stream of Character from anywhere and do any sort of manipulation you wanted before collecting them. It seems to me to be a natural representation of the problem and, mostly, I just reckon streams are cooler than traditional iteration :-)
There's already quite a few answers, but this one seemed fun. I have a different solution that should be pretty efficient:
public static int countString(String input) {
if (input == null) return 0;
int sum = 0;
int accumulator = 0;
boolean lastCharWasDigit = false;
for (int i = 0, len = input.length(); ++i) {
char c = input.charAt(i);
// If a non-digit character is found, clear the
// accumulator and add it to the sum.
if (c < '0' || c > '9') {
sum += accumulator;
accumulator = 0;
lastCharWasDigit = false;
continue;
}
// If the previous character was a digit, that means
// this is a continuation. Multiply by ten to shift
// it over one power of ten before adding the new value
if (lastCharWasDigit) {
accumulator *= 10;
}
// Add the integer value of the character
int charValue = c - '0';
accumulator += charValue;
lastCharWasDigit = true;
}
// Finally, clear the accumulator for any ending digits,
// and return the sum
sum += accumulator;
return sum;
}