Check whether the given number is fasinating or not - java

I am doing question on geeksforgeeks and i have come up with a question.
Given a number N. Your task is to check whether it is fascinating or not.
Fascinating Number: When a number(should contain 3 digits or more) is multiplied by 2 and 3 ,and when both these products are concatenated with the original number, then it results in all digits from 1 to 9 present exactly once.
Example 1:
Input:
N = 192
Output: Fascinating
Explanation: After multiplication with 2
and 3, and concatenating with original
number, number will become 192384576
which contains all digits from 1 to 9.
Example 2:
Input:
N = 853
Output: Not Fascinating
Explanation: It's not a fascinating
number.
Your Task:
You don't need to read input or print anything. Your task is to complete the function fascinating() which takes the integer n parameters and returns boolean denoting the answer.
Expected Time Complexity: O(1)
Expected Auxiliary Space: O(1)
Constraints:
100 <= N <= 107
i have to complete the following fascinating function my code is returning error.
class Solution {
boolean fascinating(String q) {
// code here
int sum = 0;
for(int i=0; i<q.length(); i++){
sum = sum + Integer.parseInt(Character.toString(q.charAt(i)));
}
if(sum == 45){
return true;
}
return false;
}
}
When i saw the solution code i am not able to understand how it is doing the things.
class Solution {
boolean fascinating(String q) {
int A[] = {0, 0, 0, 0, 0, 0,
0, 0, 0, 0}; // to store count of every digit from '0' to '9'
int i, flag = 0;
char ch;
for (i = 0; i < q.length(); i++) {
ch = q.charAt(i);
A[ch - 48]++;
}
for (i = 1; i < 10; i++) {
// checking if every digit from '1' to '9' are present exactly once
// or not
if (A[i] != 1) {
flag = 1; // flag is set to 1 if frequency is not 1
break;
}
}
if (flag == 1)
return false;
else
return true;
}
}
Can anyone please explain this to me it will be very helpful.

class Solution {
fascinating returns a boolean, true/false to the question, "is it fascinating?"
boolean fascinating(String q) {
int A[] = {0, 0, 0, 0, 0, 0,
0, 0, 0, 0}; // to store count of every digit from '0' to '9'
Here you just initialize A as an array of zeroes, effectively (but not technically) 'empty'.
int i, flag = 0;
char ch;
Here you initialize i and flag at 0 and declare ch.
for (i = 0; i < q.length(); i++) {
ch = q.charAt(i);
A[ch - 48]++;
}
Here you have a for loop that goes through each character in q.
For example, let q = 192384576. This is not N, but rather N concatenated with (Nx2) concatenated with (Nx3).
So the for loop first sets ch = q.charAt(0). This is the first character, 1. Then it increments (adds one to) a certain index in A.
This index, much credit and thanks to Andreas for explaining this, is the difference of the Numeric ASCII value for ch and 48, which is the Numeric ASCII value for 0.
In Numeric ASCII:
0 = 48
1 = 49
2 = 50
3 = 51
and the rest.
Therefore, ch-48 will give the index in A that should represent ch. For example, when ch is 1, ASCII value of ch is 49 and 49-48 = 1. Therefore, it goes to A[1] and increments it.
Remember, arrays go [0,1,2,3, etc.] So it goes to [0, 0, 0, etc] and adds one to the second 0 -- A[1], thus making A = [0,1,0,etc].
It continues through each digit in q, and thus fills the array A.
for (i = 1; i < 10; i++) {
// checking if every digit from '1' to '9' are present exactly once
// or not
if (A[i] != 1) {
flag = 1; // flag is set to 1 if frequency is not 1
break;
}
}
Here, it iterates through A, set to length 10 because we are checking 0-9, and checks at each index if the value in that index is equal to 1. Hence,
if (A[i]!=1){}
The array should look like [1,1,1,1,etc].
If any of these indices is found not to be 1, it sets flag = 1 and immediately will break or exit the for loop.
if (flag == 1)
return false;
else
return true;
}
}
This final if-else statement checks whether flag is equal to 1. Remember, we only set it equal to 1 if the array is not uniformly filled with 1's, meaning the String q does not contain exactly one of each digit 0-9.
If flag is 1, return false, meaning it is not fascinating. Otherwise, it is fascinating. Thus, when fascinating, return true.

Related

Filling an array with a mathematical sequence

