Ga naar inhoud
  • 0

Voor een regenachtig weekend :)


rmw

Vraag

Ik weet niet wie van jullie ooit de hersenbreker kruiswoordpuzzels heeft gemaakt, maar ik kwam er weer eentje tegen afgelopen weekend en dacht daar moet een custom functie voor te schrijven zijn :)

Even wat info vooraf.

Een hersenbreker is een kruiswoordpuzzel waarbij geen omschrijving van het in te vullen woord wordt opgegeven, maar een vermenigvuldiging van de plaats van de letters in het alfabet van het in te vullen woord. Dus het woord 'absurd' krijgt dan als omschrijving ( 1x2x19x21x18x4 = ) 57.456

Als je in de puzzel de 's' uit dat woord al hebt, dan wordt de omschrijving dus 57.456 / 19 = 3.024 voor de ontbrekende 5 letters.

Heb je ook nog de 'd' dan moeten de 4 overgebleven letters 756 opleveren.

Vindt je de 'a' dan wijzigt de 'omschrijving' niet, maar moet je dat resultaat met 3 letters zien te vinden.

 

En toen wilde ik graag een functie waar ik de 'omschrijving' aan mee geef, met het aantal letters en die me dan de mogelijke letter combinaties teruggeeft.

Resultaat is een custom functie met de volgende definitie:

Case (
  theNumber = 0 ; If ( IsEmpty ( theString ) ; "" ; "¶" & theString ) ;
  ( theStart > 26 ) ; Breakdown ( theGetal / theStart ; theNumber - 1 ; 1 ; "" ) ;
  ( ( theGetal / theStart ) <= ( 26 ^ ( theNumber - 1 ) ) ) and ( Mod ( theGetal ; theStart ) = 0 ) ; Breakdown ( theGetal / theStart ; theNumber - 1 ; 1 ; Char ( 64 + theStart ) & theString ) & Breakdown ( theGetal ; theNumber ; theStart + 1 ; theString ) ; 
  Breakdown ( theGetal ; theNumber ; theStart + 1 ; theString )
)

Aan te roepen als 

Breakdown ( 13200 ; 3 ; 1 ; "" )

Met als resultaat 


YXV
XYV
YVX
VYX
XVY
VXY

En nou komt de uitdaging voor een regenachtig weekend (en als je het tot hier gered hebt met lezen heb je toch niks beters te doen :))  :

Graag het resultaat opschonen op unieke letter combinaties. Het bovenstaande wordt dan dus 

YXV

Nog een voorbeeld 

Breakdown ( 168 ; 2 ; 1 ; "" )

geeft

XG
UH
NL
LN
HU
GX

moet worden

XG
UH
NL

Welke unieke combinatie teruggegeven wordt maakt mij niet zoveel uit.

Nog een voor de duidelijkheid :) 

Breakdown ( 5720 ; 3 ; 1 ; "" )

geeft 

ZVJ
VZJ
ZTK
TZK
VTM
TVM
ZKT
VMT
MVT
KZT
ZJV
TMV
MTV
JZV
VJZ
TKZ
KTZ
JVZ

moet worden

JVZ
KTZ
MTV

rmw

aangepast door rmw
Link naar reactie

5 antwoorden op deze vraag

Aanbevolen berichten

  • 0

O, en voor de zekerheid: het liefst zie ik de custom functie aangepast. Dus niet een bewerking van het resultaat achteraf.

En voor de parameters: de functie aanroep is Breakdown ( theGetal; theNumber; theStart; theString )

Dus eerst de 'omschrijving', dan het aantal letters, dan het nummer van de letter die je wilt controleren en tenslotte de letters die je al gevonden hebt.

rmw

aangepast door rmw
Link naar reactie
  • 0

Als je de losse letters van de 18 drielettercombinaties sorteert op alfabet dan houdt je uiteindelijk de drie unieke waarden over die je zoekt. Via een zelfrelatie o.i.d.?

Hoe dit programmeertechnisch moet weet ik niet, maar daar zijn (andere) knappe koppen beter in.

Link naar reactie
  • 0

Bij mij regent het niet, en heb ook genoeg te doen, maar heb toch even meegelezen :-)

Ik zou zeggen: gebruik de While functie op de grove lijst, sorteer elk item, en daar UniqueValues. Dat is niet zo moeilijk, of ik moet je verkeerd begrijpen.

Ik zou die CF ook met While inrichten ipv recursief, dan kan je alles in één keer doen met meer beheersing van de logica..

 

Link naar reactie
  • 0

Met dank aan de tips en trucs van een ieder heb ik wat ik hebben wilde!

Custom functie: 

Let (
[
	xSchrijven = Char ( 64 + theStart ) ; 
	xRest = Mod ( theGetal ; theStart ) = 0 ; 
	xMeerMogelijk = ( theGetal / theStart ) <= ( 26 ^ ( theNumber - 1 ) ) 
] ; 

Case (
	theNumber = 0 ; If ( IsEmpty ( theString ) ; "" ; "-" & Substitute (  theString ; "¶" ; "" ) ) ;
	( theStart > 26 ) ; Breakdown ( theGetal / theStart ; theNumber - 1 ; 1 ; "" ) ;
	xRest and xMeerMogelijk ; Breakdown ( theGetal / theStart ; theNumber - 1 ; 1 ; SortValues ( List ( xSchrijven ; theString ) ) ) & Breakdown ( theGetal ; theNumber ; theStart + 1 ; theString ) ; 
	Breakdown ( theGetal ; theNumber ; theStart + 1 ; theString )
)

)

