Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: Java: Matemaattisia toimintoja

koodaaja [21.12.2022 19:56:56]

#

Tässä on matemaattisia toimintoja sisältävä koodi, joka tarkistaa, onko luku Harshadin tai Armstrongin luku tai ystävällinen lukupari. Yritän parin kuukauteen olla lähettämättä mitään, mutten ole vielä parantunut koodispämmäämisen identiteetistä.

public class Lukuja {

  public static boolean Harshad(int luku){
   //Tarkistetaan, onko kyseessä Harshadin luku.
     int temp = luku;

     int summa = 0;
     while (temp > 0){
       summa += temp%10;
       temp /= 10;

     }

    return luku%summa==0;

  }


 public static boolean Armstrong(int luku){

    //Tarkistetaan, onko kyseessä Armstrongin luku.
    int temp = luku;
    int eksponentti = 0;
    int summa = 0;
    while (temp > 0){
      eksponentti++;
      temp /= 10;
    }
   temp = luku;
   while (temp > 0){
      summa += temp%10;
      temp /= 10;
    }
  return luku==summa;

 }


 public static boolean Ystavallinen_lukupari(int luku, int luku2){
   //Tarkistetaan onko kyseessä ystävällinen lukupari.
    int summa = 0;
    int summa2 = 0;

    for (int i = 1; i < luku; i++){
       summa += i;
    }
  for (int i = 1; i < luku2; i++){
       summa2 += i;
    }
    return luku==summa2 && luku2 == summa;
 }

 public static void main(String[] args){

   //Kokeillaan ohjelmaa.
    System.out.println(Harshad(82));
  System.out.println(Armstrong(82));
  System.out.println(Ystavallinen_lukupari(82,220));


 }



}

Metabolix [22.12.2022 08:59:14]

#

Se on harshad-luku, ei Harshadin luku.

Armstrongin luvun kohdalla olet unohtanut huomioida eksponentin.

Ystävällisessä lukuparissa tulisi laskea vain lukujen tekijät (jakajat), ja ensimmäinen oikea lukupari on 220 ja 284. Nythän lasket yhteen kaikki luvut 1 <= x < luku, mistä tulee summaksi luku*(luku-1)/2, ja tekemäsi tarkistus on taatusti epätosi.

Eniten hämmästyttää, että etkö viitsi edes testata näitä koodejasi jollain tunnetuilla luvuilla, joita netistä löytyy?

jalski [22.12.2022 21:17:13]

#

Armstrongin luvun tarkastamisen voi tehdä yhdellä silmukalla ja eksponentin voi suoraan laskea (esimerkki 8th:lla ettei olisi liian helppo kopioida) :

: digits?  \ n -- n
  n:ln 10 n:ln n:/ n:int n:1+ ;

: armstrong?  \ n -- T
  dup digits? swap tuck 0 >r
  repeat
    10 n:/mod swap 2 pick n:^ n:r+
  while 2drop
  r> n:= ;

Harshad luvun tarkastusrutiinin pitäisi varmaan myös suoriutua muistakin kantaluvuista?

jlaire [23.12.2022 13:10:01]

#

jalski kirjoitti:

eksponentin voi suoraan laskea

Joillain käyttöjärjestelmillä/standardikirjastoilla tuollainen on johtanut pyöristysvirheeseen ja väärään tulokseen tietyillä inputeilla. En tiedä onko tämä todellinen ongelma nykyaikana, mutta ymmärrän liukulukujen välttämisen kun inputit ja outputit ovat kokonaislukuja.

jalski kirjoitti:

(esimerkki 8th:lla ettei olisi liian helppo kopioida) :

Otin haasteen vastaan ja tein C++-version: https://godbolt.org/z/WWYejhP5h (Edit: hieman siistimpi versio https://godbolt.org/z/4eY8ebG9d)

Eikö 8th:ssäkin "over" ole sama kuin "swap tuck"?

jalski [23.12.2022 14:01:06]

#

jlaire kirjoitti:

jalski kirjoitti:

(esimerkki 8th:lla ettei olisi liian helppo kopioida) :

Otin haasteen vastaan ja tein C++-version: https://godbolt.org/z/WWYejhP5h

Eikö 8th:ssäkin "over" ole sama kuin "swap tuck"?

;D Lopputulos on tietysti sama, mutta parempi vaihtoehto olisi "1 pick".

ok> 1 2 swap tuck .s

3    n: 0000007fa4923b30 2    1
2    n: 0000007fa4923b60 1    2
1    n: 0000007fa4923b30 2    1

ok> reset

ok> 1 2 over .s

3    n: 0000007fa4923b30 2    1
2    n: 0000007fa4923b60 1    2
1    n: 0000007fa4923b30 2    1

ok> reset

ok> 1 2 1 pick .s

3    n: 0000007fa4923b30 2    1
2    n: 0000007fa4923b60 1    2
1    n: 0000007fa4923b30 2    1

muuskanuikku [24.12.2022 10:21:47]

#

jalski kirjoitti:

(22.12.2022 21:17:13): Armstrongin luvun tarkas­ta­misen voi tehdä...

Noin lyhyt koodihan on aina helppoa kopioida, jos osaa lukea kyseistä kieltä edes jollain tasolla. Nyt kun kukaan ei osaa lukea tuota räpellystä, niin mistä me tiedämme, ettet sinä vaan vaikka trollaisi ja postailisi jotain akuankkaa tänne?

Koodin "suojaaminen" suoralta copypastelta onnistuu paremmin kirjoittamalla huonosti muotoiltua koodia tai nimeämällä muuttujat ja funktiot hyvien tapojen vastaisesti, esimerkiksi käyttämällä suomen kieltä englannin sijaan.

jalski [24.12.2022 14:25:57]

#

muuskanuikku kirjoitti:

Nyt kun kukaan ei osaa lukea tuota räpellystä, niin mistä me tiedämme, ettet sinä vaan vaikka trollaisi ja postailisi jotain akuankkaa tänne?

Tuntui tuo lukeminen ainakin jlaire:lta sujuvan ja antoi ihan aiheellisen kommentin tavastani laskea likiarvolla eksponentti. Teki tuon myös kohteliaasti ilman ilkeilyä, mistä hatunnosto hänelle!

alla toinen tapa:

: digits?  \ n -- n
  [ 20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1 ]
  [ 9999999999999999999,999999999999999999,99999999999999999,
    9999999999999999,999999999999999,99999999999999,9999999999999,
    999999999999,99999999999,9999999999,999999999,99999999,9999999,
    999999,99999,9999,999,99,9,0 ]
  rot ( swap n:cmp ) a:pigeon ;

: armstrong?  \ n -- T
  dup digits? swap tuck 0 >r
  repeat
    10 n:/mod swap 2 pick n:^ n:r+
  while 2drop
  r> n:= ;

: app:main
  ( dup armstrong? if
      . space
    else
      drop
    then ) 1 100000 loop cr ;
root@DietPi:~# /opt/8th/bin/rpi64/8th luk.8th
1 2 3 4 5 6 7 8 9 153 370 371 407 1634 8208 9474 54748 92727 93084 548834
root@DietPi:~#

Vertailut olisi tietysti fiksu järjestää sen mukaan, jos tiedetään tarkastettavien lukujen olevan suuria tai pieniä, että ei tarvitsisi tehdä aina montaa vertailua eksponentin selvittämiseen.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta