-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday17-tetris.chpl
148 lines (132 loc) · 4.13 KB
/
day17-tetris.chpl
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
// day17-tetris
use IO;
var input : string;
readLine(input, stripNewline=true);
//writeln(input);
config const width = 7;
config const numRocks = 2022;
const numRockTypes = 5;
var rockPattern : [1..numRockTypes][1..4,1..4] string;
// FIXME: when tried to initialize these to = '.' here got a runtime error
const kindHeight : [1..numRockTypes] int = [1,3,3,4,2];
const kindWidth : [1..numRockTypes] int = [4,3,3,1,2];
// 13 is the number of units with all the rock types stacked on top of each other
const maxHeight = (numRocks/numRockTypes)*13+ (4+ (max reduce kindHeight));
//writeln("maxHeight=", maxHeight);
var simSpace : [1..maxHeight,1..width] string = ".";
// ####
rockPattern[1] = '.';
rockPattern[1][1,1] = "#";
rockPattern[1][1,2] = "#";
rockPattern[1][1,3] = "#";
rockPattern[1][1,4] = "#";
// .#.
// ###
// .#.
rockPattern[2] = '.';
rockPattern[2][2,1] = "#";
rockPattern[2][1,2] = "#";
rockPattern[2][2,2] = "#";
rockPattern[2][2,3] = "#";
rockPattern[2][3,2] = "#";
// ..#
// ..#
// ###
rockPattern[3] = '.';
rockPattern[3][1,1] = "#";
rockPattern[3][1,2] = "#";
rockPattern[3][1,3] = "#";
rockPattern[3][2,3] = "#";
rockPattern[3][3,3] = "#";
// #
// #
// #
// #
rockPattern[4] = '.';
rockPattern[4][1,1] = "#";
rockPattern[4][2,1] = "#";
rockPattern[4][3,1] = "#";
rockPattern[4][4,1] = "#";
// ##
// ##
rockPattern[5] = '.';
rockPattern[5][1,1] = "#";
rockPattern[5][1,2] = "#";
rockPattern[5][2,1] = "#";
rockPattern[5][2,2] = "#";
// do the simulation, x-axis, y-axis
var currHeight = 0;
var lowerLeft = (4,3); // lower left of the first rock
var currInput = 0;
for i in 1..numRocks {
//writeln("start of for loop, lowerLeft = ", lowerLeft);
var currKind = (i-1) % numRockTypes + 1;
//writeln("currKind=", currKind);
var done = false;
while !done {
// move left or right
//writeln("input[currInput]=", input[currInput]);
if input[currInput]=='<' && canMoveLeft(currKind, lowerLeft) {
lowerLeft += (0,-1);
//writeln("after pushing left, lowerLeft = ", lowerLeft);
} else if input[currInput]=='>' && canMoveRight(currKind, lowerLeft) {
lowerLeft += (0,1);
//writeln("after pushing right, lowerLeft = ", lowerLeft);
}
currInput += 1;
currInput = currInput % input.size;
// move down if possible or stop
if canMoveDown(currKind, lowerLeft) {
lowerLeft = lowerLeft - (1,0);
} else {
done = true;
}
}
//writeln("rockPattern[currKind]=", rockPattern[currKind]);
currHeight = max(currHeight,kindHeight[currKind] + lowerLeft[0]-1);
//writeln("currHeight = ", currHeight);
// mark the simulation space
//writeln("lowerLeft before marking=", lowerLeft);
for (r,c) in rockPattern[currKind].domain {
var (simr, simc) = lowerLeft + (r-1,c-1);
if rockPattern[currKind][r,c]=='#' then
simSpace[simr,simc] = rockPattern[currKind][r,c];
}
lowerLeft = (currHeight+4,3);
//writeln("lowerLeft=", lowerLeft);
}
//writeln(simSpace);
writeln("currHeight = ", currHeight);
// check if a rock can move down
// rockPattern and simSpace are being accessed
proc canMoveDown(kind : int, lowerLeft : 2*int) : bool {
if lowerLeft[0] == 1 then return false; // on floor
for (r,c) in rockPattern[kind].domain {
var (simr, simc) = lowerLeft + (r-1,c-1);
if rockPattern[kind][r,c]=='#'
&& simSpace[simr-1,simc]=='#' then return false;
}
return true;
}
// check if a rock can move right
// rockPattern and simSpace are being accessed
proc canMoveRight(kind : int, lowerLeft : 2*int) : bool {
if (lowerLeft[1]-1+kindWidth[kind]) == width then return false; // on far right boundary
for (r,c) in rockPattern[kind].domain {
var (simr, simc) = lowerLeft + (r-1,c-1);
if rockPattern[kind][r,c]=='#'
&& simSpace[simr,simc+1]=='#' then return false;
}
return true;
}
// check if a rock can move left
// rockPattern and simSpace are being accessed
proc canMoveLeft(kind : int, lowerLeft : 2*int) : bool {
if lowerLeft[1] == 1 then return false; // on far left boundary
for (r,c) in rockPattern[kind].domain {
var (simr, simc) = lowerLeft + (r-1,c-1);
if rockPattern[kind][r,c]=='#'
&& simSpace[simr,simc-1]=='#' then return false;
}
return true;
}