I want to write a code that asks for three numbers dig(1), dig(2), dig(3) and displays a sequence of numbers dig(1), dig(2), dig(3), ..., dig(n) according to this rule:
a = dig(2) - dig(1)
b = dig(3) - dig(2)
dig(n) = dig(n-1) + a if n is odd
dig(n) = dig(n-1) + b if n is even
Example:
7, 8, 5, 6, 3, 4, 1, 2, -1, 0
It asks an user for three integers dig1, dig2, dig3
It asks a number N ≥ 3 which will be the whole sequence count.
It prints a sequence beginning with
Then prints the sequence, beginning with the three leading integers, followed by N-3 other terms that follow the pattern defined by the first three integers. See examples below for more information.
(The sequence begins with n = 1, but of course the array starts at 0.)
int dig1 = 0;
int dig2 = 0;
int dig3 = 0;
int a;
int b;
int n = 0;
int i;
dig1 = scnr.nextInt();
dig2 = scnr.nextInt();
dig3 = scnr.nextInt();
n = scnr.nextInt();
int[] array = new int[n];
array[0] = dig1;
array[1] = dig2;
array[2] = dig3;
a = dig2 - dig1;
b = dig3 - dig2;
for (i = 3; i < n; i++){
if(i%2 == 0){
array[i] = b + array[i-1];
}
else{
array[i] = a + array[i-1];
}
}
System.out.println(array[i]);
}
}
whenever I try to print this out, I get this error:
java.lang.ArrayIndexOutOfBoundsException
Another example: if I put in the numbers: 0 1 0 9 into my input, I should receive back the sequence 0 1 0 1 0 1 0 1 0
Printing array[n-1] gives me back just the final output. I'm trying to iterate through each number.
Sorry if that's unclear, but any help would be great, thank you.
Your System.out.println(array[i]); seems to be out of the for loop. Then i will be equal to n. And there is no element with index n in array with length n. The elements are from 0 to n-1.
At first I thought that you were choosing an array size less than 3, and that the code was failing here, during the initialization of the array:
array[0] = dig1;
array[1] = dig2;
array[2] = dig3;
But now, I actually think that the last line of code is the problem. Have a closer look at your for loop:
for (i=3; i < n; i++) {
if (i % 2 == 0) {
array[i] = b + array[i-1];
}
else {
array[i] = a + array[i-1];
}
}
System.out.println(array[i]);
Appreciate that at the end of the for loop, i, the loop counter, will always be n, the size of the array. Accessing array[n] will always be out of bounds, because an array in Java has a highest addressable index of one less than the actual number of buckets. So, if you were intending to just print the final element, then use this:
System.out.println(array[i-1]);
or
System.out.println(array[n-1]);
at the line n=scrn.nextInt(), you are assigning to n a integer from scrn but you don't know the value of that integer.
Then with this:
int[] array = new int[n];
Your array is of size of n elements starting from index 0 to index n-1.
So let's suppose the value you affected to n with .nextInt() is inferior to 3: initial value of i, the loop will even not be reached, because you will be out of bounds just here:
array[0] = dig1;
array[1] = dig2;
array[2] = dig3;
since you will be attempting to affect a value on an array at an index that does not exists (n is inferior to three but you are trying to affect three values in an array of size n).
Then if n is superior to 3, since your printing code is out from the loop, the value of i is equal to n and there is no value at index n. remember, the loop will leave only if the condition i<n is false and to reach that condition i must be equal or superior and that will lead to an IndexOutOfBoundsException on printing.
I think you printing line code should be inside the for loop.

How to define number sequence in string?

