I have been solving the problem from UVA 101. In this problem, there will be at most 24
position in a row at beginning, and this array is zero-indexed, and for each position i
there will be a single block also numbered i
. The input will give you a number n
which means how many command will follow. There are four kinds of commands:
Say A, B are block number.
- Move A onto B: put all blocks above A, B to their initial positions, i.e. block
i
will back to posi
, then move A onto B. - Move A over B: put all blocks above A to their … (the same as 1.).
- Pile A onto B: put all blocks above B to their initial positions, then move the entire pile start from A onto B.
- Pile A over B: move the entire pile start from A to the pile contains B.
Execute those n
commands from input and print the result of all pos’, each stack is printed from bottom to top.
Can you please review it and provide me with feedback? Those I marked <<<<<...<<< ?(123)
are the parts I think could be optimized.
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#define COMMAND_BUFFER 5
#define ADJ_BUFFER 5
#define N_MAX 25
#define STRING_EQUAL(a, b) (strcmp((a), (b))==0) // string compare.
int table(N_MAX)(N_MAX);
int atPos(N_MAX);
int size(N_MAX);
void array_init();
void put_back_all_above(int above);
void pile_from_block_to_pos(int above, int toPos);
void move_top_from_pos_to_pos(int fromPos, int toPos);
int get_top_from_pos(int pos);
int main() {
array_init();
int n; if (scanf("%d", &n) != 1) // To suppress warning on Visual Studio <<<<<<<<<<<<<<<<<<<<<<<<<<<<< ?1
return 1;
int from, to;
const char command(COMMAND_BUFFER) = { 0 }, adj(ADJ_BUFFER) = { 0 };
while (scanf(" %(a-z)s", command) != EOF
&& !STRING_EQUAL(command, "quit")
&& scanf("%d%s%d", &from, adj, &to) == 3) { // will return the success # of read.
// printf("%s %d %s %dn", command, from, adj, to);
if (from == to || atPos(from) == atPos(to))
continue;
if (STRING_EQUAL(command, "move") && STRING_EQUAL(adj, "onto")) {
put_back_all_above(from);
put_back_all_above(to);
move_top_from_pos_to_pos(atPos(from), atPos(to));
;
} else if (STRING_EQUAL(command, "move") && STRING_EQUAL(adj, "over")) {
put_back_all_above(from);
move_top_from_pos_to_pos(atPos(from), atPos(to));
;
} else if (STRING_EQUAL(command, "pile") && STRING_EQUAL(adj, "onto")) {
put_back_all_above(to);
pile_from_block_to_pos(from, atPos(to));
;
} else if (STRING_EQUAL(command, "pile") && STRING_EQUAL(adj, "over")) {
pile_from_block_to_pos(from, atPos(to));
}
}
for (int pos = 0; pos < n; ++pos) { // print result <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ?2
printf("%d:", pos);
for (int j = 0; j < size(pos); ++j)
printf(" %d", table(atPos(pos))(j));
printf("n");
}
return 0;
}
void array_init() {
for (int i = 0; i < N_MAX; ++i) {
table(i)(0) = i;
atPos(i) = i;
size(i) = 1;
}
}
void put_back_all_above(int newTop) {
int currentPos = atPos(newTop);
while (get_top_from_pos(currentPos) != newTop)
move_top_from_pos_to_pos(currentPos, get_top_from_pos(currentPos))
;
}
void pile_from_block_to_pos(int block, int toPos) {
int blockIndex = -1;
int blockOldPos = atPos(block);
for (int i = 0; i < size(blockOldPos); ++i)
if (table(blockOldPos)(i) == block) {
blockIndex = i;
break;
}
int pileSize = size(blockOldPos) - blockIndex; // Compute the size of pile to be moved.
size(blockOldPos) -= pileSize;
for (int i = 0; i < pileSize; ++i) {
int movedBlock = table(blockOldPos)(size(blockOldPos)+i);
table(toPos)(size(toPos)++) = movedBlock;
atPos(movedBlock) = toPos;
}
}
void move_top_from_pos_to_pos(int fromPos, int toPos) {
table(toPos)(size(toPos)++) =
table(fromPos)(--size(fromPos)); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ?3
atPos(get_top_from_pos(toPos)) = toPos;
}
int get_top_from_pos(int pos) {
return table(pos)(size(pos)-1);
}