import
java.util.ArrayList;
import
java.util.List;
public
class
ClockPuzzle {
private
static
class
Number
implements
Cloneable {
private
boolean
marked;
private
final
int
value;
public
Number(
int
value) {
this
.value = value;
}
public
Number(
int
value,
boolean
marked) {
this
.value = value;
this
.marked = marked;
}
@Override
protected
Object clone() {
return
new
Number(value, marked);
}
}
private
static
enum
Direction {
INIT(
"Init "
),
LEFT(
"Left "
),
RIGHT(
"Right"
);
private
String str;
private
Direction(String str) {
this
.str = str;
}
@Override
public
String toString() {
return
str;
}
}
private
final
Number[] numbers;
private
final
int
size;
public
ClockPuzzle(
int
... values) {
numbers =
new
Number[values.length];
for
(
int
i =
0
; i < values.length; i++) {
numbers[i] =
new
Number(values[i]);
}
size = values.length;
}
public
void
solve(
int
index) {
List<String> result =
new
ArrayList<>();
Number[] newNumbers = copy(numbers);
result.add(createResult(Direction.INIT, index, newNumbers[index].value));
solve(newNumbers, index, result);
}
private
void
solve(Number[] numbers,
int
index, List<String> result) {
Number e = numbers[index];
if
(e.marked) {
return
;
}
e.marked =
true
;
if
(allMarked(numbers)) {
printResult(result);
}
else
{
int
leftIndex = getActualIndex(index-e.value, numbers.length);
solve(leftIndex, Direction.LEFT, numbers, result);
int
rightIndex = getActualIndex(index+e.value, numbers.length);
solve(rightIndex, Direction.RIGHT, numbers, result);
}
}
private
void
solve(
int
index, Direction direction, Number[] numbers, List<String> result) {
Number[] newNumbers = copy(numbers);
List<String> newResult = copy(result);
newResult.add(createResult(direction, index, newNumbers[index].value));
solve(newNumbers, index, newResult);
}
private
Number[] copy(Number[] numbers) {
Number[] newNumbers =
new
Number[numbers.length];
for
(
int
i =
0
; i < newNumbers.length; i++) {
newNumbers[i] = (Number) numbers[i].clone();
}
return
newNumbers;
}
private
String createResult(Direction direction,
int
index,
int
value) {
return
direction.toString() +
" --> "
+ value +
" (index: "
+ index +
")"
;
}
private
List<String> copy(List<String> list) {
List<String> newList =
new
ArrayList<>();
for
(String s : list) {
newList.add(s);
}
return
newList;
}
private
void
printHeader() {
for
(
int
i =
0
; i <
50
; i++) {
System.out.print(
"="
);
}
System.out.println();
}
private
void
printResult(List<String> result) {
printHeader();
int
i =
1
;
for
(String r : result) {
if
(i <
10
) {
System.out.println(
" "
+ i++ +
" "
+ r);
}
else
{
System.out.println(i++ +
" "
+ r);
}
}
printHeader();
}
private
boolean
allMarked(Number[] numbers) {
for
(Number n : numbers) {
if
(!n.marked) {
return
false
;
}
}
return
true
;
}
private
int
getActualIndex(
int
i,
int
arraySize) {
if
(i >= arraySize) {
return
i - arraySize;
}
if
(i <
0
) {
return
arraySize + i;
}
return
i;
}
public
static
void
main(String[] args) {
ClockPuzzle clockPuzzle =
new
ClockPuzzle(
2
,
1
,
3
,
2
,
2
,
2
,
3
,
3
);
for
(
int
i =
0
; i < clockPuzzle.size; i++) {
clockPuzzle.solve(i);
}
}
}