Skip to content

Instantly share code, notes, and snippets.

@Kyuuhachi
Last active August 29, 2015 14:01
Show Gist options
  • Save Kyuuhachi/a8a23ba19e32bfb1c6a9 to your computer and use it in GitHub Desktop.
Save Kyuuhachi/a8a23ba19e32bfb1c6a9 to your computer and use it in GitHub Desktop.
import java.io.*;
import java.util.LinkedList;
import java.util.List;
public class Hard162 {
public static void main(String[] args) {
if(args.length < 3) err("<Error: too few arguments>");
if(args.length > 3) err("<Error: too many arguments>");
if(!args[0].equals("-d") && !args[0].equals("-c")) err("<Error: unknown operation>");
File in = new File(args[1]).getAbsoluteFile();
File out = new File(args[2]).getAbsoluteFile();
out.getParentFile().mkdirs();
try(FileReader rdr = new FileReader(in); FileWriter wr = new FileWriter(out)) {
String input = read(rdr);
String output = args[0].equals("-d") ? decompress(input) : compress(input);
if(output.startsWith("<")) err(output);
wr.write(output);
} catch(IOException e) {
err("<Error: IO error '" + e.getLocalizedMessage() + "'>");
}
}
public static String compress(String s) { //Honestly, apostrophes should be allowed too. As should "What?!" and "AAAAAAAAaaaaaaaaaaaaa!!!"
final int LOWER = 1, UPPER = 2;
StringBuilder out = new StringBuilder();
int wordType = 0;
StringBuilder currentWord = new StringBuilder();
List<String> dict = new LinkedList();
for(int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if(ch >= 'a' && ch <= 'z') {
currentWord.append(ch);
wordType |= LOWER;
} else if(ch >= 'A' && ch <= 'Z') {
currentWord.append(ch);
wordType |= UPPER;
if((wordType & LOWER) != 0) return "<Error: invalid capitalization>";
} else if("- .,?!;:\n".indexOf(ch) != -1) {
if(wordType != 0) {
String word = currentWord.toString().toLowerCase();
int index = dict.indexOf(word);
if(index == -1) {
index = dict.size();
dict.add(word);
}
out.append(index);
}
if(wordType == UPPER) out.append('!');
if(wordType == (UPPER | LOWER)) out.append('^');
if(ch == ' ' || ch == '-' || ch == '\n') currentWord.setLength(0);
else if(wordType == 0) return "<error: multiple punctuation in a row>";
if(ch != '-') out.append(' ');
if(ch == '\n') out.append("R");
if(ch != ' ') out.append(ch);
wordType = 0;
} else return "<error: invalid character " + ch + ">";
}
out.append(" E");
StringBuilder outDict = new StringBuilder();
outDict.append(dict.size()).append("\n");
for(String word:dict)
outDict.append(word).append("\n");
return outDict.toString() + out.toString().replaceAll("[ ]*\n[ ]*", "\n").trim();
}
public static String decompress(String s) {
StringBuilder out = new StringBuilder();
int dictLen = -1;
List<String> dict = new LinkedList();
StringBuilder currentWord = new StringBuilder();
int currentNumber = -1;
char nextChar = 0;
for(int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if(dict.size() != dictLen) { //Fill dict
if('0' <= ch && ch <= '9') {
if(currentNumber == -1) currentNumber = 0;
currentNumber = currentNumber * 10 + ch - '0';
} else if(ch == '\n') {
if(currentNumber != -1) dictLen = currentNumber;
else dict.add(currentWord.toString());
currentWord.setLength(0);
currentNumber = -1;
} else currentWord.append(ch);
continue;
}
//Decompress
if('0' <= ch && ch <= '9') {
if(currentNumber == -1) currentNumber = 0;
currentNumber = currentNumber * 10 + ch - '0';
} else if(currentNumber != -1) {
if(nextChar != 0) out.append(nextChar);
if(ch == '!') out.append(dict.get(currentNumber).toUpperCase());
else if(ch == '^') out.append(toFirstUpper(dict.get(currentNumber)));
else out.append(dict.get(currentNumber));
currentNumber = -1;
nextChar = ' ';
} else if(ch == '-') nextChar = '-';
else if(".,?!;:".indexOf(ch) != -1) out.append(ch);
else if(ch == 'R') {
nextChar = 0;
out.append('\n');
} else if(ch == 'E') break;
else if(ch != ' ' && ch != '\n') return "<Error: unknown character>";
}
return out.toString();
}
// Misc helper functions
private static String read(Reader rdr) throws IOException {
StringBuilder sb = new StringBuilder();
int ch;
while((ch = rdr.read()) != -1)
sb.append((char)ch);
return sb.toString();
}
private static String toFirstUpper(String s) {
return s.substring(0, 1).toUpperCase() + s.substring(1);
}
private static void err(String string) {
System.err.println(string);
System.exit(1);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment