Pari simppeliä funktiota {pienellä palkalla}

Voit pyytää apua ohjelmointiongelmiin täältä.
Post Reply
DJ-Filbe
Devoted Member
Posts: 854
Joined: Sat Feb 20, 2010 2:18 pm

Pari simppeliä funktiota {pienellä palkalla}

Post by DJ-Filbe »

Olisi mukava saada kolme funktiota: loputtoman pituisten merkkijonomuotoisten lukujen vähennys-, kerto- ja jakolaskufunktio.

Perusidea selvinnee jo tekemästäni loputtomien lukujen yhteenlaskufunktiosta. Tekemääni funktiota tarvinnee myös muiden funktioiden toteutuksessa(?).

Ensimmäisen onnistuneen funktion tekijälle tarjoan (erittäin) pienen korvauksen:
vähennyslaskufunktiosta 1,5l :n Coca Cola -pullo :D
kertolaskufunktiosta 2-pack 1,5l :n Coca Cola -pulloa :D :D
ja jakolaskufunktiosta pizza.
EDIT:

Huomaa, että jakolaskufunktioon tarvitset myös vähennys- ja kertolaskufunktiota!

Palkanmaksu suoritetaan joko assyillä tai tilisiirtona, tiedä sitten kumpi on kannattavampaa ja kelle osapuolelle :?


Lussausfunktio:

Code: Select all

Function plus(luku1$,luku2$)
    vastaus$=""
    lisää=0
    length1=Len(luku1)
    length2=Len(luku2)
    If length1 < 10 And length2 < 10 Then
        l1=Int(luku1)
        l2=Int(luku2)
        vastaus$="" + (l1+l2)
    Else
        If length1 < length2 Then
            lukujenmäärä=length2
        Else
            lukujenmäärä=length1
        EndIf
        For i=1 To lukujenmäärä
            If Len(luku1$)-(i-1) > 0 Then 
                l1=Int(Mid(luku1$, Len(luku1$)-(i-1), 1))
            Else
                l1=0
            EndIf
            If Len(luku2$)-(i-1) > 0 Then 
                l2=Int(Mid(luku2$, Len(luku2$)-(i-1), 1))
            Else
                l2=0
            EndIf
            If lisää > 0 Then l1 = l1 +lisää : lisää=0 : o +1
            If l1+l2 > 9 Then
                lisää=RoundDown((l1+l2)/10)
                vastaus=""+(l1+l2-(lisää*10))+""+vastaus
            Else
                vastaus=""+(l1+l2)+""+vastaus
            EndIf
            o +1
            Text 0,0,""+vastaus
            DrawScreen
        Next i
        If lisää > 0 Then vastaus=""+lisää+""+vastaus
    EndIf
    Return vastaus$
EndFunction
EDIT:

Funktioiden toteutuskielenä siis CoolBasic tai C#. KAIKKI OSALLISTUVAT LÄHDEKOODIT TÄHÄN TOPICCIIN KAIKKIEN NÄHTÄVILLE!

Last edited by DJ-Filbe on Mon May 31, 2010 3:46 pm, edited 2 times in total.
KilledWhale
Tech Developer
Tech Developer
Posts: 545
Joined: Sun Aug 26, 2007 2:43 pm
Location: Liminka

Re: Pari simppeliä funktiota {pienellä palkalla}

Post by KilledWhale »

Koitan muistella kaivaa tuon oman isojen lukujen laskuun tarkotetun cb-koodin. Pitää vain vähän poistella siitä osia, että jää sinullekin jotain tekemistä ;)
Last edited by KilledWhale on Mon May 31, 2010 3:51 pm, edited 1 time in total.
CoolBasic henkilökuntaa
Kehittäjä

cbFUN Kello
cbSDL
Whale.dy.fi

<@cce> miltäs tuntuu olla suomen paras
Henkru
Advanced Member
Posts: 359
Joined: Sun Aug 26, 2007 2:46 pm

Re: Pari simppeliä funktiota {pienellä palkalla}

Post by Henkru »

Jos vaikka testaisit tehdä itse. Ei ole kovin vaikeaaa lähteä miettimään noita allekkainlaskuperjaatteella, millä ala-asteella laskettiin. Tämä ei ole optimaalisin tapa, mutta pääsee ainakin alkuun.
DJ-Filbe
Devoted Member
Posts: 854
Joined: Sat Feb 20, 2010 2:18 pm

Re: Pari simppeliä funktiota {pienellä palkalla}

Post by DJ-Filbe »

Kyllähän mä oon miettiny näitä juttuja. Jos saan jotain aikaiseksi, laitan funktioita tänne ellei joku ole ehtinyt ensin :)
KilledWhale
Tech Developer
Tech Developer
Posts: 545
Joined: Sun Aug 26, 2007 2:43 pm
Location: Liminka

Re: Pari simppeliä funktiota {pienellä palkalla}

Post by KilledWhale »

Tässä olisi oma isolukukikkareeni. Merkkijonojen sijaan se säilöö luvut hassusti kokonaislukuja käyttäen jolloin laskiessa tulee vähemmän sähläämistä lukujen kanssa. Etuna pitäisi olla lähinnä nopeus. Kerto- ja jakolaskufunktioita en ole jaksanut tehdä mutta katsoo nyt jos viitsisin.
Systeemi on pitkälti käännetty Programming Challenges -kirjasta löytyvästä esimerkkikoodista, mutta pientä viilausta olen joutunut tekemään koska CoolBasic.

Koodissa oleva esimerkki tulostelee 100 ensimmäistä lukua fibonaccin lukujonosta.

Code: Select all

// BIG, Tuki isoille luvuille CoolBasicissa
// Tehnyt: Jasse 'KilledWhale' Lahdenperä
// v. 0.3
//
// Init_BIG()				Luo uuden jättiluvun
// Copy_BIG(big)			Kopioi jättiluvun ja palauttaa luodun kopion
// Destroy_BIG(big) 		Poistaa jättiluvun muistista
// Set_BIG_INT(big, int)	Asettaa jättiluvun arvoksi kokonaisluvun
// Add_BIG_BIG(big, big)	Lisää jättilukuun jättiluvun ja palauttaa vastauksena uuden jättiluvun
// Sub_BIG_BIG(big, big)	Vähentää jättiluvun jättiluvusta ja palauttaa vastauksena uuden jättiluvun
// String_BIG(big)			Palauttaa jättiluvun merkkijonona
// Print_BIG(big)			Tulostaa jättiluvun ruudulle

// ASETUKSET
Const RESERVE = 1000		// Montako lohkoa varataan oletuksena ( yksi lohko = 9 merkkiä )

// Näihin ei tarvitse koskea
Const PLUS = 0
Const MINUS = 1

////////////////////////////////////////////
// ESIMERKKIKOODI
////////////////////////////////////////////

a = Init_BIG()
b = Init_BIG()

Set_BIG_INT(a, 0)
Print "1: " + String_BIG(a)
Set_BIG_INT(b, 1)
Print "2: " + String_BIG(b)
For i = 3 To 100
	c = Add_BIG_BIG(a, b)
	Print i + ": " + String_BIG(c)
	Destroy_BIG(a)
	a = b
	b = c
	Wait 250
Next i
WaitKey

////////////////////////////////////////////
// FUNKTIOT (ÄLÄ KOSKE KUN ET KUITENKAAN TIEDÄ MITÄ TEET)
////////////////////////////////////////////

Function Init_BIG()
	a = MakeMEMBlock(5 + RESERVE * 4)
	PokeInt a, 0, 0
	PokeByte a, 4, PLUS
	Return a
EndFunction

Function Copy_BIG(big As Integer)
	a = MakeMEMBlock(MEMBlockSize(big))
	MemCopy big, 0, a, 0, MEMBlockSize(big)
	Return a
EndFunction

Function Destroy_BIG(big As Integer)
	DeleteMEMBlock big
EndFunction

Function Set_BIG_INT(big As Integer, num As Integer)
	If num < 0
		neg = 1
		num = Abs(num)
	EndIf
	
	PokeInt big, 5, num Mod 1000000000
	If num >= 1000000000 Then
		PokeInt big, 9, RoundDown(num / 1000000000)
		PokeInt big, 0, 2
	Else
		PokeInt big, 0, 1
	EndIf

	PokeByte big, 4, neg
EndFunction

Function Add_BIG_BIG(big1 As Integer, big2 As Integer)
	asign = PeekByte(big1, 4)
	bsign = PeekByte(big2, 4)
	If asign = bsign Then
		csign = asign
	Else
		If asign = MINUS Then
			PokeByte big1, 4, PLUS
			big3 = Sub_BIG_BIG(big2, big1)
			PokeByte big1, 4, MINUS
		Else
			PokeByte big2, 4, PLUS
			big3 = Sub_BIG_BIG(big1, big2)
			PokeByte big2, 4, MINUS
		EndIf
		Return big3
	EndIf
	
	big3 = Init_BIG()
	size = Max(PeekInt(big1, 0), PeekInt(big2, 0))
	carry = 0
	
	i = 1
	While i <= size Or carry
		a = PeekInt(big1, 1 + i * 4)
		b = PeekInt(big2, 1 + i * 4)
		PokeInt big3, 1 + i * 4, (carry + a + b) Mod 1000000000
		carry = RoundDown((carry + a + b) / 1000000000)
		i = i + 1
	Wend

	PokeInt big3, 0, i - 1
	PokeByte big3, 4, csign
	
	Return big3
