<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress/2.3.3" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>
<channel>
	<title>Comentarios en: Proyecto Euler - Problema 1</title>
	<link>http://www.vbracco.com.ar/archivo/2009/02/19/proyecto-euler-problema-1/</link>
	<description>Sitio personal de Victor Bracco [Desarrollador Web]</description>
	<pubDate>Thu, 29 Jul 2010 19:37:51 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.3.3</generator>
		<item>
		<title>Por: Tordek</title>
		<link>http://www.vbracco.com.ar/archivo/2009/02/19/proyecto-euler-problema-1/#comment-12524</link>
		<dc:creator>Tordek</dc:creator>
		<pubDate>Sat, 17 Oct 2009 21:11:50 +0000</pubDate>
		<guid>http://www.vbracco.com.ar/archivo/2009/02/19/proyecto-euler-problema-1/#comment-12524</guid>
		<description>WTF? ¿Por qué tengo sombrerito de Troll?</description>
		<content:encoded><![CDATA[<p>WTF? ¿Por qué tengo sombrerito de Troll?</p>
]]></content:encoded>
	</item>
	<item>
		<title>Por: Tordek</title>
		<link>http://www.vbracco.com.ar/archivo/2009/02/19/proyecto-euler-problema-1/#comment-9755</link>
		<dc:creator>Tordek</dc:creator>
		<pubDate>Fri, 20 Feb 2009 17:55:24 +0000</pubDate>
		<guid>http://www.vbracco.com.ar/archivo/2009/02/19/proyecto-euler-problema-1/#comment-9755</guid>
		<description>&lt;blockquote&gt;Tordek, a menos que mi lógica me este engañando, en el primer ciclo no entra en la posición [-1]. Esa asignación de i dentro del for se ejecuta cuando finaliza cada bucle, y para el final del bucle x ya tiene un valor 1 y entonces ingresa en la posición [0].&lt;/blockquote&gt;

Ah, buen detalle... Un punto a favor para escribir el bucle de mi forma, supongo ;).

El segundo problema, lo resolví anoche en O(N^2) mientras intentaba dormir:
Haciendo un bucle de 0 a N con un step de k, para cada numero k, sobre un array A, poniendo 1 en A[k]. A tiene que tener suficiente espacio para sostener "una vuelta entera". "Una vuelta entera" == MCM (conjunto de números). Ahora tenés un array booleano que te dice si los números pertenecen al conjunto (esta parte es la O(N^2), que domina la complejidad). Después, lo único que hay que hacer, es un bucle de 0 a N, calculando la diferencia entre cada par de unos.

El primero todavía está...</description>
		<content:encoded><![CDATA[<blockquote><p>Tordek, a menos que mi lógica me este engañando, en el primer ciclo no entra en la posición [-1]. Esa asignación de i dentro del for se ejecuta cuando finaliza cada bucle, y para el final del bucle x ya tiene un valor 1 y entonces ingresa en la posición [0].</p></blockquote>
<p>Ah, buen detalle&#8230; Un punto a favor para escribir el bucle de mi forma, supongo ;).</p>
<p>El segundo problema, lo resolví anoche en O(N^2) mientras intentaba dormir:<br />
Haciendo un bucle de 0 a N con un step de k, para cada numero k, sobre un array A, poniendo 1 en A[k]. A tiene que tener suficiente espacio para sostener &#8220;una vuelta entera&#8221;. &#8220;Una vuelta entera&#8221; == MCM (conjunto de números). Ahora tenés un array booleano que te dice si los números pertenecen al conjunto (esta parte es la O(N^2), que domina la complejidad). Después, lo único que hay que hacer, es un bucle de 0 a N, calculando la diferencia entre cada par de unos.</p>
<p>El primero todavía está&#8230;</p>
]]></content:encoded>
	</item>
	<item>
		<title>Por: Sabo</title>
		<link>http://www.vbracco.com.ar/archivo/2009/02/19/proyecto-euler-problema-1/#comment-9743</link>
		<dc:creator>Sabo</dc:creator>
		<pubDate>Fri, 20 Feb 2009 10:38:08 +0000</pubDate>
		<guid>http://www.vbracco.com.ar/archivo/2009/02/19/proyecto-euler-problema-1/#comment-9743</guid>
		<description>Tordek, a menos que mi lógica me este engañando, en el primer ciclo no entra en la posición [-1]. Esa asignación de i dentro del for se ejecuta cuando finaliza cada bucle, y para el final del bucle x ya tiene un valor 1 y entonces ingresa en la posición [0].

Y por cierto, ese último código me parece mucho más lindo, solo que que  demora más en resolverlo. Con números hasta 1.000.000.000 mi código esta demorando 3.5s y el tuyo 7.7s. Mas allá de eso, me parece buenisimo.

