Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Pienin yhteinen nimittäjä

16 views
Skip to first unread message

Juha.Lyytik...@kolumbus.fi

unread,
Nov 1, 2009, 1:38:32 PM11/1/09
to
Moi,

Millaisia algoritmej� on ratkaista suurien lukujen (alle 10 kpl) PYJ?


Risto Kauppila

unread,
Nov 2, 2009, 3:05:57 AM11/2/09
to
Juha.Lyytik...@kolumbus.fi kirjoitti:

> Moi,
>
> Millaisia algoritmej� on ratkaista suurien lukujen (alle 10 kpl) PYJ?
>
>

Palautuu suurimman yhteisen tekij�n (SYT) laskemiseen, sill�
PYJ(n_1,n_2,...,n_r) = |n_1*n_2*...*n_r|/SYT(n_1,n_2,...,n_r).
SYT voidaan laskea Eukleideen algoritmilla.
http://fi.wikipedia.org/wiki/Eukleideen_algoritmi

Ohman

unread,
Nov 3, 2009, 2:43:39 AM11/3/09
to
On 2 marras, 10:05, Risto Kauppila
<risto.kauppi...@NOSPAM.saunalahti.fi.invalid> wrote:
> Juha.Lyytikainen-sa...@kolumbus.fi kirjoitti:
>
> > Moi,
>
> > Millaisia algoritmejä on ratkaista suurien lukujen (alle 10 kpl) PYJ?
>
> Palautuu suurimman yhteisen tekijän (SYT) laskemiseen, sillä

> PYJ(n_1,n_2,...,n_r) = |n_1*n_2*...*n_r|/SYT(n_1,n_2,...,n_r).
> SYT voidaan laskea Eukleideen algoritmilla.http://fi.wikipedia.org/wiki/Eukleideen_algoritmi

Olkoot luvut 2,4,6.SYT(2,4,6) = 2 ja PYJ(2,4,6) = 12. 2 x 4 x 6 = 48,
mutta 48 / 2 = 24 eikä suinkaan 12..

Tuolla kaavan nimittäjänä ei saa olla lukujen n_1, n_2, ...,n_r SYT
vaan sen pitää olla lukujen

n_1,n_2,..n_(k-1),n_(k+1)...n_r SYT. Nämä luvut ovat siis
alkuperäisten lukujen tulot, joista aina yksi luku (n_k) vuorollaan
puuttuu, siis n_1 puuttuu, sitten n_2 j.n.e.

Äskeisessä esimerkissäni nämä luvut ovat 4x6=24, 2x6=12 ja 2x4=8.
Lukujen 24,12 ja 8 SYT on 4 ja PYJ(2,4,6) oli tuo 12 ja 12 =
(2x4x6) / 4 .

Ohman

Ohman

unread,
Nov 3, 2009, 2:48:25 AM11/3/09
to

Kirjoitusvirhe: kyseessä on siis lukujen n_1 x n_2 x...n_(k-1) x n(k
+1)...n_r (siis tuollaisten tulojen) SYT. Sanon kyllä tämän oikein
jatkossa

Ohman

Ohman

unread,
Nov 3, 2009, 12:11:18 PM11/3/09
to
On 1 marras, 20:38, "Juha.Lyytikainen-sa...@kolumbus.fi"
<Juha.Lyytikainen-sa...@kolumbus.fi> wrote:
> Moi,
>
> Millaisia algoritmejä on ratkaista suurien lukujen (alle 10 kpl) PYJ?

En kyllä tiedä,onko jotain " mukavaa" algoritmiä tähän tarkoitukseen,
tuo aiemmin esittämäni korjaus Kauppilan kirjoittamaan kaavaan antaa
lausekkeen,jota ei ole kovin helppo laskea,jos luvut ovat suuria.

Jos käytössä on ohjelma,joka jakaa lukuja alkutekijöihinsä, helpompi
voisi olla laskea vanhalla kunnon "koulukaavalla".Sehän menee näin:

Olkoot luvut n1,n2,...,nr

Jaetaan kukin luku ni alkutekijöihin.

Muodostetaan tulo, jossa jokainen näin saatu alkutekijä on mukana ja
esiintyy korkeimmassa potenssissa, missä se on jonkin luvun ni
alkulukuesityksessä. Tämä tulo on noiden lukujen PYJ.

