Libraryless. Click here for Pure Java version (1855L/12K/41K).
1 | !747 |
2 | |
3 | m { |
4 | static class Ref { |
5 | int line, chars; |
6 | |
7 | *() {} |
8 | *(int *line, int *chars) {} |
9 | } |
10 | |
11 | static class Line { |
12 | Ref left; // take chars from beginning of existing line |
13 | S middle; |
14 | Ref right;// take chars from end of existing line |
15 | |
16 | S text() { |
17 | ret leftToString(left) + middle + rightToString(right); |
18 | } |
19 | |
20 | int getCompression() { |
21 | int l = length(); |
22 | ret l == 0 ? 100 : (int) (100-l(middle)*100L/l); |
23 | } |
24 | |
25 | int length() { |
26 | ret refLen(left) + l(middle) + refLen(right); |
27 | } |
28 | |
29 | int originalLine(int myIdx) { |
30 | ret left != null && left.chars == length() ? left.line : myIdx; |
31 | } |
32 | } |
33 | |
34 | static new L<Line> lines; |
35 | |
36 | p { |
37 | readLocally("lines"); |
38 | makeAndroid3("Input Storer Bot."); |
39 | print("Lines: " + l(lines) + ". Unpacked size: " + toK(totalSize()) + "K. Compression: " + totalCompression() + "%"); |
40 | } |
41 | |
42 | static synchronized S answer(S s) { |
43 | new Matches m; |
44 | |
45 | if (match3("add *", s, m)) { |
46 | S line = m.unq(0); |
47 | add(line); |
48 | int compression = last(lines).getCompression(); |
49 | ret "OK. Compression: " + compression + "%. Lines: " + l(lines); |
50 | } |
51 | |
52 | if (match3("get *", s, m)) { |
53 | int i = parseInt(m.unq(0)); |
54 | ret quote(lines.get(i).text()); |
55 | } |
56 | |
57 | if (match3("get total compression", s)) { |
58 | ret totalCompression() + "%"; |
59 | } |
60 | |
61 | ret standardQuery(s, "lines"); |
62 | } |
63 | |
64 | // index of line that the line is a copy of |
65 | static int originalLine(int i) { |
66 | ret lines.get(i).originalLine(i); |
67 | } |
68 | |
69 | static S leftToString(Ref ref) { |
70 | ret ref == null ? "" : lines.get(ref.line).text().substring(0, ref.chars); |
71 | } |
72 | |
73 | static S rightToString(Ref ref) { |
74 | ret ref == null ? "" : rsubstring(lines.get(ref.line).text(), ref.chars); |
75 | } |
76 | |
77 | static int refLen(Ref ref) { |
78 | ret ref == null ? 0 : ref.chars; |
79 | } |
80 | |
81 | static synchronized void add(S s) { |
82 | S _s = s; |
83 | new Line l; |
84 | l.left = findPrefix(s); |
85 | //print("left: " + structure(l.left)); |
86 | if (l.left != null) |
87 | s = s.substring(l.left.chars); |
88 | l.right = findSuffix(s); |
89 | //print("right: " + structure(l.left)); |
90 | if (l.right != null) |
91 | s = s.substring(0, s.length()-l.right.chars); |
92 | l.middle = s; |
93 | lines.add(l); |
94 | assertEquals(l.text(), _s); // sanity check! |
95 | saveLocally("lines"); |
96 | } |
97 | |
98 | // unoptimized |
99 | static Ref findPrefix(S s) { |
100 | if (s.isEmpty()) ret null; |
101 | Ref best = null; |
102 | for (int i = l(lines)-1; i >= 0; i--) { |
103 | Line l = lines.get(i); |
104 | int n = commonPrefix(l.text(), s).length(); |
105 | if (n > 0 && (best == null || n > best.chars)) { |
106 | best = new Ref(originalLine(i), n); |
107 | if (n == s.length()) ret best; // optimum, quit |
108 | } |
109 | } |
110 | ret best; |
111 | } |
112 | |
113 | // unoptimized |
114 | static Ref findSuffix(S s) { |
115 | if (s.isEmpty()) ret null; |
116 | Ref best = null; |
117 | for (int i = l(lines)-1; i >= 0; i--) { |
118 | Line l = lines.get(i); |
119 | int n = commonSuffix(l.text(), s).length(); |
120 | if (n > 0 && (best == null || n > best.chars)) { |
121 | best = new Ref(originalLine(i), n); |
122 | if (n == s.length()) ret best; // optimum, quit |
123 | } |
124 | } |
125 | ret best; |
126 | } |
127 | |
128 | static long totalSize() { |
129 | long len = 0; |
130 | for (Line l : lines) |
131 | len += l.length(); |
132 | ret len; |
133 | } |
134 | |
135 | static int totalCompression() { |
136 | long middle = 0, len = 0; |
137 | for (Line l : lines) { |
138 | middle += l(l.middle); |
139 | len += l.length(); |
140 | } |
141 | ret len == 0 ? 100 : (int) (100-middle*100/len); |
142 | } |
143 | } |
Good for storing changing input - compresses the data by detecting known prefixes and suffixes.
download show line numbers debug dex old transpilations
Travelled to 15 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, teubizvjbppd, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1001662 |
Snippet name: | Efficient Input Storer Bot (Compressing Data) |
Eternal ID of this version: | #1001662/1 |
Text MD5: | 6388113dd7f45eba21f63d2bbf62dce2 |
Transpilation MD5: | 146068b336cfb71082af930e688f989e |
Author: | stefan |
Category: | javax |
Type: | JavaX source code |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2015-11-02 18:06:18 |
Source code size: | 3623 bytes / 143 lines |
Pitched / IR pitched: | No / Yes |
Views / Downloads: | 687 / 790 |
Referenced in: | [show references] |