Have anyone tried the problem 529? I tried but I'm confronted to a very high complexity $O(N^2)$ with $N$ being the length of the number. The code is:
public static boolean is10Friendly(long num) {
List<Integer> numbers = new ArrayList<>();
Map<String, Integer> friendly = new HashMap<>();
int fasterCountTo10 = 0;
boolean fastValid = false;
int count = 0;
while (num > 0) {
int cur = (int) (num % 10);
fasterCountTo10 += cur;
if (fasterCountTo10 == 10)
fastValid = true;
numbers.add(cur);
friendly.put(String.valueOf(cur) + "_" + String.valueOf(count++), 0);
num /= 10;
}
//Cheap check to discard many elements. Gain is speed +30%.
if (!fastValid) {
return false;
}
for (int i = 0; i < numbers.size(); i++) {
int counter = 0;
for (int j = i; j < numbers.size(); j++) {
counter += numbers.get(j);
if (counter == 10) {
for (int jj = i; jj <= j; jj++) {
String key = String.valueOf(numbers.get(jj)) + "_" + String.valueOf(jj);
Integer val = friendly.get(key);
friendly.put(key, ++val);
}
break;
}
if (counter > 10) {
break;
}
}
}
// It must be greater than its frequency
for (Integer val : friendly.values()) {
if (val < 1) {
return false;
}
}
return true;
}
public static void main(String[] args) {
long n1 = System.currentTimeMillis();
for (int p = 2; p <= 10; p++) {
long count = 0;
for (long i = 1; i < (long) Math.pow(10, p); i++) {
if (is10Friendly(i)) {
count++;
}
}
System.out.println(count + " elapsed time: " + (System.currentTimeMillis() - n1));
// System.out.println(p + ", count = " + count);
}
//System.out.println(is10Friendly(1991)); //false
// System.out.println(is10Friendly(3523014)); //true
// System.out.println(is10Friendly(28546)); //false
}
Console Output
9 elapsed time: 3
72 elapsed time: 17
507 elapsed time: 48
3492 elapsed time: 263
23697 elapsed time: 1124
My results seem relevant according to the guidelines. Does anyone know what kind of mathematical model we could use to lower this complexity?
Many thanks in advance!
511 tilesmeans here? – lucemia Dec 27 '15 at 04:30