Esimerkkejä:

Luvut ovat 2,4,6. 2=2, 4=2x2,6=2x3; PYJ = 2x2x3 = 12.

Luvut ovat 2,4,5,9,10,15.

2=2,4=2x2,5=5,9=3x3,10=2x5,15=3x5; PYJ = 2x2x3x3x5 = 180.

Luvut ovat 2,6,8,15.PYJ = 2x2x2x3x5 = 120.

Luvut ovat 5,6,16. PYJ = 2^4 x 3x5 = 16x15=240.

Varmaan tämän laskutavan tunsitkin ja etsit jotain vielä helpompaa
mutta liekö sellaista?

Ohman

Heikki Kaskelma

unread,
Nov 3, 2009, 3:55:37 PM11/3/09
to
Risto Kauppila:

> Palautuu suurimman yhteisen tekij�n (SYT) laskemiseen, sill�
> PYJ(n_1,n_2,...,n_r) = |n_1*n_2*...*n_r|/SYT(n_1,n_2,...,n_r).
> SYT voidaan laskea Eukleideen algoritmilla.
> http://fi.wikipedia.org/wiki/Eukleideen_algoritmi

PYJ(n_1, n_2, ..., n_r) = | n_1 * n_2 * ... * n_r | / SYT(n_1, n_2, ..., n_r)^(r - 1).

Ohman

unread,
Nov 4, 2009, 2:32:25 AM11/4/09
to
On 3 marras, 22:55, "Heikki Kaskelma" <heikki.kaske...@nbl.fi.invalid>
wrote:
> Risto Kauppila:
>
> > Palautuu suurimman yhteisen tekijän (SYT) laskemiseen, sillä

> > PYJ(n_1,n_2,...,n_r) = |n_1*n_2*...*n_r|/SYT(n_1,n_2,...,n_r).
> > SYT voidaan laskea Eukleideen algoritmilla.
> >http://fi.wikipedia.org/wiki/Eukleideen_algoritmi
>
> PYJ(n_1, n_2, ..., n_r) = | n_1 * n_2 * ... * n_r | / SYT(n_1, n_2, ..., n_r)^(r - 1).

Kukkua! Esim.5,6,16. 5x6x16 = 480. SYT(5,6,16) = 1. 1^(3-1) = 1.
Joten PYJ olisi 480. Mutta se on 240.

Ohman

Heikki Kaskelma

unread,
Nov 5, 2009, 5:36:34 PM11/5/09
to
"Ohman":
Heikki Kaskelma:

>> PYJ(n_1, n_2, ..., n_r) = | n_1 * n_2 * ... * n_r | / SYT(n_1, n_2, ...,
n_r)^(r - 1).

>Kukkua! Esim.5,6,16. 5x6x16 = 480. SYT(5,6,16) = 1. 1^(3-1) = 1.
>Joten PYJ olisi 480. Mutta se on 240.

Niinp�s onkin. Ajattelin huonosti - jos ollenkaan.

Risto Kauppila

unread,
Nov 6, 2009, 9:23:44 AM11/6/09
to
Ohman kirjoitti:>> Millaisia algoritmej� on ratkaista suurien lukujen (alle 10 kpl) PYJ?
>
> En kyll� tied�,onko jotain " mukavaa" algoritmi� t�h�n tarkoitukseen,
> tuo aiemmin esitt�m�ni korjaus Kauppilan kirjoittamaan kaavaan antaa

> lausekkeen,jota ei ole kovin helppo laskea,jos luvut ovat suuria.
>
> Jos k�yt�ss� on ohjelma,joka jakaa lukuja alkutekij�ihins�, helpompi
> voisi olla laskea vanhalla kunnon "koulukaavalla".Seh�n menee n�in:
>
> Olkoot luvut n1,n2,...,nr
>
> Jaetaan kukin luku ni alkutekij�ihin.
>
> Muodostetaan tulo, jossa jokainen n�in saatu alkutekij� on mukana ja
> esiintyy korkeimmassa potenssissa, miss� se on jonkin luvun ni
> alkulukuesityksess�. T�m� tulo on noiden lukujen PYJ.
>
> Esimerkkej�:

>
> Luvut ovat 2,4,6. 2=2, 4=2x2,6=2x3; PYJ = 2x2x3 = 12.
>
> Luvut ovat 2,4,5,9,10,15.
>
> 2=2,4=2x2,5=5,9=3x3,10=2x5,15=3x5; PYJ = 2x2x3x3x5 = 180.
>
> Luvut ovat 2,6,8,15.PYJ = 2x2x2x3x5 = 120.
>
> Luvut ovat 5,6,16. PYJ = 2^4 x 3x5 = 16x15=240.
>
> Varmaan t�m�n laskutavan tunsitkin ja etsit jotain viel� helpompaa
> mutta liek� sellaista?
>
> Ohman

Onkohan meill� eroa m��ritelmiss�. Minun PYJ on teoksessa Tom M
Apostol. An Introduction to Analytic Number Theory, Teht�v�ss� 1.21
m��ritelty.PyJ ei k�sitt��kseni ole lukuteoriassa kovin t�rke� k�site,
p�invastoin kuin syt.

Jussi Piitulainen

unread,
Nov 6, 2009, 11:56:59 AM11/6/09
to
Ohman writes:

> On 1 marras, 20:38, "Juha.Lyytikainen-sa...@kolumbus.fi"
> <Juha.Lyytikainen-sa...@kolumbus.fi> wrote:
> >
> > Millaisia algoritmejä on ratkaista suurien lukujen (alle 10 kpl)
> > PYJ?
>
> En kyllä tiedä,onko jotain " mukavaa" algoritmiä tähän
> tarkoitukseen, tuo aiemmin esittämäni korjaus Kauppilan
> kirjoittamaan kaavaan antaa lausekkeen,jota ei ole kovin helppo
> laskea,jos luvut ovat suuria.

On tämmöinen: annetun lukujonon pienimpiin lukuihin lisätään
toistuvasti vastaava alkuperäinen luku kunnes jonon alkiot ovat yhtä
suuret, jolloin jono on alkuperäisen jonon (pyj, pyj, ..., pyj).

Wikipediassa (Least Common Multiple) oli selitys ja linkki.

Tiedostossa pyj.py:

def pyj(x0):
xm = x0
while min(xm) < max(xm):
xm = [ xmk if xmk > min(xm) else xmk + x0k
for (x0k,xmk) in zip(x0,xm) ]
return xm

Python-sessiossa sitten import pyj ja testitapaukset alla.


> Esimerkkejä:
>
> Luvut ovat 2,4,6. 2=2, 4=2x2,6=2x3; PYJ = 2x2x3 = 12.

>>> pyj.pyj([2,4,6])
[2, 4, 6]
[4, 4, 6]
[6, 8, 6]
[8, 8, 12]
[10, 12, 12]
[12, 12, 12]

(Tässä vaiheessa silmukassa oli käsky tulostaa xm.)


> Luvut ovat 2,4,5,9,10,15.
>
> 2=2,4=2x2,5=5,9=3x3,10=2x5,15=3x5; PYJ = 2x2x3x3x5 = 180.

>>> pyj.pyj([2,4,5,9,10,15])
[2, 4, 5, 9, 10, 15]
[4, 4, 5, 9, 10, 15]
[6, 8, 5, 9, 10, 15]
[6, 8, 10, 9, 10, 15]
... liki sata askelta ...
[176, 176, 175, 180, 180, 180]
[176, 176, 180, 180, 180, 180]
[178, 180, 180, 180, 180, 180]
[180, 180, 180, 180, 180, 180]


> Luvut ovat 2,6,8,15.PYJ = 2x2x2x3x5 = 120.

>>> pyj.pyj([2,6,8,15])
[120, 120, 120, 120]

(Nyt sitä tulostuskäskyä ei enää ole.)


> Luvut ovat 5,6,16. PYJ = 2^4 x 3x5 = 16x15=240.

>>> pyj.pyj([5,6,16])
[240, 240, 240]


En sitten tiedä, kuinka tämä käyttäytyy, kun luvut ovat niin suuria,
että niiden jakaminen tekijöihin on vaikeaa.

Ohman