I have a task to create a string with a non-defined length (input digits from the keyboard until the user presses "Enter"), then I have to define how many of digits are in sequence. Unfortunately I can't handle this. I think I'm almost there but I'm not. I've created the string which I hoped to copy character by character to an array and then compare each digit with the next one, but I have trouble with copying characters into an array.
Here's my code:
int sum = 0;
String someSymbols = sc.nextLine();
int array [] = new int[someSymbols.length()];
for(int i=0; i<someSymbols.length(); i++){
for (int j=0; j<=array.length; j++){
array[j] = someSymbols.charAt(i);
}
sum++;
}
Not sure of what you want to achieve but here are 2 examples for inspiration:
Taking digits until reaching a different digit. Ignoring non digits
String s = "22u223r5";
String digitsOnly = s.replaceAll("[^\\d.]", "");
int firstDifferentDigit = -1;
for(int i = 1; i < digitsOnly.length(); i++) {
if(digitsOnly.charAt(i) != digitsOnly.charAt(i-1)) {
firstDifferentDigit = i;
break;
}
}
System.out.println("firstDifferentDigit:"+firstDifferentDigit);
System.out.println(digitsOnly.substring(0,firstDifferentDigit));
Outputs
firstDifferentDigit:4
2222
Taking digits until first non digit
String s = "124g35h6j3lk4kj56";
int firstNonDigitCharacter = -1;
for(int i = 0; i < s.length(); i++) {
if(s.charAt(i) < '0' || s.charAt(i) > '9') {
firstNonDigitCharacter = i;
break;
}
}
System.out.println("firstNonDigitCharacter:"+firstNonDigitCharacter);
System.out.println(s.substring(0,firstNonDigitCharacter));
Outputs
firstNonDigitCharacter:3
124
EDIT
This works for how you described the exercise:
String someSymbols = "72745123";
List<String> sequences = new ArrayList<>();
boolean inSequence = false; // will flag if we are currently within a sequence
StringBuilder currentSequence = new StringBuilder(); // this will store the numbers of the sequence
for(int i = 0; i < someSymbols.length(); i++) {
char currentChar = someSymbols.charAt(i);
char nextChar = 0;
if(i < someSymbols.length()-1)
nextChar = someSymbols.charAt(i+1);
// if next number is 1 more than the current one, we are in a sequence
if(currentChar == nextChar-1) {
inSequence = true;
currentSequence.append(String.valueOf(currentChar));
// if next number is NOT 1 more than the current one and we are in a sequence, it is the last of the sequence
} else if(inSequence) {
currentSequence.append(String.valueOf(currentChar));
sequences.add(currentSequence.toString());
currentSequence = new StringBuilder();
inSequence = false;
}
}
System.out.println(sequences);
Outputs
[45, 123]
Thanks a lot! I made it with your help! It turns out that the task was to count how many numbers occur in the string of any symbols. As simple as that. My bad! But I'm grateful to be part of this forum :)
Here's the code:
String f = sc.nextLine();
int count = 0;
for(int i=0; i<f.length(); i++){
if((f.charAt(i)>='0') && (f.charAt(i)<='9')){
count++;
}
}
System.out.println("The numbers in the row are : " + count);
I deleted my first answer, because I got the question wrong, thought it's about a character sequence, of which some happen to be digits.
Trying to wrap my head around the new functional style in Java8, but conversion is complicated and full of pitfalls. Surely, this isn't canonical. I guess a collector could be appropriate here, but I broke out and made half of the work in an recursive method.
import java.util.*;
import java.util.stream.*;
String s = "123534567321468"
List<Integer> li = IntStream.range (0, s.length()-2).filter (i -> (s.charAt(i+1) != s.charAt(i)+1)).collect (ArrayList::new, List::add, List::addAll);
li.add (s.length()-1);
int maxDiff (int last, List<Integer> li , int maxdiff) {
if (li.isEmpty ())
return maxdiff;
return maxDiff (li.get(0), li.subList (1, li.size () - 1), Math.max (li.get(0) - last, maxdiff));
}
int result = maxDiff (0, li, 0);
It starts elegantly.
IntStream.range (0, s.length()-2).filter (i -> (s.charAt(i+1) != s.charAt(i)+1))
| Expression value is: java.util.stream.IntPipeline$9#5ce81285
| assigned to temporary variable $20 of type IntStream
-> $20.forEach (i -> System.out.println (i));
2
3
8
9
10
11
12
That's the List of indexes, where chains of numbers are broken.
String s = "123534567321468"
123 is from 0 to 2, 5 is just 3, 34567, the later winner from 4 to 8, ...
Note that we needn't transform the String into Numbers, since the characters are chained in ASCII or UTF-X one by one, like numbers.
To convert it into a List, the complicated collect method is used, because Array of primitive int doesn't work well with List .
For the last interval, li.add (s.length()-1) has to be added - adding elements wouldn't work with array.
maxDiff protocolls the max so far, the last element and repeatedly takes the head from the list, to compare it with the last element to build the current difference.
The Code was testet in the jshell of Java9, which is an amazing tool and needs no embedding class, nor 'main' for snippets. :)
Just for comparison, this is my solution in scala:
val s = "123534567321468"
val cuts = (0 to s.length-2).filter (i => {s.charAt(i+1) != s.charAt(i)+1}).toList ::: s.length-1 :: Nil
(0 :: cuts).sliding (2, 1).map {p => p(1) - p(0)}.max
Sliding(a,b) defines a window of width a=2 which moves forward by b=1.

Increment through int[] as an int

