How do I produce an error when input is bad? - java

I am trying to have my program output an error code when the input values are too high, but I can only get it to display the error message in the terminal window, not in the method return. Here is the code:
public class AckermannAdvanced {
public static long ack (long m, long n) {
long ans;
System.out.print("\f");
if (m > 3 && n > 1) {
System.out.print("Input values are too high");
} else {
if (m == 2) ans = (2*n)+3;
else if (m == 1) ans = n+2;
else if (m == 0) ans = n+1;
else if (n == 0) ans = ack(m-1, 1);
else ans = ack(m-1, ack(m, n-1));
System.out.print(ans);
return(ans);
}
return 0;
}
}

You could use a Long with a capital L, and then it is an object representing a long. Once you return an object you could return null. Java automatically converts a long to a Long when returning, so the other returns should be the same. So
public static Long ack(long m, long n) //...
//...
if (m > 3 && n > 1) {
return null;
}
Alternatively you could have it return an OptionalLong
public static OptionalLong ack(long m, long n) //...
//No result
return OptionalLong.empty();
//Result
return OptionalLong.of(21438999L);
https://www.geeksforgeeks.org/optionallong-orelselong-method-in-java-with-examples/

Related

How to reverse 1000 so that the output will be 1 (not 0001) using recursion or else normal in JAVA

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

Sherlock and the Valid String, giving me wrong results in 5 test cases

