Trädvy Permalänk
Medlem
Registrerad
Aug 2015

Få fram ett symmetrisk tal

Hejsan!

Jag vill först börja med att berätta att jag är extremt ny på att programmera och har precis lärt mig grunder i Java.
Så uppskattar om det går att vara övertydlig med vad ni försöker förklara.

Mitt problem är att jag vill att java / mitt program ska hitta ett symmetrisk tal.
det jag får fram när jag kör mitt program är.

-------------------------------------------------------------------------------
1 : 87 + 78 = 165
2 : 165 + 561 = 726
3 : 726 + 627 = 1353
4 : 1353 + 3531 = 4884 <---- talet som är symmetrisk och det jag vill att programmet ska stanna loopen vid.
5 : 4884 + 4884 = 9768
6 : 9768 + 8679 = 18447
7 : 18447 + 74481 = 92928
8 : 92928 + 82929 = 175857
9 : 758571 + 758571 = 1517142
10 : 1517142 + 2417151 = 3934293
11 : 3934293 + 3924393 = 7858686
12 : 7858686 + 6868587 = 14727273
13 : 37272741 + 37272741 = 74545482

74545482 är det symmetriska numret.
Det tog 13 steg för att hitta svaret.

-------------------------------------------------------------------

Kod main programmet:

import java.util.Scanner; public class test1 { public static void main(String[] args) { Scanner userInput = new Scanner(System.in); int counter = 1; int[] num = new int[4]; boolean willContinue = true; int svar = 0; numbers numbers = new numbers(num[0], num[1], svar); num[1] = 87; num[0] = numbers.reverse(num[1]); svar = num[0] + num[1]; System.out.print(counter + " : " + num[1] + " + " + num[0] + " = " + svar); while (willContinue) { for (int i = 0; i < num.length; i++) { for (int g = 1; g < num.length; g++) { counter++; num[i] = svar; num[g] = numbers.reverse(num[i]); svar = num[i] + num[g]; System.out.print("\n" + counter + " : " + num[i] + " + " + num[g] + " = " + svar); if (numbers.checkSymetric(svar)) { willContinue = false; break; } } } System.out.print("\n" + svar + "är det symetriska numret. " + "\nDet tog " + counter + " steg för att hitta svaret."); } } }

kod subklass:

public class numbers { int num1; int num2; int svar; public numbers(int Num1, int Num2, int Svar) { this.num1=Num1; this.num2=Num2; this.svar=Svar; } public boolean checkSymetric(long number) { if (number == 0) return true; else if (number < 0) return false; long DEG_10 = (long)(Math.pow(10, (int)Math.log10(number))); while (number > 0) { long dStart = number / DEG_10; long dEnd = number % 10; if (dStart != dEnd) return false; number = (number - dStart * DEG_10 - dEnd) / 10; DEG_10 /= 100; } return true; } public int reverse(int input) { long reversedNum = 0; long input_long = input; while (input_long != 0) { reversedNum = reversedNum * 10 + input_long % 10; input_long = input_long / 10; } if (reversedNum > Integer.MAX_VALUE || reversedNum < Integer.MIN_VALUE) { } return (int)reversedNum; } }

Har suttit i två dagar nu med detta och försökt att lösa det, men lyckas inte knäcka det.
Och börjar tveka på om det ens går att göra såhär i java?

Tack!

Lägger till [code]-taggar; bjuder på lite kodformatering och färguppmärkning :-)
Trädvy Permalänk
Medlem
Plats
Umeå
Registrerad
Mar 2002

Använd [code][/code] taggar när du postar kod så blir det lättare att läsa eftersom mellanslag/whitespace då bevaras.

Ett tal är symetriskt om det är lika med sin reverse:al korrekt? Så då du redan har en funktion som vänder på talet så är det väl klokt att bara använda den istället för att duplicera funktionalliteten i ytterligare en funktion då det leder till felkällor.

int val=87; while(val != reverse(val)) //kör sålänge talet inte är symetriskt

Sen fundera på din main-loop, nu har du nästlade for-loopar i en while-loop, behöver du verkligen loopa så mycket?
Du använder en array för att hålla dina tal (num[]), och loopar sedan över den arrayen, men fundera på vad det egenteligen är du försöker loopa för här.
När du kör willContinue=false och break:ar så hoppar du ur din inre for-loop, men du har fortfarande en nivå av for-loop kvar innan den kommer kolla while-vilkoret igen. Så testa ta bort/ändra lite av dina loopar.

Slutligen, här är en möjlig lösning om du kör fast. Men försök lösa den på egen hand.

import java.util.Scanner; public class A { public static void main(String[] args) { Scanner input = new Scanner(System.in); System.out.print("Enter a number: "); int val = input.nextInt(); int counter=0; while(val != reverse(val)) { int rev = reverse(val); System.out.format("%d: %d+%d=%d\n",counter+1, val, rev, val+rev); val += rev; counter++; } System.out.format("%d is symetric.\n", val); System.out.format("It took %d iterations to find\n", counter); } public static int reverse(int a) { int b=0; do { b *= 10; b += a%10; a /= 10; } while(a>0); return b; } }

Dold text

The difference between stupidity and genius - the latter has limits

Trädvy Permalänk
Medlem
Plats
Falun
Registrerad
Dec 2003

Någon här som också uppskattar Numberphile eller är det ett roligt sammanträffande?