So during a homework assignment I made a method that would increment through an integer array as if it were an integer. So what I mean by that is that the index of the int[] would represent the digits in a number.
for example:
int[] digits;
digits = new int[4]
this would be a 4 digit number. index 0 being the 1000's place, index 1 being the 100's place, index 2 being the 10's place and index 3 being the 1's place.
So the method I made increments through that array like this:
0000, 0001, 0002, 0003, 0004, --> 0010, 00011, ----> 9999.
public void increment(){
if(digits[3] <= 8){
digits[3]++;
}
else{
digits[3] = 0;
if(digits[2] <= 8){
digits[2]++;
}
else{
digits[2] = 0;;
if(digits[1] <= 8){
digits[1]++;
}
else{
digits[1] = 0;
if(digits[0] <= 8){
digits[0]++;
}
else{
digits[0] = 0;
}
}
}
}
}
My question is how would I go about making a method that does the same thing but the method requires an index to be passed in.
for example:
public void increment(int index){
//increments through index number of digits.
}
So something like this:
increment(7);
would yield this: 0000000, 0000001, 0000002, 0000003, --> 0000009, 0000010, 0000011, -----> 9999999.
This is personally for my own satisfaction so any help would be great =)
Aside: int [] = digits; is a syntax error; remove the =.
The increment routine needs access to the array of digits, and in Java arrays 'know' their bounds so you don't need a separate parameter or variable for the length. Given that, the classic hacker method (from the age of the dinosaurs when hacker meant good) is:
void increment (int[] digits){
for( int i = digits.length; --i>=0 && ++digits[i]==10; ) digits[i]=0;
}
# alter the 10 to change radix, or make it variable if desired
This mimics the procedure you learned in elementary school (or at least I did): start at the rightmost digit, add one, if it doesn't overflow you're done, if it does overflow change it to zero and move one place to the left except stop when you are already at the left end and can't move further.
Here's my implementation:
Live demo
Example for reference:
[0,0]
[0,1]
[0,2]
[0,3]
[0,4]
[0,5]
[0,6]
[0,7]
[0,8]
[0,9]
[1,0]
[1,1]
[1,2]
[1,3]
[1,4]
[1,5]
[1,6]
...
First create a 2D array where each row represent a number with n digits. We can get the 2D array height by doing 10^n because we have n digits and 10 possibilities for each digit (0-9)
We can notice a pattern in the numbers generated which is the rightmost column switches digit every one iteration, the second rightmost digit switches digit every 10 iterations, the third one switches digit each 100 iteration etc... so the kth rightmost index switches iteration every 10^k iterations. This is noted by the variable level. Also some iterations on the digits can be omitted because we know that some digits will not increase until a specific row (example the leftmost digit will not increase for row 1 if n > 1). You can get the width of digits to loop on by doing log10(row) which will give you the number of digits in the integer row minus one. This is called width in the code.
Then all we need to do is check if now it's time to switch row%level == 0 then we increment the value from above level by one, otherwise we just copy the same value from row above.
public static void numbers(int n) {
int nums[][] = new int[(int)Math.pow(10, n)][n];
for(int row=1; row < nums.length; row++) {
int width = (int) Math.log10(row);
for(int col = nums[row].length-1; col >= nums[row].length-1-width; col--) {
int level = (int) Math.pow(10, n - col - 1);
if(row % level == 0) {
nums[row][col] = (nums[row-level][col]+1) % 10;
} else {
nums[row][col] = nums[row-1][col];
}
}
System.out.println(Arrays.toString(nums[row]));
}
}
I think the following is quiet simple and readable:
public class Test{
public static void main(String[] args){
increment(7);
}
static void increment (int index){
index = Math.abs(index) ;
int[] digits = new int [index];
Arrays.fill(digits, 0); //initialize array with 0
for( int i = index-1; i>=0 ; i--) {//loop over all digits
for(int digit = 0; digit <=9 ; digit++) {//increment each
digits[i] = digit;
System.out.println(Arrays.toString(digits));
}
}
}
}

Check if each letter in ArrayList<String> is a certain character?

