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)); } }
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?
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?
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"?
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
jalski kirjoitti:
(22.12.2022 21:17:13): Armstrongin luvun tarkastamisen 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.
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.
Aihe on jo aika vanha, joten et voi enää vastata siihen.