QB64.org Forum

QB64 Team Software => InForm-based programs => Topic started by: Qwerkey on August 06, 2018, 05:32:00 am

Title: My First InForm Program - Trackword
Post by: Qwerkey on August 06, 2018, 05:32:00 am
This is my first program created with InForm.  Firstly, I must reiterate members' comments on what a superb achievement is Fellippe's work in creating InForm.  I have previously attempted to code in Microsoft's Visual Basic 6 (just about usable with no graphics available) and then their Visual Studio (completely unworkable).  Fellippe has achieved everything that we should have desired from the Microsoft stuff with much easier usage and integrated into all that we wish to do in QB64.  Hats off again to Fellippe.

The program provides all the solutions to a particular kind of puzzle (Trackword) which appears in a specialist magazine.  Many years ago, I originally created a program for this in QuickBasic 2, and I have used this as a basis for learning to use InForm.  InForm is so user-friendly that there was only a little work needed to convert from the original text-only program.  In fact, the programming difficulty and interest was in the original work in creating the algorithm which finds all the solutions (and only those which are valid).  Looking at the code now, it is quite difficult to work out how the algorithm works exactly.  I must have been brighter all those years ago.

Should you be interested to run this specialist program, you will need to download the pdf.  The solving routine needs tens of thousands of computational cycles and needs a modern fast machine.  A slower machine will give a noticeable pause before answers are displayed.  I should have programmed a progress bar, but I thought that this little starter project did not justify it.

Richard

[Edit:  Manual updated 16/2/19]
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 06, 2018, 09:03:53 am
Hi Qwerkey,

Once again my system is hung by having to remove ../ from include files but after that everything worked great!

33 words found in "Trackword" word.

Very nice use of Inform!

So it's not just the permutations of 9 letters but all the permutations of letters up to 9 and then checking it's a word.
But you probably don't check all permutations (because on my system that takes a while just to do 9 letters) but just find words with same group of letters? Darn quick finds anyway!
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 06, 2018, 09:20:40 am
Wait, it could probably be done with one pass through dictionary!

Just check each word to see if it has same letters as in the starting 9.

That algo might be same as bulls and cows (but only checking cows), except you can quit word as soon as there is no matching letter.
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 06, 2018, 09:35:22 am
oops... I just tried BPLUSLOOPS and neither PLUS nor LOOP nor LOOPS came up but with LOOPSBPLUS, PLUS did come up.

I am going dig up my algo for counting cattle.

EDIT double check BPLUSLOOP no loop, loops or plus, but LOOPBPLUS is good!
Title: Re: My First InForm Program - Trackword
Post by: Qwerkey on August 06, 2018, 09:38:57 am
Hi bplus, thanks for trying it.  I honestly thought that this was so specialist (specific to me) that nobody else would want to try it - I just put it here for reference.

Wait, it could probably be done with one pass through dictionary!

Just check each word to see if it has same letters as in the starting 9.

That algo might be same as bulls and cows (but only checking cows), except you can quit word as soon as there is no matching letter.

The puzzle is specific in that  the word has to snake through the grid, so letter order is specific.  I am spending some time to speed up the search algorithm, so any additional ideas will be gratefully accepted.  The computing time time taken up forming all the 10,256 allowed letter combinations, not so much checking the dictionary.

The ../ which I put (was not in Fellippe's original), I thought was necessary because of the /Trackwork extra folder layer and I thought the ../ wasrequired  to get back to the QB64 root folder.  Another thing that I have failed to understand.  I shall stand in the corner with a pointed hat on.

Richard
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 06, 2018, 09:46:56 am
Oh sorry, I was not familiar with game, so the word has to appear in the grid in some order ie "snake through grid"?
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 06, 2018, 10:03:16 am
Quote
I am spending some time to speed up the search algorithm, so any additional ideas will be gratefully accepted.

Hi again,

Steve has a Spellcheck program here:
http://qb64.freeforums.net/thread/33/spellcheck

I will bet it is pretty darn quick!

Do the words have to appear like in WordSearch in the grid, ie backwords or forwards, across, up/down or diagonal?
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 06, 2018, 10:11:42 am
Oh they have to connect: http://happysoft.org.uk/countdown/trackword.php

EDIT: Oh and the speed bump is NOT looking up the words but running the snakes.
Title: Re: My First InForm Program - Trackword
Post by: FellippeHeitor on August 06, 2018, 12:57:54 pm
This is my first program created with InForm.  Firstly, I must reiterate members' comments on what a superb achievement is Fellippe's work in creating InForm.  I have previously attempted to code in Microsoft's Visual Basic 6 (just about usable with no graphics available) and then their Visual Studio (completely unworkable).  Fellippe has achieved everything that we should have desired from the Microsoft stuff with much easier usage and integrated into all that we wish to do in QB64.  Hats off again to Fellippe.

Thank you so much, Richard! That makes me want to go even further in the development of InForm, I really appreciate it.

The program provides all the solutions to a particular kind of puzzle (Trackword) which appears in a specialist magazine.  Many years ago, I originally created a program for this in QuickBasic 2, and I have used this as a basis for learning to use InForm.  InForm is so user-friendly that there was only a little work needed to convert from the original text-only program.  In fact, the programming difficulty and interest was in the original work in creating the algorithm which finds all the solutions (and only those which are valid).  Looking at the code now, it is quite difficult to work out how the algorithm works exactly.  I must have been brighter all those years ago.

Should you be interested to run this specialist program, you will need to download the pdf.  The solving routine needs tens of thousands of computational cycles and needs a modern fast machine.  A slower machine will give a noticeable pause before answers are displayed.  I should have programmed a progress bar, but I thought that this little starter project did not justify it.

Richard

I love it! You seem to have gone through InForm's wiki since you used many methods we didn't even get to discuss over email. Great job there.

If you wanted to make it more portable, you'd need to include 4 extra files in your zip, so that one wanting to run your program but not interested in the full InForm package could still do so:


One last thing I forgot to ask: Did you download the zip package for InForm or did you use the installer?
Title: Re: My First InForm Program - Trackword
Post by: Aurel on August 06, 2018, 03:06:24 pm
Nice
I don't know that qb64 can produce" native" GUI apps.
So i s that wrapped trough sdl libs or is used native wrapper to win32 api calls( CDCL).
Why i babeling about this is that i have written almost complete set of GUI funcs but writtebn in o2
BUT can be build into one dll.
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 07, 2018, 01:16:34 am
Quote
The puzzle is specific in that  the word has to snake through the grid, so letter order is specific.  I am spending some time to speed up the search algorithm, so any additional ideas will be gratefully accepted.  The computing time time taken up forming all the 10,256 allowed letter combinations, not so much checking the dictionary.

Hi Qwerkey,

I have worked out a 2 part system:
Part 1 builds a one time only, Master Snakes.txt file, that contains the 10256 letter snakes that can be formed on the 3x3 grid.
The snakes are listed as strings of square numbers. This is done once for all time, no need to do again.

Part 2:
Loads the snake patterns, the dictionary words and gets down to business by translating the square numbers to letters in the given word grid or just a 9 letter word string. With the word formed it checks the word list with binary search and stores all matches in array that is sorted and then displays and recounts only unique words.

You might like to see the little recursive gem that is only about a dozen lines called "build2" that gets all snake patterns for each square of grid, the heart of the whole thing.

Title: Re: My First InForm Program - Trackword
Post by: Qwerkey on August 07, 2018, 04:03:35 am
Quote
The puzzle is specific in that  the word has to snake through the grid, so letter order is specific.  I am spending some time to speed up the search algorithm, so any additional ideas will be gratefully accepted.  The computing time time taken up forming all the 10,256 allowed letter combinations, not so much checking the dictionary.

Hi Qwerkey,

I have worked out a 2 part system:
Part 1 builds a one time only, Master Snakes.txt file, that contains the 10256 letter snakes that can be formed on the 3x3 grid.
The snakes are listed as strings of square numbers. This is done once for all time, no need to do again.

Part 2:
Loads the snake patterns, the dictionary words and gets down to business by translating the square numbers to letters in the given word grid or just a 9 letter word string. With the word formed it checks the word list with binary search and stores all matches in array that is sorted and then displays and recounts only unique words.

You might like to see the little recursive gem that is only about a dozen lines called "build2" that gets all snake patterns for each square of grid, the heart of the whole thing.

bplus, wow you've certainly taken an interest in this.  I have just started a method where the 10,256 confiurations are created then used (and maybe on 5,128 and then reverse the word), so I'll certainly look inot what you've done.

Thanks very much, Richard
Title: Re: My First InForm Program - Trackword
Post by: Qwerkey on August 07, 2018, 04:08:05 am
If you wanted to make it more portable, you'd need to include 4 extra files in your zip, so that one wanting to run your program but not interested in the full InForm package could still do so:

One last thing I forgot to ask: Did you download the zip package for InForm or did you use the installer?

Fellippe, I'll look into the portability thing.  That looks more flexible.  I've more reading of the wiki to do - you did a great job with that, as well.  I used the Installer from the Website.

Richard
Title: Re: My First InForm Program - Trackword
Post by: Qwerkey on August 07, 2018, 05:53:39 am
A quick look into timings goes as follows:

Existing method (non-Inform, tetxt only): 0.768s
Pre-prepared (as bplus, but my coding): 0.69s
Existing method in Inform: 1.15s

So, firstly changing to InForm, but exactly the same search/check routine slows the process down (not quite sure why).  Secondly, there is a slight improvement with the pre-prepared method, but I've not yet optimised this or used bplus exact method.

Richard
Title: Re: My First InForm Program - Trackword
Post by: FellippeHeitor on August 07, 2018, 06:20:24 am
Try adding this before your search routine:

Code: QB64: [Select]
  1.     TIMER(__UI_EventsTimer) OFF
  2.     TIMER(__UI_RefreshTimer) OFF

Just don't forget to turn those timers back on after you're done:

Code: QB64: [Select]
  1.     TIMER(__UI_EventsTimer) ON
  2.     TIMER(__UI_RefreshTimer) ON

InForm's events and repaint routines are timer-based and that surely takes up some cycles. The tradeoff of the above method is that your interface will remain unresponsive while the calculations take place. You must judge if the speed gain is considerable enough to justify the tweak.
Title: Re: My First InForm Program - Trackword
Post by: Qwerkey on August 07, 2018, 06:35:45 am
Crikey, Fellippe!  Is it not 06.30 in Brazil?  Richard
Title: Re: My First InForm Program - Trackword
Post by: FellippeHeitor on August 07, 2018, 06:41:55 am
A bit later, 7:40 now. Code time before the baby's up ♥️.
Title: Re: My First InForm Program - Trackword
Post by: Qwerkey on August 07, 2018, 06:51:00 am
So, you're holding down two jobs, you do all this work on QB64, you answer everybody's questions, AND you've a baby?

Incredible!
Title: Re: My First InForm Program - Trackword
Post by: FellippeHeitor on August 07, 2018, 07:00:21 am
Title: Re: My First InForm Program - Trackword
Post by: Qwerkey on August 07, 2018, 07:08:16 am
So now some technical questions.  In the Trackword program, when the solve routine is happening, we've just pressed the "Solve" button, so the program is in the SUB __UI_Click (id AS LONG) subroutine, and stays there until the solve routine is complete.  During that time, the computer doesn't "know about" the Inform part - it's just doing the calculations.  So, are the  TIMER(__UI_EventsTimer) OFF &  TIMER(__UI_RefreshTimer) OFF statements going to do anything?

When I was considering putting in a Progress Bar, I assumed that the solve routine would have to be placed in the SUB __UI_BeforeUpdateDisplay subroutine with a 30 times / second (default) _DISPLAY update.  But as this program hasn't left the SUB __UI_Click (id AS LONG) subroutine, it shouldn't be affected by any InForm stuff?  You can tell that I haven't got a clue as to how machine-level code (or any other level come to that) works.

Richard
Title: Re: My First InForm Program - Trackword
Post by: FellippeHeitor on August 07, 2018, 07:28:25 am
TIMERs are QB64's way of multithreading if you will, which means that even while the calculations are going on in SUB __UI_Click, which was fired by the __UI_EventsTimer, the interface keeps on being updated because __UI_RefreshTimer keeps being fired at ~30fps (or as otherwise set by the SetFrameRate method).

What I'd do if I wanted a ProgressBar control to be updated while the calculations take place would be something like this (pseudo code):

    DIM SHARED progressValue AS LONG
    DIM SHARED isCalculating AS _BYTE

    'in sub Click:
    if id = solveButton then
        isCalculating = True
        maxStep = whateverRichardSaysItIs
        control(ProgressBar).max = maxStep
        for progressValue = 1 to maxStep
             'do your thing
        next
        isCalculating = False
    end if

    'in sub BeforeUpdateDisplay:
    if isCalculating then
        control(ProgressBar).Hidden = False
        control(ProgressBar).value = progressValue
    else
        control(ProgressBar).Hidden = True
    end if

Notice how BeforeUpdateDisplay sub will deal with whatever is going on in sub Click.
Title: Re: My First InForm Program - Trackword
Post by: Qwerkey on August 07, 2018, 10:57:48 am
bplus, I've looked into your work.  Thanks very much.  Your algorithm to build the 10,256 combinations is amazing.  I never understood recursion.  In my code, every possible cell-to-cell connection is tried one after the other.

When your algorithm 2 is used, the time taken to do the search is 0.66seconds, compared to my values above (it's slightly dependent upon which word is searched).  So values are similar.  However, that time includes reading the dictionary file into the array, which you have to do.

The time taken to do the seach (after the dictionary is loaded) in your method is 0.05seconds.  That is quite a change indeed.

In my program, I do the dictionary search directly from hard disc file.  I had assumed that the computation time would be taken up in doing the text manipulations to create the 10,256 words.  But it does now seem as if it is the dictionary search which is taking the time.  I'll try your method in my code.

Thanks a lot, Richard
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 07, 2018, 11:16:02 am
Hi Richard,

You are most welcome! Thank you for such an interesting post I seemed ready to help.
Title: Re: My First InForm Program - Trackword
Post by: Qwerkey on August 08, 2018, 05:30:42 am
bplus, I quickly tried changing my code to using an array (like you do) instead of searching the dictionary.rnd file and then the time taken increased to an extraordinary 13.5 seconds!!  I've also noticed that sometimes my code can be unstable, sometimes not quite getting all the words and/or not getting all the nine-letter words: very odd and I must have checked the code many times.  So, I'll completely overwrite my searching code with yours, and then I'll add your name to the credits for which your actual name as well would be useful.

Richard
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 08, 2018, 08:55:12 am
Hi Richard,

Make sure you are loading files once at the beginning of program, a one time only event and you definitely want event checking off while doing that along with using Fellippe's ideas for turning off event checking while doing the calculations.

As far as using my actual name, my first name is Mark, my initials are MGA, and that is as far as I am comfortable revealing personal info at moment.

On 2nd thought, the file / array loading code could be done in main section of bas file, before any event? Again check with Fellippe.

PPS Again I remind you, Steve's methods / example used for his spell checker program are probably way better optimized than what I wrote in a night just to test the concepts. Before the binary search method was employed (the found sub), my word find (brute force) was really slow too!

PS ^2 use "QB64 Team" as my last name!
Title: Re: My First InForm Program - Trackword
Post by: Qwerkey on August 08, 2018, 12:03:19 pm
bplus, I didn't wish to intrude into your privacy.  "QB64 Team" will do quite well for credits.

I'll definitely do all the loading, array addressing as a one-off at program start.  I'm happy to copy exactly what you've done: it works so well.  I'd be grateful if you'd just give your search function another check over.

Code: QB64: [Select]
  1. FUNCTION found% (w$)
  2.     lo& = 0: hi& = UBOUND(words$)
  3.     WHILE hi& - lo& > 1
  4.         test& = (hi& - lo&) / 2 + lo&
  5.         IF w$ = words$(test&) THEN
  6.             found% = 1: EXIT FUNCTION
  7.         ELSEIF w$ > words$(test&) THEN
  8.             lo& = test&
  9.         ELSE
  10.             hi& = test&
  11.         END IF
  12.     WEND
  13.     'if still here then
  14.     found% = 0

My equivalent of this would use  test& = (hi& - lo&) \ 2 + lo& instead of  test& = (hi& - lo&) / 2 + lo&.  And when the RHS is odd, yours gives one integer higher than mine (which rounds down - your rounds up).

I ought to be able to work out which is the correct one, but the (simple) algorithm scrambles my brain.  If you're happy that yours always finds any match as it clearly seems to, I'll go with that.

Thanks a lot, Richard
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 08, 2018, 01:00:35 pm
Ha! That's funny, I thought x/2 always returns the lower if x is integer type or long type...

Without researching carefully, I would strongly guess it doesn't matter whether it is rounded up or down.

Maybe change
WHILE hi& - lo& > 1

to
WHILE hi& - lo& >= 1

to cover our butts?  Whatever way, the conservative answer is to keep test& rounded down for low side and rounded up for hi side, so that test& never jumps past our target word.

OK I will test these ideas... stay tuned, unless you've done your own tests already.

I am glad you like QB64 Team, they should get credit! :)
Title: Re: My First InForm Program - Trackword
Post by: FellippeHeitor on August 08, 2018, 01:03:05 pm
What are we getting credit for?
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 08, 2018, 01:11:15 pm
Being helpful, creating a great PL, keeping it updated, fixing bugs adding features and documented and answering questions, the people at this forum helping each other with ideas and moral support...

When I say QB64 Team, I mean all who participate in this process.

Does QB64 Team have another meaning?
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 08, 2018, 02:06:12 pm
The Binary search method works the same as playing the Hi Lo Game with AI;
Code: QB64: [Select]
  1. _TITLE "Hi Lo Game AI"
  2. ' Hi Lo AI.bas SmallBASIC 0.12.9 (B+=MGA) 2017-08-14
  3.  
  4. DEFLNG A-Z
  5.  
  6. secret = 0
  7. secret = 11 'another limit test
  8.  
  9. 'test intelligence of this program with boner!  comment next code line
  10.  
  11. '  for limit tests comment next line or uncomment for normal range test
  12. secret = INT(RND * 10) + 1 ' < 1 to 10
  13.  
  14.  
  15. Hi = 11: Lo = 0 '<<<<  make these higher and lower than what the secret number can be (just tested secret = 10, oops!)
  16. guessNumber = 0
  17. WHILE Hi - Lo > 1 '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< test both > 1 AND >= 1  Result: Does not work with >= 1
  18.     guess = (Hi - Lo) \ 2 + Lo '<<<<<<<<<<<<<<<<<<<<<<<< test both / AND \       Result: Both work OK
  19.     guessNumber = guessNumber + 1
  20.  
  21.     PRINT guessNumber; " Guess is "; guess; ", ";
  22.     IF guess = secret THEN
  23.         PRINT "Yes! The secret number was "; guess
  24.         PRINT: PRINT "Here comes another round! "
  25.         INPUT "OK, press enter"; dummy$
  26.         PRINT
  27.         Hi = 11: Lo = 0: guessNumber = 0: secret = INT(RND * 10) + 1
  28.     ELSEIF guess > secret THEN
  29.         PRINT "Too high!"
  30.         Hi = guess
  31.     ELSE
  32.         PRINT "Too Low!"
  33.         Lo = guess
  34.     END IF
  35. PRINT "Yikes! Programming error, did not find secret number."
  36. PRINT "WTH? did someone mess with secret number?"
  37.  

What could go wrong is NOT setting Hi, high enough at start or Lo, low enough at start. (And I don't think I did make Hi high enough AND Lo low enough with my test code. Fortunately a word wasn't first or last.)

While Hi  - Lo > 1   keep testing,     NOT While Hi - Lo >= 1, it will never finish!

It did NOT make a difference if / or \ was used.

Sorry, code needed further edits.
Title: Re: My First InForm Program - Trackword
Post by: FellippeHeitor on August 08, 2018, 02:19:22 pm
Does QB64 Team have another meaning?

Well, kind of (https://twitter.com/qb64team). Luke, STxAxTIC and I maintain qb64.org under that name, so I guess that's what you meant after all?
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 08, 2018, 04:51:23 pm
Does QB64 Team have another meaning?

Well, kind of (https://twitter.com/qb64team). Luke, STxAxTIC and I maintain qb64.org under that name, so I guess that's what you meant after all?

Hi Fellippe,

Well I know you 3 above in quote as Odin from here of course, and I remember you using the "QB64 Team" name with the Christmas Challenge on Facebook (from NET) and assumed you were referencing all the people who submitted code, STxAxTIC and Luke had not participated then with that as I recall.

I am totally unfamiliar with Twitter stuff and link, so I didn't know.

If "QB64 Team" name is "taken", I am sure we can come up with something else that is satisfactory to all.

Maybe "Team QB64"? ;-))

 
Append:
Oh it was Happy 2017 thing not Christmas:

BTW, only time I spent any time on Facebook was to check that 2017 thing out.
Title: Re: My First InForm Program - Trackword
Post by: SMcNeill on August 08, 2018, 06:13:51 pm
Maybe "Team QB64"? ;-))

