java divisor finding takes unlimited time - java

I've started my friend's school task as practicing, but I stucked at one point. I think my code is right, but definitely not if I see the result.
My problem is the following. The program has to go from 1 to a natural number, and find the least number which has that number of divisors as the current number.
for example: [1;1], [2;2], [3;4], [4;6], [5;16], [6;12]
because the 12 is the least number which has 6 divisor.
Extra requirement is to find all the 100 divisor-number pair in approx. 5 minutes on a standard, not too fast, not too slow PC.
But if I run the code, it stuck at the 23th number, and couldn't go further.
I've tried to shorten the operation number with a condition (if the current number has more divisor than what currently need, it breaks the loop), but it doesn't make any difference, and I don't know why couldn't find the right number and go on.
I would be grateful if Somebody could help me.
Thanks in advance!
public static String message (int numb){
String[] messages = new String[4];
messages[0] = "Working...";
messages[1] = "Done!";
messages[2] = "Please give the interval! [1-100]";
return messages[numb];
}
public static int intervIn (){
Scanner sc = new Scanner(System.in);
int inter = sc.nextInt();
sc.close();
return inter;
}
public static int finding (int need){
int divisor = 1;
int out=1;
if (need!=1){
for (;out<2147483647;){
for (int i = 2;i<=out/2;i++){
if (out%i!=0){
}
else {
divisor++;
if (divisor>=need){
break;
}
}
}
divisor++;
if (divisor==need){
break;
}
else {
divisor=1;
out++;
}
}
}
return out;
}
public static int[][] doit (int row, int column){
int[][] arrayN = new int[row][column];
int divisorNeed = 1;
for (int k = 0;k<row;k++){
arrayN[k][0]=divisorNeed;
arrayN[k][1]=finding(divisorNeed);
divisorNeed++;
}
return arrayN;
}
public static void main(String[] args) {
System.out.println(message(2));
int intervIn = intervIn();
System.out.println(message(0)+'\n');
int[][] arrayNRevis = doit(intervIn,2);
System.out.println(message(1));
for (int i=0;i<intervIn;i++){
System.out.print("[");
for (int j=0;j<2;j++){
System.out.print(arrayNRevis[i][j]+" ");
}
System.out.println("\b]");
}
}
Output now (after almost 8 hours..):
Please give the interval! [1-100] 100 Working...
[1;1] [2;2] [3;4] [4;6] [5;16] [6;12] [7;64] [8;24] [9;36] [10;48]
[11;1024] [12;60] [13;4096] [14;192] [15;144] [16;120] [17;65536]
[18;180] [19;262144] [20;240] [21;576] [22;3072]

