print random characters without repeat in square? - java

I'm generating random characters via my code below:
static void printRandomWhatEver(int NUMBER_OF_CHARACTER,
int NUMBER_OF_LINES,
char char1, char char2) {
int DIFFERENCE_SQUARE = 4;
char oldChar, newChar, random;
for (int i = 0; i < NUMBER_OF_CHARACTER; i++) {
random = getRandomCharacter(char1, char2);
if ((i + 1) % NUMBER_OF_LINES == 0) { // new line each new NUMBER_OF_LINE
System.out.println(random);
} else {
System.out.print(random);
}
}
}
My getReandomCharacter:-
private static char getRandomCharacter(char ch1, char ch2) {
return (char) (ch1 + Math.random() * (ch2 - ch1 + 1));
}
All working fine, what i need is the chars inside square 2*2 numbers to not be equal, here is image to explain what i need.
The digit 4 is in the same square:-
**
**
How i can prevent digits to be equal in a part of square?
Thanks in advance.

Just store the last line of your output, and compare the digit at position N to the digits last_line[N-1], last_line[N] and last_line[N+1]. Take care of the array boundaries for N-1 and N+1.
But you should be aware that you reduce the strength of your random number generator this way. To a human it will most likely look "more random", though.
But there may be even more patterns a human may recognize as "not random", e.g. sequential digits:
154
298
364

To avoid repeats you are better off shuffling rather than picking randomly. You will have to repeatedly select different groups of digits to shuffle to avoid repeats.
To start, pick four digits from [0..9] and shuffle them:
0 1
2 3
Working from left to right, the next two digits come from [0, 2, 4..9] with 1 and 3 omitted:
0 1 7
2 3 8
Repeat the process, adding two from the eight possible digits at a time.
Use a similar "pick two from seven" process to add digits in the next row. You only have seven digits to pick from because it is dangerous to pick an '8' in the given configuration:
0 1 7
2 3 8
1 8
Would be an error, so the '8' cannot be picked:
0 1 7
2 3 8
1 5
Is safe.
Once you move away from the left hand edge, you will be picking from six, as there will be four digits in the row above that you must avoid.
ETA: Working with two rows is overly complex. Generate one row at a time, with any existing adjacent digits cut out of the pre-shuffle selection. That will be 3 digits in the row above, plus the previous digit in the current row, with appropriate adjustments for left and right boundaries.

Related

find the maximum possible ones

I have a string of 0's and 1's
Now I want to change 0 to 1 only if adjacent elements for that 0 are not 1'string. Find the maximum ones possible after doing this operation.
Example:
110011000001 is the input string
Option 1:
I can change position 8 and position 10 from 0 to 1 to make the string: 110011010101, here there are 7 ones
Option 2:
Another way is to change position 9 from 0 to 1, to make the string: 110011001001, here there are 6 ones.
So the maximum between 6 and 7 is 7. So the result is 7.
Here is my code, I am able to find only one possible way here:
int process(String s) {
char[] ch = s.toCharArray();
int n = ch.length;
for(int i=1; i<n-1; i++) {
char e = ch[i];
if(e == '0' && ch[i-1] != '1' && ch[i+1] != '1') {
ch[i] = '1';
}
}
int count = 0;
for(char c : ch) {
if(c == '1') count++;
}
return count;
}
How to get the maximum possible ones here.
Notice that if the 0's are surrounded by 1's, you only need 2n + 1
adjacent 0's in order to add n 1's. In order to add one 1, you
need at least three 0's: 2*1+1=3. In order to add two 1's, you
need at least five 0's: 2*2+1=5. Since the number of 0's can be
described as, Z >= 2n + 1, we can instead solve for n. We get n <= (Z - 1) / 2. Thus, when surrounded by 1's, each group of 0's can
fit n=floor((Z-1)/2); we floor the value since we can't add half of a 1.
For groups of 0's only bounded by a 1 on a single side, we notice
that we need at least 2n 0's in order to add n 1's. Again, we
rearrange the equation Z >= 2n in order to get n <= Z / 2. Thus,
for groups bounded by a single 1, n=floor(Z/2).
For our last case, with a string of all 0's, we see that Z >= 2n - 1. So, n <= (Z + 1) / 2, or for our purposes floor((Z+1)/2).
Least common will be category 3. This will only happen if there are no 1's. If this is the case, you cannot have anything from category 1 or 2 -- so check this category first.
Second most common will be category 2. This happens when the beginning OR end of the string is a 0, but there are 1's elsewhere. Check this category second because you can fit more 1's with it than with the formula for the first case. Depending on your solution, you may have to keep track of the places you've already checked before moving on to using case 1 by using a substring of the original.
Most cases will land in category 1, since (in a random combination of 1's and 0's) most groups of 0's will be surrounded by 1's.
Your answer only checks the first case. Using these three cases together will give you the number of 1's that you can add to the string. Add this to the number of 1's you had originally and you'll have your answer.
Edited for clarity.
Count all existing ones as they are going to be a part of the answer.
To convert 0 to 1, count all zeroes between two ones.
If string is 100001, you have total 4 zeroes in between. Here let us leave boundary zeroes as we can't change them as they are adjacent to 1. So, now we are left with 2 zeroes in the middle out of which we can place only in 1 of them.
So count is just ceil(all valid zeroes / 2).
If you have a string like 00001, here you can place 2 ones excluding that boundary 0 adjacent to 1. So, count is ceil(3/2) which is 2. Your string would look like 10101.
Final answer is just step 1 + step 2.