How about The QBCoders?  With a nice QBC logo drawn over by a 64 for a pretty visual.
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 08, 2018, 07:12:04 pm
Maybe QB64 Synergy

the interaction or cooperation of two or more organizations, substances, or other agents to produce a combined effect greater than the sum of their separate effects.

Nice goal.
Title: Re: My First InForm Program - Trackword
Post by: Qwerkey on August 10, 2018, 04:52:38 am
Nearly ready to update program with mods as discussed above.

Fellippe, you mentioned making the program portable which is a good idea.

If you wanted to make it more portable, you'd need to include 4 extra files in your zip, so that one wanting to run your program but not interested in the full InForm package could still do so:

    InForm/InForm.ui
    InForm/xp.uitheme
    InForm/InFormVersion.bas
    falcon.h


I tried moving the four files into the Trackword folder, and changed
'$INCLUDE:'..\InForm\InForm.ui'
'$INCLUDE:'..\InForm\xp.uitheme'

to
'$INCLUDE:'InForm.ui'
'$INCLUDE:'xp.uitheme'

The IDE was happy, but failed C++ compilation.  As you know I like to supply all my work in a folder which can be deleted when no longer required - it makes it easier than trying to remove individual files from the QB64 directory.  At the moment, then, I haven't learnt how to make the program independent of InForm.