Obviously you are not stuck on the 23rd number but it will take approx 120 hours to evaluate it. See http://oeis.org/A005179
Here is a APL NARS2000 workspace that speed up things a lot.
The first 100 take only 1/10 second.
)WSID
C:\Users\Ab\AppData\Roaming\NARS2000\workspaces\combfactor
)FNS
combfactor factors listws save
)VARS
COMBFACTOR DESCRIBE DIV RESULTSfor100
∇ z ← combfactor n;f;p
[1] f ← (⊂,n),factors n ⋄ ⍝ find all factors combinations of n
[2] p ← ⍸0π⍳¯2π32 ⋄ ⍝ The first 32 primes numbers
[3] z ← ((⍴¨f)↑¨⊂⍟p)+.רf-1 ⋄ ⍝ give ratios of all combinations
[4] z ← ∊¯1+((⌊/z)=z)/f ⋄ ⍝ get the combination with minimum ratio
[5] z ← (0x+(⍴z)↑p)×.*z ⋄ ⍝ evaluate p_1^(f_1-1) * p_2^(f_2-1) * ... * p_n^(f_n-1)
∇
∇ z ← {fmax} factors n;f;d
[1] :if 0 = ⎕NC 'fmax' ⋄ fmax ← 2*63 ⋄ :endif
[2] z ← ⍬ ⋄ f ← ⌊fmax⌊n÷2
[3] :while f ≥ 2
[4] :if 0 = f∣n
[5] d ← n÷f ⋄ :if d ∧.≤ f,fmax ⋄ z ,← ⊂f,d ⋄ :endif
[6] z ,← f,¨f factors d
[7] :endif ⋄ f -← 1
[8] :endwhile
∇
COMBFACTOR
RESULTSfor100 ← ⍪(,¨⍳100),¨combfactor¨,¨⍳100 ⋄ ⍝ 0.1 second
DESCRIBE
DESCRIBE
⍝ def factors(number, max_factor=sys.maxint):
⍝ result = []
⍝
⍝ factor = min(number / 2, max_factor)
⍝ while factor >= 2:
⍝ if number % factor == 0:
⍝ divisor = number / factor
⍝
⍝ if divisor <= factor and divisor <= max_factor:
⍝ result.append([factor, divisor])
⍝
⍝ result.extend([factor] + item for item in factors(divisor, factor))
⍝
⍝ factor -= 1
⍝
⍝ return result
⍝
⍝ print factors(12) # -> [[6, 2], [4, 3], [3, 2, 2]]
⍝ print factors(24) # -> [[12, 2], [8, 3], [6, 4], [6, 2, 2], [4, 3, 2], [3, 2, 2, 2]]
⍝ print factors(157) # -> []
DIV
divisors←{z[⍋z←∊∘.×/1,¨(∪π⍵)*¨⍳¨∪⍦π⍵]}
RESULTSfor100
1 1
2 2
3 4
4 6
5 16
6 12
7 64
8 24
9 36
10 48
11 1024
12 60
13 4096
14 192
15 144
16 120
17 65536
18 180
19 262144
20 240
21 576
22 3072
23 4194304
24 360
25 1296
26 12288
27 900
28 960
29 268435456
30 720
31 1073741824
32 840
33 9216
34 196608
35 5184
36 1260
37 68719476736
38 786432
39 36864
40 1680
41 1099511627776
42 2880
43 4398046511104
44 15360
45 3600
46 12582912
47 70368744177664
48 2520
49 46656
50 6480
51 589824
52 61440
53 4503599627370496
54 6300
55 82944
56 6720
57 2359296
58 805306368
59 288230376151711744
60 5040
61 1152921504606846976
62 3221225472
63 14400
64 7560
65 331776
66 46080
67 73786976294838206464
68 983040
69 37748736
70 25920
71 1180591620717411303424
72 10080
73 4722366482869645213696
74 206158430208
75 32400
76 3932160
77 746496
78 184320
79 302231454903657293676544
80 15120
81 44100
82 3298534883328
83 4835703278458516698824704
84 20160
85 5308416
86 13194139533312
87 2415919104
88 107520
89 309485009821345068724781056
90 25200
91 2985984
92 62914560
93 9663676416
94 211106232532992
95 21233664
96 27720
97 79228162514264337593543950336
98 233280
99 230400
100 45360
And here is a C program that take 62 microsecond !
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define MaxInt 0x7fffffffffffffff
#define ll long long
int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61,
67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131};
ll minimums[16]; // contains minimum for each level
ll ipow(ll base, int exp) {
ll result = 1;
while (exp) {
if (exp & 1) result *= base;
exp >>= 1; base *= base;
} return result;
}
ll factors(ll number, ll max_factor, int level) {
ll result = MaxInt;
ll factor = min(number / 2, max_factor);
while (factor >= 2) {
if (number % factor == 0) {
ll divisor = number / factor;
ll tempf = ipow(primes[level], factor-1);
if (divisor <= factor && divisor <= max_factor) {
ll tempd = ipow(primes[level+1], divisor-1);
minimums[level] = min(minimums[level], tempf * tempd);
}
ll fct = factors(divisor, factor, level+1);
if (fct < MaxInt)
minimums[level] = min(minimums[level], tempf * fct);
result = minimums[level];
minimums[level+1] = MaxInt;
}
factor -= 1;
}
return result;
}
ll fact(int number) {
for (int level = 0; level < 16; level++) minimums[level] = MaxInt;
ll res = factors(number, MaxInt, 0);
if (res < MaxInt) return res;
else return 0;
}
int main(int argc, char *argv[]) {
int N = 100;
if (argc > 1) N = atoi(argv[1]);
ll res[N];
clock_t Start = clock();
for(int n = 1; n <= 10000; n++)
for (int i = 1; i <= N; i++) res[i] = fact(i);
printf("\n%0.6f second(s)\n", (clock() - Start)/1000.0/10000.0);
for (int i = 1; i <= N; i++)
if (res[i] > 0) printf("%d %lld\n", i, res[i]);
else if (i > 64 ) printf("%d 2 power %d\n", i, i-1);
else printf("%d %lld\n", i, ipow(2, i-1));
return 0;
}

Every natural number N can be expressed as multiplication of prime numbers p_i raised to some powers k_i where k_i >= 0. So let's say you have number n equal to:
n = p_1^k_1 * p_2^k_2 * ... * p_z^k_z
this number will have (k_1+1)*(k_2+1)*...*(k_z+1) dividers, e.g.
18 = 2^1 * 3^2
and have (1+1)*(2+1) dividers or 6 dividers: 1, 2, 3, 6, 9, 18.
Prime numbers may be precomputed using sieve algorithm (https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes)
Then you may use dynamic programming to compute number of dividers of given number n. If n = n_1 * p_i^k_i (n can be divided by p_i^k_i), then number of dividers of n is number of dividers of n_1 * (k_i+1).
This should speed up computation of dividers counts.

Related

Rearrange Array Alternately