unread,
Nov 6, 2009, 12:31:09 PM11/6/09
to
On 6 marras, 16:23, Risto Kauppila

<risto.kauppi...@NOSPAM.saunalahti.fi.invalid> wrote:
> Ohman kirjoitti:
>
>
>
>
>
> > On 1 marras, 20:38, "Juha.Lyytikainen-sa...@kolumbus.fi"
> > <Juha.Lyytikainen-sa...@kolumbus.fi> wrote:
> >> Moi,
>
> >> Millaisia algoritmejä on ratkaista suurien lukujen (alle 10 kpl) PYJ?
>
> > En kyllä tiedä,onko jotain " mukavaa" algoritmiä tähän tarkoitukseen,
> > tuo aiemmin esittämäni korjaus Kauppilan kirjoittamaan  kaavaan antaa

> > lausekkeen,jota ei ole kovin helppo laskea,jos luvut ovat suuria.
>
> > Jos käytössä on ohjelma,joka jakaa lukuja alkutekijöihinsä, helpompi
> > voisi olla laskea vanhalla kunnon "koulukaavalla".Sehän menee näin:
>
> > Olkoot luvut  n1,n2,...,nr
>

> > Jaetaan kukin luku ni alkutekijöihin.
>
> > Muodostetaan tulo, jossa jokainen näin saatu alkutekijä on mukana ja
> > esiintyy korkeimmassa potenssissa, missä se on jonkin luvun ni
> > alkulukuesityksessä. Tämä tulo on noiden lukujen PYJ.
>
> > Esimerkkejä:

>
> > Luvut ovat 2,4,6. 2=2, 4=2x2,6=2x3; PYJ = 2x2x3 = 12.
>
> > Luvut ovat 2,4,5,9,10,15.
>
> > 2=2,4=2x2,5=5,9=3x3,10=2x5,15=3x5; PYJ = 2x2x3x3x5 = 180.
>
> > Luvut ovat 2,6,8,15.PYJ = 2x2x2x3x5 = 120.
>
> > Luvut ovat 5,6,16. PYJ = 2^4 x 3x5 = 16x15=240.
>
> > Varmaan tämän laskutavan tunsitkin ja etsit jotain vielä helpompaa
> > mutta liekö sellaista?
>
> > Ohman
>
> Onkohan meillä  eroa määritelmissä. Minun PYJ  on teoksessa  Tom  M
> Apostol. An Introduction to Analytic Number Theory, Tehtävässä 1.21
> määritelty.PyJ ei käsittääkseni ole lukuteoriassa kovin tärkeä käsite,
> päinvastoin kuin syt.- Piilota siteerattu teksti -
>
> - Näytä siteerattu teksti -

Ei tässä PYJ:ssä mitään epäselvyyttä ole.Lukujen a(i), 1<= i <=n PYJ
on pienin sellainen luku, joka on jaollinen jokaisella luvulla a(i).
Esitin kaksi oikeata tapaa laskea tämän. Ensimmäinen löytyy mistä
tahansa hyvästä algebran kirjasta,jos otetaan suomalainen, niin
F.Nevanlinna:Johdatus lukuteoriaan ja algebraan. Toinen opetetaan jo
esikoulussa. Näytin myös esimerkeillä, kuinka lasketaan.
Kai nyt huomasit,että kaavasi johti heti virheelliseen tulokseen. PYJ
(2,4,6) = 12 eikä 2*4*6 / 2 = 24.

Tämä riittää minun osaltani tästä asiasta.

Ohman

Risto Kauppila

unread,
Nov 7, 2009, 5:59:56 AM11/7/09
to
Jussi Piitulainen kirjoitti:

Turussa on tuota lukuteoriaa enemmän harrastettu, toivottavsti joku
heistä kommentoii tätä säiettä. Olet näköjään Python kavereita,
itse testaan matikkajuttuni Perlilä. Aika merkillistä olisi jos tuossa
Apostolin teoksessa olisi virhe.

Juha.Lyytik...@kolumbus.fi

unread,
Nov 7, 2009, 7:02:10 AM11/7/09
to
Jussi Piitulainen kirjoitti:

>
> On tämmöinen: annetun lukujonon pienimpiin lukuihin lisätään
> toistuvasti vastaava alkuperäinen luku kunnes jonon alkiot ovat yhtä
> suuret, jolloin jono on alkuperäisen jonon (pyj, pyj, ..., pyj).
>
> Wikipediassa (Least Common Multiple) oli selitys ja linkki.
>
> Tiedostossa pyj.py:
>
> def pyj(x0):
> xm = x0
> while min(xm) < max(xm):
> xm = [ xmk if xmk > min(xm) else xmk + x0k
> for (x0k,xmk) in zip(x0,xm) ]
> return xm
>

Tuohan on kätevää. Samalla selviää kerroin osoittajalle kun luvut halutaan laventaa samannimisiksi.

Pohdin tässä piin arvon laskemista käyttäen laskutoimituksissa pelkästään kokonaislukuja.

Ohman

unread,
Nov 7, 2009, 10:48:10 PM11/7/09
to
On 6 marras, 18:56, Jussi Piitulainen <jpiit...@ling.helsinki.fi>
wrote:

Vaikka lupasinkin jo olla puuttumatta enää tähän tehtävään, en näy
malttavan olla esittämättä vielä erästä huomiota.Olkoot luvut a(i),
1<= i <= r
Tuo esittämäsi tapa johtaa sellaisiin lukuihin n(1),....,n(r), että n
(1) a(1) = n(2) a(2) = ...=n(r) a(r)

Ohman

unread,
Nov 7, 2009, 11:24:52 PM11/7/09
to
> (1) a(1) = n(2) a(2) = ...=n(r) a(r)- Piilota siteerattu teksti -

>
> - Näytä siteerattu teksti -

Jatketaan,klikkasin vahingossa lähetä-kenttää ennen aikojaan!
Olkoon n(i)a(i) = D. on selvää, että D on jaollinen jokaisella luvulla
a(i).Se on ensimmäinen tällainen luku, joka menetelmällä
löytyy,laskenta pysäytetään siihen.

Minun esittämässäni 1. tavassa muodostetaan luvut

b(1) = a(2) a(3)...a(r)
b(2) = a(1) a(3)...a(r)
.
.
b(i) = a(1)a(2)...a(i-1)a(i+1)...a/r)
.
.
b(r) = a(1)....a(r-1)

Siis yksi luvuista a(i) vuorollaan puuttuu noista tuloista.Olkoon
kaikkien a(i)-lukujen tulo T. Tällöin a(1) b(1) = a(2) b(2) =...=a(r)
b(r) = T.

Jokainen luvuista a(i) tietenkin jakaa T:n ja T on siis niiden
yhteinen jaettava.Se ei kuitenkaan välttämättä ole pienin yhteinen
jaettava, sillä jos d = lukujen b(i) SYT ja merkitään
n(i) = b(i) / d,on n(1) a(1) = n(2) a(2)=...n(r) a(r) = D = T / d ja
jokainen a(i) jakaa luvun D.Tämä pätee tietenkin myös silloin kun d =
1.

Nämä luvut n(i) = b(i) / d ovat juuri ne samat n(i) - luvut,jotka
löytyvät tuolla sinun esittämälläsi algoritmillä.Ja D on tuo a(i)-
lukujen PYJ ja sama D joka löytyi esittämälläsi algoritmillä.

Niin että ihan samoista asioista näissä on kyse!

Ohman

Juha.Lyytik...@kolumbus.fi

unread,
Nov 8, 2009, 4:11:37 AM11/8/09
to
Juha.Lyytik...@kolumbus.fi kirjoitti:

> Jussi Piitulainen kirjoitti:
>>
>> On tämmöinen: annetun lukujonon pienimpiin lukuihin lisätään
>> toistuvasti vastaava alkuperäinen luku kunnes jonon alkiot ovat yhtä
>> suuret, jolloin jono on alkuperäisen jonon (pyj, pyj, ..., pyj).
>>
>> Wikipediassa (Least Common Multiple) oli selitys ja linkki.
>>
>> Tiedostossa pyj.py:
>>
>> def pyj(x0):
>> xm = x0
>> while min(xm) < max(xm):
>> xm = [ xmk if xmk > min(xm) else xmk + x0k
>> for (x0k,xmk) in zip(x0,xm) ]
>> return xm
>>
>
> Tuohan on kätevää. Samalla selviää kerroin osoittajalle kun luvut
> halutaan laventaa samannimisiksi.