how a splitting number to a separate digits algorithm works

i'm getting back to software development and i was playing around with algorithms in java,and today i'm doing the algorithm the splits a number to a separate digits, I've found it here i wrote it in java ..it works but honestly i don't how ?? there is the code just i didn't understand a part of it :
public static void main(String[] args) {
Integer test = 0, i, N;
ArrayList array_one= new ArrayList<Integer>();
Scanner sc = new Scanner(System.in);
System.out.print("Write An Integer :");
test = sc.nextInt();
while (test > 0){
int mod = test % 10; // <= DON'T UNDERSTAND THE WORK OF THAT PART
// (i know it's the modulo of the entered value)
test = test / 10;
array_one.add(mod);
}
System.out.print(array_one);
}
i know it's a newbie question i'm just passionate about software engineering and algorithms just want to know how it exactly works and thks in advance.
test % 10; gives you the last (least significant) digit of the number, which is the remainder when dividing the number by 10.
test = test / 10 reduces the number by one digit (123456 becomes 12345), making the former 2nd least significant digit the new least significant digit. Therefore, in the next iteration, test % 10; would return the 2nd digit.
And so on...
test % 10; --> Always gives you the last digit.
test / 10; --> divides the existing number by 10.
while loop --> executes until test > 0
So, if your number is 234,
234%10 would be 4
234/10 would be 23.4 which will be converted to 23.
Apply 23 % 10 and 23/10 and so on..
By using %10 you'll get only the last digit.
/10 will give what is before your last digit.
And so you can construct your array.
124%10 --> 4
124/10 --> 12 % 10 --> 2
12 / 10 --> 1
The logic used here is to separate the units place first by dividing the number by 10 and getting the reminder value.
e.g x=153
"% " is the modulus operator that gives the remainder of the division
"/" is the division operator that gives only the quotient
then 153%10= 3 //this is the remainder that separates the first digit.
The number is then divided by 10 so as to get the quotient
i.e 153/10 =15 // Only the quotient
Progressing with the loop, now 15 is taken as the new original number and is again divided by 10 to get the remainder and hence the next digit.
i.e 15%10 =5 //next digit
15/10=1;
1%10=1 //digit
1/10=0 //The loop ends here
You can understand it by an example
Your number to divide it's digits is 345
If you divide it by 10 your remaining and first digit is 5

From 5 dice rolls, generate a random number in the range [1 - 100]