Given a sorted array of positive integers. Your task is to rearrange the array elements alternatively i.e first element should be max value, second should be min value, third should be second max, fourth should be second min and so on.
class RearrangeAlternate{
public void swapMax(int arr[], int i, int n){
int x = arr[i];
int j;
for(j = n-1; j>i; j--){
if(arr[j] > x){
break;
}
}
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public void swapMin(int arr[], int i, int n){
int x = arr[i];
int j;
int res = n-1;
for(j = n-1; j>i; j--){
if(arr[j] < x){
if(arr[j] < arr[res]){
res = j;
}
}
}
int temp = arr[i];
arr[i] = arr[res];
arr[res] = temp;
}
public void rearrange(int arr[], int n){
for(int i = 0; i<n; i++){
if(i%2 == 0){
swapMax(arr, i, n);
}
else swapMin(arr, i, n);
}
}
}
Please help me find the error
It is showing wrong output for somecases.
eg.
82
12 23 28 43 44 59 60 68 70 85 88 92 124 125 136 168 171 173 179 199 212 230 277 282 306 314 316 325 328 336 337 363 365 368 369 371 374 387 394 414 422 427 430 435 457 493 506 527 531 538 541 546 568 583 650 691 730 737 751 764 778 783 785 789 794 803 809 815 847 858 863 874 887 896 916 920 926 927 930 957 981 997
My codes output: 997 12 981 23 957 28 930 43 927 44 926 59 920 60 916 68 896 70 887 85 874 88 863 92 858 124 847 125 815 136 809 168 803 171 794 173 789 179 785 199 783 212 778 230 764 277 751 282 737 306 730 314 691 316 650 325 568 328 527 336 506 337 430 363 374 369 541 365 583 368 531 371 493 387 538 394 457 414 435 422 546 427
Answer: 997 12 981 23 957 28 930 43 927 44 926 59 920 60 916 68 896 70 887 85 874 88 863 92 858 124 847 125 815 136 809 168 803 171 794 173 789 179 785 199 783 212 778 230 764 277 751 282 737 306 730 314 691 316 650 325 583 328 568 336 546 337 541 363 538 365 531 368 527 369 506 371 493 374 457 387 435 394 430 414 427 422
Since your array is sorted, you can simply do it as follows:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int temp;
for (int i = 0; i < arr.length; i++) {
if (i % 2 == 0) {
// Store the last element to 'temp'
temp = arr[arr.length - 1];
// Shift all elements, starting from index, 'i', to one place right
for (int j = arr.length - 2; j >= i; j--) {
arr[j + 1] = arr[j];
}
// Put the value stored in 'temp' to index, 'i'
arr[i] = temp;
}
}
System.out.println(Arrays.toString(arr));
}
}
Output:
[10, 1, 9, 2, 8, 3, 7, 4, 6, 5]
Since the array is sorted and we need to rearrange alternatively,we can use the technique to store two numbers at a single position in such a manner that we are also able to retrieve back the original element when required.
Let's say we need to store n1 and n2 at same position then we can formulate it like :
====================== n1 = n1 + (n2%z)*z ======================
To extract n1 we can modulo n1 by z and to extract n2 we can divide n1 by z.
For more detailed explanation,you can refer this video : https://youtu.be/KOglcclYgXI
using lambda — doing the rearranging outside the original arr
O(n) time complexity
int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
int[] tmp = IntStream.range( 0, (arr.length + 1) / 2 )
.flatMap( n -> IntStream.of( arr[arr.length - n - 1], arr[n] ) ).toArray();
System.arraycopy( tmp, 0, arr, 0, arr.length );
gets for arr: [11, 1, 10, 2, 9, 3, 8, 4, 7, 5, 6]
The solution mentioned below solves the problem in O(N) Time complexity and O(1) Space Complexity WITHOUT using the "storing 2 values at one location concept". Moreover this algorithm can also handle duplicate values & float values given the input list is non-decreasingly sorted and consists of positive real numbers only.
PS: If you wish you can modify my algorithm slightly to make it work for negative values as well.
Please don't get intimidated by looking at the code. Implementation is very simple. Algorithm might be a bit tricky to understand.
def reArrange(arr, print_arr_state=True):
# arr: non-decreasingly sorted list of positive floats/ints
length = len(arr)
for i in range(length):
if arr[i] > 0:
cycler(arr, i, length, print_arr_state)
arr[i] = abs(arr[i]) # This is the tricky part
# printing the array after every iteration
if print_arr_state:
print('after', i, 'th iteration:', arr)
def cycler(arr, start_index, length, print_cycler_array=True):
if print_cycler_array:
print('cycler function:', arr, end=' ---> ')
half_length_index = length // 2
swap_index = start_index
current_value = arr[start_index]
while True:
if swap_index < half_length_index:
swap_index = 2 * swap_index + 1
else:
swap_index = 2 * (length - 1 - swap_index)
# Placing the current value at swap_index and making the making current_value variable refer to the value which was at swap_index
swap_value = arr[swap_index]
arr[swap_index] = -1 * current_value # -1 * ?? This is the tricky part of the algo
current_value = swap_value
# cycler function will not stop until the simple cycle is complete
# simple cycle is complete when swap_index == start_index
if swap_index == start_index:
if print_cycler_array:
print(arr)
return
Giving Input (input_array) and Calling reArrange function:
input_array = [0.1, 2, 3.2, 3.3, 3.3, 4, 5.7, 5.7, 6.8, 7, 8, 9]
reArrange(input_array)
Output:
answer_array = [9, 0.1, 8, 2, 7, 3.2, 6.8, 3.3, 5.7, 3.3, 5.7, 4]
Understanding the algorithm
Tricky part of the algorithm:
Every value belongs to exactly 1 cycle and this cycle is a simple cycle (simple cycle vs complex cycle in graphs). One execution of cycler function corresponds to one cycle which is also a simple cycle.
Whenever I cover a value during a cycle, I multiply it with -1 (to indicate that it is covered) and store it in the input array itself.
During the i-th iteration of the loop of reArrange function, if I find the i-th value to be negative I get an indication that this value is a part of a cycle executed for some j-th iteration (where j < i), thus I don't call the cycler function on this value. But if this value is positive (indicating that none of cycles executed so far has covered this value), it implies that it is not covered yet and hence should be covered in the i-th iteration using the cycler function.
But wait!, if I have multiplied all values with -1 my final answer will be -1 * correct_answer_array. To solve this problem, one solution is to reiterate my answer_array (which was input_array initially and now has transformed to my answer_array) and take the absolute of each value OR I can do the same thing during my first and only iteration (of reArrange function's loop) by taking the absolute of the value before moving to the i+1-th iteration.
Some valid questions
There are few aspects of this algorithm that I haven't covered in this post. Let me leave you with some of these aspects in the form of questions:
Is the while loop of cycler function guaranteed to terminate?
Why should we not cover a value more than once?
How can we handle the negative input values (if any)?
Isn't a single cycle sufficient to cover all the values of the input_array. (Isn't a single call of the cycler function sufficient to cover all the values)?
Hint: eg: 1 2 3 4 5 6 7, this example will lead to 3 cycles. (cycler function will be called thrice)
What happens during a single call of cycler function?
Hint: Every value which is the part of this cycle shifts to the place where it is supposed to be in the correct_answer_array. Once a value is at its correct place, it should not be disturbed again.
Please visit the comments section at the bottom of this page (GeeksforGeeks) to see the dry run of the algorithm. Please make sure you read all of the comments by me because I have created a bit of mess there.
Given a sorted array of positive integers. Your task is to rearrange the array elements alternatively i.e first element should be max value, second should be min value, third should be second max, fourth should be second min and so on.
//c#
using System;
using System.Collections.Generic;
using System.Text;
namespace vijay
{
class oddEven
{
public static void Main()
{
int n = Convert.ToInt32(Console.ReadLine());
int[] arr = new int[n];
for(int i=0;i<n;i++)
arr[i]=Convert.ToInt32(Console.ReadLine());
// example input int[] arr = {8,7,6,5,4,3,2,1 };
Array.Sort(arr); //sorting array
Array.Sort(arr);
int f = 1,f1=0;
int[] dummy = new int[n];
int a = arr.Length / 2;
for(int i=0;i<n;i++)
{
if(i<a) //first half add in even position
{
dummy[f]=arr[i];
f += 2;
}
else //second half add in odd positions
{
dummy[f1] = arr[i];
f1 += 2;
}
}
Console.WriteLine("\n\n\n\n"); //print the result
foreach(int q in dummy)
{
Console.WriteLine(q);
}
}
}
}
//python
list=[2,5,8,9,4,6,7,1]
a=sorted(list)
b=reversed(sorted(list))
c=a[0:len(a)//2]
d=a[len(a)//2:][::-1]
for i in range(len(c)):
print(d[i],end=' ')
print(c[i],end=' ')

generate a Series / return nth term in the series

I need to generate a sequence such that its members contain only 1, 2, 3 digits. For example, 1 2 3 11 12 13 21 22 23 31 32 33 111 .... and so on up to 10^18th term.
I'm not able to deduce any pattern for this. It seems impossible to write a code up to 10^18 numbers of terms in the series.
1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33, 111, 112, 113, 121, 122,
123, 131, 132, 133, 211, 212, 213, 221, 222, 223, 231, 232, 233, 311,
312, 313, 321, 322, 323, 331, 332, 333, 1111, 1112, 1113, 1121, 1122,
1123, 1131, 1132, 1133, 1211, 1212, 1213, 1221 ...
I expect to find the given n-th term in the series. It's a number system which contains only 1, 2, 3 or is combinations of these digits as a number as explained in the sequence just like our normal number system.
This is just a base-3 numbering system only the digits go from 1 to 3 instead of 0 to 2. The math works out the same way:
1 = 1*3^0
2 = 2*3^0
3 = 3*3^0
4 = 1*3^1 + 1*3^0
5 = 1*3^1 + 2*3^0
6 = 1*3^1 + 3*3^0
7 = 2*3^1 + 1*3^0
...
19 = 1*3^2 + 3*3^1 + 1*3^0
Write two methods:
digit(n): computes the right-most digit for a given n. Some test cases: digit(4) = 1, digit(5)=2, digit(15)=3.
leftover(n): computes the number which represents n but with the right-most digit chopped off. Some test cases: leftover(4) = 1, leftover(15) = 4, leftover(23) = 7.
Now combine the two methods into the solution to your problem which repeatedly chops off the right most digit until there's nothing left. You might find it easier to do this recursively.
The sequence you've mentioned already is known as Numbers that contain only 1's, 2's and 3's. It is formulated by Hieronymus Fischer.
a(n) = sum_{j=0..m-1} (1 + b(j) mod 3)*10^j,
where m = floor(log_3(2*n+1)), b(j) = floor((2*n+1-3^m)/(2*3^j)).
You can examine explanation of the formula on the aforementioned link above. I've written so far basic level of it using long. To reach 10^18th term, you need to use BigInteger class of Java.
class SequenceGeneratorWith123 {
// Written by Soner
private static double logOfBase(long base, long num) {
return Math.log(num) / Math.log(base);
}
private static int mfunc(long n) {
return (int) Math.floor(logOfBase(3, 2 * n + 1));
}
private static int b(int j, double m, long n) {
return (int) Math.floor((2 * n + 1 - Math.pow(3, m)) / (2 * Math.pow(3, j)));
}
public static void main(String[] args) {
for (int i = 0; i < 9; i++) {
long n = (long) Math.pow(10, i);
int m = mfunc(n);
long sum = 0;
for (int j = 0; j < m ; j++) {
sum += ((1 + b(j, m, n) % 3) * Math.pow(10, j));
}
System.out.printf("a(10^%d) = %d\n", i, sum);
}
System.out.println("After the point, overflow will occur " +
"because of long type.");
}
}
Output:
a(10^0) = 1
a(10^1) = 31
a(10^2) = 3131
a(10^3) = 323231
a(10^4) = 111123331
a(10^5) = 11231311131
a(10^6) = 1212133131231
a(10^7) = 123133223331331
a(10^8) = 13221311111312132
After the point, overflow will occur because of long type.
You just need to play with the code, that is, we can obtain your wish by merely changing main() somewhat.
long n = 1;
// How many terms you need you can alter it by pow() method.
// In this example 10^2 = 100 terms will be obtained.
int term = (int)Math.pow(10, 2);
for (int i = 0; i < term; i++) {
int m = mfunc(n);
long sum = 0;
for (int j = 0; j < m ; j++) {
sum += ((1 + b(j, m, n) % 3) * Math.pow(10, j));
}
System.out.printf("%d. term = %d\n", i + 1, sum);
n++;
}
Output:
1. term = 1
2. term = 2
3. term = 3
4. term = 11
5. term = 12
6. term = 13
7. term = 21
8. term = 22
9. term = 23
10. term = 31
11. term = 32
12. term = 33
13. term = 111
14. term = 112
15. term = 113
16. term = 121
17. term = 122
18. term = 123
19. term = 131
20. term = 132
21. term = 133
22. term = 211
23. term = 212
24. term = 213
25. term = 221
26. term = 222
27. term = 223
28. term = 231
29. term = 232
30. term = 233
31. term = 311
32. term = 312
33. term = 313
34. term = 321
35. term = 322
36. term = 323
37. term = 331
38. term = 332
39. term = 333
40. term = 1111
41. term = 1112
42. term = 1113
43. term = 1121
44. term = 1122
45. term = 1123
46. term = 1131
47. term = 1132
48. term = 1133
49. term = 1211
50. term = 1212
51. term = 1213
52. term = 1221
53. term = 1222
54. term = 1223
55. term = 1231
56. term = 1232
57. term = 1233
58. term = 1311
59. term = 1312
60. term = 1313
61. term = 1321
62. term = 1322
63. term = 1323
64. term = 1331
65. term = 1332
66. term = 1333
67. term = 2111
68. term = 2112
69. term = 2113
70. term = 2121
71. term = 2122
72. term = 2123
73. term = 2131
74. term = 2132
75. term = 2133
76. term = 2211
77. term = 2212
78. term = 2213
79. term = 2221
80. term = 2222
81. term = 2223
82. term = 2231
83. term = 2232
84. term = 2233
85. term = 2311
86. term = 2312
87. term = 2313
88. term = 2321
89. term = 2322
90. term = 2323
91. term = 2331
92. term = 2332
93. term = 2333
94. term = 3111
95. term = 3112
96. term = 3113
97. term = 3121
98. term = 3122
99. term = 3123
100. term = 3131

How to fulfill diagonal in array in 75% with number 1, and the rest (25%) with number -1?

I have to code function that create two-dimensional array of Integer numbers with random size from [50, 100] and divisible by 4. Number of rows is equal to number of columns. Next, an array is fulfill with random numbers (except elements that are on diagonal) from range [a, b), where a and b are enter by user.
Values on diagonal have got fulfill in random arrangement in 75% by number 1, and the rest of 25% with number -1.
Functions, should print-out to console amount of cells which value is less than product of index from row and column these cell.
I have no idea how to deal with these diagonals and amount of cells...
So far I come off with something like this:
public static void createArray()
{
Random generator = new Random();
Scanner in = new Scanner(System.in);
int drawed = 1, rows, cols;
while (drawed %4 != 0)
{
drawed = 50 + generator.nextInt(51);
}
rows = drawed;
cols = rows;
int[][] array = new int[rows][cols];
System.out.println("Input a: ");
int a = in.nextInt();
System.out.println("Input b: ");
int b = in.nextInt();
for (int i = 0; i < array.length; i++)
for (int j = 0; j < array[i].length; j++)
{
if (i != j)
array[i][j] = a + generator.nextInt(b - a);
}
}
How to fulfill diagonal in 75% with number 1, and the rest (25%) with number -1?
How count cells which value is less than product from index of rows and columns?
Hi I could not understood your last point of displaying the output to console. However the following program will solve the problem you are facing for diagonal values.
public class Application {
public static void main(String[] args) {
doJob(12, 20, 200);
}
private static void doJob(int size, int a, int b) {
if (size % 4 == 0) {
int[][] array = new int[size][size];
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (i != j && (i + j) != (size - 1))
array[i][j] = generateRandomNumber(a, b);
}
}
int positiveOneSize = calculateLocationRequiredForOne(size * 2);
int negetiveOneSize = (size - 1) - positiveOneSize;
/* Fill the diagonals with random values for positive one */
while (positiveOneSize > 0 || negetiveOneSize > 0) {
int location = generateRandomNumber(0, size - 1); // Random loc
int posOrNeg = generateRandomNumber(0, 2);
if (posOrNeg == 0) {
array[location][location] = 1;
array[location][(size - 1) - location] = 1;
} else {
array[location][location] = -1;
array[location][(size - 1) - location] = -1;
}
positiveOneSize--;
negetiveOneSize--;
}
/* Print array */
for (int m = 0; m < size; m++) {
for (int n = 0; n < size; n++) {
System.out.print(" " + array[m][n]);
}
System.out.println();
}
}
else {
System.out.println("Error");
}
}
private static int generateRandomNumber(int a, int b) {
return a + (int) (Math.random() * ((b - a) + 1));
}
private static int calculateLocationRequiredForOne(int size) {
return (int) (0.75 * size);
}
}
I have no idea how to deal with these diagonals
First, let's try to draw a diagonal of any char, as in this answer
Basically you have to know when the indexes belong to the diagonal or not, this can be done with some logic, let's use a N x N board where N = 8:
[0][0] [0][1] [0][2] [0][3] [0][4] [0][5] [0][6] [0][7]
[1][0] [1][1] [1][2] [1][3] [1][4] [1][5] [1][6] [1][7]
[2][0] [2][1] [2][2] [2][3] [2][4] [2][5] [2][6] [2][7]
[3][0] [3][1] [3][2] [3][3] [3][4] [3][5] [3][6] [3][7]
[4][0] [4][1] [4][2] [4][3] [4][4] [4][5] [4][6] [4][7]
[5][0] [5][1] [5][2] [5][3] [5][4] [5][5] [5][6] [5][7]
[6][0] [6][1] [6][2] [6][3] [6][4] [6][5] [6][6] [6][7]
[7][0] [7][1] [7][2] [7][3] [7][4] [7][5] [7][6] [7][7]
There is a pattern there for the diagonals: can you see it?
\: Row and column are the same number
/ Row = number - column - 1
How to fulfill diagonal in 75% with number 1, and the rest (25%) with number -1?
You need to know how many numbers you're gonna use, but... you already know that! Remember N? Well we're going to use a formula to know what is 75% of N:
75% of N = N * 75 / 100
25% of N = N * 25 / 100
In our case using N = 8 that becomes:
8 * 75 = 600 / 100 = 6
8 * 25 = 200 / 100 = 2
Then create your own function which returns either 1 or -1 based on how many positive or negative numbers you've added already as in the code below
How count cells which value is less than product from index of rows and columns?
That, in code means that you need to know how many values are less than i * j
if (array[i][j] < i * j) {
count++;
}
Joining everything (without using a Scanner as I'm lazy for that):
import java.util.Random;
public class SquareDiagonalNumbers {
private static int positive = 0;
private static int negative = 0;
private static int n = 8;
private static int positiveOnes = n * 75 / 100; //75%
private static int negativeOnes = n * 25 / 100; //25%
private static int a = 10;
private static int b = 20;
public static void main(String[] args) {
int[][] array = new int[n][n];
int products = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
array[i][j] = i == j || i == (n - j - 1) ? randomOnes() : randomNumber();
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
System.out.print(array[i][j] + " ");
}
System.out.println();
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (array[i][j] < i * j) {
products++;
System.out.println("At [" + i + ", " + j + "] number " + array[i][j] + " is lower than [i * j]: " + (i * j));
}
}
}
System.out.println("Total of numbers lower than the product of their row and column: " + products);
}
private static int randomNumber() {
Random r = new Random();
return r.nextInt(b - a) + a;
}
private static int randomOnes() {
Random r = new Random();
boolean isPositive = r.nextBoolean();
if (isPositive) {
if (positive < positiveOnes) {
positive++;
return 1;
} else {
negative++;
return -1;
}
} else {
if (negative < negativeOnes) {
negative++;
return -1;
} else {
positive++;
return 1;
}
}
}
}
Produces a similar output to this:
-1 17 14 19 14 19 14 -1
11 1 11 18 18 14 1 14
11 14 1 14 12 1 17 13
16 10 12 1 1 12 10 11
11 11 14 -1 1 19 14 19
15 12 -1 19 14 1 13 15
13 -1 17 10 12 12 1 10
1 19 15 18 12 11 13 1
At [0, 0] number -1 is lower than [i * j]: 0
At [0, 7] number -1 is lower than [i * j]: 0
At [1, 6] number 1 is lower than [i * j]: 6
At [2, 2] number 1 is lower than [i * j]: 4
At [2, 5] number 1 is lower than [i * j]: 10
At [2, 7] number 13 is lower than [i * j]: 14
At [3, 3] number 1 is lower than [i * j]: 9
At [3, 4] number 1 is lower than [i * j]: 12
At [3, 5] number 12 is lower than [i * j]: 15
At [3, 6] number 10 is lower than [i * j]: 18
At [3, 7] number 11 is lower than [i * j]: 21
At [4, 3] number -1 is lower than [i * j]: 12
At [4, 4] number 1 is lower than [i * j]: 16
At [4, 5] number 19 is lower than [i * j]: 20
At [4, 6] number 14 is lower than [i * j]: 24
At [4, 7] number 19 is lower than [i * j]: 28
At [5, 2] number -1 is lower than [i * j]: 10
At [5, 4] number 14 is lower than [i * j]: 20
At [5, 5] number 1 is lower than [i * j]: 25
At [5, 6] number 13 is lower than [i * j]: 30
At [5, 7] number 15 is lower than [i * j]: 35
At [6, 1] number -1 is lower than [i * j]: 6
At [6, 3] number 10 is lower than [i * j]: 18
At [6, 4] number 12 is lower than [i * j]: 24
At [6, 5] number 12 is lower than [i * j]: 30
At [6, 6] number 1 is lower than [i * j]: 36
At [6, 7] number 10 is lower than [i * j]: 42
At [7, 3] number 18 is lower than [i * j]: 21
At [7, 4] number 12 is lower than [i * j]: 28
At [7, 5] number 11 is lower than [i * j]: 35
At [7, 6] number 13 is lower than [i * j]: 42
At [7, 7] number 1 is lower than [i * j]: 49
Total of numbers lower than the product of their row and column: 32