Vill bara passa på att säga att det inte är bevisat att alla siffror skapar palindromer. Med det sagt så kommer ditt program att hänga sig likt en "foreverloop" eller så krashar det för att minnet tar slut. Kan vara bra att slänga in en iterationsbegränsning eller liknande.

ηλί, ηλί, λαμά σαβαχθανί!?

Trädvy Permalänk
Datavetare
Plats
Stockholm
Registrerad
Jun 2011

@Zevon pekade dig på rätt väg.

Som lite kuriosa: en lite variant för att vända talet skulle vara att konvertera det till en sträng, vänd strängen och konvertera tillbaka till heltal

Long l = 1234L; Long r = Long.parseLong(new StringBuilder(l.toString()).reverse().toString());

Alltid bra att experimentera lite när man ska lära sig!

Av ingen större anledning, gjorde en variant i Ruby för den som är intresserad

# Extend standard integers with the ability to reverse themself and # calculate the series to the next symmetrical number class Integer def reverse self.to_s.reverse.to_i end def symmetrical n = self r = [ ] loop do n = n + n.reverse r << n break if n == n.reverse end r.reverse end end

Ser ut så här när man kör

irb(main):001:0> 87.reverse => 78 irb(main):002:0> 87.symmetrical => [4884, 1353, 726, 165]

är nu alltså möjligt att skicka meddelandena reverse och symmetrical till alla heltal för att vända dem respektive få serien upp till nästa symmetriska heltal.

Dold text

edit: @Teknocide: bra poäng med att det inte nödvändigtvis fungerar med godtyckligt stora tal, Ruby versionen fungerar också med godtyckligt stora tal då jag utökade Integer klassen som är basklass till både Fixnum (ungefär Javas Integer) och Bignum.

> 89.symmetrical => [8813200023188, 1801200002107, 955594506548, 176881317877, 93445163438, 47267087164, 13297007933, 7193004016, 3602001953, 1317544822, 664272356, 159487405, 85189247, 17735476, 8872688, 1716517, 907808, 173437, 91718, 17347, 9218, 1837, 968, 187]

Dold text

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Trädvy Permalänk
Medlem
Registrerad
Aug 2015

Zevon:

Herregud... Det funka :D.
Wow!
Jag vet inte riktigt om jag vågar testa med en annan siffra nu xD.
Tack!

Gillar också att din kod va mindre och enklare att både läsa och skriva, uppskattas ^^.
Tror jag gick vilse lite i ren desperation med all kod, blir väl lätt så.
Tog även bort en loop, planen va att den skulle sätta värde på num[].
Så i = 0. för varje loop ökar ju i +1 i värde.
Likaså ville jag göra med G.
Det jag gjorde i stället nu va att tabort en loop, och lägga g++; i loopen med int i.
Koden är rätt kladdig och ostädad atm, så jag vet att jag hade en del parameterar samt, instansvariabler/varibler jag inte använde alls.

Ska repetera lite och leka runt lite med koden, innan jag går till nästa utmaning, som jag ännu inte vet va det ska bli.
Men återigen, tack!

Leedow:

Nja, det var väl mer en polare som sa, kan du göra det här.
Lös!
Och naiv som jag var så antog jag utmaningen :D.

Trädvy Permalänk
Medlem
Plats
i din garderob
Registrerad
Sep 2007

Obligatorisk version i Scala. Tillåter arbiträrt stora tal.

def reverse(n: BigInt) = BigInt(n.toString.reverse) def findPalindrome(n: BigInt) = { def rec(n: BigInt, ns: List[BigInt]): List[BigInt] = { val tried = n :: ns if (n == reverse(n)) tried else rec(n + reverse(n), tried) } rec(n, Nil).reverse } findPalindrome(89) > res0: List[BigInt] = List(89, 187, 968, 1837, 9218, 17347, 91718, 173437, 907808, 1716517, 8872688, 17735476, 85189247, 159487405, 664272356, 1317544822, 3602001953, 7193004016, 13297007933, 47267087164, 93445163438, 176881317877, 955594506548, 1801200002107, 8813200023188)

Bilanaloger är som Volvo — varenda svenne kör med dem

Trädvy Permalänk
Medlem
Registrerad
Maj 2012
Skrivet av Paccman:

Zevon:

Herregud... Det funka :D.
Wow!
Jag vet inte riktigt om jag vågar testa med en annan siffra nu xD.
Tack!

Gillar också att din kod va mindre och enklare att både läsa och skriva, uppskattas ^^.
Tror jag gick vilse lite i ren desperation med all kod, blir väl lätt så.
Tog även bort en loop, planen va att den skulle sätta värde på num[].
Så i = 0. för varje loop ökar ju i +1 i värde.
Likaså ville jag göra med G.
Det jag gjorde i stället nu va att tabort en loop, och lägga g++; i loopen med int i.
Koden är rätt kladdig och ostädad atm, så jag vet att jag hade en del parameterar samt, instansvariabler/varibler jag inte använde alls.

Ska repetera lite och leka runt lite med koden, innan jag går till nästa utmaning, som jag ännu inte vet va det ska bli.
Men återigen, tack!

Leedow:

Nja, det var väl mer en polare som sa, kan du göra det här.
Lös!
Och naiv som jag var så antog jag utmaningen :D.

Då kan du säga att du lät @Zevon lösa problemet, eftersom du tjuvkollade.

Trädvy Permalänk
Medlem
Registrerad
Aug 2015

@Silcan: Haha jo du har så rätt, men kunskapen saknades nog också från min sida^^.
Man lär sig ändå, även om jag lätt andra lösa det för mig.