螺旋顺序
想象立方体站在它的角落。它可以被飞机切割。每个与立方体相交的平面都是三角形或六边形。对于该交点的每个点,交点处的坐标总和都相同。让我们称之为一个级别。
0 级是微不足道的 - 它只是一个顶点。
级别 1 包含三个顶点。它的螺旋路径包含两条线:向右一步,向下一步。
级别 2 包含六个顶点。螺旋路径:向右两步,向下两步,向上一步。
第 3 级:向右三步,向下三步,向上两步,向右一步。
在 5x5x5 立方体中,我们有 1 个角顶点,5 个三角形,然后是 4 个六边形,然后是 5 个三角形,再次以最后一个角顶点结束。
这是以螺旋顺序打印第一个三角形坐标的算法。六边形的算法也可以这样写。
Each level coordinates sum equals to the level.
Level 0: ( 0, 0, 0 )
Level 1: ( 1, 0, 0 ) - decrement value at 0 and increment value at 1 to get next vertex coordinates
( 0, 1, 0 ) - decrement 1 and increment 2 to get next coordinates
( 0, 0, 1 )
Level 2: ( 2, 0, 0 ) - dec 0, inc 1 to get next line
( 1, 1, 0 ) - dec 0, inc 1
( 0, 2, 0 ) - dec 1, inc 2
( 0, 1, 1 ) - dec 1, inc 2
( 0, 0, 2 ) - dec 2, inc 0
( 1, 0, 1 )
Level 3: ( 3, 0, 0 ) - dec 0, inc 1
( 2, 1, 0 ) - dec 0, inc 1
( 1, 2, 0 ) - dec 0, inc 1
( 0, 3, 0 ) - dec 1, inc 2
( 0, 2, 1 ) - dec 1, inc 2
( 0, 1, 2 ) - dec 1, inc 2
( 0, 0, 3 ) - dec 2, inc 0
( 1, 0, 2 ) - dec 2, inc 0
( 2, 0, 1 ) - dec 0, inc 1
( 1, 1, 1 )
你能看到图案吗?
每个级别的模式重复几次。
Level 1: pattern 1 then pattern 2
Level 2: pattern 1 twice then pattern 2 twice, then pattern 3
Level 3: pattern 1 thrice then pattern 2 thrice, then pattern 3 twice, then pattern 1 again
所以我们得到:
Level 1: 1, 1
Level 2: 2, 2, 1
Level 3: 3, 3, 2, 1
Level 4: 4, 4, 3, 2, 1
Level 5: 5, 5, 4, 3, 2, 1
应用这些模式可以得到正确的螺旋顺序。
import java.util.Arrays;
import java.util.Iterator;
public class CoordsPrinter {
public static final int COORDS_CNT = 3;
public static class CoordsIterator implements Iterator< int[] > {
private final int maxLevel;
private final int coords[];
private int currentLevel;
private int currentTurn;
private int currentStep;
private int currentEdge;
public CoordsIterator( int max ) {
this.maxLevel = max;
coords = new int[ COORDS_CNT ];
}
@Override
public boolean hasNext() {
return currentLevel <= maxLevel;
}
@Override
public int[] next() {
int ret[] = coords.clone();
int stepsQuantity = currentTurn == 0 ? currentLevel : currentTurn == currentLevel ? 2 : currentLevel - currentTurn + 1;
int nextEdge = currentEdge + 1;
if ( nextEdge == COORDS_CNT )
nextEdge = 0;
coords[ currentEdge ]--;
coords[ nextEdge ]++;
currentStep++;
if ( currentStep >= stepsQuantity ) {
currentTurn++;
currentStep = 0;
if ( currentTurn > currentLevel ) {
currentLevel++;
currentTurn = 0;
currentEdge = 0;
Arrays.fill( coords, 0 );
coords[ 0 ] = currentLevel;
} else
currentEdge = nextEdge;
}
return ret;
}
}
public static class CoordsIterable implements Iterable< int[] > {
private final int maxLevel;
public CoordsIterable( int max ) {
this.maxLevel = max;
}
@Override
public Iterator< int[] > iterator() {
return new CoordsIterator( maxLevel );
}
}
public static void main( String args[] ) {
for ( int coords[] : new CoordsIterable( 5 ) )
System.out.println( Arrays.toString( coords ) );
}
}
currentLevel 确定三角形的水平。 currentTurn 决定了我们改变螺旋方向的次数。 currentStep 决定了我们在当前方向经过了多少步。 currentEdge 和 nextEdge 显示方向(我们从 currentEdge 移动到 nextEdge)。