EndFunction

Function Sub_BIG_BIG(big1 As Integer, big2 As Integer)
	asign = PeekByte(big1, 4)
	bsign = PeekByte(big2, 4)
	
	If asign = MINUS Or bsign = MINUS Then
		PokeByte big2, 4, (bsign = PLUS) * MINUS + (bsign = MINUS) * PLUS
		big3 = Add_BIG_BIG(big1, big2)
		PokeByte big2, 4, bsign
		Return big3
	EndIf
	
	If Comp_BIG_BIG(big1, big2) = 1 Then
		big3 = Sub_BIG_BIG(big2, big1)
		PokeByte big3, 4, MINUS
		Return big3
	EndIf
	
	big3 = Init_BIG()
	size = Max(PeekInt(big1, 0), PeekInt(big2, 0))
	borrow = 0
	
	For i = 1 To size
		v = PeekInt(big1, 1 + i * 4) - borrow - PeekInt(big2, 1 + i * 4)
		If PeekInt(big1, 1 + i * 4) > 0 Then borrow = 0
		If v < 0 Then
			v = v + 1000000000
			borrow = 1
		EndIf
		PokeInt big3, 1 + i * 4, v Mod 1000000000
	Next i
	PokeInt big3, 0, size
	
	Return big3
EndFunction

Function Comp_BIG_BIG(big1 As Integer, big2 As Integer)
	asign = PeekByte(big1, 4)
	bsign = PeekByte(big2, 4)
	asize = PeekInt(big1, 0)
	bsize = PeekInt(big2, 0)
	
	asgn = (asign = PLUS) - (asign = MINUS)
	
	If asign = MINUS And bsign = PLUS Then Return 1
	If asign = PLUS And bsign = MINUS Then Return -1
	
	If bsize > asize Then Return asgn
	If asize > bsize Then Return -1 * asgn
	
	For i = asize To 1 Step -1
		If PeekInt(big1, 1 + i * 4) > PeekInt(big2, 1 + i * 4) Then Return asgn * -1
		If PeekInt(big2, 1 + i * 4) > PeekInt(big1, 1 + i * 4) Then Return asgn
	Next i
EndFunction

Function String_BIG(big As Integer)	
	If PeekByte(big, 4)
		ret$ = "-"
	EndIf
	size = PeekInt(big, 0)
	For i = size To 1 Step -1
		a$ = Str(PeekInt(big, 1 + i * 4))
		a$ = String("0", (9 - Len(a$)) * (i <> size)) + a$
		ret$ = ret$ + a$
	Next i
	Return ret$
EndFunction

Function Print_BIG(big As Integer)
	Print String_BIG(big)
EndFunction
CoolBasic henkilökuntaa
Kehittäjä

cbFUN Kello
cbSDL
Whale.dy.fi

<@cce> miltäs tuntuu olla suomen paras
DJ-Filbe
Devoted Member
Posts: 854
Joined: Sat Feb 20, 2010 2:18 pm

Re: Pari simppeliä funktiota {pienellä palkalla}

Post by DJ-Filbe »

KilledWhale wrote:Tässä olisi oma isolukukikkareeni. Merkkijonojen sijaan se säilöö luvut hassusti kokonaislukuja käyttäen jolloin laskiessa tulee vähemmän sähläämistä lukujen kanssa. Etuna pitäisi olla lähinnä nopeus. Kerto- ja jakolaskufunktioita en ole jaksanut tehdä mutta katsoo nyt jos viitsisin.
Systeemi on pitkälti käännetty Programming Challenges -kirjasta löytyvästä esimerkkikoodista, mutta pientä viilausta olen joutunut tekemään koska CoolBasic.

Koodissa oleva esimerkki tulostelee 100 ensimmäistä lukua fibonaccin lukujonosta.

Code: Select all

// BIG, Tuki isoille luvuille CoolBasicissa
// Tehnyt: Jasse 'KilledWhale' Lahdenperä
// v. 0.3
//
// Init_BIG()				Luo uuden jättiluvun
// Copy_BIG(big)			Kopioi jättiluvun ja palauttaa luodun kopion
// Destroy_BIG(big) 		Poistaa jättiluvun muistista
// Set_BIG_INT(big, int)	Asettaa jättiluvun arvoksi kokonaisluvun
// Add_BIG_BIG(big, big)	Lisää jättilukuun jättiluvun ja palauttaa vastauksena uuden jättiluvun
// Sub_BIG_BIG(big, big)	Vähentää jättiluvun jättiluvusta ja palauttaa vastauksena uuden jättiluvun
// String_BIG(big)			Palauttaa jättiluvun merkkijonona
// Print_BIG(big)			Tulostaa jättiluvun ruudulle

// ASETUKSET
Const RESERVE = 1000		// Montako lohkoa varataan oletuksena ( yksi lohko = 9 merkkiä )

// Näihin ei tarvitse koskea
Const PLUS = 0
Const MINUS = 1

////////////////////////////////////////////
// ESIMERKKIKOODI
////////////////////////////////////////////

a = Init_BIG()
b = Init_BIG()

Set_BIG_INT(a, 0)
Print "1: " + String_BIG(a)
Set_BIG_INT(b, 1)
Print "2: " + String_BIG(b)
For i = 3 To 100
	c = Add_BIG_BIG(a, b)
	Print i + ": " + String_BIG(c)
	Destroy_BIG(a)
	a = b
	b = c
	Wait 250
Next i
WaitKey

////////////////////////////////////////////
// FUNKTIOT (ÄLÄ KOSKE KUN ET KUITENKAAN TIEDÄ MITÄ TEET)
////////////////////////////////////////////

Function Init_BIG()
	a = MakeMEMBlock(5 + RESERVE * 4)
	PokeInt a, 0, 0
	PokeByte a, 4, PLUS
	Return a
EndFunction

Function Copy_BIG(big As Integer)
	a = MakeMEMBlock(MEMBlockSize(big))
	MemCopy big, 0, a, 0, MEMBlockSize(big)
	Return a
EndFunction

Function Destroy_BIG(big As Integer)
	DeleteMEMBlock big
EndFunction

Function Set_BIG_INT(big As Integer, num As Integer)
	If num < 0
		neg = 1
		num = Abs(num)
	EndIf
	
	PokeInt big, 5, num Mod 1000000000
	If num >= 1000000000 Then
		PokeInt big, 9, RoundDown(num / 1000000000)
		PokeInt big, 0, 2
	Else
		PokeInt big, 0, 1
	EndIf

	PokeByte big, 4, neg
EndFunction

Function Add_BIG_BIG(big1 As Integer, big2 As Integer)
	asign = PeekByte(big1, 4)
	bsign = PeekByte(big2, 4)
	If asign = bsign Then
		csign = asign
	Else
		If asign = MINUS Then
			PokeByte big1, 4, PLUS
			big3 = Sub_BIG_BIG(big2, big1)
			PokeByte big1, 4, MINUS
		Else
			PokeByte big2, 4, PLUS
			big3 = Sub_BIG_BIG(big1, big2)
			PokeByte big2, 4, MINUS
		EndIf
		Return big3
	EndIf
	
	big3 = Init_BIG()
	size = Max(PeekInt(big1, 0), PeekInt(big2, 0))
	carry = 0
	
	i = 1
	While i <= size Or carry
		a = PeekInt(big1, 1 + i * 4)
		b = PeekInt(big2, 1 + i * 4)
		PokeInt big3, 1 + i * 4, (carry + a + b) Mod 1000000000
		carry = RoundDown((carry + a + b) / 1000000000)
		i = i + 1
	Wend

	PokeInt big3, 0, i - 1
	PokeByte big3, 4, csign
	
	Return big3
EndFunction

Function Sub_BIG_BIG(big1 As Integer, big2 As Integer)
	asign = PeekByte(big1, 4)
	bsign = PeekByte(big2, 4)
	
	If asign = MINUS Or bsign = MINUS Then
		PokeByte big2, 4, (bsign = PLUS) * MINUS + (bsign = MINUS) * PLUS
		big3 = Add_BIG_BIG(big1, big2)
		PokeByte big2, 4, bsign
		Return big3
	EndIf
	
	If Comp_BIG_BIG(big1, big2) = 1 Then
		big3 = Sub_BIG_BIG(big2, big1)
		PokeByte big3, 4, MINUS
		Return big3
	EndIf
	
	big3 = Init_BIG()
	size = Max(PeekInt(big1, 0), PeekInt(big2, 0))
	borrow = 0
	
	For i = 1 To size
		v = PeekInt(big1, 1 + i * 4) - borrow - PeekInt(big2, 1 + i * 4)
		If PeekInt(big1, 1 + i * 4) > 0 Then borrow = 0
		If v < 0 Then
			v = v + 1000000000
			borrow = 1
		EndIf
		PokeInt big3, 1 + i * 4, v Mod 1000000000
	Next i
	PokeInt big3, 0, size
	
	Return big3
EndFunction

Function Comp_BIG_BIG(big1 As Integer, big2 As Integer)
	asign = PeekByte(big1, 4)
	bsign = PeekByte(big2, 4)
	asize = PeekInt(big1, 0)
	bsize = PeekInt(big2, 0)
	
	asgn = (asign = PLUS) - (asign = MINUS)
	
	If asign = MINUS And bsign = PLUS Then Return 1
	If asign = PLUS And bsign = MINUS Then Return -1
	
	If bsize > asize Then Return asgn
	If asize > bsize Then Return -1 * asgn
	
	For i = asize To 1 Step -1
		If PeekInt(big1, 1 + i * 4) > PeekInt(big2, 1 + i * 4) Then Return asgn * -1
		If PeekInt(big2, 1 + i * 4) > PeekInt(big1, 1 + i * 4) Then Return asgn
	Next i
EndFunction

Function String_BIG(big As Integer)	
	If PeekByte(big, 4)
		ret$ = "-"
	EndIf
	size = PeekInt(big, 0)
	For i = size To 1 Step -1
		a$ = Str(PeekInt(big, 1 + i * 4))
		a$ = String("0", (9 - Len(a$)) * (i <> size)) + a$
		ret$ = ret$ + a$
	Next i
	Return ret$
EndFunction

Function Print_BIG(big As Integer)
	Print String_BIG(big)
EndFunction
Kröhöm!
Puhuin yksinkertaisesta funktiosta, jolle viedään parametrit (luku1$, luku2$). Noista pitäisi saada erotus, tulo ja osamäärä erillisillä funktioilla. Ja tuossa on jo vaikka kuinka monta funktiota.
Versio vain missä ei tarvitse koskea koodiin millään tavalla ja saada oikea vastaus vaikka miljardin numeron pituisesta luvusta.
Muuten erinomaista työtä.
Henkru
Advanced Member
Posts: 359
Joined: Sun Aug 26, 2007 2:46 pm

Re: Pari simppeliä funktiota {pienellä palkalla}

Post by Henkru »

Jos vaan ottaisit paperia ja kynän ja miettisit hetken. Tekemällä kerralla yhteenlasku funktion joka toimii myös murto- ja negatiivisilla luvuilla niin vähennys, kerto, jako ja potenssi ovat helppo johtaa yhteenlaskuun

a-b = a+(-b)
a*b = b+b+b..(a kappaletta)
a:b = a*(1/b) = 1/b + 1/b + 1/b + 1/b + 1/b...(a kappaletta)
a^b = a*a*a...(b kappaletta)

Mietit miten toimit tämmöisissä tilanteissa:

10+15
15+10

15+(-14)
15+(-16)

-15+14
-14+15

-15-16

Muista myö,s että a + b = b + a
Latexi95
Guru
Posts: 1166
Joined: Sat Sep 20, 2008 5:10 pm
Location: Lempäälä

Re: Pari simppeliä funktiota {pienellä palkalla}

Post by Latexi95 »

DJ-Nerd wrote: Kröhöm!
Puhuin yksinkertaisesta funktiosta, jolle viedään parametrit (luku1$, luku2$). Noista pitäisi saada erotus, tulo ja osamäärä erillisillä funktioilla. Ja tuossa on jo vaikka kuinka monta funktiota.
Versio vain missä ei tarvitse koskea koodiin millään tavalla ja saada oikea vastaus vaikka miljardin numeron pituisesta luvusta.
Muuten erinomaista työtä.
Mikä ongelma? Eihän siitä puutu muuta kuin merkkijonon muuton luvuksi.
Muuten hieno funktiokirjasto.

Saanko minä palkinnon kun tein(lue: löysin) sinulle C# version? Tästä ainakin löytyy kaikki tarvitsemasi.
Luvun voi luoda monista eri tieto tyypeistä, mm. merkkijonoista.
Kokeilin laskea 617486214978126412^412762174 (IntX.Pow(617486214978126412,4127674,MultiplyMode.AutoFht)),
mutta lopetin laskennan kun ohjelma oli kuluttanut jo 1,5Gt RAM:ia. :lol:
Joten tässä kaikki tarvitsemasi jos teet ohjelmasi C#:lla.
Post Reply