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;  
 }  
 }  

lunes, 25 de abril de 2011

Grupos Lie

Esto es simetría:


Empecé por funciones especiales, y acabé en los grupos Lie. Un día normal viendo artículos de física y matemáticas en wikipedia jojo.

miércoles, 23 de marzo de 2011

Smith chart



Aparte de ser muy funcional para análisis de líneas de transmisión, se ve chido.

martes, 22 de marzo de 2011

netping.bat

Y bueno, para aquellos que pensaban que el bash scripting no existía en windows, los tendré que probar mal. Aunque es cierto que es medio raro, y no soporta casi nada, se pueden hacer scripts rápidamente, una vez se conoce la sintáxis.

Esta vez lo que hice fue un programa que recorre todas las dirs IP en un octeto y devuelve si se respondió el ping. Una manera muy rápida y simple de ver qué IP están ocupados en la subred. Bueno les dejo el script:

:: Author: Andrés Páez Martínez paezand@gmail.com

:: Uso - netping [octetos a recorrer] [dirección IP acortada]
:: octetos puede ser 1 o 2.
:: Dir. IP varía si es 1 octeto o dos.
:: Por ejemplo,
:: netping 1 192.168.0
:: netping 2 192.168
:: NOTA - Netping se tarda aprox. 0.3 segs. por dirección. Por lo tanto dos octetos se tarda como 5 horas


@echo off

::Detecta qué octeto fue de input %1 = primer input
IF "%1"=="1" echo One octet on && goto ONE
IF "%1"=="2" echo Two octets on && goto TWO

:ONE
:: Detecta si hubo input, pero no si hubo error en el input
IF "%2"=="" echo Three octets necessary && goto END
echo pinging net
::var es la variable como contador dentro del loop (e.g for(int var=255;var!=0;var--))
set var=255

:LOOP1
set "a=%2%."
set a=%a%%var%
:: EL comando core del script, hace ping, luego busca el string "ttl=" en lo que
:: devuelve ping. Si lo encuentra
:: entonces imprime la dir. ip seguida por "is up", sino lo mismo pero con down.
ping -w 500 -n 1 %a% | findstr "TTL=">NUL && echo %a% is up || echo %a% is down
set /a var=%var%-1
if not %var%==0 goto LOOP1
goto END

:: Lo mismo que one pero con un loop anidado
:TWO
IF "%2"=="" echo Two octets necessary && goto END
echo pinging net
set var=255
:LOOP2a
set var1=255
:LOOP2b
set "a=%2%."
set "a=%a%%var%.%var1%"
ping -w 500 -n 1 %a% | findstr "TTL=">NUL && echo %a% is up || echo %a% is down
set /a var1=%var1%-1
if not %var1%==0 goto LOOP2b
set /a var=%var%-1
if not %var%==0 goto LOOP2a


:END

PAUSE

sábado, 11 de diciembre de 2010

Superposición de ondas

Debido a un experimento de física que estaré realizando me vi en la penosa necesidad de hacer mi propio simulador de ondas...
Aquí se los dejo:Superpos ondas

jueves, 9 de diciembre de 2010

Mapa de Bernoulli

Recordando un poco de los números aleatorios en una computadora (gracias a una pregunta en fb de RAMIS) quise probar un Mapa de Bernoulli home made. Pongo el código en Java:

/* AUTHOR: Andrés Páez Martínez paezand@gmail.com*/
public static void main(String[] args) {
double random = Math.random();
double delta = 0.0000000000000001;
System.out.println("Init val: " + random + " delta " + delta);
double sieve1 = random;
double sieve2 = delta + random;
sieve2 %= 1;
Scanner in = new Scanner(System.in);
System.out.println("Da iteraciones");
int iter = in.nextInt();
while(iter>0){
System.out.println(sieve1 + " " + sieve2);
sieve1*=3;
sieve2*=3;
sieve1 %= 1;
sieve2 %= 1;
iter--;
}
}

Lo que quería ver es cuántas iteraciones era necesario para que la función tomara una característica aleatoria. Lo que hace el programa es tomar un número "random" proveído por el API de Java, declarar una delta de 10^(-16) (número MUY pequeño) sumárselo a nuestro random y meter ambos al mapa de bernoulli:
Random = 0.4617143798319837
Delta = 0.0000000000000001


Bueno, como ven, después de la iteración 30 aprox. la diferencia entre los números ya es del orden de 10^(-1). Básicamente la diferencia s1(i)-s2(i) para i>35, puede considerarse un número aleatorio:



Como se puede apreciar, antes de volverse caótica la gráfica, la función parece exponencial. Supongo que la tao (de e^(i/tao) está determinada por el multiplicando que en este caso es 3. Si variamos este valor las secuencias divergen más rápido. NOTA: Jajajja obviamente con valores par no funciona el mapa.
Y namás pa que no quede duda, va una gráfica con el multiplicando 97(premio al que me diga porqué 97 jajajjaja):

miércoles, 1 de diciembre de 2010

Signals in a Nutshell




Pues sí, efectivamente, casi todo un semestre de señales se reduce a una hoja de ecuaciones en Word. Quizás si el profesor hubiese empezado por enseñar esta hoja, todo hubiese salido mejor jajajajjaa.