fork download
  1. import java.util.ArrayList;
  2. import java.util.Collections;
  3. import java.util.List;
  4.  
  5. public class Main {
  6.  
  7. public static void main(String[] args) {
  8. Main app = new Main();
  9. app.run();
  10. }
  11.  
  12. private void run() {
  13. System.out.println(compress("tttaaabbbcedg"));
  14. System.out.println(decompress("t2a12bce"));
  15.  
  16. BigInt left = new BigInt("-701");
  17. BigInt right = new BigInt("-29");
  18. System.out.println(minus(left, right));
  19. }
  20.  
  21. private class CharacterCount {
  22. private char character;
  23. private int count;
  24.  
  25. CharacterCount(char character) {
  26. this(character, 1);
  27. }
  28.  
  29. CharacterCount(char character, int count) {
  30. this.character = character;
  31. this.count = count;
  32. }
  33.  
  34. void increment() {
  35. this.count++;
  36. }
  37.  
  38. void setCount(int count) {
  39. this.count = count;
  40. }
  41.  
  42. int getCount() {
  43. return count;
  44. }
  45.  
  46. char getCharacter() {
  47. return character;
  48. }
  49.  
  50. @Override
  51. public String toString() {
  52. return "" + character + (count < 2 ? "" : count);
  53. }
  54.  
  55. String toRawString() {
  56. return String.join("", Collections.nCopies(this.count, "" + this.character));
  57. }
  58. }
  59.  
  60. private String compress(String plainText) {
  61. List<CharacterCount> characters = new ArrayList<>();
  62. CharacterCount currentCharacter = new CharacterCount(plainText.charAt(0));
  63.  
  64. int plainTextLength = plainText.length();
  65.  
  66. for (int i = 1; i < plainTextLength; i++) {
  67. final char character = plainText.charAt(i);
  68.  
  69. if (character == currentCharacter.getCharacter()) {
  70. currentCharacter.increment();
  71. continue;
  72. }
  73.  
  74. characters.add(currentCharacter);
  75. currentCharacter = new CharacterCount(character);
  76. }
  77.  
  78. characters.add(currentCharacter);
  79.  
  80. return characters.stream().reduce("", (acc, c) -> acc + c, (l, r) -> l + r);
  81. }
  82.  
  83. private String decompress(String encryptText) {
  84. List<CharacterCount> characters = new ArrayList<>();
  85. CharacterCount currentCharacter = new CharacterCount(encryptText.charAt(0));
  86. boolean isDigit = true;
  87.  
  88. int encryptTextLength = encryptText.length();
  89.  
  90. for (int i = 1; i < encryptTextLength; i++) {
  91. final char character = encryptText.charAt(i);
  92.  
  93. if (Character.isDigit(character)) {
  94. final int count = Character.getNumericValue(character);
  95.  
  96. if (isDigit) {
  97. currentCharacter.setCount(count);
  98. isDigit = false;
  99. continue;
  100. }
  101.  
  102. currentCharacter.setCount(currentCharacter.getCount() * 10 + count);
  103. continue;
  104. }
  105.  
  106. characters.add(currentCharacter);
  107. currentCharacter = new CharacterCount(character);
  108. isDigit = true;
  109. }
  110.  
  111. characters.add(currentCharacter);
  112.  
  113. return characters.stream().reduce("", (acc, c) -> acc + c.toRawString(), (l, r) -> l + r);
  114. }
  115.  
  116. private class BigInt {
  117. private String number;
  118. private int sign; // 0: positive, 1: negative
  119.  
  120. BigInt(String number) {
  121. final char signCharacter = number.charAt(0);
  122. if (signCharacter == '+') {
  123. this.number = number.substring(1);
  124. this.sign = 0;
  125. } else if (signCharacter == '-') {
  126. this.number = number.substring(1);
  127. this.sign = 1;
  128. } else {
  129. this.number = number;
  130. this.sign = 0;
  131. }
  132.  
  133. this.number = new StringBuilder(this.number).reverse().toString();
  134. }
  135.  
  136. private BigInt(String number, int sign) {
  137. this.number = number;
  138. this.sign = sign;
  139. }
  140.  
  141. String getNumber() {
  142. return new StringBuilder(number).reverse().toString();
  143. }
  144.  
  145. void setNumber(String number) {
  146. this.number = new StringBuilder(number).reverse().toString();
  147. }
  148.  
  149. int getSign() {
  150. return sign;
  151. }
  152.  
  153. void setSign(int sign) {
  154. this.sign = sign;
  155. }
  156.  
  157. @Override
  158. public String toString() {
  159. return (sign == 0 ? "" : "-") + getNumber();
  160. }
  161.  
  162. BigInt minus(BigInt right) {
  163. final int leftSign = this.sign;
  164. final int rightSign = right.sign;
  165.  
  166. if (leftSign == rightSign && this.number.equals(right.number)) {
  167. return new BigInt("0");
  168. }
  169.  
  170. if (leftSign == 1 && rightSign == 1) {
  171. final BigInt positiveLeft = new BigInt(this.number, 0);
  172. final BigInt positiveRight = new BigInt(right.number, 0);
  173. return positiveRight.minus(positiveLeft);
  174. }
  175.  
  176. if (leftSign == 0 && rightSign == 1) {
  177. return new BigInt(this.addTwoPositive(right.number), 0);
  178. } else if (leftSign == 1 && rightSign == 0) {
  179. return new BigInt(this.addTwoPositive(right.number), 1);
  180. }
  181.  
  182. // Case: Positive Left and Positive Right
  183. if (this.number.length() < right.number.length()) {
  184. return new BigInt(right.minusTwoPositive(this.number), 1);
  185. } else if (this.number.length() > right.number.length()) {
  186. return new BigInt(this.minusTwoPositive(right.number), 0);
  187. }
  188.  
  189. int comparableResult = this.compareReverseNumber(right.number);
  190. if (comparableResult == -1) {
  191. return new BigInt(right.minusTwoPositive(this.number), 1);
  192. }
  193.  
  194. if (comparableResult == 1) {
  195. return new BigInt(this.minusTwoPositive(right.number), 0);
  196. }
  197.  
  198. return null;
  199. }
  200.  
  201. private String addTwoPositive(String right) {
  202. String left = this.number;
  203.  
  204. final int leftLength = left.length();
  205. final int rightLength = right.length();
  206. final int length = Math.max(leftLength, rightLength);
  207.  
  208. if (leftLength < rightLength) {
  209. left = new StringBuilder(left).append(String.join(
  210. "", Collections.nCopies(rightLength - leftLength, "0")
  211. )).toString();
  212. }
  213.  
  214. if (leftLength > rightLength) {
  215. right = new StringBuilder(right).append(String.join(
  216. "", Collections.nCopies(leftLength - rightLength, "0")
  217. )).toString();
  218. }
  219.  
  220. StringBuilder builder = new StringBuilder();
  221. int remainder = 0;
  222.  
  223. for (int i = 0; i < length; i++) {
  224. int leftDigit = Character.getNumericValue(left.charAt(i));
  225. int rightDigit = Character.getNumericValue(right.charAt(i));
  226.  
  227. Digit digit = add(leftDigit, rightDigit, remainder);
  228. builder.append(digit.getDigit());
  229. remainder = digit.getRemainder();
  230. }
  231.  
  232. if (remainder > 0) {
  233. builder.append(remainder);
  234. }
  235.  
  236. return builder.toString();
  237. }
  238.  
  239. private String minusTwoPositive(String right) {
  240. String left = this.number;
  241.  
  242. final int length = left.length();
  243.  
  244. if (length > right.length()) {
  245. right = new StringBuilder(right).append(String.join(
  246. "", Collections.nCopies(length - right.length(), "0")
  247. )).toString();
  248. }
  249.  
  250. StringBuilder builder = new StringBuilder();
  251. int remainder = 0;
  252.  
  253. for (int i = 0; i < length; i++) {
  254. int leftDigit = Character.getNumericValue(left.charAt(i));
  255. int rightDigit = Character.getNumericValue(right.charAt(i));
  256.  
  257. Digit digit = minus(leftDigit, rightDigit, remainder);
  258. builder.append(digit.getDigit());
  259. remainder = digit.getRemainder();
  260. }
  261.  
  262. return builder.toString();
  263. }
  264.  
  265. private Digit add(int left, int right, int remainder) {
  266. int result = left + right + remainder;
  267. if (result > 10) {
  268. return new Digit(result - 10, 1);
  269. }
  270. return new Digit(result, 0);
  271. }
  272.  
  273. private Digit minus(int left, int right, int remainder) {
  274. right += remainder;
  275. if (left < right) {
  276. return new Digit(left + 10 - right, 1);
  277. }
  278. return new Digit(left - right, 0);
  279. }
  280.  
  281. private int compareReverseNumber(String right) {
  282. int length = this.number.length();
  283. for (int i = length - 1; i >= 0; i--) {
  284. char leftChar = this.number.charAt(i);
  285. char rightChar = right.charAt(i);
  286.  
  287. if (leftChar < rightChar) {
  288. return -1;
  289. } else if (leftChar > rightChar) {
  290. return 1;
  291. }
  292. }
  293.  
  294. return 0;
  295. }
  296. }
  297.  
  298. private class Digit {
  299. private int digit;
  300. private int remainder;
  301.  
  302. Digit(int digit, int remainder) {
  303. this.digit = digit;
  304. this.remainder = remainder;
  305. }
  306.  
  307. int getDigit() {
  308. return digit;
  309. }
  310.  
  311. void setDigit(int digit) {
  312. this.digit = digit;
  313. }
  314.  
  315. int getRemainder() {
  316. return remainder;
  317. }
  318.  
  319. void setRemainder(int remainder) {
  320. this.remainder = remainder;
  321. }
  322. }
  323.  
  324. private BigInt minus(BigInt left, BigInt right) {
  325. return left.minus(right);
  326. }
  327. }
Success #stdin #stdout 0.22s 33692KB
stdin
Standard input is empty
stdout
t3a3b3cedg
ttaaaaaaaaaaaabce
-672