I was going through some coding exercises, and had some trouble with this question:
From 5 dice (6-sided) rolls, generate a random number in the range [1 - 100].
I implemented the following method, but the returned number is not random (called the function 1,000,000 times and several numbers never show up in 1 - 100).
public static int generator() {
Random rand = new Random();
int dices = 0;
for(int i = 0; i < 5; i++) {
dices += rand.nextInt(6) + 1;
}
int originalStart = 5;
int originalEnd = 30;
int newStart = 1;
int newEnd = 100;
double scale = (double) (newEnd - newStart) / (originalEnd - originalStart);
return (int) (newStart + ((dices - originalStart) * scale));
}
Ok, so 5 dice rolls, each with 6 options. if they are un-ordered you have a range of 5-30 as mentioned above - never sufficient for 1-100.
You need to assume an order, this gives you a scale of 1,1,1,1,1 - 6,6,6,6,6 (base 6) assuming 1 --> 0 value, you have a 5 digit base 6 number generated. As we all know 6^5 = 7776 unique possibilities. ;)
For this I am going to give you a biased random solution.
int total = 0;
int[] diceRolls;
for (int roll : diceRolls) {
total = total*6 + roll - 1;
}
return total % 100 + 1;
thanks to JosEdu for clarifying bracket requirement
Also if you wanted to un-bias this, you could divide range by the maxval given in my description above, and subsequently multiply by your total (then add offset), but you would still need to determine what rounding rules you used.
Rolling a 6 sided die 5 times results in 6^5 = 7776 possible sequences, all equally probable. Ideally you'd want to partition those sequences into 100 groups of equal size and you'd have your [1 - 100] rng, but since 7776 isn't evenly divisible by 100 this isn't possible. The best you can do to minimize the bias is 76 groups mapped to by 78 sequences each and 24 groups mapped to by 77 sequences each. Encode the (ordered) dice rolls as a base 6 number n, and return 1 + (n % 100).
Not only is there no way to remove the bias with 5 dice rolls, there is no number of dice rolls that will remove the bias entirely. There is no value of k for which 6^k is evenly divisible by 100 (consider the prime factorizations). That doesn't mean there's no way to remove the bias, it just means you can't remove the bias using a procedure that is guaranteed to terminate after any specific number of dice rolls. But you could for example do 3 dice rolls producing 6^3 = 216 sequences encoded as the base 6 number n, and return 1 + (n % 100) if n < 200. The catch is that if n >= 200 you have to repeat the procedure, and keep repeating until you get n < 200. That way there's no bias but there's also no limit to how long you might be stuck in the loop. But since the probability of having to repeat is only 16/216 each time, from a practical standpoint it's not really much of a problem.
The problem is there aren't enough random values in 5-30 to map one to one to 1-100 interval. This means certain values are destined to never show up; the amount of these "lost" values depends on the size ratio of the two intervals.
You can leverage the power of your dice in a way more efficient way, however. Here's how I'd do it:
Approach 1
Use the result of the first dice to choose one subinterval from the
6 equal subintervals with size 16.5 (99/6).
Use the result of the second dice to choose one subinterval from the 6 equal sub-subintervals of the subinterval you chose in step one.
Use... I guess you know what follows next.
Approach 2
Construct your random number using digits in a base-6 system. I.E. The first dice will be the first digit of the base-6 number, the second dice - the second digit, etc.
Then convert to base-10, and divide by (46656/99). You should have your random number. You could in fact only use 3 dice, of course, the rest two are just redundant.

permutations of certain digits in Java

I realize permutations in programming language is a very frequently asked question, however I feel like my question is sort of unique.
I have received input of a certain length integer N and stored each digit in an array where the index of the array stores the number of times that digit occurs in N.
now I want to test if some function holds true with all permutations of N's original length with no leading zeroes. Ex:
int[] digits = new int[10];
String n = "12345675533789025";
for (char c : n.toCharArray())
digits[c-'0']++;
for (Long f : allPermutationsOf(digits))
if (someCondition(f))
System.out.println(f);
a precondition to the following code is that N must be less than 2^64-1, (long's maximum value.)
The question is, how would I take all permutations of the digits array and return a Long[] or long[] without using some kind of String concatenation? Is there a way to return a long[] with all permutations of digits[] in the "Integer scope of things" or rather using only integer arithmetic?
To elaborate on one of the above comments, putting a digit d in a given place in the resulting long is easy: d*1 puts it in the 1s place, d*1000 puts it in the thousands place, and in general d * (10^k) puts d into the k+1th digit. You have N total digits to fill, so you need to do permutations on the powers of 10 from 1 to 10^(N-1).
If you are expecting the permutations to be Longs anyway, instead of representing n as an array of counts, it might be easier to represent it as a Long too.
Here are a couple of ways you can generate the permutations.
Think of generating permutations as finding the next largest number with the same set of digits, starting from the number consisting of the sorted digits of n. In this case, the answers to this StackOverflow question is helpful. You can use arithmetic operations and modding instead of string concatenation to implement the algorithm there (I can provide more details if you like). A benefit of this is that the permutations you generate will automatically be in order.
If you don't care about the order of the permutations and you expect the number of digit duplicates to be small, you can use the Steinhaus-Johnson-Trotter algorithm, which (according to Robert Sedgewick) is the fastest algorithm for generating permutations of unique elements. To make sure duplicate permutations are not generated, you would have to distinguish every duplicate digit and only emit the permutations where they appear in order (i.e., if 2 appears three times, then create the elements 2_1, 2_2, 2_3 and make sure those three elements always appear in that order in an emitted permutation).
For the requirement, assuming that the length of N is n, we can generate all permutations by going from digit to digit, starting from 0 and end at n - 1. With 0 is the leading digit.
For each digit, we only go through each possibility (0 to 9) once , which will avoid duplicate permutation.
From digit x to digit x + 1, we can easily generate the current value by passing a number called current
For example: at digit 3, we have current = 1234, so at digit 4, if we choose 5 to be at digit 4, the current will be 1234*10 + 5 = 12345
Sample code in Java:
public void generate(int index, int length, int[] digits, long current, ArrayList<Long> result) {
//All the permutation will be stored in result ArrayList
for (int i = 0; i < 10; i++) {
if (digits[i] > 0 && (i != 0 || index != 0)) {
digits[i]--;
if (index + 1 == length) {//If this is the last digit, add its value into result
result.add(current * 10 + i);
} else {//else, go to next digit
generate(index + 1, length, digits, current * 10 + i, result);
}
digits[i]++;
}
}
}

Adding a while and for loop

The question asks: Design and implement an application that first reads a list of 10 three-digit integers and then counts the number of appearances for each digit from 0 to 9.
Here is an example of 3 three-digit numbers
Input number [123, 456, 789]
Output:
Digit 0 has appeared 0 times
Digit 1 has appeared 1 times
Digit 2 has appeared 1 times
…
Digit 9 has appeared 1 times
I believe that I have figured out the correct formulas to computate the amount of times each number appears, but I am not sure how to create the array and begin searching through it. I think I need a while and a for loop, but I am not sure how to incorporate them. I am afraid however, that my current if statements will need to change once the loops are implemented. Am I going in the right direction here? Any help would be greatly appreciated!
double i1, i2, i3, i4, i5, i6, i7, i8, i9, i10;
int c0=0, c1=0, c2=0, c3=0, c4=0, c5=0, c6=0, c7=0, c8=0, c9=0;
Scanner scan = new Scanner(System.in);
System.out.println ("Enter 10 3-digit integers");
//Counts the 1st number
System.out.println ("Enter first 3-digit integer");
i1 = scan.nextDouble();
if (i1%10==0)
c0++;
if (i1%10==1)
c1++;
if (i1%10==2)
c2++;
if (i1%10==3)
c3++;
if (i1%10==4)
c4++;
if (i1%10==5)
c5++;
if (i1%10==6)
c6++;
if (i1%10==7)
c7++;
if (i1%10==8)
c8++;
if (i1%10==9)
c9++;
if ((i1%100>=0) & (i1%100<10))
c0++;
if ((i1%100>=10) & (i1%100<20))
c1++;
if ((i1%100>=20) & (i1%100<30))
c2++;
if ((i1%100>=30) & (i1%100<40))
c3++;
if ((i1%100>=40) & (i1%100<50))
c4++;
if ((i1%100>=50) & (i1%100<60))
c5++;
if ((i1%100>=60) & (i1%100<70))
c6++;
if ((i1%100>=70) & (i1%100<80))
c7++;
if ((i1%100>=80) & (i1%100<90))
c8++;
if ((i1%100>=90) & (i1%100<100))
c9++;
if((i1/1000>=.0) & (i1/1000<.1))
c0++;
if((i1/1000>=.1) & (i1/1000<.2))
c1++;
if((i1/1000>=.2) & (i1/1000<.3))
c2++;
if((i1/1000>=.3) & (i1/1000<.4))
c3++;
if((i1/1000>=.4) & (i1/1000<.5))
c4++;
if((i1/1000>=.5) & (i1/1000<.6))
c5++;
if((i1/1000>=.6) & (i1/1000<.7))
c6++;
if((i1/1000>=.7) & (i1/1000<.8))
c7++;
if((i1/1000>=.8) & (i1/1000<.9))
c8++;
if((i1/1000>=.9) & (i1/1000<1.00))
c9++;
Hints:
Get rid of all of the c<n> and i<n> declarations and all of the if tests. They don't help you solve the problem.
Make use of the fact that '0' + <n> == '<n>' where <n> is 0 .. 9.
Or use Character.digit(char, 10). Read the javadocs.
You don't use nextDouble() to read an integer. Read the javadocs.
More Hints:
Generalise the problem to 'count the distinct characters in a string'. Since you're reading the input as a string anyway, just forget that you're counting integers for the moment, and focus on counting char appearances within a string.
Think of a data structure that can contain a pair of (distinct char, count).
Iterate through the characters within a string, add the character to your data structure in point 2 if it doesn't exist with a default value of 0, then increment the count of the char you're currently looking at.
When showing the output of your program, iterate through the entries of your data structure, validate that the char is an integer (if validation is important), and return the count for that char.
I'm not sure if you have trouble with iteration or not, but here is how to loop through the characters of a string:
String s = "123 456 789";
for (int i = 0; i < s.length(); i++){
char c = s.charAt(i);
// process c
}
// or, if you know what 'smart loops' in Java are...
for(char c : s.toCharArray()) {
// process c
}
To confuse matters, here it is in... 'pseudocode' (edited based on comments) ;)
>>> s = "012 345 678 900"
>>> datastructure = {}
>>> for c in s:
... if c not in datastructure:
... datastructure[c] = 0
... datastructure[c] += 1
...
>>> for c in '0123456789':
... if c not in datastructure:
... datastructure[c] = 0
... print 'Digit %s appeared %d times' % (c, datastructure[c])
...
Digit 0 appeared 3 times
Digit 1 appeared 1 times
Digit 2 appeared 1 times
Digit 3 appeared 1 times
Digit 4 appeared 1 times
Digit 5 appeared 1 times
Digit 6 appeared 1 times
Digit 7 appeared 1 times
Digit 8 appeared 1 times
Digit 9 appeared 1 times
Your idea isn't that bad, you just obviously need some loops :)
1: loop to get numbers - you can't duplicate the same code 10x - write it once, in a loop.
2: loop to check digits - you can use your's ifs, or do it as Josh said
but before - you need data structure to store your data - occurs of digits. 10 variables is bad, BAD:), idea.
use array[2][10] or simply array[10] (where number of digits = index of array and value = occurs) or even better - HashMap<> - google it.
then inside loop you do:
for(int i = 0; i<10; i++){
if (myCurrentNumberToCheck %10 == i)
array[i] = array[i] + 1; // approach with simple array[10]
if ((myCurrentNumberToCheck %100 >= i*10) && (myCurrentNumberToCheck %100 < (i+1)*10 )) // needs to be tested
array[i] = array[i] + 1;
if ((myCurrentNumberToCheck %1000 >= i*100) && (myCurrentNumberToCheck %1000 < (i+1)*100 )) // needs to be tested
array[i] = array[i] + 1;
}
ahh and your inserted numbers should be in some structure too - try List numbers = new ArrayList<int>() here :) and iterate thou list, to take a look at next number.
so you will need to add numbers to List, and nextly - go thou that list and check them and here use that loop i wrote above
the problem with readInt() and readDouble() is that it ignores leading 0 and trailing 0 after the decimal i.e. 01.10 => 1.1
A much simpler approach is to just read every character.
int ch;
while((ch = System.in.read())>=0) {
// you have one character
}

Categories

Resources