Tehtävä on : poista luvusta suurin numero Esim. 1732 -> 132
Tämän jälkeen kerrotaan summa poistetulla eli 132*7
Summalle tehdään taas sama juttu
Tämän jälkeen kerrotaan summa poistetulla eli 132*7
Summalle tehdään taas sama juttu
Turvaa tilisi vahvistamalla puhelinnumerosi. Voit silloin palauttaa unohtuneen salasanan tekstiviestillä.
Ketjusta on poistettu 1 sääntöjenvastainen viesti.
Näihin keskusteluihin ei ole vielä vastattu. Ole ensimmäinen.
Vastaukset 34
Vanhimmat
Jos käsittelee lukua merkkijonona (String), ja käyttää kääreluokkia, parseInt,toString, metodeita esim Integer-luokassa, ja ottaa talteen aina luvun isoimman numeron, minkä saa selville ohjelmoimalla vertailumetodin, ja uuden luvun voi muodostaa sen jälkeen StringBufferilla.
Sitten kyseessä on yksinkertainen rekursio, jos Integer.toString(sb.toSTring)*7 annettaan palautuksena kutsu samaan metodiin.
Metodin otsikko voi olla esim.
public int laske(String mJono)
Pistin koodia jakoon Dropboxiini,kopioi tuolta, ja editoi toimivaksi.
Teoria on kuitenkin tämä, ja käytännön toteutus jäi nopeasti tehdessä puolitiehen...Toivottavasti handlaat casen!
https://goo.gl/dN3kkq
Sait mielenkiinnon heräämään, joten tässä ratkaisu:
class pulmaLuokka {
static void pulma(int luku) {
// Muunnetaan luku tekstiksi ja edelleen kirjaintaulukoksi
String lukuTekstina = Integer.toString(luku);
char[] lukuKirjainTaulukkona = lukuTekstina.toCharArray();
int indeksi;
int suurimmanLuvunIndeksi = 0;
// Käydään läpi kirjaintaulukko ja otetaan ensimmäisen suurimman luvun indeksi talteen
for (indeksi = 0 ; indeksi < lukuKirjainTaulukkona.length ; indeksi ) {
if (Character.getNumericValue(lukuKirjainTaulukkona[suurimmanLuvunIndeksi])
< Character.getNumericValue(lukuKirjainTaulukkona[indeksi])) {
suurimmanLuvunIndeksi = indeksi;
}
System.out.println("Indeksi " indeksi ": Luku " lukuKirjainTaulukkona[indeksi]);
}
// Jaetaan luku alku- ja loppuosaan ensimmäisen suurimman mukaan
String luvunAlku = lukuTekstina.substring(0, suurimmanLuvunIndeksi);
String luvunLoppu = lukuTekstina.substring(suurimmanLuvunIndeksi 1, lukuTekstina.length());
int suurinLuku = Character.getNumericValue(lukuKirjainTaulukkona[suurimmanLuvunIndeksi]);
String lukuIlmanSuurinta = luvunAlku luvunLoppu;
int lopputulos = Integer.valueOf(lukuIlmanSuurinta) * suurinLuku;
// Tulostetaan
System.out.println("Luvun alku: " luvunAlku);
System.out.println("Luvun loppu: " luvunLoppu);
System.out.println("Suurin luku: " suurinLuku);
System.out.println("Luku ilman suurinta: " lukuIlmanSuurinta);
System.out.println("Lopputulos: " lopputulos);
}
}
Minäkin innostuin ratkaisemaan tuon, mutta tein sen Pythonilla, ja tulos on tässä:
http://i.imgur.com/ipWzDcb.png
Tarkoitatko summalla lukua esittävän pilkotun merkkijonon puolikkaiden yhdistämistä? Mitä tehdään jos on useapi samanarvoinen numero? Poistetaanko jokainen ennen kertomista, vai pelkästään esimerkiksi ensimmäinen?
Jos luku sisältää 2 tai useamman numeron, jotka edustaa suurinta numeroa, ensinmäinen vasemmalta poistetaan, ja siirretään kertojaksi.
Tai siis noin se minulla tuo Python pätkä toimii.
Avaajahan ei asiaa maininut.
Pitääkö huomioida myös negatiiviset luvut? Entä desimaaliluvut?
Entä kompleksiluvut?
Samma på Pascal:
program pulma;
uses
SysUtils;
var
a, i, p: integer;
b: string;
m: char;
begin
a := 1732;
repeat
b := IntToStr(a);
if length(b) < 2 then
break;
writeln(b);
m := #0;
for i := 1 to length(b) do
if b[i] > m then
begin
m := b[i];
p := i;
end;
Delete(b, p, 1);
writeln(b);
a := StrToInt(b) * (Ord(m) - 48);
until False;
end.
Python on paras!
Tässä "Kokemus-opettaa"-koodarin vähän muokattu koodi:
#!/usr/bin/python
a=1732
b=str(a)
print(b)
while len(b) >1:
k=int(max(b))
b=b.replace(max(b),'',1)
a=int(b)*k
print(k,b,a)
b=str(a)
mikä tulostaa:
1732
(7, '132', 924)
(9, '24', 216)
(6, '21', 126)
(6, '12', 72)
(7, '2', 14)
(4, '1', 4)
Kirjoitin ajankuluksi näin aaton aaton alkuillasta Javalla Rekursiivisen metodin, ja luokan, joka tekee tuon, mitä alunperin kysyit. Tsekkaa GitHub-profiilini "Java-stuff" -hakemisto ja "Recursion.java".
https://goo.gl/B2NH2z
Toimiiko tuo sinun java-koodisi mielestäsi oikein ?
http://i.imgur.com/dxiAEW4.png
Vasen Python, ja Oikea Java
Molemmat toimii oikein. Java-sw näyttää luvun kertolaskun jälkeen.
Python-version tulostus vähän harhaanjohtava, se näyttää luvun kun numero poistettu,
eikä seuraavana käsiteltävää lukua.
Tässä molemmat arvot tulostettuna:
4752
(7, '452', 3164)
(6, '314', 1884)
(8, '184', 1472)
(7, '142', 994)
(9, '94', 846)
(8, '46', 368)
(8, '36', 288)
(8, '28', 224)
(4, '22', 88)
(8, '8', 64)
(6, '4', 24)
(4, '2', 8)
Miten tuohon java-versioon saa tungettua noin paljon rivejä?
Näinhän tuo on nähtävä, taidankin lainata tuota sinun riviä ( print(k,b,a) ) omaani, niin ei enään toistamiseen tule sekaannusta.
Joo, tosiaan tuo ohjelmani näyttää kertolaskun jälkeen ainoastaan tuloksen. Sielläon kommenttina yksi System.out..println-rivi, joka selventää välivaiheita.
Java-koodista tuli aika hirviömäinen, täytyy myöntää, ehkä Java ei ole tosiaan otollisin kieli toteuttaa kyseinen tehtää? Pythonillakin näyttäisi selviävän kourallisella rivejä.
Joo, tosiaan tuo ohjelmani näyttää tuloksen ainoastaan kertolaskun jälkeen. Siellähän on System out println rivi kommenttina, joka näyttää välivaiheita, jos selennystä kaipaa.
Tuosta Java-koodista tuli aika hirviömäinen, ja ehkä Java ei ole paras kielivalinta kyseisen alkuperäisen ongelman ratkaisemiseksi? Pythonillakin näyttäisi näköjään selviävän kourallisella ohjelmakoodirivejä.
Joo, tosiaan tuo ohjelmani näyttää tuloksen ainoastaan kertolaskun jälkeen. Siellähän on System out println rivi kommenttina, joka näyttää välivaiheita, jos selennystä kaipaa.
Tuosta Java-koodista tuli aika hirviömäinen, ja ehkä Java ei ole paras kielivalinta kyseisen alkuperäisen ongelman ratkaisemiseksi? Pythonillakin näyttäisi näköjään selviävän kourallisella ohjelmakoodirivejä.
Mitkä ovat viralliset ohjeet tehtävän suorittamiseksi? Huomioidaan pelkästään positiiviset kokonaisluvut, ja vain vasemmanpuoleisin suurin numero poistetaan?
Tossa tosiaan tulee poistettua ainoastaan ensimmäinen vastaantuleva maksimiarvo. Epäselväksi jäi, pitäisikö kaikki kyseiset arvot poistaa samalla kertaa luvusta, vai tosiaan riittääkö, että poistetaanko ensimmäinen vastaantuleva. Itse asiassa kun silmukassa käydään läpi, ja tarkistetaan jokainen arvo, jos on kaksi yhtä suurta maksimia, jälkimmäinen poistetaan, joka muuttaa lukua ja lopputulosta oleellisesti.
Alkuperäinen viestin kirjoittaja voisit ehkä vähän rajata ongelmanasettelua, koska jos luvussa on tosiaan kaksi korkeinta arvoa, kumpi pitäisi poistaa esim?
Jos ajatellaan, että kyse olisi jostain kriittisen järjestelmän toiminnosta, esimerkiksi avaruuslennosta, tai vaikka niinkin maallisesta asiasta, kuin pankin ohjelmasta, ei ole ollenkaan sama, positetaanko suurin merkkijonossa oleva luku kymmenistä, sadoista, tai ykkösistä? Seuraava tulos on heti virheellinen, jos ei tarkkoja ohjeita anneta.
Avaruuslennossakin saattaa ihmishenkiä olla kyseessä, ja kai ymmärrät, että jos pankissa on esimerkiksi jokin asiakasnumeroiden päivitysalgoritmi ajettava, tai vaikka vielä maallisempi ongelmatilanne, saldojen päivitys eräajona, ei ole ollenkaan sama , mistä kohtaa lukua poistaa maksimiarvon, koska tosiaan useassa kohtaa on sama arvo. Jos asiakasnumeroista poistaa väärästä kohtaa pankissa esim. numeron, seuraavat siirrot etenee väärille asiakkaille, ja saldossa taasen ei ole ollenkaan sama, vai oletko niin rikas, että sama posituuko tililtäsi tuhansista tai sadoista ykkösten sijaan rahaa nostettavaksi automaatista, jos tilisi saldo olisi esimerkiksi 9919.=?
Jos voisit täsmentää alkuperäistä ongelman asettelua, niin olisi kiva.
Kieli kuin kieli, rekursio ja muutama rivi.
Sekö tuo python koodin pätkä näyttää rekursiivisiselta ohjelmarutiinilta sinun katsellessa sitä ?
Ei. Ikävän imperatiivista koodia tuo.
Elegantti ratkaisu olisi semmoinen missä ei olisi sijoituslausekkeita.
Mitä järkeä koko tehtävässä? Eikö ole parempaa tekemistä?
Räpelsin+tuon+nyt+C-kielellä+ja+niillä+ehdoin,+että+vain+positiivinen+kokonaisluku+kelpaa,+ja+poistetaan+aina+vasemmanpuoleisin+suurin+numero.+Tein+funktiosta+myös+rekursiivisen.
Ensin+tehdään+lukua+esittävästä+merkkijonosta+(komentoriviltä+syötetään+ohjelman+parametriksi+luku)+muunnos+kokonaisluvuksi,+ja+loppu+käsittely+tehdään+kokonaisluku-tyyppisten+apumuuttujien+kanssa+laskemalla.+Toinen+tapahan+olisi+yhdistellä+ja+pilkkoa+merkkijonoja,+mutta+ajattelin+tämän+olevan+tehokkaampi+tapa.+
Kymmenen+potenssille+tein+apufunktion,+kun+C-kielessä+ei+potenssia+voi+suoraan+laskea.+Olisi+tietysti+voinut+käyttää+matikkakirjastoa,+mutten+jaksanut+kirjoittaa+ylimääräistä+include-riviä.
Kokeilin+sekä+64-+että+32-bittisissä+järjestelmissä.+64-bittisessä+voi+syötellä+huomattavasti+isompia+lukuja.+Viime+hetken+paikkauksena+piti+lisätä+vielä+edellisen+tuloksen+siirto+seuraavalle+kierrokselle,+kun+ohjelma+jäi+luvulla+2880+ikiluuppiin,+syystä+että+8+x+280+=+2880.
Luvulla+1732+edetään+näin:
mint@mint171124+~/koodi+$+./temppu+1732
Luku:+1732,+max.numero+=+7,+uusi+luku+on+7+x+132+->+1148
Luku:+1148,+max.numero+=+8,+uusi+luku+on+8+x+114+->+912
Luku:+912,+max.numero+=+9,+uusi+luku+on+9+x+12+->+216
Luku:+216,+max.numero+=+6,+uusi+luku+on+6+x+21+->+126
Luku:+126,+max.numero+=+6,+uusi+luku+on+6+x+12+->+72
Luku:+72,+max.numero+=+7,+uusi+luku+on+7+x+2+->+28
Luku:+28,+max.numero+=+8,+uusi+luku+on+8+x+2+->+16
Luku:+16,+max.numero+=+6,+uusi+luku+on+6+x+1+->+6
mint@mint171124+~/koodi+$+
Ohjelmakoodi:
#include+<stdio.h>
#include+<stdlib.h>
int+main(int+argc,+char+*argv[]);
unsigned+long+pot10(char+potenssi);
unsigned+long+int+temppu(unsigned+long+int+luku,+unsigned+long+int+edellinen);
unsigned+long+pot10(char+potenssi)+{
unsigned+long+paluuarvo=1;
if+(potenssi==0)+return+paluuarvo;
else+if+(potenssi+>+0)+{
do+{
paluuarvo*=10;
potenssi--;
}+while+(potenssi>0);
return+paluuarvo;
}
return+0;
}
int+main(int+argc,+char+*argv[])+{
char+*endptr=NULL;
if(argc==2)+{
temppu(strtoul(argv[1],&endptr,10),0);
}+else+{
printf("Anna+komennon+%s+parametriksi+luku+",+argv[0]);
printf("väliltä+10-%lu\n",((unsigned+long+int)0-1)/9);
}
return+0;
}
unsigned+long+int+temppu(unsigned+long+int+luku,+unsigned+long+int+edellinen)
{
unsigned+long+int+apuluku=luku,vasen=0,oikea=0;
unsigned+char+numero=0,numeroita=0,maxnumero=0,sijainti=0;
if(luku==0+||+luku>((unsigned+long+int)0-1)/9)+{
printf("Luvun+on+oltava+väliltä+10-%lu\n",((unsigned+long+int)0-1)/9);
return+0;
}
while(1)+{
numeroita++;
if(apuluku>(((unsigned+long+int)0-1)/9))+return+0;
if(apuluku>9)+{
numero=apuluku-((apuluku/10)*10);
if(numero>=maxnumero)+{
maxnumero=numero;
sijainti=numeroita;
}
apuluku=apuluku/10;
}+else+{
numero=apuluku;
if(numero>=maxnumero)+{
maxnumero=numero;
sijainti=numeroita;
}
break;
}
}
printf("Luku:+%lu",luku);
printf(",+max.numero+=+%u",maxnumero);
vasen=luku/pot10(sijainti);
vasen=vasen*pot10(sijainti-1);
oikea=luku/pot10(sijainti-1);
oikea=oikea*pot10(sijainti-1);
oikea=luku-oikea;
vasen=vasen+oikea;
apuluku=maxnumero*(vasen+oikea);
printf(",+uusi+luku+on+%u+x+%lu+->+%lu\n",maxnumero,vasen,apuluku);
if(apuluku>9+&&+apuluku<(((unsigned+long+int)0-1)/9))+{
if(apuluku!=edellinen)+temppu(apuluku,luku);
}
return+apuluku;
}
Jaahas, ei olisi pitänyt vielä postata. Tuo toimii näköjään väärin. Heti alussa laskee väärin. Eihän 7 x 132 ole 1148, eikä 7 x 2 28. Debuggaamaan.
Virhe oli rivillä 65, laskin vahingossa kahteen kertaan oikean puoliskon vasempaan.
Tämä on väärin:
apuluku=maxnumero*(vasen oikea);
Pitäisi olla:
apuluku=maxnumero*vasen;
Nyt näyttää toimivan vähän paremmin:
mint@mint171124 ~/koodi $ ./temppu 1732
Luku: 1732, max.numero = 7, uusi luku on 7 x 132 -> 924
Luku: 924, max.numero = 9, uusi luku on 9 x 24 -> 216
Luku: 216, max.numero = 6, uusi luku on 6 x 21 -> 126
Luku: 126, max.numero = 6, uusi luku on 6 x 12 -> 72
Luku: 72, max.numero = 7, uusi luku on 7 x 2 -> 14
Luku: 14, max.numero = 4, uusi luku on 4 x 1 -> 4
mint@mint171124 ~/koodi $
Laitoin vielä koodin Pastebiniin, jos se ei näy foorumilla oikein.
https://pastebin.com/UBpJVNVh
Java-versionkin+sain+tehtyä.+Eli+tämä+on+taas+lähes+samanlainen+kuin+ensimmäinen+C-kielinenkin.+Vähän+aikaa+piti+miettiä+luokkajuttuja,+kun+ei+ole+olio-ohjelmointia+tullut+oikein+harrastettua.+Muuten+oli+aika+helppo+muuttaa+C-kielestä.+Castausta+piti+vähän+lisätä,+charit+muuttaa+byteiksi+ja+jotain+pientä.+Sen+yhden+ruman+breakin+otin+while-silmukasta+pois,+kun+ei+sitä+näköjään+tarvinnut.
https://pastebin.com/pEJhjDLp
Koodi:
public+class+Temppu+{
public+Temppu()+{
System.out.println("Lukua+ei+annettu");
}
public+Temppu(long+l)+{
this.temppuile(l);
}
private+long+pot10(byte+potenssi)+{
long+paluuarvo=1;
if+(potenssi==0)+return+paluuarvo;
else+if+(potenssi+>+0)+{
do+{
paluuarvo*=10;
potenssi--;
}+while+(potenssi>0);
return+paluuarvo;
}
return+0;
}
private+long+temppuile(long+luku)+{
long+apuluku=luku,vasen=0,oikea=0;
byte+numero=0,numeroita=0,maxnumero=0,sijainti=0;
while(apuluku>0)+{
numeroita++;
numero=(byte)(apuluku-((apuluku/10)*10));
if(numero>=maxnumero)+{
maxnumero=numero;
sijainti=numeroita;
}
apuluku=apuluku/10;
}
numero=(byte)apuluku;
if(numero>=maxnumero)+{
maxnumero=numero;
sijainti=numeroita;
}
vasen=luku/this.pot10(sijainti);
vasen=vasen*this.pot10((byte)(sijainti-1));
oikea=luku/this.pot10((byte)(sijainti-1));
oikea=oikea*this.pot10((byte)(sijainti-1));
oikea=luku-oikea;
vasen=vasen+oikea;
apuluku=maxnumero*vasen;
System.out.printf("Luku:+%d",+luku);
System.out.printf(",+max.numero+=+%d",maxnumero);
System.out.printf(",+uusi+luku+on+%d+x+",maxnumero);
System.out.println(vasen+"+->+"+apuluku);
if(apuluku>9)+{
this.temppuile(apuluku);
}
return+apuluku;
}
public+static+void+main(String+[]args)+{
if(args.length>0)+{
try+{
long+luku=Long.parseLong(args[0]);
if(luku>9)+{
Temppu+temppu=new+Temppu(luku);
}+else+{+
System.out.println("Luvun+pitää+vähintään+10");
}
}+catch+(NumberFormatException+e)+{
System.out.println("Epäkelpo+luku:+"+e.getMessage());
}
}+else+{
System.out.println("Lukua+ei+annettu.");
}
}
}
---
Tulos:
mint@mint171124+~/java+$+javac+Temppu.java
mint@mint171124+~/java+$+java+Temppu+1732
Luku:+1732,+max.numero+=+7,+uusi+luku+on+7+x+132+->+924
Luku:+924,+max.numero+=+9,+uusi+luku+on+9+x+24+->+216
Luku:+216,+max.numero+=+6,+uusi+luku+on+6+x+21+->+126
Luku:+126,+max.numero+=+6,+uusi+luku+on+6+x+12+->+72
Luku:+72,+max.numero+=+7,+uusi+luku+on+7+x+2+->+14
Luku:+14,+max.numero+=+4,+uusi+luku+on+4+x+1+->+4
mint@mint171124+~/java+$
Jaahas, Python3-versioni on jostain syystä poistettu. No kokeillaan uudelleen. On myös rekursiivinen toiminnaltaan.
https://pastebin.com/5nXgTDpw
Koodi:
# -*- encoding: utf8 -*-
import sys
def temppu(luku):
if luku<9:
print("Luvun pitää olla 10 tai suurempi")
return 0
apuluku=luku
numeroita=0
maxnumero=0
while True:
numeroita =1
if apuluku>9:
numero=apuluku-int(apuluku/10)*10
if numero>=maxnumero:
maxnumero=numero
sijainti=numeroita
apuluku=int(apuluku/10)
else:
numero=apuluku
if numero>=maxnumero:
maxnumero=numero
sijainti=numeroita
break
vasen=int(luku/10**sijainti)*10**(sijainti-1)
oikea=luku-int(luku/10**(sijainti-1))*10**(sijainti-1)
vasen=vasen oikea
apuluku=maxnumero*vasen
print("Luku:",luku,", max.numero =",maxnumero, end="")
print(", uusi luku on",maxnumero,"x",vasen,"->",apuluku)
if apuluku>9: temppu(apuluku)
return apuluku
def main(argv):
try:
temppu(int(argv[0]))
except:
print("Lukua ei annettu tai se ei ole kokonaisluku")
return 0
if __name__ == "__main__":
main(sys.argv[1:])
---
Tulos:
mint@mint171124 ~/koodi $ python3 temppu.py 1732
Luku: 1732 , max.numero = 7, uusi luku on 7 x 132 -> 924
Luku: 924 , max.numero = 9, uusi luku on 9 x 24 -> 216
Luku: 216 , max.numero = 6, uusi luku on 6 x 21 -> 126
Luku: 126 , max.numero = 6, uusi luku on 6 x 12 -> 72
Luku: 72 , max.numero = 7, uusi luku on 7 x 2 -> 14
Luku: 14 , max.numero = 4, uusi luku on 4 x 1 -> 4
mint@mint171124 ~/koodi $
Tein nyt vielä neljännenkin version. Tällä kertaa PHP:llä ja tämän voi ajaa palvelimella, johon on asennettu PHP. Laitan pelkän linkin, kun ei ole varmuutta miten täällä näkyy HTML-tageja sisältävät tekstit.
https://pastebin.com/LCj2d3LB
Tuon voi siis tallentaa palvelimelle .php päätteellä ja avata sitten nettiselaimella. Tulee sivu jossa on yksi tekstikenttä, johon voi syöttää kokonaislukuja 10:stä miljardiin. Sitten on nappula josta käynnistyy varsinainen rutiini, ja rivit tulostuvat siihen napin alapuolelle. Itse ratkaisuperiaate on sama mitä olen tehnyt aiemminkin.
Hauska kun tytötkin ovat alkaneet koodaamaan, joku yrittää saada näkyvää hahmoa ruudulle liikkumaan :D
Tämä on hyvä kysymys: kumpi on näistä nopeampi: gravitoni vai fotoni?
Hauska kun tytötkin ovat alkaneet koodaamaan, joku yrittää saada näkyvää hahmoa ruudulle liikkumaan :D
Tämä on hyvä kysymys: kumpi on näistä nopeampi: gravitoni vai fotoni?
Hauska kun tytötkin ovat alkaneet koodaamaan, joku yrittää saada näkyvää hahmoa ruudulle liikkumaan :D
Tämä on hyvä kysymys: kumpi on näistä nopeampi: gravitoni vai fotoni?
Hauska kun tytötkin ovat alkaneet koodaamaan, joku yrittää saada näkyvää hahmoa ruudulle liikkumaan :D
Tämä on hyvä kysymys: kumpi on näistä nopeampi: gravitoni vai fotoni?