Aanroep: 

Replace ( UniqueValues ( Substitute ( Breakdown ( 13200 ; 3 ; 1 ; "" ) ; "-" ; "¶" ) ) ; 1 ; 1 ; "" )

Uitkomst:

VXY

Nog een voorbeeld: 

Replace ( UniqueValues ( Substitute ( Breakdown ( 168 ; 2 ; 1 ; "" ) ; "-" ; "¶" ) ) ; 1 ; 1 ; "" )

Uitkomst: 

GX
HU
LN

Net niet helemaal alles in de custom functie, maar het is wel 1 aanroep. Dank voor de aangedragen suggesties!!

 

Ik heb ook nog gekeken of en hoe ik dit met een While zou kunnen bereiken, maar dat zie ik nog niet 1,2,3 gebeuren. Het voordeel van recursie is dat je de logica maar 1 keer hoeft te schrijven en daarna kan aanroepen zo vaak je wilt. Ik ben het overigens absoluut met @Marsau eens dat het er daardoor niet doorzichtiger op wordt!

Ik zal proberen duidelijk te maken waarom ik denk dat de While niet gaat werken.

Als je drie letters moet vinden start je de eerste  keer met het afgaan van het alfabet af en de 'omschrijving' deel je dan door de waarde van de letter. Het is echter niet mogelijk om dat volledig te doen en dan verder te gaan met de tweede ronde. Zodra je in de eerste ronde een letter vindt die voldoet (rest = 0) moet je gaan kijken of het resultaat is klein genoeg om nog minimaal 2 keer een Z te bevatten en begin je opnieuw met het berekenen, maar dan voor letter 2 en met de nieuwe 'omschrijving' nl. oorspronkelijke 'omschrijving' gedeeld door de waarde van de letter.

Voor het eerste voorbeeld (13200) vindt je dus als eerste de T (13200/20 heeft rest nul). Ook het resultaat van de deling (660) is kleiner dan 2 maal de Z (26x26=676).

Met het resultaat begin je dus aan de 2e ronde, waarbij je eigenlijk dezelfde logica afloopt (rest moet nul zijn en resultaat moet nu minimaal 1 Z kunnen bevatten).

En als je daarbij een letter vindt die voldoet, dan start je dezelfde logica voor ronde 3. Vindt je in ronde 2 geen letter, dan kan je aan het einde van het alfabet, ronde 3 overslaan.

En als je dan klaar bent met ronde 3, ga je dus weer verder waar je gebleven was in ronde 1.

Met de While functie kan ik wel nesten, maar alleen door eerst het aantal letter-rondes te definiëren en daarbinnen de alfabet-ronde. Dat is niet recursief, maar lineair.

Maar ik laat me graag corrigeren, dus als het iemand lukt met de While functie zie ik dat graag hier gepost :)

rmw

Link naar reactie
  • 0

Kleine aanpassing nog...

Omdat we pas aan de volgende ronde kunnen beginnen als we alle letters van het alfabet hebben gehad (de controle 'theStart > 26') moeten we nog een extra test doen voordat we echt aan de volgende ronde beginnen. Het kan namelijk voorkomen dat letter 27 ([) een heel getal oplevert (bijvoorbeeld bij 324 en drie letters), waardoor de volgende ronde ten onrechte wordt gestart.

Dus als letter 27 mogelijk als OK kan worden aangemerkt (er is geen rest bij deling) dan kunnen we toch aannemen dat er toch geen volgende ronde nodig is. Ergo de toevoeging 'If ( xGeenRest ; 0 ; theNumber - 1 )' bij het starten van de volgende ronde, als alle letters zijn geweest.

Let (
[
	xGeenRest = Mod ( theGetal ; theStart ) = 0 ; 
	xMeerMogelijk = ( theGetal / theStart ) <= ( 26 ^ ( theNumber - 1 ) ) ; 
	xNextGetal = theGetal / theStart ; 
	xSchrijven = SortValues ( List ( Char ( 64 + theStart ) ; theString ) )  
] ; 

Case (
	theNumber = 0 ; If ( Substitute ( theString ; "¶" ; "" ) = "" ; "" ; "-" & Substitute ( theString ; "¶" ; "" ) ) ;
	theStart > 26 ; Breakdown ( xNextGetal ; If ( xGeenRest ; 0 ; theNumber - 1 ) ; 1 ; "" ) ;
	xGeenRest and xMeerMogelijk ; Breakdown ( xNextGetal ; theNumber - 1 ; 1 ; xSchrijven ) & Breakdown ( theGetal ; theNumber ; theStart + 1 ; theString ) ; 
	Breakdown ( theGetal ; theNumber ; theStart + 1 ; theString )
)

)

rmw

PS. Ik dacht in de vorige post de oplossing te hebben, maar die heb ik toch maar weer verwijderd. Deze is beter :)

Link naar reactie

Doe mee aan dit gesprek

Je kunt dit nu plaatsen en later registreren. Indien je reeds een account hebt, log dan nu in om het bericht te plaatsen met je account.

Gast
Beantwoord deze vraag...

×   Geplakt als verrijkte tekst.   Plak in plaats daarvan als platte tekst

  Er zijn maximaal 75 emoji toegestaan.

×   Je link werd automatisch ingevoegd.   Tonen als normale link

×   Je vorige inhoud werd hersteld.   Leeg de tekstverwerker

×   Je kunt afbeeldingen niet direct plakken. Upload of voeg afbeeldingen vanaf een URL in

×
×
  • Nieuwe aanmaken...