Knight's Least Amount of Moves Debug Java

Basically I need to find the smallest amount of moves it would take for a knight to reach a certain position on a 8x8 grid numbered 0-63 inclusive.
I have cross checked all test cases that I could think of and every test case is exactly what I am looking for. I used an elimination and placement algorithm modeled after an O(1) solution but for a knight instead.
The test cases I receive for the problem are confidential and I am left to guess what I have missed. When I try to verify my code I receive an output of:
Test 1 passed!
Test 2 failed.
Test 3 passed!
Test 4 failed.
Test 5 failed.
Test 6 failed.
Test 7 failed.
Test 8 failed.
Test 9 failed.
Test 10 failed.
Code:
public class Test {
public static boolean found = false;
public static void main (String[] args) {
int[][] arr = { // 0 1 2 3 4 5 6 7
{ 0, 1, 2, 3, 4, 5, 6, 7}, // 0
{ 8, 9, 10, 11, 12, 13, 14, 15}, // 1
{16, 17, 18, 19, 20, 21, 22, 23}, // 2
{24, 25, 26, 27, 28, 29, 30, 31}, // 3
{32, 33, 34, 35, 36, 37, 38, 39}, // 4
{40, 41, 42, 43, 44, 45, 46, 47}, // 5
{48, 49, 50, 51, 52, 53, 54, 55}, // 6
{56, 57, 58, 59, 60, 61, 62, 63}, // 7
};
int src = 63; // Changed to parameters values later on in testing
int dest = 30; // Changed to parameters values later on in testing
int[] loc = pos(arr, src);
int[][] productMatrix;
int finalNumber = 0;
while(!found && arr[loc[0]][loc[1]] != dest)
{
productMatrix = createknights(arr, loc[0], loc[1], dest);
printMatrix(productMatrix);
System.out.println("--------------------");
finalNumber++;
}
System.out.println(finalNumber);
}
public static int[][] createknights(int[][] arr, int r, int c, int goal)
{
arr[r][c] = -1;
int[][] knightLoc = getKnightLoc(arr);
for(int i = 0; i < knightLoc.length; i++)
{
int[][] possiblePositions = {
{knightLoc[i][0] - 2, knightLoc[i][1] - 1}, //Up Left
{knightLoc[i][0] - 2, knightLoc[i][1] + 1}, //Up Right
{knightLoc[i][0] + 2, knightLoc[i][1] - 1}, //Down Left
{knightLoc[i][0] + 2, knightLoc[i][1] + 1}, //Down Right
{knightLoc[i][0] - 1, knightLoc[i][1] - 2}, //Left Up
{knightLoc[i][0] + 1, knightLoc[i][1] - 2}, //Left Down
{knightLoc[i][0] - 1, knightLoc[i][1] + 2}, //Right Up
{knightLoc[i][0] + 1, knightLoc[i][1] + 2} //Right Down
};
for( int[] row : possiblePositions)
{
if( checkLoc(arr, row[0], row[1]) )
{
if( arr[row[0]][row[1]] == goal )
{
found = true;
break;
}
arr[row[0]][row[1]] = -1;
}
}
}
return arr;
}
public static int[][] getKnightLoc(int[][] arr)
{
int knightNum = getKnightNum(arr);
int[][] knightLocArray = new int[knightNum][2];
for(int i = 0; i < arr.length; i ++)
{
for(int a = 0; a < arr[i].length; a++)
{
if(arr[i][a] == -1)
{
knightLocArray[(knightNum - 1)] = new int[]{i,a};
knightNum--;
}
}
}
return knightLocArray;
}
public static int getKnightNum(int[][] arr)
{
int knightNum = 0;
for(int i = 0; i < arr.length; i ++)
{
for(int a = 0; a < arr[i].length; a++)
{
if(arr[i][a] == -1)
{
knightNum++;
}
}
}
return knightNum;
}
public static boolean checkLoc(int[][] arr, int r, int c)
{
if(r >= 0 && c >= 0 && r < arr.length && c < arr[r].length && arr[r][c] != -1)
{
return true;
}
return false;
}
public static int[] pos(int[][] arr, int src)
{
for(int i = 0; i < arr.length; i ++)
{
for(int a = 0; a < arr[i].length; a++)
{
if(arr[i][a] == src)
{
return new int[]{i , a};
}
}
}
return null;
}
public static void printMatrix(int[][] arr)
{
for(int i = 0; i < arr.length; i ++)
{
for(int a = 0; a < arr[i].length; a++)
{
System.out.print(arr[i][a] + " ");
}
System.out.println();
}
}
}
The O(1) model I checked my answers with:
O(1) model
Output example (ending value is the answer: src=63, dest=30):
0 1 2 3 4 5 6 7
8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23
24 25 26 27 28 29 30 31
32 33 34 35 36 37 38 39
40 41 42 43 44 45 -1 47
48 49 50 51 52 -1 54 55
56 57 58 59 60 61 62 -1
--------------------
0 1 2 3 4 5 6 7
8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23
24 25 26 27 28 -1 30 -1
32 33 34 35 -1 37 -1 39
40 41 42 -1 44 45 -1 -1
48 49 50 51 -1 -1 54 55
56 57 58 -1 60 -1 62 -1
--------------------
0 1 2 3 4 5 6 7
8 9 10 11 -1 13 -1 15
16 17 18 -1 20 -1 22 -1
24 25 -1 27 -1 -1 30 -1
32 -1 34 -1 -1 -1 -1 -1
40 41 -1 -1 -1 45 -1 -1
48 -1 50 -1 -1 -1 54 -1
56 57 -1 -1 -1 -1 -1 -1
--------------------
3 <----Answer
Please tell me what I am missing. Thanks!
Edit:
int src & int dest will not be hard coded at run time. The values will be replaced with parameter values. The values are hard coded for testing purposes.
I’m afraid your program prints 3 every time. This is because you have hardcoded the source as square 63 and the destination as square 30. Coincidentally the answers to two of the test cases are indeed 3. This is a reasonable guess. So you pass those two and fail the rest.
Instead you should of course read the input in whatever way is specified with your assignment.
It turns out that this block of code is a perfect solution except for the fact that apparently the test cases are tested in one continuous section of code.
For example, making a separate method allowed for me to call this section of code:
public static void main (String[] args) {
//Test Cases
System.out.println(answer(63,5));
System.out.println(answer(19,4));
System.out.println(answer(63,0));
}
This would print out:
5
0
0
After further debugging, I found what had caused the leading zeros is disregarding the found variable at the top of the code. Thus, leading to completely incorrect answers.
Previous Code:
while(!found && arr[loc[0]][loc[1]] != dest)
{
productMatrix = createknights(arr, loc[0], loc[1], dest);
printMatrix(productMatrix);
System.out.println("--------------------");
finalNumber++;
}
System.out.println(finalNumber);
New Code:
while(!found && arr[loc[0]][loc[1]] != dest)
{
productMatrix = createknights(arr, loc[0], loc[1], dest);
printMatrix(productMatrix);
System.out.println("--------------------");
finalNumber++;
}
found = false;
System.out.println(finalNumber);
Thus now relaying the correct answers.
Thank you Ole V.V. for brainstorming a solution! I guess just needed some time away from the problem and a couple of ideas.