Murtoluvussa osoittajat voivat olla samanlaisessa vektorissa ja niitä voi summata samassa loopissa kuin nimittäjiä. Jos siis tavoitteena on samalla nimittäjällä olevat murtoluvut.

Timo Korvola

unread,
Nov 8, 2009, 5:15:37 PM11/8/09
to
Jussi Piitulainen <jpii...@ling.helsinki.fi> writes:
> Wikipediassa (Least Common Multiple) oli selitys ja linkki.
>
> Tiedostossa pyj.py:
>
> def pyj(x0):
> xm = x0
> while min(xm) < max(xm):
> xm = [ xmk if xmk > min(xm) else xmk + x0k
> for (x0k,xmk) in zip(x0,xm) ]
> return xm

Voi isoilla luvuilla hieman kest��, koska tuo tekee jokaista i kohti
pyj(x0) / x0[i] yhteenlaskua.

Useamman luvun tapauksen voi palauttaa kahteen lukuun, sill�
pyj(x1, x2, ..., xn) = pyj(x1, pyj(x2, ..., xn)).
Kahden luvun tapauksen voi rouskuttaa Eukleideen algoritmilla:
pyj(x1, x2) = x1 x2 / syt(x1, x2).

--
Timo Korvola <URL:http://www.iki.fi/tkorvola>

Juha.Lyytik...@kolumbus.fi

unread,
Nov 9, 2009, 5:29:58 PM11/9/09
to
Timo Korvola kirjoitti:

> Jussi Piitulainen <jpii...@ling.helsinki.fi> writes:
>> Wikipediassa (Least Common Multiple) oli selitys ja linkki.
>>
>> Tiedostossa pyj.py:
>>
>> def pyj(x0):
>> xm = x0
>> while min(xm) < max(xm):
>> xm = [ xmk if xmk > min(xm) else xmk + x0k
>> for (x0k,xmk) in zip(x0,xm) ]
>> return xm
>
> Voi isoilla luvuilla hieman kest��, koska tuo tekee jokaista i kohti
> pyj(x0) / x0[i] yhteenlaskua.

Luulisi ett� bin��rimuotoinen yhteenlasku on koneelle nopea toimitus. Luuppi on koneelle vain yksi hyppyk�sky.
Suurien lukujen vertailun nopeudesta en tied�. P��asia ett� luvut s�ilyv�t yhdess� muuttujassa jota ei sijoitella uudelleen. Kokonaislukujen k�yt�ll� pyrit��n eroon jakolaskusta.

Jussi Piitulainen

unread,
Nov 10, 2009, 4:34:16 AM11/10/09
to
Juha.Lyytik...@kolumbus.fi writes:
> Timo Korvola kirjoitti:
> > Jussi Piitulainen <jpii...@ling.helsinki.fi> writes:
> >> Wikipediassa (Least Common Multiple) oli selitys ja linkki.
> >>
> >> Tiedostossa pyj.py:
> >>
> >> def pyj(x0):
> >> xm = x0
> >> while min(xm) < max(xm):
> >> xm = [ xmk if xmk > min(xm) else xmk + x0k
> >> for (x0k,xmk) in zip(x0,xm) ]
> >> return xm
> > Voi isoilla luvuilla hieman kestää, koska tuo tekee jokaista i

> > kohti pyj(x0) / x0[i] yhteenlaskua.
>
> Luulisi että binäärimuotoinen yhteenlasku on koneelle nopea
> toimitus. Luuppi on koneelle vain yksi hyppykäsky. Suurien lukujen
> vertailun nopeudesta en tiedä. Pääasia että luvut säilyvät yhdessä
> muuttujassa jota ei sijoitella uudelleen. Kokonaislukujen käytöllä
> pyritään eroon jakolaskusta.

Huomio on osuva: yhteenlaskujen lukumäärä kasvaa suhteessa lukujen
tuloon.

Jos haet pyj:tä neljälle nelinumeroiselle alkuluvulle - ei yhteisiä
tekijöitä - niin yhteenlaskujen määrän ilmoittaa 12-numeroinen luku,
tai sinne päin, kun pyj on 16-numeroinen.