I am trying to run a program from hackerrank. This is the question:
Sherlock considers a string to be valid if all characters of the string appear the same number of times. It is also valid if he can remove just one character at one index in the string, and the remaining characters will occur the same number of times. Given a string , determine if it is valid.
For example, if s="abc", it is a valid string because frequencies are {a:1,b:1,c:1}. So is abcc because we can remove one c and have 1 of each character in the remaining string. If s='abccc' however, the string is not valid as we can only remove 1 occurrence of c . That would leave character frequencies of {a:1,b:1,c:2}.
This is the link:
https://www.hackerrank.com/challenges/sherlock-and-valid-string/problem?h_l=interview&playlist_slugs%5B%5D=interview-preparation-kit&playlist_slugs%5B%5D=strings
One of the 5 test cases that failed would be:
aaaabbcc should give false, but it is giving me true.
aabbc should give true but is giving me false.
But somehow 5 of my test cases are coming to be wrong:
Here is the following program.
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
public class SherlokValidString
{
boolean is_valid(String s)
{
int count=0;
HashMap<Character, Integer> map = new HashMap<>();
char[] str_arr= s.toCharArray();
for(char c:str_arr)
{
if(map.containsKey(c))
{
map.put(c, map.get(c)+1);
}
else
{
map.put(c,1);
}
}
if (map.size()==1)
{
return true;
}
else {
List ll=new ArrayList<>(map.values());
System.out.println(ll);
Collections.sort(ll);
int first_element=(int)ll.get(0);
for(int i=1;i<(ll.size()-1);i++)
{
//System.out.println((int)ll.get(i)+1);
if (first_element==(int)ll.get(i+1))
{
count=0;
}
else if(first_element!=(int)ll.get(i+1))
{
count++;
}
}
if(count<=1)
{
//System.out.println(count);
return true;
}
else
{
return false;
}
}
}
public static void main(String[] args)
{
SherlokValidString svs = new SherlokValidString();
System.out.println(svs.is_valid("abbccc"));
}
}
It should be returning false, its giving me true.
Please help. Thanks.
With Java 8, one can do a very elegant job:
public static boolean sherlockStr(String s) {
// First, we're going to walk over the characters and count how many
// times each character occurs
Map<Character, Long> charOccurs = s.chars()
.mapToObj(t -> (char) t)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
// Then we're going to map each amount of characters found to its count,
// e.g. in the string "aabbcc" each character occurs twice → [2, 2, 2].
// That will yield a map: [2=3]
Map<Long, Long> counts = charOccurs.entrySet().stream()
.map(Map.Entry::getValue)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
switch (counts.size()) {
// If all characters occur an equal number of times, then the map
// contains just a single entry.
case 1:
return true;
// If there are two different amounts, then the difference between
// those two must be 1. Also, one of the numbers must occur exactly
// once.
case 2:
Iterator<Long> it = counts.keySet().iterator();
boolean diff = Math.abs(it.next() - it.next()) == 1;
return (diff && (counts.values().stream()
.anyMatch(i -> i == 1)));
// If the map's size is 3 or more, there are differents of amounts of
// characters.
default:
return false;
}
}
In short:
public static boolean sherlockStr(String s) {
Map<Long, Long> counts = s.chars()
.mapToObj(t -> (char) t)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet().stream()
.map(Map.Entry::getValue)
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
switch (counts.size()) {
case 1:
return true;
case 2:
Iterator<Long> it = counts.keySet().iterator();
return (Math.abs(it.next() - it.next()) == 1 && (counts.values().stream()
.anyMatch(i -> i == 1)));
default:
return false;
}
}
I see the following fails in your logic:
The end bound of the last loop is wrong. It really does not matter starting at i==1 (for the first item is implicitly processed when initializing first_element), but the end bound must be ll.size(), not ll.size()-1.
The condition to decide if count must be incremented is too broad, and should be more restrictive: It is not enough that an appearing frequency be different from the lowest frequency (contained in first_element); it must be also ensured that it is, at least 1+first_element. And, if it is even higher, the loop must be broken and return false.
Try the following, see comments :
boolean isValid(String s)
{
HashMap<Character, Integer> map = new HashMap<>();
char[] str_arr= s.toCharArray();
for(char c:str_arr)
{
if(map.containsKey(c))
{
map.put(c, map.get(c)+1);
}
else
{
map.put(c,1);
}
}
//define min max frequencies
int min = (int) Math.pow(10, 5); int max = 0;
for(int value : map.values()) {
if (value < min ) {
min = value;
}
if(value > max ) {
max = value;
}
}
if(min == max) { return true;} //all frequencies equal
if( (max - min) > 1) {return false;} //removing one character can not make the equal
//for other cases make sure that only one frequency is different
int countBiggerThanMin = 0;
for(int value : map.values()) {
if(value > min ) {
countBiggerThanMin++;
}
}
if((countBiggerThanMin == 1) || //only one bigger than min
(countBiggerThanMin == (map.size() - 1))) { //min is samller than all others
return true;
}
return false;
}
By using java 8 Stream it becomes more concise :
boolean isValidForJava8(String s) {
Stream<String> stream = Stream.of(s.split(""));
Map<String, Long> map = stream.collect(
Collectors.groupingBy( Function.identity(), Collectors.counting() ));
Long min = map.values().stream().min(Long::compareTo).get();
Long max = map.values().stream().max(Long::compareTo).get();
if(min == max) { return true;} //all frequencies equal
if( (max - min) > 1) {return false;} //removing one character can not make the equal
//for other cases make sure that only one frequency is different
int countBiggerThanMin = map.values().stream().mapToInt(v -> (v > min) ? 1 : 0).sum();
if((countBiggerThanMin == 1) || //only one bigger than min
(countBiggerThanMin == (map.size() - 1))) { //min is samller than all others
return true;
}
return false;
}
This is a perfectly working solution:
{
if ((s.size() == 1) || (s.size() == 2))
return "YES";
std::map <char, int> hashValues;
for (char &c: s)
{
if (hashValues.count(c) != 0)
hashValues[c]++;
else
hashValues.insert(std::pair <char, int> (c,1));
}
int highest = 0;
int lowest = 100000;
for (map<char,int>::iterator it = hashValues.begin(); it != hashValues.end(); it++)
{
if (it->second < lowest)
lowest = it->second;
if (it->second > highest)
highest = it->second;
}
int countMin = 0;
int countMax = 0;
for (map<char,int>::iterator it = hashValues.begin(); it != hashValues.end(); it++)
{
if (it->second == highest)
countMax++;
if (it->second == lowest)
countMin++;
}
if ((highest - lowest) == 0) {return "YES";};
if (((highest - lowest) == 1) && (countMax == 1))
return "YES";
if (((highest - lowest) == 2))
return "NO";
if ((lowest == 1) && (countMin == 1))
return "YES";
return "NO";
}
Kotlin brings a bit of elegance =)
if (s.length == 1) return "YES"
val freq = s.groupingBy { it }.eachCount()
val max:Int = freq.maxBy { it.value }!!.value
val maxCount = freq.count { it.value == max }
val min = freq.minBy { it.value }!!.value
val minCount = freq.count { it.value == min }
val freqOfFreq = freq.map { it.value }.groupingBy { it }.eachCount()
return when {
freqOfFreq.size > 2 -> return "NO"
freqOfFreq.size == 1 -> return "YES"
minCount == 1 -> return "YES"
max - maxCount == min -> return "YES"
else -> "NO"
}
static List myCharList = new ArrayList<>();
static int isValidStringProcessor(String s) {
int returnStatus=-2;
List<Character> chars = s.chars().mapToObj(e -> (char)e).collect(Collectors.toList());
List<Integer> myList = new ArrayList<>();
Map<Character, Long> frequencyMap =
chars.stream().collect(Collectors.groupingBy(Function.identity(),
Collectors.counting()));
for (Map.Entry<Character, Long> entry : frequencyMap.entrySet()) {
myList.add(entry.getValue().intValue());
myCharList.add(entry.getKey());
}
int min = Collections.min(myList);
int max = Collections.max(myList);
int minFrequency = Collections.frequency(myList, min);
int maxFrequency = Collections.frequency(myList, max);
if ((max==min)) {
returnStatus=-1;
} else if ((minFrequency==1 && maxFrequency==(myList.size()-1)) && (max-min==1)) {
returnStatus=myList.indexOf(min);
} else if ((minFrequency==(myList.size()-1) && maxFrequency==1) && (max-min==1)) {
returnStatus=myList.indexOf(max);
}
return returnStatus;
}
// Complete the isValid function below.
static String isValid(String s) {
String result ="NO";
int validIdenfitier = isValidStringProcessor(s);
if (validIdenfitier == -1) {
result="YES";
} else if (validIdenfitier >= 0) {
Character ch = myCharList.get(validIdenfitier);
String newString = s.replaceFirst(ch+"", "");
if (isValidStringProcessor(newString) == -1)
result="YES";
}
return result;
}
Try this it passes all test cases , similar to your approach. :)
static String isValid(String s) {
char c[]=s.toCharArray();
HashMap<Character,Integer> map=new HashMap<Character,Integer>();
for(char ch: c){
if(!map.containsKey(ch)){
map.put(ch,1);
}
else
map.put(ch,map.get(ch)+1);
}
Set<Integer> st = new HashSet<>();
for(int freq : map.values())
{
st.add(freq);
}
if(st.size() > 2)//More than 2 frequencies
System.out.println("NO");
else if(st.size() == 1)
return "YES";
else{
int f1 = 0;
int f2 = 0;
int f1Count = 0;
int f2Count = 0;
int i = 0;
for(int n : st)
{
if(i == 0) f1 = n;
else f2 = n;
i++;
}
for(int freq : map.values())
{
if(freq == f1) f1Count++;
if(freq == f2) f2Count++;
}
if((f1 == 1 && f1Count == 1 ) || (f2 == 1 && f2Count == 1 ))
return "YES";
else if ((Math.abs(f1 - f2) == 1) && (f1Count == 1 || f2Count == 1))
return "YES";
else
return "NO";
}
return "NO";
}
public String isValid(String s) {
HashMap<Character, Integer> trackFrequency = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
Character c = s.charAt(i);
if (trackFrequency.containsKey(c)) {
int count = trackFrequency.getOrDefault(c, 0);
count = count + 1;
trackFrequency.put(c, count);
} else {
trackFrequency.put(c, 1);
}
}
int sample = trackFrequency.get(s.charAt(0));
int unEqualFrequency = 0;
int unEqualValue = 0;
for (Integer value : trackFrequency.values()) {
if (sample != value) {
unEqualFrequency++;
}
if (unEqualFrequency == 1) {
unEqualValue = value;
}
}
if (unEqualFrequency > 1) {
return "NO";
} else if (Math.abs(sample - unEqualValue) <= 1 ||
unEqualFrequency <= 1) {
return "YES";
}
return "NO";
}
Here i am calculating the no of times the values are different in hashmap . There are three cases
if its == 0 > its sherlock string
if its >1 -> its not a Sherlock String
if its == 1 and the difference of the two values is ==1 -> its sherlock string
Here is the complete solution with all test cases passed in C#
public static string isValid(string s)
{
char[] charArray = s.ToCharArray();
char[] distinct = charArray.Distinct().ToArray();
Dictionary<char, int> result = new Dictionary<char, int>();
string ans = "NO";
if (charArray.Length != distinct.Length)
{
for (int i = 0; i < distinct.Length; i++)
{
var count = charArray.Where(x => x == distinct[i]).Count();
result.Add(distinct[i], count);
}
List<int> lcount = null;
lcount = result.Values.Distinct().ToList();
lcount.Sort();
lcount.Reverse();
if (lcount.Count > 1)
{
if (lcount.Count <= 2)
{
var diff = lcount[0] - lcount[1];
var a1 = result.Where(y => y.Value == lcount[0]).Count();
if (diff > 1 && lcount[1] != 1)
{
ans = "NO";
}
else
{
List<int> mcount = new List<int>();
foreach (var item in lcount)
{
var a = result.Where(y => y.Value == item).Count();
mcount.Add(a);
}
if (mcount.Count <= 2)
{
var fstValue = mcount[0];
var nextValue = mcount[1];
if (fstValue == 1 && (lcount[0] == 1 || diff == 1))
{
ans = "YES";
}
else if (nextValue == 1 && (lcount[1] == 1 || diff == 1))
{
ans = "YES";
}
}
}
}
}
else
ans = "YES";
}
else
ans = "YES";
return ans;
}