Richard
Title: Re: My First InForm Program - Trackword
Post by: Qwerkey on August 10, 2018, 05:12:37 am
I'm somewhat bewildered by the above discussion about names to credit.  I hope that nobody will mind if my code starts with lines:
': Trackword Solver by QWERKEY (Richard Notley) 09-08-2018
': bplus created search algorithms
': This program uses
': InForm - GUI library for QB64 - Beta version 7
': Fellippe Heitor, 2016-2018 - fellippe@qb64.org - @fellippeheitor
': https://github.com/FellippeHeitor/InForm

The first line is untrammelled vanity by Qwerkey.
The second maintains bplus's privacy.
The next lines come automatically from the InForm compilation, and rightly acknowledge Fellippe's magnificent work.
We acknowledge the QB64 Team (Team QB64?) by default.

Incidentally, I'm slightly mystified by the Team names "Odin" (I am picturing a stereotypic wise old Nordic god) and "The Librarian" (I am picturing a stereotypic bespectacled quinquagenarian spinster)?

Richard
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 10, 2018, 09:37:19 am
Hi Richard,

There are 4 files to be included in the InForm project folder (and YES! A folder is best way to distribute.)

These are over and above the minimal two you develop for your particular app.

Your folder still needs the falcon.h and the InForm.bas file you created your InForm .bas and .frm files with.
Fellippe called that one InFormVersion.bas (not to be confused with the .bas file you create).