Pero poniendolo de esta forma, queda si más amigable que mi último código, y demora practicamente lo mismo
&lt;pre&gt;
    for(int i=0, x=0; i &lt; 1000; i += patron[x], x = (x==6)? 0 : x+1)
       result += i;
    printf("%d\n",result);
&lt;/pre&gt;

Los problemitas (creo) son bastante locos :D pero te escribo algunos posts si lo llegas a hacer.&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>Tordek, a menos que mi lógica me este engañando, en el primer ciclo no entra en la posición [-1]. Esa asignación de i dentro del for se ejecuta cuando finaliza cada bucle, y para el final del bucle x ya tiene un valor 1 y entonces ingresa en la posición [0].</p>
<p>Y por cierto, ese último código me parece mucho más lindo, solo que que  demora más en resolverlo. Con números hasta 1.000.000.000 mi código esta demorando 3.5s y el tuyo 7.7s. Mas allá de eso, me parece buenisimo.</p>
<p>Pero poniendolo de esta forma, queda si más amigable que mi último código, y demora practicamente lo mismo</p>
<pre>
    for(int i=0, x=0; i < 1000; i += patron[x], x = (x==6)? 0 : x+1)
       result += i;
    printf("%d\n",result);
</pre>
<p>Los problemitas (creo) son bastante locos <img src='http://www.vbracco.com.ar/wordpress/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> pero te escribo algunos posts si lo llegas a hacer.</pre>
]]></content:encoded>
	</item>
	<item>
		<title>Por: Tordek</title>
		<link>http://www.vbracco.com.ar/archivo/2009/02/19/proyecto-euler-problema-1/#comment-9741</link>
		<dc:creator>Tordek</dc:creator>
		<pubDate>Fri, 20 Feb 2009 06:05:45 +0000</pubDate>
		<guid>http://www.vbracco.com.ar/archivo/2009/02/19/proyecto-euler-problema-1/#comment-9741</guid>
		<description>Ahora, dos problemas interesantes (creo) relacionados a ambas soluciones:

1) Dada una lista de números A, generar una lista Restas, tal que sum(flatten(map(hallar_divisores, A))) - sum(flatten(map(hallar_divisores, Restas))) sea la suma de todos los múltiplos de A entre 1 y 1000 (asumiendo que hallar_divisores encuentra los números divisibles por k entre 1 y 1000).

2) Dada una lista de números A, generar una lista que haga la función de tu array patron.</description>
		<content:encoded><![CDATA[<p>Ahora, dos problemas interesantes (creo) relacionados a ambas soluciones:</p>
<p>1) Dada una lista de números A, generar una lista Restas, tal que sum(flatten(map(hallar_divisores, A))) - sum(flatten(map(hallar_divisores, Restas))) sea la suma de todos los múltiplos de A entre 1 y 1000 (asumiendo que hallar_divisores encuentra los números divisibles por k entre 1 y 1000).</p>
<p>2) Dada una lista de números A, generar una lista que haga la función de tu array patron.</p>
]]></content:encoded>
	</item>
	<item>
		<title>Por: Tordek</title>
		<link>http://www.vbracco.com.ar/archivo/2009/02/19/proyecto-euler-problema-1/#comment-9737</link>
		<dc:creator>Tordek</dc:creator>
		<pubDate>Fri, 20 Feb 2009 02:15:28 +0000</pubDate>
		<guid>http://www.vbracco.com.ar/archivo/2009/02/19/proyecto-euler-problema-1/#comment-9737</guid>
		<description>De paso, en tu solución:
&lt;code&gt;for(int i=0; i &#60; 1000; i+=patron[x-1] ){&lt;/code&gt;

Me sorprende que siquiera funcione, dado que en el primer paso estás accediendo a patron[-1].

Una vez eliminado el -1 de ahí, podemos evitar el que el índice empiece en 1:
&lt;code&gt;x = (x==7) ? 1 : x+1;&lt;/code&gt;
por
&lt;code&gt; x = (x+1)%7&lt;/code&gt;

Y, dado que x sólo actua sobre el índice, y no el resultado, me parece más apropiado que sea parte del bucle:

&lt;code&gt;
main()
{
    int patron[7] = {3,2,1,3,1,2,3};
    int result=0;

    for(int i=0, x=0; i &#60; 1000; i += patron[x], x = (x+1)%7)
        result += i;

    printf("%d",result);
}
&lt;/code&gt;</description>
		<content:encoded><![CDATA[<p>De paso, en tu solución:<br />
<code>for(int i=0; i &lt; 1000; i+=patron[x-1] ){</code></p>
<p>Me sorprende que siquiera funcione, dado que en el primer paso estás accediendo a patron[-1].</p>
<p>Una vez eliminado el -1 de ahí, podemos evitar el que el índice empiece en 1:<br />
<code>x = (x==7) ? 1 : x+1;</code><br />
por<br />
<code> x = (x+1)%7</code></p>
<p>Y, dado que x sólo actua sobre el índice, y no el resultado, me parece más apropiado que sea parte del bucle:</p>
<p><code><br />
main()<br />
{<br />
    int patron[7] = {3,2,1,3,1,2,3};<br />
    int result=0;</p>
<p>    for(int i=0, x=0; i &lt; 1000; i += patron[x], x = (x+1)%7)<br />
        result += i;</p>
<p>    printf("%d",result);<br />
}<br />
</code></p>
]]></content:encoded>
	</item>
	<item>
		<title>Por: Sabo</title>
		<link>http://www.vbracco.com.ar/archivo/2009/02/19/proyecto-euler-problema-1/#comment-9734</link>
		<dc:creator>Sabo</dc:creator>
		<pubDate>Fri, 20 Feb 2009 01:29:49 +0000</pubDate>
		<guid>http://www.vbracco.com.ar/archivo/2009/02/19/proyecto-euler-problema-1/#comment-9734</guid>
		<description>Efectivamente Tordek, la solución usando progresiones aritmeticas es creo la mejor que resuelve este problema y creo que también es la que más abunda por internet.

Al marge, el problema es con los multiplos hasta 1000 y no hasta 100, pero ese código igual lo resulve en un tiempo cortisimo.

Mi solución simplemente es "no tan común" y que reduce considerablemente el tiempos y los calculos sobre el primer código.

Gracias por participar y espero que comentes los problemas que siguen tambien!</description>
		<content:encoded><![CDATA[<p>Efectivamente Tordek, la solución usando progresiones aritmeticas es creo la mejor que resuelve este problema y creo que también es la que más abunda por internet.</p>
<p>Al marge, el problema es con los multiplos hasta 1000 y no hasta 100, pero ese código igual lo resulve en un tiempo cortisimo.</p>
<p>Mi solución simplemente es &#8220;no tan común&#8221; y que reduce considerablemente el tiempos y los calculos sobre el primer código.</p>
<p>Gracias por participar y espero que comentes los problemas que siguen tambien!</p>
]]></content:encoded>
	</item>
	<item>
		<title>Por: Tordek</title>
		<link>http://www.vbracco.com.ar/archivo/2009/02/19/proyecto-euler-problema-1/#comment-9733</link>
		<dc:creator>Tordek</dc:creator>
		<pubDate>Fri, 20 Feb 2009 00:21:49 +0000</pubDate>
		<guid>http://www.vbracco.com.ar/archivo/2009/02/19/proyecto-euler-problema-1/#comment-9733</guid>
		<description>Hay una forma O(1):

Entre 1 y N hay floor(N/k) numeros divisibles por K.

Vos querés la suma de esos números, para K=3 y K=5. Pero si simplemente sumaras los divisores correspondientes, sumarías los múltiplos de 3*5 dos veces. Entonces, querés:
suma_de_divisores(3)+suma_de_divisores(5)+suma_de_divisores(15).

Sabiendo la cantidad de divisores, podemos hacer:
for i in range(1, cantidad + 1): suma += i*3

Pero eso nos da dos pistas. La primera, es que podemos pasar el producto hacia afuera:
for i in range(1, cantidad + 1): suma+=i
suma*=3

La segunda, es que estamos sumando todos los números de 1 a n. Y eso ya aprendimos que es igual a n * (n + 1)/2. Finalmente

def suma_de_divisores(num, div):
    cant = math.floor(num / div)
    suma = cant * (cant + 1)/2
    return suma * num

suma_de_divisores(100, 3)+suma_de_divisores(100, 5)-suma_de_divisores(100, 15)

2148</description>
		<content:encoded><![CDATA[<p>Hay una forma O(1):</p>
<p>Entre 1 y N hay floor(N/k) numeros divisibles por K.</p>
<p>Vos querés la suma de esos números, para K=3 y K=5. Pero si simplemente sumaras los divisores correspondientes, sumarías los múltiplos de 3*5 dos veces. Entonces, querés:<br />
suma_de_divisores(3)+suma_de_divisores(5)+suma_de_divisores(15).</p>
<p>Sabiendo la cantidad de divisores, podemos hacer:<br />
for i in range(1, cantidad + 1): suma += i*3</p>
<p>Pero eso nos da dos pistas. La primera, es que podemos pasar el producto hacia afuera:<br />
for i in range(1, cantidad + 1): suma+=i<br />
suma*=3</p>
<p>La segunda, es que estamos sumando todos los números de 1 a n. Y eso ya aprendimos que es igual a n * (n + 1)/2. Finalmente</p>
<p>def suma_de_divisores(num, div):<br />
    cant = math.floor(num / div)<br />
    suma = cant * (cant + 1)/2<br />
    return suma * num</p>
<p>suma_de_divisores(100, 3)+suma_de_divisores(100, 5)-suma_de_divisores(100, 15)</p>
<p>2148</p>
]]></content:encoded>
	</item>
</channel>
</rss>
