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=' ')
Related
I am stuck and need helpful input with my beginner code. I have a text file that contains:
{001 012 023 034 045 056 067 078 089 102 113 124 135 146 157 168 179 181 203 214 225 236 247 258 269 271 282 304 315 326 337 348 359 361 372 383 405 416 427 438 449 451 462 473 484 506 517 528 539 541 552 563 574 585 607 618 629 631 642 653 664 675 686 708 719 721 732 743 754 765 776 787 809 811 822 833 844 855 866 877 888}
Each triplet corresponds to the X and Y axis for the first two numbers and the value to put in this index is the third one.
Step 1) I buffered in the text and removed spaces to isolate each value(X,Y,Z) in its own string to ease use further out.
Step 2) I convert a specific character in each string to INT giving me 3 values I can then insert manually in my 9X9 matrix.
Step 3) For now I can manually select the index and populate one value in the matrix(in this example, in the code I selected index 8), I need to do this for all values in a loop but can't seem to figure out how to go forward with this.
Code:
import java.io.*;
public class readBuffer {
static void theBuffer() throws IOException {
File file = new File("D://Documents/-/DOCS/School/Prog/game1.txt");
String xString = ""; //three strings used for the coordinates
String yString = "";
String zString = "";
int[][] tab = new int[9][9]; //9X9 matrix created
try (
//read file
FileReader aFile = new FileReader(file);
//
BufferedReader theBuffer = new BufferedReader(aFile);
) {
//Conversion to a String of characters
String string = theBuffer.readLine();
//removes spaces in the string
string = string.replaceAll("\\s", "");
//Loop that generates the X,Y,Z coord and value strings
//Row X (1st value in the triplet)
for (int i = 0, n = string.length(); i < n; i++) {
if ((i + 2) % 3 == 2)
xString += (string.charAt(i));
}
//Column Y (2nd value in the triplet)
for (int i = 0, n = string.length(); i < n; i++) {
if ((i + 1) % 3 == 2)
yString += (string.charAt(i));
}
//Value Z (3rd value in the triplet)
for (int i = 0, n = string.length(); i < n; i++) {
if (i % 3 == 2)
zString += (string.charAt(i));
}
//Visualization for testing
System.out.println("Row #:" + xString);
System.out.println("Col #:" + yString);
System.out.println("Num #:" + zString);
int x = Character.getNumericValue(xString.charAt(8)); //Convert specific char to an INT
int y = Character.getNumericValue(yString.charAt(8)); //Convert specific char to an INT
int z = Character.getNumericValue(zString.charAt(8)); //Convert specific char to an INT
//Visualization for testing
System.out.println("");
System.out.println("//Converted INT numbers//");
System.out.println("Row #:" + x);
System.out.println("Col #:" + y);
System.out.println("Num #:" + z);
//Loop that generates then 9X9 matrix
tab[x][y] = z;
System.out.println("");
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++)
System.out.print(tab[i][j] + " ");
System.out.println();
}
} catch (IOException e) {
System.out.println(e);
}
}
public static void main(String[] args) throws IOException {
theBuffer();
}
}
Image of console Result
Need to fill this out and that is where I need advice.
Seems like you should just iterate the "triplets" and extract the 3 digits.
static int[][] parseMatrix(String values) {
int[][] matrix = new int[9][9];
for (String triplet : values.split(" ")) {
int row = Character.digit(triplet.charAt(0), 10);
int col = Character.digit(triplet.charAt(1), 10);
int val = Character.digit(triplet.charAt(2), 10);
matrix[row][col] = val;
}
return matrix;
}
Test
int[][] matrix = parseMatrix("001 012 023 034 045 056 067 078 089" +
" 102 113 124 135 146 157 168 179 181" +
" 203 214 225 236 247 258 269 271 282" +
" 304 315 326 337 348 359 361 372 383" +
" 405 416 427 438 449 451 462 473 484" +
" 506 517 528 539 541 552 563 574 585" +
" 607 618 629 631 642 653 664 675 686" +
" 708 719 721 732 743 754 765 776 787" +
" 809 811 822 833 844 855 866 877 888");
for (int[] row : matrix) {
for (int value : row)
System.out.print(value + " ");
System.out.println();
}
Output
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9 1
3 4 5 6 7 8 9 1 2
4 5 6 7 8 9 1 2 3
5 6 7 8 9 1 2 3 4
6 7 8 9 1 2 3 4 5
7 8 9 1 2 3 4 5 6
8 9 1 2 3 4 5 6 7
9 1 2 3 4 5 6 7 8
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.
I am trying to print all possible sequences of n and I don't know where I went wrong.
Example: If I let n = 3, then I have to get 33 possible combinations.
import java.util.Scanner;
public class MyPermutations {
public static void show(int[] a) {
for (int i = 0; i < a.length; i++)
System.out.printf("%d", a[i]);
System.out.printf("\n");
}
public static void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static boolean hasNext(int[] a) {
int N = a.length;
// find rightmost element a[k] that is smaller than element to its right
int k;
for (k = N-2; k >= 0; k--)
if (a[k] < a[k+1]) break;
if (k == -1) return false;
// find rightmost element a[j] that is larger than a[k]
int j = N-1;
while (a[k] > a[j])
j--;
swap(a, j, k);
for (int r = N-1, s = k+1; r > s; r--, s++)
swap(a, r, s);
return true;
}
public static void perm(int N) {
// initialize permutation
int[] a = new int[N];
for (int i = 1; i < N; i++) {
a[0]=1;
a[i] = i+1;
}
// print permutations
show(a);
while (hasNext(a))
show(a);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = Integer.parseInt(sc.next());
perm(N);
}
}
Input:
3
My Output:
123 132 213 231 312 321
Expected Output:
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
Forget about swap, and start over.
Think of it like incrementing a number, except you can only use digits 1-N.
E.g. for N=4, start with 1111. Print it.
Increment to 1112, then 1113, then 1114.
Next increment carries over, so 1121, 1122, ..., 1144.
Handle multiple carry overs, 1211.
And so on until you reach 4444, and you're done.
Of course, you could just loop through the N^N combinations, and use division and remainder to build to "digits" for each combination:
private static void perm(int n) {
char[] digits = new char[n];
final int combinations = (int)Math.pow(n, n);
for (int i = 0; i < combinations; i++) {
for (int num = i, j = n - 1; j >= 0; num /= n, j--)
digits[j] = (char)('1' + num % n);
System.out.print(digits);
System.out.print((i + 1) % (n * n) == 0 ? System.lineSeparator() : " ");
}
}
Output
// perm(1)
1
// perm(2)
11 12 21 22
// perm(3)
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
// perm(4)
1111 1112 1113 1114 1121 1122 1123 1124 1131 1132 1133 1134 1141 1142 1143 1144
1211 1212 1213 1214 1221 1222 1223 1224 1231 1232 1233 1234 1241 1242 1243 1244
1311 1312 1313 1314 1321 1322 1323 1324 1331 1332 1333 1334 1341 1342 1343 1344
1411 1412 1413 1414 1421 1422 1423 1424 1431 1432 1433 1434 1441 1442 1443 1444
2111 2112 2113 2114 2121 2122 2123 2124 2131 2132 2133 2134 2141 2142 2143 2144
2211 2212 2213 2214 2221 2222 2223 2224 2231 2232 2233 2234 2241 2242 2243 2244
2311 2312 2313 2314 2321 2322 2323 2324 2331 2332 2333 2334 2341 2342 2343 2344
2411 2412 2413 2414 2421 2422 2423 2424 2431 2432 2433 2434 2441 2442 2443 2444
3111 3112 3113 3114 3121 3122 3123 3124 3131 3132 3133 3134 3141 3142 3143 3144
3211 3212 3213 3214 3221 3222 3223 3224 3231 3232 3233 3234 3241 3242 3243 3244
3311 3312 3313 3314 3321 3322 3323 3324 3331 3332 3333 3334 3341 3342 3343 3344
3411 3412 3413 3414 3421 3422 3423 3424 3431 3432 3433 3434 3441 3442 3443 3444
4111 4112 4113 4114 4121 4122 4123 4124 4131 4132 4133 4134 4141 4142 4143 4144
4211 4212 4213 4214 4221 4222 4223 4224 4231 4232 4233 4234 4241 4242 4243 4244
4311 4312 4313 4314 4321 4322 4323 4324 4331 4332 4333 4334 4341 4342 4343 4344
4411 4412 4413 4414 4421 4422 4423 4424 4431 4432 4433 4434 4441 4442 4443 4444
If you look at your output, the problem is obvious. You are not accounting for multiple instances of the same number (i.e. 2 2's or 3 3's).
If you want all possible permutations your code is just fine, as permutations are made from swapping elements only and not reusing them.
If you want to build all possible combinations (including aaa, aab, etc.) instead it won't be enough to just swap the elements.
public List<String> combinations(List<Character> elements) {
List<String> combinations = new ArrayList<>();
if (elements.isEmpty()) {
return combinations;
}
if (elements.size() == 1) {
combinations.add(String.valueOf(elements.get(0)));
return combinations;
}
for (int i = 0; i < elements.size(); i++) {
int current = elements.get(i);
List<String> subCombinations = combinations(elements);
StringBuilder builder;
for (String s : subCombinations) {
builder = new StringBuilder();
builder.append(current).append(s);
combinations.add(builder.toString());
}
}
return combinations;
}
//Justin Simpson
//CSC-251-FON01, Project 2
//Problem# 7, Page# 1003
//March 22, 2015
import java.util.Random;
/**
* This program uses sorting algorithms to take a array that is randomly generated arrays of 50 integers.
* All four arrays are identical to the original array. Bubble sort, Insertions sort, selection sort, and
* Quick sort will be used to place the arrays in Ascending order.
*/
public class JustinSorting
{
public static int count = 0;
public static int count2 = 0;
public static int size = 50; //Holds the size of the arrays.
public static void main(String[] args)
{
/**
* Randomly creates the array then copies the same array to 4 other arrays.
*/
int[] original = new int[size];
Random rand = new Random();
for(int i = 0; i < size; i++)
{
original[i] = rand.nextInt(1000 - 100)+ 100;
}
int[] array1 = new int[size];
int[] array2 = new int[size];
int[] array3 = new int[size];
int[] array4 = new int[size];
System.arraycopy(original, 0, array1, 0, original.length);
System.arraycopy(original, 0, array2, 0, original.length);
System.arraycopy(original, 0, array3, 0, original.length);
System.arraycopy(original, 0, array4, 0, original.length);
//Calss each one of the sorting methods.
bubbleSort(array1);
insertionSort(array2);
selectionSort(array3);
quickSort(array4);
}
/**
* Uses the bubble sort algorithm to sort the array.
* #param array will pass the copied array.
*/
public static void bubbleSort(int[] array)
{
System.out.print("Bubble Sort:");
System.out.print("\n-----------------------------------------");
// Display the array's contents.
System.out.println("\n|Original order: |");
printArray(array);
int lastPos; // Position of last element to compare
int index; // Index of an element to compare
int temp; // Used to swap to elements
// The outer loop positions lastPos at the last element
// to compare during each pass through the array. Initially
// lastPos is the index of the last element in the array.
// During each iteration, it is decreased by one.
for (lastPos = array.length - 1; lastPos >= 0; lastPos--)
{
// The inner loop steps through the array, comparing
// each element with its neighbor. All of the elements
// from index 0 thrugh lastPos are involved in the
// comparison. If two elements are out of order, they
// are swapped.
for (index = 0; index <= lastPos - 1; index++)
{
// Compare an element with its neighbor.
if (array[index] > array[index + 1])
{
count++;
// Swap the two elements.
temp = array[index];
array[index] = array[index + 1];
array[index + 1] = temp;
}
count2++;
}
}
// Display the array's contents.
System.out.print("| |\n");
System.out.println("|Sorted order: |");
printArray(array);
System.out.print("| |\n");
System.out.print("|Swaps:" + count + " |");
System.out.print("\n|Comparisons:" + count2 + " |");
System.out.print("\n-----------------------------------------\n");
count = 0;
count2 = 0;
}
/**
* Uses the insertion sort algorithm to sort the array.
* #param array will pass the copied array.
*/
public static void insertionSort(int[] array)
{
int unsortedValue; // The first unsorted value
int scan, scan1; // Used to scan the array
System.out.print("Insertion Sort: ");
System.out.print("\n-----------------------------------------");
// Display the array's contents.
System.out.println("\n|Original order: |");
printArray(array);
// The outer loop steps the index variable through
// each subscript in the array, starting at 1. The portion of
// the array containing element 0 by itself is already sorted.
for (int index = 1; index < array.length; index++)
{
// The first element outside the sorted portion is
// array[index]. Store the value of this element
// in unsortedValue.
unsortedValue = array[index];
// Start scan at the subscript of the first element
// outside the sorted part.
scan = index;
scan1 = index;
// Move the first element in the still unsorted part
// into its proper position within the sorted part.
while (scan > 0 && array[scan-1] > unsortedValue)
{
array[scan] = array[scan - 1];
scan--;
count++;
count2++;
}
count2++;
// Insert the unsorted value in its proper position
// within the sorted subset.
array[scan] = unsortedValue;
}
// Display the array's contents.
System.out.print("| |\n");
System.out.println("|Sorted order: |");
printArray(array);
System.out.print("| |\n");
System.out.print("|Swaps:" + count + " |");
System.out.print("\n|Comparisons:" + count2 + " |");
System.out.print("\n-----------------------------------------\n");
count = 0;
count2 = 0;
}
/**
* Uses the selection sort algorithm to sort the array.
* #param array will pass the copied array.
*/
public static void selectionSort(int[] array)
{
int startScan; // Starting position of the scan
int index; // To hold a subscript value
int minIndex; // Element with smallest value in the scan
int minValue; // The smallest value found in the scan
System.out.print("Selection Sort: ");
System.out.print("\n-----------------------------------------");
// Display the array's contents.
System.out.println("\n|Original order: |");
printArray(array);
// The outer loop iterates once for each element in the
// array. The startScan variable marks the position where
// the scan should begin.
for (startScan = 0; startScan < (array.length-1); startScan++)
{
count++;
// Assume the first element in the scannable area
// is the smallest value.
minIndex = startScan;
minValue = array[startScan];
// Scan the array, starting at the 2nd element in
// the scannable area. We are looking for the smallest
// value in the scannable area.
for(index = startScan + 1; index < array.length; index++)
{
if (array[index] < minValue || array[index] < minValue)
{
count2++;
}
if (array[index] < minValue)
{
minValue = array[index];
minIndex = index;
count2++;
}
}
// Swap the element with the smallest value
// with the first element in the scannable area.
array[minIndex] = array[startScan];
array[startScan] = minValue;
}
// Display the array's contents.
// Display the array's contents.
System.out.print("| |\n");
System.out.println("|Sorted order: |");
printArray(array);
System.out.print("| |\n");
System.out.print("|Swaps:" + count + " |");
System.out.print("\n|Comparisons:" + count2 + " |");
System.out.print("\n-----------------------------------------\n");
count = 0;
count2 = 0;
}
/**
* Uses the quick sort algorithm to sort the array.
* #param array will pass the copied array.
*/
public static void quickSort(int array[])
{
System.out.print("Quick Sort: ");
System.out.print("\n-----------------------------------------");
// Display the array's contents.
System.out.println("\n|Original order: |");
printArray(array);
doQuickSort(array, 0, array.length - 1);
// Display the array's contents.
System.out.print("| |\n");
System.out.println("|Sorted order: |");
printArray(array);
System.out.print("| |\n");
System.out.print("|Swaps:" + count + " |");
System.out.print("\n|Comparisons:" + count2 + " |");
System.out.print("\n-----------------------------------------\n");
}
/**
The doQuickSort method uses the QuickSort algorithm
to sort an int array.
#param array The array to sort.
#param start The starting subscript of the list to sort
#param end The ending subscript of the list to sort
*/
public static void doQuickSort(int array[], int start, int end)
{
int pivotPoint;
if (start < end)
{
// Get the pivot point.
pivotPoint = partition(array, start, end);
// Sort the first sub list.
doQuickSort(array, start, pivotPoint - 1);
// Sort the second sub list.
doQuickSort(array, pivotPoint + 1, end);
}
}
/**
The partiton method selects a pivot value in an array
and arranges the array into two sub lists. All the
values less than the pivot will be stored in the left
sub list and all the values greater than or equal to
the pivot will be stored in the right sub list.
#param array The array to partition.
#param start The starting subscript of the area to partition.
#param end The ending subscript of the area to partition.
#return The subscript of the pivot value.
*/
public static int partition(int array[], int start, int end)
{
int pivotValue; // To hold the pivot value
int endOfLeftList; // Last element in the left sub list.
int mid; // To hold the mid-point subscript
// Find the subscript of the middle element.
// This will be our pivot value.
mid = (start + end) / 2;
// Swap the middle element with the first element.
// This moves the pivot value to the start of
// the list.
swap(array, start, mid);
// Save the pivot value for comparisons.
pivotValue = array[start];
// For now, the end of the left sub list is
// the first element.
endOfLeftList = start;
// Scan the entire list and move any values that
// are less than the pivot value to the left
// sub list.
for (int scan = start + 1; scan <= end; scan++)
{
if (array[scan] < pivotValue)
{
count++;
endOfLeftList++;
swap(array, endOfLeftList, scan);
}
count2++;
}
// Move the pivot value to end of the
// left sub list.
swap(array, start, endOfLeftList);
// Return the subscript of the pivot value.
return endOfLeftList;
}
/**
The swap method swaps the contents of two elements
in an int array.
#param The array containing the two elements.
#param a The subscript of the first element.
#param b The subscript of the second element.
*/
public static void swap(int[] array, int a, int b)
{
int temp;
temp = array[a];
array[a] = array[b];
array[b] = temp;
}
public static void printArray(int[] array)
{
int index = 0;
int index2 = 1;
for (int element : array)
{
index++;
if (index == 1 || index == 11 || index == 21 || index == 31 || index == 41 || index2 == 51)
System.out.print("|");
if (index % 10 != 0)
System.out.print(element + " ");
else
System.out.println(element + "|" );
}
}
}
My output from 50 integer randomly generated array copied 4 times into each sort algorithm is:
Bubble Sort:
-----------------------------------------
|Original order: |
|572 125 205 590 213 611 983 631 111 711|
|195 305 185 432 914 555 655 432 475 156|
|873 447 276 856 767 126 626 149 383 711|
|766 917 628 342 527 976 751 429 280 392|
|526 568 199 877 796 515 292 454 444 617|
| |
|Sorted order: |
|111 125 126 149 156 185 195 199 205 213|
|276 280 292 305 342 383 392 429 432 432|
|444 447 454 475 515 526 527 555 568 572|
|590 611 617 626 628 631 655 711 711 751|
|766 767 796 856 873 877 914 917 976 983|
| |
|Swaps:557 |
|Comparisons:1225 |
-----------------------------------------
Insertion Sort:
-----------------------------------------
|Original order: |
|572 125 205 590 213 611 983 631 111 711|
|195 305 185 432 914 555 655 432 475 156|
|873 447 276 856 767 126 626 149 383 711|
|766 917 628 342 527 976 751 429 280 392|
|526 568 199 877 796 515 292 454 444 617|
| |
|Sorted order: |
|111 125 126 149 156 185 195 199 205 213|
|276 280 292 305 342 383 392 429 432 432|
|444 447 454 475 515 526 527 555 568 572|
|590 611 617 626 628 631 655 711 711 751|
|766 767 796 856 873 877 914 917 976 983|
| |
|Swaps:557 |
|Comparisons:606 |
-----------------------------------------
Selection Sort:
-----------------------------------------
|Original order: |
|572 125 205 590 213 611 983 631 111 711|
|195 305 185 432 914 555 655 432 475 156|
|873 447 276 856 767 126 626 149 383 711|
|766 917 628 342 527 976 751 429 280 392|
|526 568 199 877 796 515 292 454 444 617|
| |
|Sorted order: |
|111 125 126 149 156 185 195 199 205 213|
|276 280 292 305 342 383 392 429 432 432|
|444 447 454 475 515 526 527 555 568 572|
|590 611 617 626 628 631 655 711 711 751|
|766 767 796 856 873 877 914 917 976 983|
| |
|Swaps:49 |
|Comparisons:240 |
-----------------------------------------
Quick Sort:
-----------------------------------------
|Original order: |
|572 125 205 590 213 611 983 631 111 711|
|195 305 185 432 914 555 655 432 475 156|
|873 447 276 856 767 126 626 149 383 711|
|766 917 628 342 527 976 751 429 280 392|
|526 568 199 877 796 515 292 454 444 617|
| |
|Sorted order: |
|111 125 126 149 156 185 195 199 205 213|
|276 280 292 305 342 383 392 429 432 432|
|444 447 454 475 515 526 527 555 568 572|
|590 611 617 626 628 631 655 711 711 751|
|766 767 796 856 873 877 914 917 976 983|
| |
|Swaps:155 |
|Comparisons:252 |
-----------------------------------------
On insertion sort and selection sort my friend was saying the swaps and comparisons should be about the same. I am not sure if I am counting the swaps and comparisons differently than how I should be doing them. Also these are the algorithms that I have to use; even though they are the worse case scenario algorithms.
A while back I created a testing program to visualize sorting. It came with a custom array type that registered the swap count and the comparison count - each on every access.
That being said, running a few tests with n=1,000:
Bubble Sort:
n | Comparisons | Swaps
-------+-------------+---------
1000 | 499455 | 252385
1000 | 496944 | 253857
1000 | 499122 | 251105
Insertion sort:
n | Comparisons | Swaps
-------+-------------+---------
1000 | 249434 | 248438
1000 | 256309 | 255315
1000 | 246906 | 245910
Generally, bubble sort has far more comparisons. This is due to the fact that elements have to be compared an average of n/2 times, repeated for n times.
This is because the first element has to compare against the next n-1 elements, the second element has to compare against the next n-2, and so on. You can see this since (1000 / 2) * 1000 = 500,000, which is within a few hundred of most runs.
Insertion sort however only has to go until it reaches an element less than the temporary one. Therefore it will compare an average of n/2 times until it finds a lower element. It also has to perform an average of n/2 comparisons - since the working array gradually gets bigger. Hence (1000 / 2) * (1000 / 2) = 250000, which is once again within a few thousand of most runs.
The first element would have to compare against one value. The second element would have to compare against either one value or two values. The third would be either one, two or three values, etc.
You're calculations are spot on and provable by examining the algorithms.
Swaps and comparisons should not be about the same as each other. You only swap after a comparison tells you to. However, if your friend meant there isn't a huge difference between these sorting algorithms then it's more subjective. It's not surprising that bubble sort is the slowest.
Consider renaming count and count2. Those are horrible names. countSwaps and countComparisons are much better.
while (scan > 0 && array[scan-1] > unsortedValue)
is followed by
count2++
This is an undercount since two comparisons were just performed.
If I was doing this I'd take the lazy way out and write two helper functions that counted every time they were called.
public static int comparisionCount = 0;
public static int swapCount = 0;
public static void swap(int[] array, int i, int j) {
int temp = array[j];
array[j] = array[i];
array[i] = temp;
swapCount++;
}
public static boolean isGreater(int left, int right) {
comparisionCount++;
return left > right;
}
Only use those to do swaps and comparisons and the counting magically happens without you having to worry about it.
For example:
while (scan > 0 && array[scan-1] > unsortedValue)
would become:
`while (isGreater(scan, 0) && isGreater(array[scan-1], unsortedValue))
One little nit pick:
if (index == 1 || index == 11 || index == 21 || index == 31 || index == 41 || index2 == 51)
could have just been:
if (index % 10 == 1)
This is a Java program that finds the nth prime number in a given range.
The max range that can be input is 1-1500000.
The code output is correct for all the possible test cases, but has to be optimized for runtime. What optimization techniques can be applied in this code?
import java.io.*;
class prime
{
public static void main(String[] args)throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String m1,m2,m;
int n1=0,n2=0,n=0;
try
{
//input as string instead of integer because errors must be displayed only after all the values have been input
m1=br.readLine(); //range minimum value
m2=br.readLine(); //range max value
m=br.readLine(); //nth value in range
n1=Integer.parseInt(m1);
n2=Integer.parseInt(m2);
n=Integer.parseInt(m);
if(n1<0||n2>1500000||n1>n2||n==0)
throw new Exception();
}
catch(Exception e)
{
System.out.println("Invalid Input");
System.exit(0);
}
int k=n1,count=0,count1=0;
while(k<=n2&&count1<=n)
{
count=0;
for(int i=1;i<=k;i++)
{
if(k%i==0)
count++;
}
if(count==2)
{
count1++;
}
k++;
}
if(count1==n)
{
System.out.println(k);
System.exit(0);
}
if(count1<n)
{
System.out.println("No prime number is present at this index");
System.exit(0);
}
}
}
Don't test "has exactly 2 divisors", test "is not divisible by numbers other than 1 and itself".
Don't test all values <= k as divisors, test all values <= sqrt(k).
(If a number is divisible by a number greater than sqrt(k), then the result of the division is also an divisor, but would have been found earlier)
Maybe reuse already calculated primes; You only need to test prime numbers as possible divisors. However you need to be careful. If you e.g. search in range 9999-9999, it doesn't make sense to calculate all the smaller primes, however if the range is 1-9999, it reduces the number of checks you have to make. You could combine both approaches and test numbers smaller than n1 the "normal" way and test all larger divisors using the primes you already found.
Your loop can be rewritten like this to apply 1. and 2.:
int k=Math.max(2, n1); // 0 and 1 are no prime
int count1 = 0;
while(k <= n2 && count1 <= n) {
final int sqrt = (int) Math.sqrt(k);
count1++; // asume it's a prime
for(int i = 2; i <= sqrt; i++) {
if(k % i == 0) {
// divisible by number other than 1 and itself -> not a prime
count1--;
break;
}
}
k++;
}
This reduces the running time from O((n2)² - (n1)²) to
Check for divisors between 2 and square root of k. If you don't find any, you've found a prime.
int k=n1,count1=0;
while(k<=n2&&count1<=n)
{
boolean isPrime = true;
for(int i=2;i <= Math.sqrt(k) ;i++)
{
if(k%i==0)
{
isPrime = false;
break;
}
}
if (isPrime)
count1++;
k++;
}
Also, you can handle 2 explicitly and skip every other even number.
As your maximum value is limited, it makes sense to keep a table of the primes from 2 to 1229 (1229² = 1510441) and try them in turn until the number gets smaller than the square of the prime. 2 can be tested without a division. You can also store a table of the squares.
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 137 139 149 151 157 163 167 173
179 181 191 193 197 199 211 223 227 229
233 239 241 251 257 263 269 271 277 281
283 293 307 311 313 317 331 337 347 349
353 359 367 373 379 383 389 397 401 409
419 421 431 433 439 443 449 457 461 463
467 479 487 491 499 503 509 521 523 541
547 557 563 569 571 577 587 593 599 601
607 613 617 619 631 641 643 647 653 659
661 673 677 683 691 701 709 719 727 733
739 743 751 757 761 769 773 787 797 809
811 821 823 827 829 839 853 857 859 863
877 881 883 887 907 911 919 929 937 941
947 953 967 971 977 983 991 997 1009 1013
1019 1021 1031 1033 1039 1049 1051 1061 1063 1069
1087 1091 1093 1097 1103 1109 1117 1123 1129 1151
1153 1163 1171 1181 1187 1193 1201 1213 1217 1223
1229