I think the falcon.h file might have to be stored in same folder as the QB64.exe version you are using. It is hard to tell because that is where mine is. I suppose I could test by renaming and seeing if the falcon.h file works from the project folder.

These 4 files are needed to reconstruct and compile the .exe from QB64 so that the exe is for the users platform.


Also the Binary search routine:
When I tested for differences between / and \ ( no difference) I did discover I did not set the Lo low enough and the Hi high enough at  the start of the search, did you catch that when rewriting the code? If you missed it the first and last words from the dictionary will not be "found" by the function of that name and it will return a false false (a 0 when it should return 1 for found).
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 10, 2018, 10:19:23 am
Confirmed:

On my system I had a folder with the falcon.h file on same level as .bas for app and also in the Inform subfolder of the project.
I renamed my falcon.h in my QB64.exe folder falconX.h and the app would not run, but would run when I renamed the falcon.h in folder with QB64.exe.

So those instructions might also be included in the project folder distribution: "Move (or copy) the falcon.h file to the same folder as QB64.exe if you don't already have one there."
Title: Re: My First InForm Program - Trackword
Post by: Qwerkey on August 11, 2018, 05:46:00 am
The final version is now ready, and I confirm bplus's observation that the file falcon.h needs to be in the QB64 folder, but no other part of InForm needs to be present.

The bplus search method gives a much improved search time, now about 0.1s.  This compares to 0.05s which the full bplus method gives.  My sort method for the found words slows it down a little and Inform increases the time by a tiny fraction.  Even on a slow machine of mine it's pretty instantaneous.  We are there!

I thought that I might try to understand the binary search method in detail, and so I went to Wikipedia's expert where the following is given:

Procedure

Given an array A of n elements with values or records A0, A1, ..., An-1, sorted such that A0 = A1 = ... = An-1, and target value T, the following subroutine uses binary search to find the index of T in A.

1.    Set L to 0 and R to n - 1.
2.    If L > R, the search terminates as unsuccessful.
3.    Set m (the position of the middle element) to the floor, [the greatest integer less than or equal to], (L + R)?/?2.
4.    If Am < T, set L to m + 1 and go to step 2.
5.    If Am > T, set R to m - 1 and go to step 2.
6.    Now Am = T, the search is done; return m.

This iterative procedure keeps track of the search boundaries with the two variables. The procedure may be expressed in pseudocode as follows, where the variable names and types remain the same as above, floor is the floor function, and unsuccessful refers to a specific variable that conveys the failure of the search.

Our dictionary array has elements from 1 to 155237 (rather than from "0 to n-1"), so just add 1 to everything.

Then, the following routine (which I have always used in the past) follows this procedure exactly:

Code: QB64: [Select]
  1. Located` = False: P0& = 1: P100& = Entries&
  2. WHILE P0& <= P100& AND NOT Located`
  3.         P50& = INT((P0& + P100&) / 2)
  4.         GET #4, P50&
  5.         InWord$ = RTRIM$(Lex$)
  6.         IF Tt$ = InWord$ THEN
  7.                 Located` = True
  8.         ELSEIF Tt$ > InWord$ THEN
  9.                 P0& = P50& + 1
  10.         ELSE
  11.                 P100& = P50& - 1
  12.         END IF
  13.  

You can see that it works by thinking through an array with 1 to 4 elements and then with 1 to 5 elements.  So, I have used this method in the search function instead of bplus's.  In the actual Trackword program, the BIT variable Located` is replaced by a BYTE variable Located%% as BIT variables are not successfully transferred to/from Functions or Subroutines.

I constructed a program which created an ordered dictionary file with elements 1 to 150,000 and then checked that every element is correctly found and that any word between every element is not found and that a word before and a word after the dictionary elements is not found.

The Wikipedia instruction is that rounding down must be used (as does this function), but I think that because of the P0& = P50& + 1 and P100& = P50& - 1 statements, rounding up also probably works.  Anyway, I'm confident that we've done it correctly.

The simplest procedure for me will be to replace the User Manual in the first section of this post with my updated version, but there is no "Modify" procedure on this website.  Is there a way to modify what's already there?  If I've missed the obvious in usage of the site, I apologise.

Richard
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 11, 2018, 09:44:17 am
Hi Qwerkey,

Code: QB64: [Select]
  1. The final version is now ready,...

Remember you don't need all of the 4 files Fellippe listed but someone who doesn't have InForm does need all 4 files and to move the Falcon.h to same folder as QB64.exe as mentioned before but doesn't hurt to repeat.

Are you still using disk file access for the Binary search?

Just post the code, forget about modifying a previous post. (Can you tell I am eager to test code?)
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 11, 2018, 11:01:18 am
I see a number of improvements in this over the Binary search code I had posted:

Located` = False: P0& = 1: P100& = Entries&  '<<< this starts with Lo one step higher and Hi one step lower
WHILE P0& <= P100& AND NOT Located`
   P50& = INT((P0& + P100&) / 2)              '<<< this is one less calculation than what I had and I wish now I had started with average instead of average of difference! (It would have saved me from the f... comment!
   GET #4, P50&                                       '<<< this, disk file access I still think is slower but are you using that in TrackWord?
   InWord$ = RTRIM$(Lex$)
   IF Tt$ = InWord$ THEN
      Located` = True
   ELSEIF Tt$ > InWord$ THEN
      P0& = P50& + 1                            '<<< ah! a step closer and why not!?
   ELSE
      P100& = P50& - 1                          '<<< ah! also a step closer and why not!?
   END IF
WEND

Plus all the variables are typed better.


Append:
An improvement on this code might be to exit the sub as soon as the word is matched and the function return value is set.

With that done the line
WHILE P0& <= P100& AND NOT Located`

can be reduced to just:
 WHILE P0& <= P100&

Which is one less logical calculation check and one less variable needed: Located`
Title: Re: My First InForm Program - Trackword
Post by: Qwerkey on August 11, 2018, 11:55:50 am
Apologies, bplus.  You may use the existing User Manual.  It will have the correct download pointer.  The updated Manual just has updated instructions (InForm not needed, falcon.h copying required).  Just overwrite everything in the Trackword folder.  The file "HalfABC.rnd" is equivalent to" Master Snakes.txt".  The updated Manual will be clearer for new users.

Of course this program uses dictionary searching within an array and not from the disc file (pardon me for the confusion).  So, the program load time is now a little longer, but not really noticeable.  However, I still use my old method for sorting the found words (which is the part that slows it down a little).

I got the search code from some "standard files" that came with Quickbasic 2.0.  Not mine at all.

Richard
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 11, 2018, 12:02:21 pm
Oh ha! I had forgotten, the link to the download files was in the manual. OK thanks!

Append (why start another reply?):
Code: QB64: [Select]
  1. I got the search code from some "standard files" that came with Quickbasic 2.0.  Not mine at all.

This may explain why EXIT FUNCTION was not used and the flag, Located`, was used.