Jos haet neljälle kahdeksannumeroiselle alkuluvulle, yhteenlaskujen
määrä on 24-numeroinen. Kahdeksalle nelinumeroiselle 28-numeroinen.

Kahdeksalle kahdeksannumeroiselle pyj on 64-numeroinen ja
yhteenlaskujen määrä 56-numeroinen. Siis luokkaa 10 potenssiin 56
yhteenlaskua, karkeasti.

Jos tehdään sekunnissa 10**12 yhteenlaskua, niin ensimmäinen tapaus
vie sen sekunnin, ja viimeinen vie 10**44 sekuntia. Vuodessa on kai
luokkaa 10**7 sekuntia. (** tässä potenssin merkkinä)

Pää on kyllä flunssasta pahasti sekaisin. Kirjoitin ylle ensin ihan
hölynpölyä ja sitten kokonaan uudelleen.

Jossain sanottiin, että syt:n laskenta-aika on suhteessa lukujen
numeroiden määrään. Silloin nelinumeroisista kahdeksannumeroisiin
siirtyminen vain kaksinkertaistaa laskenta-ajan, ei 100-kertaista tai
10000-kertaista. Näin ajatellen niitä mn/syt(m,n)-pohjaisia laskuja
kannattaa varmasti vielä tutkia. Siinähän on vain yksi jakolasku, ja
sekin menee aina tasan.

Jussi Piitulainen

unread,
Nov 12, 2009, 7:18:49 AM11/12/09
to
Timo Korvola writes:
> Jussi Piitulainen <jpii...@ling.helsinki.fi> writes:
> > Wikipediassa (Least Common Multiple) oli selitys ja linkki.
> >
> > Tiedostossa pyj.py:
> >
> > def pyj(x0):
> > xm = x0
> > while min(xm) < max(xm):
> > xm = [ xmk if xmk > min(xm) else xmk + x0k
> > for (x0k,xmk) in zip(x0,xm) ]
> > return xm
>
> Voi isoilla luvuilla hieman kestää, koska tuo tekee jokaista i kohti

> pyj(x0) / x0[i] yhteenlaskua.
>
> Useamman luvun tapauksen voi palauttaa kahteen lukuun, sillä

> pyj(x1, x2, ..., xn) = pyj(x1, pyj(x2, ..., xn)).
> Kahden luvun tapauksen voi rouskuttaa Eukleideen algoritmilla:
> pyj(x1, x2) = x1 x2 / syt(x1, x2).

Kirjoittelin tuossa pari versiota lisää ja kokeilin satunnaisilla
luvuilla. Näin niiden kävi:

xs = [1219, 1835, 1451]
pyj_rem(xs) = 3245691115 in 1.59740447998e-05 seconds
pyj_sub(xs) = 3245691115 in 4.98294830322e-05 seconds
pyj_add(xs) = 3245691115 in 15.2581701279 seconds

xs = [1239, 1244, 1399, 1224]
pyj_rem(xs) = 219942710568 in 5.79357147217e-05 seconds
pyj_sub(xs) = 219942710568 in 0.569249868393 seconds
pyj_add(xs) = 219942710568 in 2026.36223602 seconds

Selvästi paras on pyj_rem, joka käyttää Eukleideen algoritmin
jakojäännös-versiota, ja selvästi toiseksi paras on pyj_sub, joka
käyttää sitä vähennys-versiota, joka on kai alkuperäinen Eukleideen
algoritmi. Tuo Wikipediasta poimimani pyj_add räjähtää käsiin: neljän
pienen luvun pyj:n laskeminen vie siltä yli puoli tuntia, kun muut
laskevat sen sekunnin murto-osissa. Tulos on sentään oikea.

Kilpailuun osallistuneet Python-pätkät:

# pyj(pyj(x,y),z) = pyj(x,y) z / syt(pyj(x,y),z),
# Eukleideen algoritmissa jakojäännös

def pyj_rem(xs):
p = 1
for x in xs:
p *= x // syt_rem(p,x)
return p

def syt_rem(x,y):
while y > 0:
x, y = y, x % y
return x

# sama,
# Eukleideen algoritmissa vähennyslasku

