-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMinStepsTo1Comb.java
More file actions
186 lines (164 loc) · 4.55 KB
/
MinStepsTo1Comb.java
File metadata and controls
186 lines (164 loc) · 4.55 KB
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/**
* Implements algorithms to get 1 from any number with a set of operations
* using 2 threads: one search from top to down, another one from bottom to
* top.
*/
package dp;
import java.util.ArrayList;
import java.util.HashMap;
/**
* Thread class to search top down.
*/
class TopDown implements Runnable {
// The number to get 1 from.
private int searchingFor;
/**
* Sets class variables.
* @param a The number to get 1 from.
*/
public TopDown(int a) {
this.searchingFor = a;
}
/**
* Prints the result and calls the function to get the result.
*/
public void run() {
System.out.println("TD: Steps to break " +
this.searchingFor + ": " +
getMinSteps());
}
/**
* Calculates how to get from the number to 1 by:
* - Creating a queue and adding there the number,
* - Iterating through the queue and adding all variations to it,
* - Terminates when finds 1 or the value calculated by BottomUp class.
*/
private int getMinSteps() {
ArrayList<QueueItem> queue = new ArrayList<QueueItem>();
queue.add(new QueueItem(this.searchingFor, 0,
Integer.toString(this.searchingFor)));
int i = 0;
while (queue.size() > 0) {
QueueItem item = queue.remove(0);
i++;
if (item.value == 1) {
System.out.println(this.searchingFor + " = " + item.calcs);
System.out.println(i + " cycles for top down");
BottomUp.finished = true;
return item.curStep;
}
QueueItem ready = BottomUp.ready.get(item.value);
if (ready != null) {
System.out.println(item.value + " = " + item.calcs);
System.out.println(item.value + " = " + ready.calcs);
System.out.println(i + " cycles for top down");
BottomUp.finished = true;
return item.curStep + ready.curStep;
}
if (item.value % 3 == 0) {
queue.add(new QueueItem(
item.value / 3,
item.curStep + 1,
item.calcs + " / 3"
));
}
if (item.value % 2 == 0) {
queue.add(new QueueItem(
item.value / 2,
item.curStep + 1,
item.calcs + " / 2"
));
}
queue.add(new QueueItem(
item.value - 1,
item.curStep + 1,
'(' + item.calcs + " - 1)"
));
}
return -1;
}
}
/**
* Thread class to search bottom up.
*/
class BottomUp implements Runnable {
// Queue items keyed by their value.
public static HashMap<Integer, QueueItem> ready = new HashMap<Integer, QueueItem>();
// Flag to stop the thread.
public static boolean finished = false;
// The queue to iterate through.
private ArrayList<QueueItem> queue = new ArrayList<QueueItem>();
// The number to get 1 from.
private int searchingFor;
/**
* Constructor, sets class variables and
* adds 1 to the queue.
* @param a The value to search for.
*/
public BottomUp(int a) {
this.searchingFor = a;
queue.add(new QueueItem(1, 0, "1"));
}
/**
* Iterates through the queue and adds to the queue
* all variations from the current element, stops when
* finished variable is externally set to true.
*/
public void run() {
int i = 0;
while (!finished) {
QueueItem item = queue.remove(0);
if (item.value > this.searchingFor) {
continue;
}
i++;
QueueItem newElem;
if (ready.get(item.value * 3) == null) {
newElem = new QueueItem(
item.value * 3,
item.curStep + 1,
item.calcs + " * 3");
addNewElem(newElem);
}
if (ready.get(item.value * 2) == null) {
newElem = new QueueItem(
item.value * 2,
item.curStep + 1,
item.calcs + " * 2");
addNewElem(newElem);
}
if (ready.get(item.value + 1) == null) {
newElem = new QueueItem(
item.value + 1,
item.curStep + 1,
'(' + item.calcs + " + 1)");
addNewElem(newElem);
}
}
}
/**
* Adds new queue element to the queue and to
* the HashMap of ready elements.
* @param newElem Element to add.
*/
private void addNewElem(QueueItem newElem) {
queue.add(newElem);
ready.put(newElem.value, newElem);
}
}
/**
* Main class to start the algorithm.
*/
class MinStepsTo1Comb {
/**
* Sets the number and starts two threads.
* @param args Program arguments, unused.
*/
public static void main(String[] args) {
int a = 586;
Thread t = new Thread(new TopDown(a), "Top down");
Thread b = new Thread(new BottomUp(a), "Top down");
b.start();
t.start();
}
}