Tässä ohjelmassa päätellään käyttäjän antamien syötteiden perusteella, voidaanko lukujono muodostaa. Lukujonoa on tässä ohjelmassa kahta eri tyyppiä, joko lisätään tai kerrotaan samalla luvulla.
import java.util.Scanner; /* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ /** * * @author jonir */ public class Lukujono { public static void main(String[] args){ Scanner syote = new Scanner(System.in); int luku_1 = 0; int luku_2 = 0; int luku_3 = 0; int luku = 0; int luvut = 0; //Syötetään lähtötiedot. System.out.println("Syötä kolme lukua."); luku_1 = syote.nextInt(); luku_2 = syote.nextInt(); luku_3 = syote.nextInt(); System.out.println("Syötä lukujen määrä."); luvut = syote.nextInt(); //Päätellään, muodostuuko näistä lukujono. if (luku_2 - luku_1 == luku_3 - luku_2){ luku = luku_2 - luku_1; //Lukujonoja saadaan jatkettua, kun lisätään aina samalla luvulla. for (int x = 3; x < luvut; x++){ luku_3 += luku; System.out.println(luku_3); } } if (luku_2 / luku_1 == luku_3 / luku_2){ luku = luku_2 / luku_1; //Lukujonoja saadaan jatkettua, kun kerrotaan aina samalla luvulla. for (int x = 3; x < luvut; x++){ luku_3 *= luku; System.out.println(luku_3); } } } }
Pythonilla tehtynä. Syötteen pituus saa olla minkä hyvänsä mittainen ja lisäsin tähän myös Fibonaccin lukujonot.
numbers = [ int(n) for n in input("Lukujonon alku välilyönneillä erotettuna: ").split() ] # Using any two values a and b, calculate the next value rules = [ lambda a, b: b + b - a, # Arithmetic lambda a, b: b * b / a, # Geometric lambda a, b: a + b, # Fibonacci ] for rule in rules: # Test if the rule matches a, b, *rest = numbers for n in rest: if n != rule(a, b): break a, b = b, n else: # Rule matched, generate a series out = numbers[:2] for i in range(8): out += rule(out[-2], out[-1]), print(out)
Alkuperäisessä koodissa on pari merkittävää vikaa.
Ensinnäkin jakolaskun tekeminen kokonaisluvulla johtaa väärään tulokseen jakolaskusäännön soveltamisessa. Esimerkiksi luvut 1, 2, 5 jatkuvat kahdella kertoen 10, 20, 40, 80, ja luvut 2, 3, 5 jatkuvat yhdellä kertoen 5, 5, 5. Pyöristysvirheiden välttämiseksi kokonaisluvuilla a/b == c/d kannattaa muuttaa kertolaskuksi normaalien matematiikan sääntöjen mukaan: a*d == b*c.
Toiseksi tuossa else-sanan puuttumisen vuoksi lasketaan ensin lukuja ensimmäisellä säännöllä ja vasta sitten tarkastetaan toisen säännön toimivuus, joten on mahdollista, että lukujonoa jatketaan kahteen kertaan. Virheenä on siis sekä väärä määrä lukuja että epälooginen lukujono. Vika on helpointa nähdä isoilla luvuilla, joilla jakolaskun tulos on 1 jo edellä kuvatusta jakolaskuvirheestä johtuen. Ohjelma tuottaa siis esimerkiksi 6 luvun lukujonon 101, 102, 103, 104, 105, 106, 106, 106, 106. Pienemmistä luvuista löytyy 5 luvun lukujono 1, 3, 5, 7, 9, 27, 81 ja vaikkapa 6 luvun lukujono 1, 4, 7, 10, 13, 16, 64, 256, 1024.
Muuttujat on siistimpää esitellä vasta käyttöpaikalla. Osa näistä voisi olla myös vakioita. Tässä tapauksessa erityisesti syötteet voi laittaa vakioiksi, jotta ei tule sitä virhettä, että toinen lukujono jatkuisi ensimmäisen lopusta.
final int luku_1 = syote.nextInt();
Siisteyden vuoksi kannattaa poistaa koodin alusta editorin automaattiset kommentit – on aika pöljää kopioida niitä ympäriinsä.
Aihe on jo aika vanha, joten et voi enää vastata siihen.