Skip to content

Commit 130ece9

Browse files
committed
a java solution
1 parent 1176818 commit 130ece9

File tree

3 files changed

+74
-2
lines changed

3 files changed

+74
-2
lines changed

mask.sh

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
#!/bin/sh
22

3-
# Call your program here instead of cat.
4-
cat
3+
java -cp solution/classes luhnybin.Filter
2.8 KB
Binary file not shown.

solution/src/luhnybin/Filter.java

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package luhnybin;
2+
3+
import java.io.IOException;
4+
import java.io.InputStream;
5+
import java.io.OutputStream;
6+
import java.util.ArrayList;
7+
import java.util.List;
8+
9+
public class Filter {
10+
11+
InputStream in;
12+
OutputStream out;
13+
List<Integer> buffer = new ArrayList<Integer>();
14+
List<Integer> digits = new ArrayList<Integer>();
15+
16+
public static void main(String[] args) throws IOException {
17+
new Filter(System.in, System.out).process();
18+
}
19+
20+
public Filter(InputStream in, OutputStream out) {
21+
this.in = in;
22+
this.out = out;
23+
}
24+
25+
public void process() throws IOException {
26+
for (int b; (b = in.read()) != -1;) {
27+
if (!isCreditCardSymbol(b)) {
28+
flush();
29+
out.write(b);
30+
continue;
31+
}
32+
buffer.add(b);
33+
if (isDigit(b)) digits.add(b);
34+
if (digits.size() < 14) continue;
35+
int count = findLongestTrailingCreditCardNumber();
36+
maskTrailingDigitsInBuffer(count);
37+
}
38+
flush();
39+
}
40+
41+
void flush() throws IOException {
42+
for (Integer b : buffer) out.write(b);
43+
buffer.clear();
44+
digits.clear();
45+
}
46+
47+
void maskTrailingDigitsInBuffer(int count) {
48+
for (int i = buffer.size() - 1; i >= 0 && count > 0; i--)
49+
if (isDigit(buffer.get(i))) {
50+
buffer.set(i, (int)'X');
51+
count--;
52+
}
53+
}
54+
55+
int findLongestTrailingCreditCardNumber() {
56+
int result = 0, sum = 0, limit = Math.min(digits.size(), 16);
57+
for (int i = 1; i <= limit; i++) {
58+
int digit = digits.get(digits.size() - i) - 48;
59+
if (i % 2 == 0) digit *= 2;
60+
sum += digit / 10 + digit % 10;
61+
if (i >= 14 && sum % 10 == 0) result = i;
62+
}
63+
return result;
64+
}
65+
66+
boolean isCreditCardSymbol(int b) {
67+
return isDigit(b) || b == 32 || b == 45;
68+
}
69+
70+
boolean isDigit(int b) {
71+
return b >= 48 && b <= 57;
72+
}
73+
}

0 commit comments

Comments
 (0)