Firstly, I'm SUPER new to stackoverflow (so excuse my ugly formatting), and have only a few years of programming experience (about 6 programming classes total)
I'm working on a hangman project. I've elected to use a StringBuilder for some of it. For example, I want to check what index or indices the char chosenLetter = 'C' is in the StringBuilder chosenWord = new StringBuilder("Ceramics");
Ideally, I would have a for loop to go through the StringBuilder word "Ceramics" and tell me the indices 0 and 7. I absolutely cannot figure it out. I've tried using the indexOf() function, but for some reason if I do
for (int i = 0; i < chosenWord.length(); i++) {
if (chosenWord.indexOf(chosenLetter, i) != -1) {
System.out.println("This should be a match at index " + i);
}
}
It would print out for example:
This should be a match at index 0
This should be a match at index 1
This should be a match at index 2
This should be a match at index 3
This should be a match at index 4
This should be a match at index 5
This should be a match at index 6
This should be a match at index 7
This should be a match at index 8
Instead of
This should be a match at index 0
This should be a match at index 7
Any ideas how to go about doing this? Thanks.
And again, sorry for the ugly format. If there's any questions on clarification I would be glad to try to clarify!
Check this out
for (int i = 0; i < chosenWord.length(); i++) {
if (chosenWord.charAt(i) == chosenLetter) {
System.out.println("This should be a match at index " + i);
}
}
This will print your desired out put
You can use StringBuilder#indexOf(String, int), but you need to be sure to increment the index position after each successful match, otherwise you will end up in a infinite loop...
StringBuilder sb = new StringBuilder("ceramics");
int index = 0;
while ((index = sb.indexOf("c", index)) >= 0) {
System.out.println(index);
index++;
}
Should also beware, that this is a case sensitive search, as you can see, I've made the text all lower case so I can catch positions 0 AND 6
The basic issue with your first attempt is that you are actually ignoring the result of indexOf
if (chosenWord.indexOf(chosenLetter, i) != -1) {
System.out.println("This should be a match at index " + i);
But then print i, so on each iteration, you are getting a result of either 0 or 6, so hence the reason it prints results for 0 - 6
So...
i = 0; chosenWord.indexOf(chosenLetter, i) == 6, print 0
i = 1; chosenWord.indexOf(chosenLetter, i) == 6, print 1
i = 2; chosenWord.indexOf(chosenLetter, i) == 6, print 2
i = 3; chosenWord.indexOf(chosenLetter, i) == 6, print 3
i = 4; chosenWord.indexOf(chosenLetter, i) == 6, print 4
i = 5; chosenWord.indexOf(chosenLetter, i) == 6, print 5
i = 6; chosenWord.indexOf(chosenLetter, i) == 6, print 6
i = 7; chosenWord.indexOf(chosenLetter, i) == -1, ignored
You actually don't need the outter loop, you just need to keep looping until indexOf is < 0, as demonstrated above...
The reason why you are seeing that output is because indexOf will return 0 for i = 0 and 6 for i = 1 to 7. In all those cases, the return is different from -1, which satisfies the if statement. Consider using charAt, in the same way suggested by #ppuskar.

Boolean with loops to check an array

Write Java code for a loop that sets boolean variable isOrdered to true if the elements of a given array of ints called are in non-decreasing order, otherwise it sets isOrdered to false.
int i[] = { 1, 2, 3, 4, 5 };
int b = 0;
boolean isOrdered = false;
while (b < i.length) {
if (i[0] <= i[b]) {
isOrdered = true;
}
b++;
}
out.println(isOrdered);
Am I doing this correctly?
Let's see what is wrong.
if (i[0] <= i[b])
This is the main area which troubles me with your code. How are you checking if the next value you is lower/higher then i[b] you are only comparing values at index zero to index b!
Essentially your code would look like this in a loop.
/w int i[] = { 1, 2, 3, 4, 5 };
i[0] i[b]
1 1
1 2
1 3
...
you get the picture right? What you really need is to check the next value after b.
so the code would look like i[b] > i[b+1]
Honestly, you could probably make it work on how you initialized the order of isOrdered to true and false. I would first initialize it to true. Then the idea is to break out of whatever process you are doing if you find a fallacy in the question with a false. Please look at my examples for further references.
iterative
boolean isOrdered = true;
while(isOrdered && array.length - 1 > b){
if(array[b] > array[b+1]) isOrdered = false;
b++;
}
recursive
boolean isOrdered(int[] array, index){
if(index == array.length - 1) return true;
if(array[index] > array[index + 1]) return false;
return isOrdered(array, index + 1);
}
The recursive method for this is waaaaaaaaaay cooler.
No; you are only checking whether the first element of the array is smaller than or equal to at least one of the elements - including the first element itself, which will always be equal to itself, setting isOrdered to true no matter what the remaining elements are.
Hint #1: you should be comparing every element except the first one with the element immediately before it.
Hint #2: you should be optimistic and assume that the array is ordered, then search for a counter-example. As soon as you found a pair of elements that violate the ordering, set isOrdered to false and break out of the loop.
do a for loop on the size of the array to check if the next item is less then the current:
int arr[] = { 1, 2, 3, 4, 5 };
int b = 0;
boolean isOrdered = true;
for (int i = 0; i< arr.length - 1 ; i ++) {
if (arr[i] > arr[i+1])
{
isOrdered = false;
break;
}
b++;
}
out.println(isOrdered);

Categories

Resources