View difference between Paste ID: 7Sistcqv and
SHOW:
|
|
- or go back to the newest paste.
1 | - | |
1 | + | import java.io.BufferedOutputStream; |
2 | import java.io.FileDescriptor; | |
3 | import java.io.FileOutputStream; | |
4 | import java.io.PrintStream; | |
5 | import java.math.BigInteger; | |
6 | import java.util.Scanner; | |
7 | ||
8 | public class Main { | |
9 | ||
10 | /** | |
11 | * Brute Force method. | |
12 | * Keeps incrementing by one until a palindrome is found. | |
13 | * @param s | |
14 | * @return the next palindrome | |
15 | */ | |
16 | public static String bruteForce(String s){ | |
17 | BigInteger i = new BigInteger(s) ; | |
18 | while(true){ | |
19 | i = i.add(BigInteger.ONE); | |
20 | String result = i.toString(); | |
21 | if(isPalindrome(result)){ | |
22 | return result; | |
23 | } | |
24 | } | |
25 | } | |
26 | ||
27 | /** | |
28 | * Mirrors a string around the centre. | |
29 | * Example: abc -> aba and abcd -> abba | |
30 | * @param s | |
31 | * @return mirrored string | |
32 | */ | |
33 | public static String mirror(String s) { | |
34 | final char[] arr = s.toCharArray(); | |
35 | int midpoint = arr.length / 2; | |
36 | int i = arr.length % 2 == 0 ? midpoint : midpoint + 1; | |
37 | while (i < arr.length) { | |
38 | arr[i] = arr[midpoint - 1]; | |
39 | i++; | |
40 | midpoint--; | |
41 | } | |
42 | return new String(arr); | |
43 | } | |
44 | ||
45 | /** | |
46 | * Increments the middle digit. | |
47 | * Example: 12345 -> 12445 and 1234 -> 1334 | |
48 | * 9s get incremented to 0 and carried over. | |
49 | * Example: 12945 -> 13045 | |
50 | * @param s | |
51 | * @return incremented string | |
52 | */ | |
53 | public static String incrementFromMiddle(String s) { | |
54 | ||
55 | final char[] arr = s.toCharArray(); | |
56 | final int midpoint = arr.length / 2; | |
57 | int currPoint = arr.length % 2 == 0 ? midpoint - 1 : midpoint; | |
58 | boolean found = false; | |
59 | ||
60 | while (currPoint >= 0 && !found) { | |
61 | char c = arr[currPoint]; | |
62 | char inc; | |
63 | if (c == '9') { | |
64 | inc = '0'; | |
65 | } | |
66 | else { | |
67 | inc = (char) (c + 1); | |
68 | found = true; | |
69 | } | |
70 | arr[currPoint] = inc; | |
71 | if (!found) { | |
72 | currPoint--; | |
73 | } | |
74 | } | |
75 | ||
76 | if (!found) { | |
77 | // we have fallen off the start of the string | |
78 | // example 999 has become 009. Add a one on to give: 1009 | |
79 | final char[] newarr = new char[arr.length + 1]; | |
80 | newarr[0] = '1'; | |
81 | System.arraycopy(arr, 0, newarr, 1, arr.length); | |
82 | return new String(newarr); | |
83 | } | |
84 | else { | |
85 | return new String(arr); | |
86 | } | |
87 | } | |
88 | ||
89 | ||
90 | ||
91 | /** | |
92 | * Next Palindrome using the mirroring approach. | |
93 | * @param s | |
94 | * @return | |
95 | */ | |
96 | public static String getNextPalindrome(String s) { | |
97 | String mirrored = mirror(s); | |
98 | ||
99 | //the mirror might be smaller than original, so increment it and try again. | |
100 | if (compare(mirrored, s) <= 0) { | |
101 | mirrored = mirror(incrementFromMiddle(s)); | |
102 | } | |
103 | return mirrored; | |
104 | } | |
105 | ||
106 | /** | |
107 | * @param s | |
108 | * @return true if the specified string is a palindrome. | |
109 | */ | |
110 | private static boolean isPalindrome(String s) { | |
111 | //compare first and last chars, second and second-last and so on. | |
112 | for (int i = 0, j = s.length() - 1; i < j; i++, j--) { | |
113 | if (s.charAt(i) != s.charAt(j)) { | |
114 | return false; | |
115 | } | |
116 | } | |
117 | return true; | |
118 | } | |
119 | ||
120 | /** | |
121 | * Compares two numerical mirrored strings. | |
122 | * Assumes they have the same length. | |
123 | * Only compares the second half of the strings. | |
124 | * @param s | |
125 | * @param t | |
126 | * @return -1, 0 or 1 if s<t, s==t or s>t | |
127 | */ | |
128 | private static int compare(String s, String t){ | |
129 | //only check second half | |
130 | int midpoint = s.length() / 2; | |
131 | int i = s.length() % 2 == 0 ? midpoint : midpoint + 1; | |
132 | for (; i < s.length(); i++) { | |
133 | if(s.charAt(i) < t.charAt(i)){ | |
134 | return -1 ; | |
135 | } | |
136 | else if (s.charAt(i) > t.charAt(i)){ | |
137 | return 1; | |
138 | } | |
139 | } | |
140 | return 0; | |
141 | } | |
142 | ||
143 | /** | |
144 | * The main method. | |
145 | * | |
146 | * @param args | |
147 | */ | |
148 | public static void main(String[] args) { | |
149 | // fast output as there is no flush on \n | |
150 | final FileOutputStream fdout = new FileOutputStream(FileDescriptor.out); | |
151 | final BufferedOutputStream bos = new BufferedOutputStream(fdout, 1024); | |
152 | final PrintStream ps = new PrintStream(bos, false); | |
153 | System.setOut(ps); | |
154 | ||
155 | try { | |
156 | final Scanner scanner = new Scanner(System.in); | |
157 | scanner.next(); | |
158 | while (scanner.hasNext()) { | |
159 | final String s = scanner.next(); | |
160 | System.out.println(getNextPalindrome(s)); | |
161 | } | |
162 | } | |
163 | catch (Exception e) { | |
164 | e.printStackTrace(); | |
165 | } | |
166 | finally { | |
167 | ps.close(); | |
168 | } | |
169 | } | |
170 | } |