Title: Re: My First InForm Program - Trackword
Post by: bplus on August 11, 2018, 12:30:54 pm
Yeah! Works right out of the box.

I see a surprise! The number snakes cut in half, you are using word reverse for the symmetric snake that has letters reversed, so from the Master Snakes.txt file you removed all the symmetric reverse snakes. Nice touch!

Now here is the million dollar question (well 25 cents at least) what 9 letter word gives us the most words made from snakes of 3x3 grid? I bet this has been found already, if I know my word enthusiasts.
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 11, 2018, 05:54:52 pm
And the results are in:

Title: Re: My First InForm Program - Trackword
Post by: bplus on August 11, 2018, 11:06:34 pm
Here is a much more interesting screen full. 9 letter words that have 200 or more words snaked around the 3x3 grid.

   


Now I am wondering how many are anagrams of each other.
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 12, 2018, 01:19:44 am
I was surprised, not many of the Trackword 200+ were anagrams of each other:
Code: QB64: [Select]
  1. _TITLE "Trackword 200 Anagram Analysis"
  2. CONST ww = 800
  3. CONST wh = 600
  4.  
  5. SCREEN _NEWIMAGE(ww, wh, 32)
  6. _SCREENMOVE (1280 - ww) / 2 + 30, (760 - wh) / 2
  7.  
  8. 'PRINT AnagramTF%("artss", "stars")      'yeah!
  9. DIM w$(70), a$(70)
  10. wTop = 0
  11. OPEN "Trackword 200.txt" FOR INPUT AS #1
  12.     wTop = wTop + 1
  13.     INPUT #1, w$(wTop)
  14. FOR i = 1 TO wTop
  15.     IF w$(i) <> "" THEN
  16.         ai = ai + 1
  17.         a$(ai) = w$(i)
  18.         FOR j = i + 1 TO wTop
  19.             IF w$(j) <> "" THEN
  20.                 IF AnagramTF(w$(i), w$(j)) THEN
  21.                     a$(ai) = a$(ai) + " " + w$(j) 'move to i word group
  22.                     w$(j) = "" ' this word is used
  23.                 END IF
  24.             END IF
  25.         NEXT
  26.     END IF
  27. 'show results
  28. FOR i = 1 TO ai
  29.     IF i > 33 THEN
  30.         l = i - 33: m = 40
  31.     ELSE
  32.         l = i: m = 1
  33.     END IF
  34.     LOCATE l, m: PRINT i; " "; a$(i)
  35.  
  36. FUNCTION AnagramTF% (w1$, w2$)
  37.     'this only works for words 9 repeated letters or less
  38.     IF LEN(w1$) <> LEN(w2$) THEN EXIT FUNCTION 'false
  39.     'still here
  40.     aw1$ = STRING$(26, "0")
  41.     aw2$ = aw1$
  42.     FOR i = 1 TO LEN(w1$)
  43.         c$ = UCASE$(MID$(w1$, i, 1))
  44.         ac = ASC(c$) - 64
  45.         vc = VAL(MID$(aw1$, ac, 1))
  46.         MID$(aw1$, ac, 1) = LTRIM$(STR$(vc + 1))
  47.         c$ = UCASE$(MID$(w2$, i, 1))
  48.         ac = ASC(c$) - 64
  49.         vc = VAL(MID$(aw2$, ac, 1))
  50.         MID$(aw2$, ac, 1) = LTRIM$(STR$(vc + 1))
  51.     NEXT
  52.     IF aw1$ = aw2$ THEN AnagramTF% = -1
  53.  

EDIT: fix with Ltrim$ the str$ of values

Dang! missing last word.
EDIT 2: fixed
Title: Re: My First InForm Program - Trackword
Post by: Qwerkey on August 12, 2018, 04:34:19 am
bplus, you certainly seem to have found much interest in this little problem.  Thanks for your stimulating inputs.

Richard
Title: Re: My First InForm Program - Trackword
Post by: Qwerkey on August 12, 2018, 06:01:59 am
Another interesting thing to investigate is whether an arrangement of letters gives more than one nine-letter solution.

If you use the following grid, you gey both CARTHORSE and ORCHESTRA (well-known anagrams of each other):
CAR
RHT
OSE

I think that I remmber Clive Doig (he who invented Trackword) setting a puzzle where there were three nine-letter anagrams.  Can there be more than one such solution?  I don't suppose that there can be more than three?

Richard
Title: Re: My First InForm Program - Trackword
Post by: Qwerkey on August 12, 2018, 06:54:50 am
bplus, the following arrangements (and others) all give the same results:

CAR   OSE   CRO   ETR
RHT   RHT    AHS   SHA
OSE   CAR   RTE   ORC

Working out symmetry considerations is beyond me.  Can we reduce HalfABC further by symmetry considerations?  Can we reduce search time even more?

Richard
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 12, 2018, 09:27:09 am
Hi Richard,

