/*
David Kaufman
Montgomery Blair High School
#1026
Senior
*/
import java.util.*;
/**
* A combination of a
queue and a stack (QUeue stACK) with ACSL specified functions.
*/
public class Quack {
private
boolean isStack;
private
ArrayList<Character> quack;
private
static final ArrayList<Character> init;
static {
init
= new ArrayList<Character>(5);
for
(char c='A';c<='E';c++) init.add(c);
}
private
static final HashMap<String,Integer> numArgs;
static {
numArgs
= new HashMap<String,Integer>();
numArgs.put("POP",
1);
numArgs.put("PSH",
1);
numArgs.put("DUP",
1);
numArgs.put("SWP",
1);
numArgs.put("SWH",
0);
numArgs.put("CRC",
1);
numArgs.put("INS",
2);
numArgs.put("PIN",
1);
numArgs.put("SRT",
1);
numArgs.put("PRT",
1);
}
public
static void main(String unusedArgs[]) {
boolean
done = false;
int
counter = 1;
Scanner
s = new Scanner(System.in);
while
(!done) {
try
{
System.out.print("Enter
input line "+counter+": ");
String
line = s.nextLine();
StringTokenizer
st = new StringTokenizer(line,"[ ,]");
Quack
q = new Quack(Character.toUpperCase(st.nextToken().trim().charAt(0))=='S');
while
(st.hasMoreTokens()) {
String
cmd = st.nextToken().trim().toUpperCase();
int
numArgs = getNumArgs(cmd);
String
args[] = new String[numArgs];
for
(int i=0;i<numArgs;i++) {
args[i]
= st.nextToken();
}
callFunc(cmd,args,q);
}
}
catch
(Exception e) {
System.err.println("There
was an exception. Enter the next input.");
}
counter++;
}
}
public
static int getNumArgs(String cmd) {
return
numArgs.get(cmd);
}
public
static void callFunc(String cmd, String[] args, Quack q) {
if
(cmd.equals("POP")) q.pop(Integer.parseInt(args[0]));
if
(cmd.equals("PSH")) q.psh(args[0].trim().charAt(0));
if
(cmd.equals("DUP")) q.dup(Integer.parseInt(args[0]));
if
(cmd.equals("SWP")) q.swp(Integer.parseInt(args[0]));
if
(cmd.equals("SWH")) q.swh();
if
(cmd.equals("CRC")) q.crc(Integer.parseInt(args[0]));
if
(cmd.equals("INS"))
q.ins(Integer.parseInt(args[0]),args[1].trim().charAt(0));
if
(cmd.equals("PIN")) q.pin(args[0].trim().charAt(0));
if
(cmd.equals("SRT")) q.srt(args[0].trim().charAt(0));
if
(cmd.equals("PRT"))
System.out.println(q.prt(Integer.parseInt(args[0])));
}
/**
* Make a new quack and initialize it with
letters ABCDE in that order
* @param isStack
*/
public
Quack(boolean isStack) {
this.isStack
= isStack;
quack
= new ArrayList<Character>(init);
}
public void
pop(int numTimes) {
if
(numTimes>0 && quack.size()>0) {
if
(isStack) quack.remove(quack.size()-1);
else
quack.remove(0);
pop(numTimes-1);
}
}
public void
psh(char c) {
quack.add(c);
}
public void
dup(int numToDup) {
for
(int i=0;i<numToDup;i++) {
quack.add(quack.get(i));
}
}
public void
swp(int numToSwp) {
char
temp[] = new char[numToSwp];
for
(int i=0;i<numToSwp;i++) {
temp[i]
= quack.get(i);
}
for
(int i=0;i<numToSwp;i++) {
quack.set(i,
quack.get(quack.size()-numToSwp+i));
}
for
(int i=0;i<numToSwp;i++) {
quack.set(quack.size()-numToSwp+i,
temp[i]);
}
}
public void
swh() {
isStack
= !isStack;
}
public void
crc(int numTimes) {
for
(int i=0;i<numTimes;i++) {
if
(isStack) quack.add(0, quack.remove(quack.size()-1));
else
quack.add(quack.remove(0));
}
}
/**
* location is 1 based from end; for example
in the stack ABCDE the call ins(2,A) results
* in the new stack ABCDAE
* @param location the 1-based distance from
the pop-end to insert
* @param c the char to insert
*/
public void
ins(int location, char c) {
if
(isStack) quack.add(quack.size()-location+1, c);
else
quack.add(location-1,c);
}
public void
pin(char c) {
quack.add(0,c);
}
/**
* Sorts the quack
* @param direction 'a' for ascending, 'd' for
descending
*/
public void
srt(char direction) {
Collections.sort(quack);
if
(Character.toLowerCase(direction)=='d') Collections.reverse(quack);
}
public
String prt(int numItems) {
int
startIndex;
if
(isStack) startIndex = quack.size()-numItems;
else
startIndex = 0;
String
s = "";
for
(int i=startIndex;i<startIndex+numItems;i++) {
s+=quack.get(i);
if
(i+1<startIndex+numItems) s+= ", ";
}
return
s;
}
}
/*
*INS is 1-based
(check this)
*DUP probably means
duplicate from the bottom
*SWH means stack
ABCDE (top) becomes queue ABCDE (back); that is, for SWH and SRT treat both
structures as arrays with the bottom or front on the left and the top or back
on the right (add to the right, remove where applicable)
*PRT means in order
left to right
*
* Sample 1:
* Input: S, POP 1,
PSH A, PRT 2
* Output: D, A
* Trace:
* INIT : Stack: ABCDE (top)
* POP 1: Stack: ABCD
* PSH A: Stack: ABCDA
* PRT 2: Outputs D,A
*
* Sample 2:
* Input: Q, PSH C,
POP 3, DUP 1, SRT a, PRT 3
* Output: C, D, D
* INIT : Queue: ABCDE (back)
* PSH C: Queue: ABCDEC
* POP 3: Queue: DEC
* DUP 1: Queue: DECD
* SRT a: Queue: CDDE
* PRT 3: Output: CDD
*
* Sample 3:
* Input: S, CRC 3,
PIN D, INS 3, A, PRT 4
* Output: E, A, A, B
* INIT : Stack: ABCDE (top)
* CRC 3: Stack: CDEAB
* PIN D: Stack: DCDEAB
* INS 3,A: Stack:
DCDEAAB
* PRT 4: Output: EAAB
*
* Sample 4:
* Input: S, SWP 2,
POP 1, PSH A, SWH, POP 2, INS 2,E, PRT 3
* Output: C, E, A
* INIT : Stack: ABCDE (top)
* SWP 2: Stack: DECAB
* POP 1: Stack: DECA
* PSH A: Stack: DECAA
* SWH :
Queue: DECAA (back)
* POP 2: Queue: CAA
* INS 2,E: Queue:
CEAA
* PRT 3: Output: CEA
*
* Sample 5:
* Input: Q, PSH C,
CRC 2, SWH, SRT d, PSH A, POP 1, PRT 2
* Output: B, A
* INIT : Queue ABCDE (back)
* PSH C: Queue ABCDEC
* CRC 2: Queue CDECAB
* SWH :
Stack CDECAB (top)
* SRT d: Stack EDCCBA
* PSH A: Stack EDCCBAA
* POP 1: Stack EDCCBA
* PRT 2: Output: B, A
*
*/