Nested if statement with multiple condition returns

What I'm trying to do is return "fizz" when a number is divisible by fizzNumber and return "fizzbuzz" when a number is divisible by fizzNumber AND buzzNumber. I know I can just make an && statement but I'm trying to use the least amount of code possible to achieve what I need. The problem here is that the nested if statement is unreachable, I'm assuming because the if statement ends after the return statement. How can I fix this so that this mimcks an && statement using a nested if while also returning both strings if the condition is true?
public String getValue(int n) {
if (n % fizzNumber == 0) {
return "fizz";
if (n % buzzNumber == 0) {
return "buzz";
}
return Integer.toString(n); // return the number itself as a String
}
}
Solution:
public String getValue(int n) {
if (n%fizzNumber==0) {
if (n%buzzNumber==0) {
// dividable by both fizzNumber and buzzNumber
return "fizzbuzz";
}
// dividable by fizzNumber only
return "fizz";
}
return Integer.toString(n);
}
or shorter (using terniary operator):
public String getValue(int n) {
return (n%fizzNumber==0) ? (n%buzzNumber==0 ? "fizzbuzz" : "fizz") : Integer.toString(n);
}
You could use this:
public String getValue(int n) {
String ret = "";
if(n % fizzNumber == 0) {
ret += "fizz";
}
if(n % buzzNumber == 0) {
ret += "buzz";
}
if(ret.equals("")) {
ret = Integer.toString(n);
}
return ret;
}
This can be optimized to:
public String getValue(int n) {
StringBuilder sb = new StringBuilder();
if(n % fizzNumber == 0) sb.append("fizz");
if(n % buzzNumber == 0) sb.append("buzz");
return sb.length() == 0 ? Integer.toString(n) : sb.toString();
}
As you can see, this solution doesn't use nested if-statements.