def pyj_sub(xs):
p = 1
for x in xs:
p *= x // syt_sub(p,x)
return p

def syt_sub(x,y):
while y > 0:
if x > y:
x = x - y
else:
y = y - x
return x

# Wikipediasta,
# liian hidas

def pyj_add(x0):
xm = x0
minxm = min(xm)
while minxm < max(xm):
xm = [ xmk + x0k if xmk == minxm else xmk
for (x0k,xmk) in zip(x0,xm) ]
minxm = min(xm)
return xm[0]

Heikki Kaskelma

unread,
Nov 12, 2009, 6:23:03 PM11/12/09
to
Jussi Piitulainen:

> # liian hidas
>
> def pyj_add(x0):
> xm = x0
> minxm = min(xm)
> while minxm < max(xm):
> xm = [ xmk + x0k if xmk == minxm else xmk

Eikö tässä pitäisi olla xmk < max(xm) ?

Jussi Piitulainen

unread,
Nov 12, 2009, 9:39:23 PM11/12/09
to

Taidat olla oikeassa. Tehdyt lisäykset pysyvät kaikkiaan samoina,
mutta samalla kierroksella tedään useampia.

Laskenta-aika näyttää yleensä putoavan puoleen tai jopa kolmasosaan
entisestä. (Kymmenkunta koetta kolmella tai neljällä luvulla väliltä
100 - 200.)

def pyj_adx(x0):
xm = x0
maxxm = max(xm)
while min(xm) < maxxm:
xm = [ xmk + x0k if xmk < maxxm else xmk
for (x0k,xmk) in zip(x0,xm) ]
maxxm = max(xm)
return xm[0]

Heikki Kaskelma

unread,
Nov 13, 2009, 7:53:08 PM11/13/09
to
Jussi Piitulainen:

> def pyj_adx(x0):
> xm = x0
> maxxm = max(xm)
> while min(xm) < maxxm:
> xm = [ xmk + x0k if xmk < maxxm else xmk
> for (x0k,xmk) in zip(x0,xm) ]
> maxxm = max(xm)
> return xm[0]

Vähän lisää nopeutta saataneen vielä, jos lisätään
kerralla xm niin, että kaikki alkiot ovat vähintään
max(xm) (siis edellinen max(xm)):

xm = [xmk + ceil((maxxm-xmk)/x0k)*x0k for (x0k,xmk) in zip(x0,xm)].

Juha.Lyytik...@kolumbus.fi

unread,
Nov 14, 2009, 8:54:14 AM11/14/09
to
Heikki Kaskelma kirjoitti:

Alkuperäisessä ongelmassa (piin laskeminen) on kysymys tästä kaavasta

http://upload.wikimedia.org/math/a/1/e/a1e9cdd753103629a0dcea20304df9a0.png

siinä laskettavien lukujen nimittäjät ovat 8i+1, 8i+4, 8i+5 ja 8i+6 ja i juoksee kohti ääretöntä. Voisi kenties tehdä oletuksen millä luvulla nimittäjät vähintään pitää kertoa että PYJ saadaan kun tiedetään i?



Juha.Lyytik...@kolumbus.fi

unread,
Nov 14, 2009, 8:54:35 AM11/14/09
to
Heikki Kaskelma kirjoitti:

Alkuperäisessä ongelmassa (piin laskeminen) on kysymys tästä kaavasta

Timo Korvola

unread,
Nov 21, 2009, 4:50:02 AM11/21/09
to
"Juha.Lyytik...@kolumbus.fi"
<Juha.Lyytik...@kolumbus.fi> writes:
> Voisi kenties tehd� oletuksen mill� luvulla nimitt�j�t v�hint��n
> pit�� kertoa ett� PYJ saadaan kun tiedet��n i?

Tee symbolisesti. Esim. Maximalla:
(%i1) ratsimp(4/(8*i+1) - 2/(8*i+4) - 1/(8*i+5) - 1/(8*i+6));
2
120 i + 151 i + 47
(%o1) --------------------------------------
4 3 2
512 i + 1024 i + 712 i + 194 i + 15

Tuosta eteenp�in p�rj�� liukuluvuillakin, kun summaa termit lopusta
alkaen.

0 new messages