Most nem a híres kisvonatról van szó, hanem egy ismert kriptoaritmetikai feladványról. Ebben a feladattípusban egyszerű matematikai műveletek szerepelnek és a különböző betűk különböző számjegyeket jelölnek. Általában többféleképpen megoldhatók: intuíció, ötlet, módszeres próbálkozás, következtetés, kizárás vagy klasszikus behelyettesítés. Ha van megoldás és meg is találunk egyet, akkor a következő kérdés az, hogy van-e még, illetve összesen hány megoldás van?
Íme a feladat:
Érdemes minden megoldás során figyelembe venni a minden számjegyet 0-9-ig végigpróbáló lépések helyett legalább az alábbi öt feltételt:
- C >= 5, hiszen CHOO olyan négyjegyű szám, aminek a kétszerese ötjegyű szám,
- T = 1, mivel két négyjegyű szám összege 10000 < TRAIN < 20000 (ebben az esetben),
- O >= 6, hiszen maradéknak képződnie kell, mert I és N különbözik,
- 2 <= N < I és
- I >= 3 és szintén a maradékképződés miatt.
Esetleg még tovább gondolkodva, felfedezhetünk egyéb összefüggéseket, illetve kizárhatunk egyéb értékeket, így jelentősen csökkenthető egy-egy Java implementáció lépésszáma.
1. megoldás
Ez adatszerkezet nélküli megoldás, így eléggé összetett feltétellel valósul meg a művelet teljesülése (megfelelő helyiértékek használatával) és a különbözőségek vizsgálata.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public static void chooChooTrain1() { for (int c = 5; c <= 9; c++) for (int h = 0; h <= 9; h++) for (int o = 6; o <= 9; o++) for (int r = 0; r <= 9; r++) for (int a = 0; a <= 9; a++) for (int i = 3; i <= 9; i++) for (int n = 2; n < i; n++) if((1000*c+100*h+10*o+o)*2 == 10000+1000*r+100*a+10*i+n && c!=h && c!=o && c!=1 && c!=r && c!=a && c!=i && c!=n && h!=o && h!=1 && h!=r && h!=a && h!=i && h!=n && o!=1 && o!=r && o!=a && o!=i && o!=n && r!=1 && r!=a && r!=i && r!=n && a!=1 && a!=i && a!=n && i!=1 && i!=n && n!=1) System.out.println( " "+c+h+o+o+"\n+ "+c+h+o+o+"\n------\n "+1+r+a+i+n+"\n"); } |
2. megoldás
Itt az ellenőrzési feltétel egyszerűbb, mert a különbözőség/egyediség tesztelését áthárítottam a halmazszerűen működő HashSet generikus kollekcióra, építve annak beépített képességére.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public static void chooChooTrain2() { HashSet<Integer> hs=new HashSet<>(); for (int c = 5; c <= 9; c++) for (int h = 0; h <= 9; h++) for (int o = 6; o <= 9; o++) for (int r = 0; r <= 9; r++) for (int a = 0; a <= 9; a++) for (int i = 3; i <= 9; i++) for (int n = 2; n < i; n++) { hs.add(c); hs.add(h); hs.add(o); hs.add(1); hs.add(r); hs.add(a); hs.add(i); hs.add(n); if(hs.size()==8 && (1000*c+100*h+10*o+o)*2 == 10000+1000*r+100*a+10*i+n) System.out.println( " "+c+h+o+o+"\n+ "+c+h+o+o+"\n------\n "+1+r+a+i+n+"\n"); hs.clear(); } } |
Mit gondolsz, melyik megoldás hajtódik végre gyorsabban? Miért?
A feladatnak két megoldása van: 5466 + 5466 = 10932 és 5488 + 5488 = 10976.
A bejegyzéshez tartozó teljes – időméréssel kiegészített – forráskódot ILIAS e-learning tananyagban tesszük elérhetővé tanfolyamaink résztvevői számára.
Akinek kedve támadt, lásson hozzá hasonló feladatokhoz:
- SEND + MORE = MONEY
- 6 * KAYAK = SPORT
- 2 * MOST = TOKYO
- CROSS + ROADS = DANGER
- FORTY + TEN + TEN = SIXTY
- mathsisfun.com – Algebra Puzzles
- cryptarithms.awardspace.us – Crack-a-Puzzle Online – Puzzles Menu
- www.campusgate.co.in – Cryptoarithmetic problem with explanation
A feladat a Java SE szoftverfejlesztő tanfolyam szakmai moduljának 9-12. óra: Metódusok, rekurzió alkalomhoz, illetve a 21-24. óra: Objektumorientált programozás, 2. rész alkalomhoz kötődik.
A SEND+MORE=MONEY kézi megoldását láthatjuk a videóban lépésenként:
https://www.youtube.com/watch?v=kKF-qBaGgAY
Ajánljuk rendezvényeinket, ahol időről-időre tartunk élményszerű foglalkozásokat, válogatva a logikus gondolkodásra nevelés feladatgyűjteményünkből.
Itt egy másik hasonló gondolkodtató feladvány:
Az alábbi weboldalon találtam, ahol van hozzá szöveges magyarázat, ppt és videó is:
https://mindyourdecisions.com/blog/2020/01/27/solve-for-3-digits-belgian-olympiad/
Én is találtam egy jót:
A népszerű gyermekdal (YT videó) 🙂
Train Song: Choo Choo Train for Children, Kids, Babies and Toddlers | Counting Song | Miss Patty
Íme néhány nehezebb példa a kihívást keresőknek. Ezeket már másképpen érdemes/hatékony megoldani:
AN + ACCELERATING + INFERENTIAL + ENGINEERING + TALE + ELITE + GRANT + FEE + ET + CETERA = ARTIFICIAL + INTELLIGENCE
NIIHAU ± KAUAI ± OAHU ± MOLOKAI ± LANAI ± MAUI ± HAWAII = 0
PI * R * R = AREA
NORTH / SOUTH = EAST / WEST
Nem csak egy konkrét példa megoldásának szintjén lehet gondolkodni, így aki még kitartóbb általánosabban is lehet: keresse meg az összes
n1 + ... + nt = n'1 + ... + n't'
alakú egyenletet úgy, hogy angolul mind matematikailag, mind pedig alfametikailag igazak legyenek, ha minden változó 20-nál kisebb különböző pozitív egész. Például:TWELVE + NINE + TWO = ELEVEN + SEVEN + FIVE
Forrás: D. E. Knuth: A számítógép-programozás művészete, 4. kötet, 2. rész, Permutációk és n-esek előállítása, AnTonCom Infokommunikációs Kft., Budapest, 2008, ISBN 987-963-87947-1-0
Úgy érzem, hogy megértettem a rekurziót az ILIAS-os példák alapján és próbálkoztam ezzel a feladattal. Tehát íme a CHOO + CHOO = TRAIN rekurzívan:
Látszik, hogy alaposan átgondoltad és megértetted a rekurziót Anett. A szöveg jelenti az emlékezetet a programodban. A karakterek számmá átalakításához a karakterkódok különbségeit használtad. Én is továbbgondoltam a megoldásodat és kicseréltem ezt csomagolóosztály konvertáló függvényére úgy, hogy a számjegyeket
;
választja el egymástól:Nem mértem, hogy melyikünk megoldása hatékonyabb, csak egy alternatívát szerettem volna mutatni. A rekurzió általában mindig lassabban működik az iterációhoz képest. Persze a használt adatszerkezet karbantartó műveleteinek igényeire is tekintettel kell lenni. Örülök, hogy inspirált a feladat.
Gratulálok Anett, hogy már itt tartasz. Én ezeket még nem ugrottam meg, de már kitaláltam, hogy a két alábbi
c
miért egyezik meg:c=s.charAt(0)-'0';
c=Integer.parseInt(s.split(";")[1]);
😉
Ez is rendben van Kriszta, hiszen fontos és szükséges lépés az odavezető úton.
Köszönöm Sándor. Kipróbáltam az ILIAS-ban lévő Unit tesztes időmérő tesztkörnyezettel és ezeket kaptam:
1. megoldás végrehajtási ideje: 9 ms
2. megoldás végrehajtási ideje: 129 ms
3. megoldás végrehajtási ideje: 395 ms
4. megoldás végrehajtási ideje: 2361 ms
Szóval a rekurzió fejben nagyon szép, de a gyakorlatban nem annyira.
Köszönöm Anett. Örülök, hogy ehhez összeraktad fejben az öröklődéssel való testre szabást is, ami kellett a teszteléshez ebben a környezetben.
Nohát, micsoda aktivitás van itt újév alkalmából. 🙂 Anett, Kriszta: igazán motiváltak vagytok, szuper!