recursive factorial formula

I want to get an output that displays something like 1*2*3*4 but instead I get 4*3*2*1
this is my code:
public static int fact(int n)
{
if(n ==1)
return 1;
else
return n * fact(n-1);
}
public static int factorForm(int n)
{
System.out.print(n);
if (n == 1)
return 1;
else
{
System.out.print("*");
return n + '*' + factorForm(n-1);
}
}
You are calling fact(4)
Then you print
Then you call fact(3)
If you invert that you'll get what you want:
public class fact {
static int f(int n)
{
if (n ==1 )
{
System.out.print(1);
return 1;
}
int ret= (n * f(n-1));
System.out.print("*");
System.out.print(n);
return ret;
}
public static void main(String[] args)
{
int ret=f(4);
System.out.print("=");
System.out.println(ret);
}
}
To reverse the output, n should be printed after making the recursive call:
public static int factorForm(int n)
{
if (n == 1)
{
System.out.print(1);
return 1;
}
else
{
int rest = factorForm(n-1); // prints 1*2*...*n-1
System.out.print("*");
System.out.print(n);
return rest * n;
}
}
The expression n + '*' + factorForm(n-1) performs integer addition, not multiplication or string concatenation. I changed it to perform multiplication. If the intention is to return the string that was printed, the return type and the type of rest should be changed to String, the return value in the base case should be "1", and that expression should be changed to rest + "*" + n.
Return after printing as below, more importantly understand how recursion works:
public static int factorForm(int n)
{
if (n == 1){
System.out.print("1*");
return 1;
}
else
{
int val = n * factorForm(n-1);
System.out.print(n + "*");
return val;
}
}
if you want to get like 1*2*3*4 result. i think you can do this.
this is my code:
public static String fact(int n) {
if (n < 1) {
throw new RuntimeException("n must be int type and up 0");
}
else if (n == 1) {
return "1";
} else {
return n + "*" + fact(n - 1);
}
}
public static String factorForm(String str) {
String [] arr = str.split("\\*");
String [] newArr = new String[arr.length];
String result = "";
if (arr.length > 1) {
for (int i = 0; i < arr.length; i++) {
newArr[arr.length - i - 1] = arr[i];
}
for (int i = 0; i < newArr.length; i++) {
result += newArr[i] + (i != newArr.length - 1 ? "*" : "");
}
return result;
} else {
return str;
}
}
like this. you can get results what you get. may be complicated.

2 returns firing in the same function?

Well been working for hours today so i might be missing something silly, but, at this point I'm kinda blind with this and looking for an explanation for this behaviour
i made an example of the problem I'm having and the solution i found is not quite a solution.
The Problem: to the following function I pass 1 as shotCount and 9 as Countdown
the result when i debug, i see the first if run, and run the return 2, but then also the else decides to run to and finally return -1
public int getNextShot(int shotCount, int Countdown)
{
if ((shotCount == 1) && (Countdown != 10)) return 2;
else if (shotCount == 0) return 1;
else return -1;
}
BUT if i do this (same parameters) it works:
public int getNextShot(int shotCount, int Countdown)
{
int res = -2;
if ((shotCount == 1) && (Countdown != 10)) res = 2;
else if (shotCount == 0) res = 1;
else res = -1;
return res;
}
Am I missing something here?
Thanks :)
I think you are mistaken.
Sometimes the debugger in Eclipse acts like its jumping to the last line of the method call but then does return the correct value.
For example, I just copied and pasted your code and it ran fine for me. The below code prints 2.
public class AA {
public static void main(String[] args) {
System.out.println(getNextShot(1, 9));
}
public static int getNextShot(int shotCount, int Countdown)
{
if ((shotCount == 1) && (Countdown != 10)) return 2;
else if (shotCount == 0) return 1;
else return -1;
}
}
This code is OK. When I run this:
public static int getNextShot1(int shotCount, int Countdown) {
if ((shotCount == 1) && (Countdown != 10)) {
return 2;
} else if (shotCount == 0) {
return 1;
} else {
return -1;
}
}
public static int getNextShot2(int shotCount, int Countdown) {
int res = -2;
if ((shotCount == 1) && !(Countdown == 10)) {
res = 2;
} else if (shotCount == 0) {
res = 1;
} else {
res = -1;
}
return res;
}
public static void main(String[] args) throws KeyStoreException, ParseException {
System.out.println(getNextShot1(1, 9));
System.out.println(getNextShot2(1, 9));
}
I get
2
2
on console :)
Second function could look like this (final keyword):
public static int getNextShot2(int shotCount, int Countdown) {
final int res;
if ((shotCount == 1) && !(Countdown == 10)) {
res = 2;
} else if (shotCount == 0) {
res = 1;
} else {
res = -1;
}
return res;
}

Categories

Resources