jueves, 28 de abril de 2011

Project Euler 61

Tengo que decir que me llevo un buen rato resolver éste. Al final mi solución tarda unos cuantos ms... Escribí mi propio método para permutar (lo cual SIEMPRE me había dado mucha flojera), y otros cuantos. Estuvo pesado pero lo saqué:

Triangle, square, pentagonal, hexagonal, heptagonal, and octagonal numbers are all figurate (polygonal) numbers and are generated by the following formulae:

Triangle P3,n=n(n+1)/2 1, 3, 6, 10, 15, ...
Square P4,n=n2 1, 4, 9, 16, 25, ...
Pentagonal P5,n=n(3n1)/2 1, 5, 12, 22, 35, ...
Hexagonal P6,n=n(2n1) 1, 6, 15, 28, 45, ...
Heptagonal P7,n=n(5n3)/2 1, 7, 18, 34, 55, ...
Octagonal P8,n=n(3n2) 1, 8, 21, 40, 65, ...
The ordered set of three 4-digit numbers: 8128, 2882, 8281, has three interesting properties.

The set is cyclic, in that the last two digits of each number is the first two digits of the next number (including the last number with the first).
Each polygonal type: triangle (P3,127=8128), square (P4,91=8281), and pentagonal (P5,44=2882), is represented by a different number in the set.
This is the only set of 4-digit numbers with this property.
Find the sum of the only ordered set of six cyclic 4-digit numbers for which each polygonal type: triangle, square, pentagonal, hexagonal, heptagonal, and octagonal, is represented by a different number in the set.

Approaches:

1.- Fuerza muy a lo bruta. Combinaciones de 2 en 1000 a 9999. Si tienen chance, seguir con tercer número etc. etc. Muy largo....
2.- Sacar la lista de todos los números poligonales, y hacer lo mismo que en el paso anterior: Funciona, aunque todavía se pueda mejorar mucho más, y con menos códgio:

 import java.util.ArrayList;  
 import java.util.Arrays;  
 import java.util.HashMap;  
 /**  
 *  
 * @author Andres  
 */  
 public class pe61{  
 public static void main(String[] args) throws InterruptedException{  
 HashMap tups = new HashMap();  
 double a = 0.5;  
 double b = 0.5;  
 for (int j = 0; j < 6; j++){  
 int i = 0;  
 int k = (int)(a*i*i+b*i);  
 while(k<1000 data-blogger-escaped-br=""> i++;  
 k = (int)(a*i*i+b*i);  
 }  
 while(k<10000 data-blogger-escaped-br=""> tups.put(k,j);  
 i++;  
 k = (int)(a*i*i+b*i);  
 }  
 a+=0.5;  
 b-=0.5;  
 System.out.println("size: " + tups.size());  
 }  
 System.out.println(isSCycle(new int[]{3066,6655}));  
 for (Integer integer : tups.keySet()) {  
 findCycle(new int[]{integer},tups);  
 System.out.println(integer);  
 }  
 }  
 public static void findCycle(int[] in, HashMap list){  
 for (Integer integer : list.keySet()) {  
 boolean ret = false;  
 for(int c = 0 ; c &lt; in.length;c++)  
 if(integer==in[c] || list.get(integer) == list.get(in[c]))  
 ret = true;  
 if(ret)  
 continue;  
 int[] arr = new int[in.length+1];  
 for (int j = 0; j &lt; in.length; j++)  
 arr[j]=in[j];  
 arr[arr.length-1]=integer;  
 if(arr.length==6 &amp;&amp; isCycle(arr)){  
 System.err.println(Arrays.toString(arr));  
 return;  
 } else if(arr.length==6){  
 //System.out.println(Arrays.toString(arr));  
 return;  
 }else if (isSCycle(arr)){  
 findCycle(arr,list);  
 }  
 }  
 }  
 public static long iFact(long x) {  
 for (long i = x - 1; i &gt; 1; i--) {  
 x = x * i;  
 }  
 return x;  
 }  
 public static boolean isSCycle(int[] arr){  
 String[] s = new String[arr.length];  
 for (int i = 0; i &lt; s.length; i++)  
 s[i]=arr[i]+"";  
 String[][] perms = new String[(int)iFact(arr.length)][arr.length];  
 permute(perms,0,s,0);  
 for (int i = 0; i &lt; perms.length; i++) {  
 boolean check = true;  
 for (int j = 0; j &lt; perms[i].length-1; j++) {  
 if(!perms[i][j].substring(2, 4).equals(perms[i][j+1].substring(0, 2)))  
 check= false;  
 }  
 if(check)  
 return true;  
 }  
 return false;  
 }  
 public static boolean isCycle(int[] arr){  
 String[] s = new String[arr.length];  
 for (int i = 0; i &lt; s.length; i++)  
 s[i]=arr[i]+"";  
 String[][] perms = new String[(int)iFact(arr.length)][arr.length];  
 permute(perms,0,s,0);  
 for (int i = 0; i &lt; perms.length; i++) {  
 boolean check = true;  
 for (int j = 0; j &lt; perms[i].length; j++) {  
 if(j == perms[i].length-1){  
 if(!perms[i][j].substring(2, 4).equals(perms[i][0].substring(0, 2)))  
 check= false;  
 continue;  
 }  
 if(!perms[i][j].substring(2, 4).equals(perms[i][j+1].substring(0, 2)))  
 check= false;  
 }  
 if(check)  
 return true;  
 }  
 return false;  
 }  
 public static int permute(String[][] perms, int pc, String[] original, int a){  
 if(a==original.length-2){  
 perms[pc++] = original.clone();  
 swap(original,original.length-1,original.length-2);  
 perms[pc++] = original.clone();  
 return pc;  
 }  
 ArrayList list = new ArrayList();  
 for(int c = a ; c &lt; original.length;c++)  
 list.add(original[c]);  
 while(!list.isEmpty()){  
 String t = list.remove(0);  
 if(!t.equals(original[a]))  
 swap(original,a,find(original,t));  
 pc=permute(perms,pc,original,a+1);  
 }  
 return pc;  
 }  
 public static int find(String[] t, String k){  
 for (int i = 0; i &lt; t.length; i++)  
 if(t[i].equals(k))  
 return i;  
 return -1;  
 }  
 public static void swap(T[] arr, int a, int b){  
 T t= arr[a];  
 arr[a] = arr[b];  
 arr[b] = t;  
 }  
 }  

No hay comentarios:

Publicar un comentario