Random Number Generator of Even and Odd Numbers

I need to create an application that generates 25 random integers between 0 and 99 and then outputs those integers on two separate lines one for odd numbers and one for even numbers. I will need to use one array for even numbers and one for odd numbers. This is what I have so far:
public static void main(String[] args) {
//Odd Numbers
int[] oddNums = new int[25];
for (int index = 0; index < oddNums.length; index++) {
oddNums[index] = (int) (Math.random()*99);
}
System.out.print("ODD: ");
for (int index = 0; index < oddNums.length; index++) {
System.out.print(oddNums[index] + " ");
}
//Even Numbers
int[] evenNums = new int[25];
for (int index = 0; index < evenNums.length; index++) {
evenNums[index] = (int) (Math.random()*99);
}
System.out.print("\nEVEN: ");
for (int index = 0; index < evenNums.length; index++) {
System.out.print(evenNums[index] + " ");
}
}
I have set up the program to print out 25 random integers, but I do not know how I am going to get the program to print out only even numbers on one line and odd numbers on another (I am new to java).
Here is a sample output I am getting:
ODD: 28 36 54 98 35 1 59 43 96 69 41 66 37 15 30 17 29 67 56 83 71 4
24 70 38
EVEN: 34 45 36 26 73 84 60 39 21 49 28 98 69 14 32 24 72 29 26 88 77 2
23 58 47
This is wrong since there are both even and odd numbers on both lines.
This is what the output should look like:
ODD: 25 97 23 45 63 91 13 47 93 51 29
EVEN: 22 94 46 74 18 48 32 84 28 92 56
There are only odd numbers on one line and even numbers on another line.
Does anyone know what I need to add here?
A little modification to your program will yield the desired result.
public static void main(String[] args) {
//Odd Numbers
int[] randomNumbers = new int[25];
int[] evenNumbers = new int[25];
int[] oddNumbers = new int[25];
int k = 0, l = 0;
for (int index = 0; index < randomNumbers.length; index++) {
randomNumbers[index] = (int) (Math.random() * 99);
}
for (int i = 0; i < 25; i++) {
if (randomNumbers[i] % 2 == 0) {
evenNumbers[k] = randomNumbers[i];
k++;
} else {
oddNumbers[l] = randomNumbers[i];
l++;
}
}
}
You can generate an even number uniformly at random in [0,100] with the formula n = 2*x where x is uniformly random in [0, 49].
You can similarly generate an uniformly random odd number with n = 2*x+1 where x is uniformly random in [0,49].
You can just generate the 25 number. After generating those ints, you can locate them in the array they belong.
int num;
int oddIndex = -1;
int evenIndex = -1;
for (index = 0; index < 25 ; index++){
num = (int) (Math.random()*99);
if (num % 2 == 1){
oddIndex++;
oddNum[oddIndex] = num;
}
else{
evenIndex++;
evenNum[evenIndex] = num;
}
}
In this case, you're not sure about the sizes of each array. So, I advise you to use ArrayList instead of array. If you use an ArrayList, you won't need to deal with oddIndex and evenIndex.
Firstly,The random function you have written will be generating random numbers between 0 and 99. It will not be considering whether the numbers are odd or even.
If there is no restriction on the number of odd numbers and number of even numbers, just use the random generator once and depending on whether it is odd or even place it in the correct array.
For doing so, use the MOD operator i.e. check for remainder after dividing by 2 to see odd or even
At some point in your code, you need to have something like,
Pseudocode:
if (nextNumber is odd) then
put nextNumber at end of ODD array
else
put nextNumber at end of EVEN array
endif
You should also have a look at util.Random.nextInt() which is preferable for generating random integers.
Here's a solution that uses Java 8 streams:
public class NumberGenerator {
public static void main(String[] args) {
Random random = new Random();
int[] ints = random.ints(25, 0, 99).sorted().toArray();
int[] even = IntStream.of(ints).filter(x -> x % 2 == 0).toArray();
int[] odd = IntStream.of(ints).filter(x -> x % 2 == 1).toArray();
System.out.println(Arrays.toString(even));
System.out.println(Arrays.toString(odd));
}
}
First an array of all random integers are being created. 25 random integers are created and they should all be between 0 and 99.
The evens and odds are filtered out into two separate arrays.
[0, 4, 6, 16, 18, 22, 40, 42, 58, 64, 82, 84, 98]
[7, 27, 29, 31, 35, 55, 73, 75, 75, 79, 83, 91]

Categories