With the 3x3 grid, there were 3 types of square, the corner, the side, and the middle. The middle was unique but the corner and side had 3 equivalent rotations that likely could be "translated" number for number for the snake patterns and in same manner for the letter patterns. The snakes could be worked out with results from one corner, side and middle but snakes are one time shot. Doing the same with letter patterns would likely take longer to calculate and translate than just translating a snake pattern to a letter pattern, So is it worth it to reduce snake patterns but require and do the same amount of translations?

The reverse trick was quite clever, easiest to understand and use.

Have you any thought about 4x4 grids? Probably learn even fancier words. :D   If one bothers to check them out eg, wadsetter :)  Which reminds me, do I have an actual dictionary with word AND definition? Such would be a natural addition if you'd like to try Menus with InForm. Heck, it might even be educational, learn while playing... :)

PS a message box would be handy for a quick definition.

Title: Re: My First InForm Program - Trackword
Post by: Qwerkey on August 13, 2018, 12:51:56 pm
Good heavens, bplus!  I am startled to find that our little topic here has made it into the Top Ten posts by replies.  We have only 21 more suggestions each and then we get to No. 1!

Richard
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 13, 2018, 01:39:12 pm
Oh rats!

You have me looking for, and then at, forum stats. Interesting...

Well as Fellippe has mentioned numbers don't exactly mean quality but as I said, quantity is one quality of many...

How does Odin have so many posts? I looked at a quality Odin's posts, only 2 pages not exactly 500+ ???

Append: OK so it doesn't look like a blatant inflation of replies, something more on topic and that I am curious about.

What do you all think of adding an additional capability to define words? To me, it is a most logical, practical, educational and maybe even fun extension of this application of InForm.
Title: Re: My First InForm Program - Trackword
Post by: FellippeHeitor on August 13, 2018, 01:41:44 pm
Odin wanted to show from the start that post racing would be frowned upon
Title: Re: My First InForm Program - Trackword
Post by: bplus on August 13, 2018, 02:12:41 pm
Odin wanted to show from the start that post racing would be frowned upon
Title: Re: My First InForm Program - Trackword
Post by: Qwerkey on August 14, 2018, 01:19:07 pm
User Manual replaced in first section (updated with finished program instructions).  Previous version plus temporary updated version here downloaded 125/39 times (this reply modified 16/02/2019).
Title: Re: My First InForm Program - Trackword
Post by: codeguy on September 04, 2018, 04:55:18 pm
one more attack that may speed up your progress is to generate permutations of your letters in alphabetic order and then do a modified merge search. Since the permutations are in the same lexicographical order as Steve's word list, there is no need to do binary search with a sorted array. Here is the code for generating permutations in ascending order.
Code: [Select]
WIDTH 80, 43
DIM parray(0 TO 8) AS LONG
FOR i = 0 TO UBOUND(parray)
    parray(i) = i
NEXT
PRINT
PRINT
PRINT "permutations"
Permute parray(), 0, UBOUND(parray), np
DO
    x$ = INKEY$
LOOP UNTIL x$ > ""
SYSTEM

SUB DisplayResults (PArray() AS LONG, start, finish, np AS DOUBLE)
DIM i AS LONG
PRINT USING "#,###,###,###,###"; np;
FOR i = LBOUND(parray) TO UBOUND(parray)
    PRINT PArray(i);
NEXT
PRINT
END SUB

SUB Rotate (parray() AS LONG, Start AS LONG, finish AS LONG)
DIM ts AS LONG
ts = parray(Start)
FOR i = Start TO finish - 1
    SWAP parray(i), parray(i + 1)
NEXT
parray(finish) = ts
END SUB

SUB Permute (parray() AS LONG, start AS LONG, finish AS LONG, np AS DOUBLE)
np = np + 1
DisplayResults parray(), LBOUND(parray), UBOUND(parray), np
IF start < finish THEN
    DIM i AS LONG
    DIM j AS LONG
    FOR i = finish - 1 TO start STEP -1
        FOR j = i + 1 TO finish
            SWAP parray(i), parray(j)
            Permute parray(), i + 1, finish, np
        NEXT
        Rotate parray(), i, finish
    NEXT
END IF
END SUB


Code: QB64: [Select]
  1. '* essentially finds the intersection of 2 arrays
  2. '* both arrays must be sorted exactly the same order.
  3. SUB ModifiedMergeSearch (StevesWordList$(), MyWordList$())
  4. a& = 0
  5. b& = 0
  6.     IF a& > UBOUND(StevesWordList$) THEN
  7.         EXIT DO
  8.     ELSE
  9.         IF b& > UBOUND(MyWordList$) THEN
  10.             EXIT DO
  11.         ELSE
  12.             IF StevesWordList$(a&) > MyWordList$(b&) THEN
  13.                 b& = b& + 1
  14.             ELSEIF StevesWordList$(a&) < MyWordList$(b&) THEN
  15.                 a& = a& + 1
  16.             ELSE
  17.                 '* it's a word in both lists
  18.                 '* advance both pointers
  19.                 a& = a& + 1
  20.                 b& = b& + 1
  21.             END IF
  22.         END IF
  23.     END IF
  24.  
Title: Re: My First InForm Program - Trackword
Post by: Qwerkey on September 05, 2018, 06:44:14 am
Hmm.  Thanks codeguy.  I'm knee-deep in another program at the moment, but then I'll try to give this some consideration.

Richard