# Small Basic program using Text.GetSubText • ### Question

• I am a new user of Small Basic and have not programmed for over 30 years.  I am writing a program to find all the solutions of a 8x8x8 Thomasson Cube where all diagonals crossing the center of the cube equal 260.  I have an external text file (test.txt) that contains all possible permutations of the eight different levels of the cube (8! or 40,320) with the first permutation being abcdefgh where each letter represents a level of the cube.  The first four permutations listed in the file are abcdefgh abcdefhg abcdegfh abcdeghf.  The numerical value of all diagonals in the first and third permutations equal 260, while the second and fourth permutations do not.

After accessing the first permutation from the external file, I use Text.GetSubText to assign the letters to an array.  I would like to use the letters in the array to be assigned to the variables from level1 to level8 in the same order as in the letters are in the permutation.  I can manually enter the letters after level1 to level 8 in the program and run the program.  The program prints the correct permutation where all diagonals equal 260 to a new text file called test2.txt.  I need help figuring out how to make this part of the code run automatically without having to manually add the correct order of the letters from a permutation to level1 to level8.  It could take over 2.5 years to find all possible solutions manually.  I hope to have this program print out all solutions to a file in only a few minutes or less.

Here is the code of the program I have written:

' Small Basic program to find all solutions of a Thomasson Cube

'written by Daniel E. Thomasson - 09/04/2003

'Assign diagonal numerical values of each level of the cube to an array

diag ["num1"] = "42" 'level 1 - a8 (using algebraic notation from a chesss board)

diag ["num2"] = "18" 'level 1 - b7

diag ["num3"] = "20" 'level 1 - c6

diag ["num4"] = "44" 'level 1 - d5

diag ["num5"] = "12" 'level 1 - e4

diag ["num6"] = "52" 'level 1 - f3

diag ["num7"] = "50" 'level 1 - g2

diag ["num8"] = "10" 'level 1 - h1

diag ["num9"] = "31" 'level 1 - a1

diag ["num10"] = "7" 'level 1 - b2

diag ["num11"] = "55" 'level 1 - c3

diag ["num12"] = "29" 'level 1 - d4

diag ["num13"] = "61" 'level 1 - e5

diag ["num14"] = "23" 'level 1 - f6

diag ["num15"] = "39" 'level 1 - g7

diag ["num16"] = "63" 'level 1 - h8

diag ["num1"] = "39" 'level 2 - a8

diag ["num2"] = "63" 'level 2 - b7

diag ["num3"] = "61" 'level 2 - c6

diag ["num4"] = "37" 'level 2 - d5

diag ["num5"] = "5" 'level 2 - e4

diag ["num6"] = "29" 'level 2 - f3

diag ["num7"] = "31" 'level 2 - g2

diag ["num8"] = "7" 'level 2 - h1

diag ["num9"] = "50" 'level 2 - a1

diag ["num10"] = "10" 'level 2 - b2

diag ["num11"] = "26" 'level 2 - c3

diag ["num12"] = "52" 'level 2 - d4

diag ["num13"] = "20" 'level 2 - e5

diag ["num14"] = "58" 'level 2 - f6

diag ["num15"] = "42" 'level 2 - g7

diag ["num16"] = "18" 'level 2 - h8

diag ["num1"] = "7" 'level 3 - a8

diag ["num2"] = "31" 'level 3 - b7

diag ["num3"] = "29" 'level 3 - c6

diag ["num4"] = "5" 'level 3 - d5

diag ["num5"] = "37" 'level 3 - e4

diag ["num6"] = "61" 'level 3 - f5

diag ["num7"] = "63" 'level 3 - g6

diag ["num8"] = "39" 'level 3 - h8

diag ["num9"] = "18" 'level 3 - a1

diag ["num10"] = "42" 'level 3 - b2

diag ["num11"] = "58" 'level 3 - c3

diag ["num12"] = "20" 'level 3 - d4

diag ["num13"] = "52" 'level 3 - e5

diag ["num14"] = "26" 'level 3 - f6

diag ["num15"] = "10" 'level 3 - g7

diag ["num16"] = "50" 'level 3 - h8

diag ["num1"] = "10" 'level 4 - a8

diag ["num2"] = "50" 'level 4 - b7

diag ["num3"] = "52" 'level 4 - c6

diag ["num4"] = "12" 'level 4 - d5

diag ["num5"] = "44" 'level 4 - e4

diag ["num6"] = "20" 'level 4 - f3

diag ["num7"] = "18" 'level 4 - g2

diag ["num8"] = "42" 'level 4 - h1

diag ["num9"] = "63" 'level 4 - a1

diag ["num10"] = "39" 'level 4 - b2

diag ["num11"] = "23" 'level 4 - c3

diag ["num12"] = "61" 'level 4 - d4

diag ["num13"] = "29" 'level 4 - e5

diag ["num14"] = "55" 'level 4 - f6

diag ["num15"] = "7" 'level 4 - g7

diag ["num16"] = "31" 'level 4 - h8

diag ["num1"] = "55" 'level 5 - a8

diag ["num2"] = "15" 'level 5 - b7

diag ["num3"] = "13" 'level 5 - c6

diag ["num4"] = "53" 'level 5 - d5

diag ["num5"] = "21" 'level 5 - e4

diag ["num6"] = "45" 'level 5 - f3

diag ["num7"] = "47" 'level 5 - g2

diag ["num8"] = "23" 'level 5 - h1

diag ["num9"] = "2" 'level 5 - a1

diag ["num10"] = "26" 'level 5 - b2

diag ["num11"] = "42" 'level 5 - c3

diag ["num12"] = "4" 'level 5 - d4

diag ["num13"] = "36" 'level 5 - e5

diag ["num14"] = "10" 'level 5 - f6

diag ["num15"] = "58" 'level 5 - g7

diag ["num16"] = "34" 'level 5 - h8

diag ["num1"] = "26" 'level 6 - a8

diag ["num2"] = "2" 'level 6 - b7

diag ["num3"] = "4" 'level 6 - c6

diag ["num4"] = "28" 'level 6 - d5

diag ["num5"] = "60" 'level 6 - e4

diag ["num6"] = "36" 'level 6 - f3

diag ["num7"] = "34" 'level 6 - g2

diag ["num8"] = "58" 'level 6 - h1

diag ["num9"] = "15" 'level 6 - a1

diag ["num10"] = "55" 'level 6 - b2

diag ["num11"] = "39" 'level 6 - c3

diag ["num12"] = "13" 'level 6 - d4

diag ["num13"] = "45" 'level 6 - e5

diag ["num14"] = "7" 'level 6 - f6

diag ["num15"] = "23" 'level 6 - g7

diag ["num16"] = "47" 'level 6 - h8

diag ["num1"] = "58" 'level 7 - a8

diag ["num2"] = "34" 'level 7 - b7

diag ["num3"] = "36" 'level 7 - c6

diag ["num4"] = "60" 'level 7 - d5

diag ["num5"] = "28" 'level 7 - e4

diag ["num6"] = "4" 'level 7 - f3

diag ["num7"] = "2" 'level 7 - g2

diag ["num8"] = "26" 'level 7 - h1

diag ["num9"] = "47" 'level 7 - a1

diag ["num10"] = "23" 'level 7 - b2

diag ["num11"] = "7" 'level 7 - c3

diag ["num12"] = "45" 'level 7 - d4

diag ["num13"] = "13" 'level 7 - e5

diag ["num14"] = "39" 'level 7 - f6

diag ["num15"] = "55" 'level 7 - g7

diag ["num16"] = "15" 'level 7 - h8

diag ["num1"] = "23" 'level 8 - a8

diag ["num2"] = "47" 'level 8 - b7

diag ["num3"] = "45" 'level 8 - c6

diag ["num4"] = "21" 'level 8 - d5

diag ["num5"] = "53" 'level 8 - e4

diag ["num6"] = "13" 'level 8 - f3

diag ["num7"] = "15" 'level 8 - g2

diag ["num8"] = "55" 'level 8 - h1

diag ["num9"] = "34" 'level 8 - a1

diag ["num10"] = "58" 'level 8 - b2

diag ["num11"] = "10" 'level 8 - c3

diag ["num12"] = "36" 'level 8 - d4

diag ["num13"] = "4" 'level 8 - e5

diag ["num14"] = "42" 'level 8 - f6

diag ["num15"] = "26" 'level 8 - g7

diag ["num16"] = "2" 'level 8 - h8

'Assign diagonal arrays to letter variables representing individual levels of the cube

a=diag

b=diag

c=diag

d=diag

e=diag

f=diag

g=diag

h=diag

'Read each line of text from file containing 8! or 40,320 permutations of the word 'abcdefgh'

For

i = 1 To1 'Need to change 'To' value to length of lines in file (40,320).  Might use a space delimited file containing all permutations.

permutation = file.ReadLine("c:\users\dan\test.txt",i) 'Test.txt contains all 40,320 permutations to be checked

word = permutation 'Assign first line of text to the variable - word

Forj = 1 To8 'The number of letters in the 'word' variable

letter[j] = Text.GetSubText(word, j, 1) 'Parse the letters of the variable 'word' to an array

EndFor

'*********************************************************************************

'Need to assign the order of letters from the letter[j] array to  'level1 - level8' variables

'*********************************************************************************

'Assign letters to level1-level8 according to their order in the variable 'word.'  This part of the code needs to be automated and is currently only working manually.

level1 = a

level2 = b

level3 = d

level4 = c

level5 = f

level6 = h

level7 = g

level8 = e

'Add all numerical values for each diagonal crossing the center of the cube

diag1 = level1 ["num1"] + level2 ["num2"] + level3 ["num3"] + level4 ["num4"] + level5 ["num5"] + level6 ["num6"] + level7 ["num7"] + level8 ["num8"]

diag2 = level1 ["num8"] + level2 ["num7"] + level3 ["num6"] + level4 ["num5"] + level5 ["num4"] + level6 ["num3"] + level7 ["num2"] + level8 ["num1"]

diag3 = level1 ["num9"] + level2 ["num10"] + level3 ["num11"] + level4 ["num12"] + level5 ["num13"] + level6 ["num14"] + level7 ["num15"] + level8 ["num16"]

diag4 = level1 ["num16"] + level2 ["num15"] + level3 ["num14"] + level4 ["num13"] + level5 ["num12"] + level6 ["num11"] + level7 ["num10"] + level8 ["num9"]

'Append value of 'word' variable to file if all diagonals equal 260

If

(diag1 = 260 And diag2 = 260 And diag3 = 260 And diag4 = 260) then

TextWindow.WriteLine("This is a Magic Cube") 'Remove this line of code once program is working correctly

File.AppendContents ("c:\Users\Dan\Test2.txt", word)

Else

'Remove this line of code once program is working correctly

TextWindow.WriteLine("The is not a Magic Cube") 'Remove this line of code once program is working correctly

EndIf

'Clear value in following variables

diag1 = ""

diag2 = ""

diag3 = ""

diag4 = ""

permutation = ""

word = ""

EndFor

Sunday, September 8, 2013 1:20 AM

• A nice problem (both the magic cube and your particular issue).

If I understand correctly....

Perhaps use numbers rather than letters in your file, and also numbers (9) instead of strings like "num9".  This may help.

You could create an array like this:

```levelIndex["a"] = a
levelIndex["b"] = b
levelIndex["c"] = c
levelIndex["d"] = d
levelIndex["e"] = e
levelIndex["f"] = f
levelIndex["g"] = g
levelIndex["h"] = h
```

Then use this array to set the levels:

level1 = levelIndex[letter]
level2 = levelIndex[letter]
level3 = levelIndex[letter]
level4 = levelIndex[letter]
level5 = levelIndex[letter]
level6 = levelIndex[letter]
level7 = levelIndex[letter]
level8 = levelIndex[letter]

There are a lot of multi-dimensional arrays (slow in SB) so when you get it going, some work to rationalize these a bit may improve performance - good job so far though.

• Marked as answer by Sunday, September 8, 2013 8:32 PM
Sunday, September 8, 2013 9:49 AM
• I did some re-factoring in order to make the data part more compact and modularized.

Hope that helps you out a little.  :-D

`'**********************************************************************************************************'InitDiags()SumDiags()For i = 1 To sumCount  TextWindow.WriteLine(d[i])EndForTextWindow.WriteLine("")'**********************************************************************************************************'Sub InitDiags    'diags[] = "1=;2=;3=;4=;5=;6=;7=;8=;9=;10=;11=;12=;13=;14=;15=;16=;"    diags = "1=42;2=18;3=20;4=44;5=12;6=52;7=50;8=10;9=31;10=7;11=55;12=29;13=61;14=23;15=39;16=63;"  diags = "1=39;2=63;3=61;4=37;5=5;6=29;7=31;8=7;9=50;10=10;11=26;12=52;13=20;14=58;15=42;16=18;"  diags = "1=7;2=31;3=29;4=5;5=37;6=61;7=63;8=39;9=18;10=42;11=58;12=20;13=52;14=26;15=10;16=50;"  diags = "1=10;2=50;3=52;4=12;5=44;6=20;7=18;8=42;9=63;10=39;11=23;12=61;13=29;14=55;15=7;16=31;"  diags = "1=55;2=15;3=13;4=53;5=21;6=45;7=47;8=23;9=2;10=26;11=42;12=4;13=36;14=10;15=58;16=34;"  diags = "1=26;2=2;3=4;4=28;5=60;6=36;7=34;8=58;9=15;10=55;11=39;12=13;13=45;14=7;15=23;16=47;"  diags = "1=58;2=34;3=36;4=60;5=28;6=4;7=2;8=26;9=47;10=23;11=7;12=45;13=13;14=39;15=55;16=15;"  diags = "1=23;2=47;3=45;4=21;5=53;6=13;7=15;8=55;9=34;10=58;11=10;12=36;13=4;14=42;15=26;16=2;"    diagsCount = Array.GetItemCount(diags)  EndSub'**********************************************************************************************************'Sub SumDiags    d = ""    For i = 1 To 8    d = d + diags[i][i]    d = d + diags[i][9-i]    d = d + diags[i][8+i]    d = d + diags[i][17-i]  EndFor    sumCount = Array.GetItemCount(d)  EndSub'**********************************************************************************************************'`

Click on "Propose As Answer" if some post solves your problem or "Vote As Helpful" if some post has been useful to you! (^_^)

• Marked as answer by Sunday, September 8, 2013 8:37 PM
• Edited by Monday, September 9, 2013 3:49 AM More compact!
Sunday, September 8, 2013 9:52 AM
• In the SB interface, hit the Import button on the top, then enter or Copy/Paste the 6 digit import ID.

Same to export a code, using Export button it will give you a code for the uploaded file.

• Marked as answer by Monday, September 9, 2013 5:19 PM
Monday, September 9, 2013 1:13 PM

### All replies

• A nice problem (both the magic cube and your particular issue).

If I understand correctly....

Perhaps use numbers rather than letters in your file, and also numbers (9) instead of strings like "num9".  This may help.

You could create an array like this:

```levelIndex["a"] = a
levelIndex["b"] = b
levelIndex["c"] = c
levelIndex["d"] = d
levelIndex["e"] = e
levelIndex["f"] = f
levelIndex["g"] = g
levelIndex["h"] = h
```

Then use this array to set the levels:

level1 = levelIndex[letter]
level2 = levelIndex[letter]
level3 = levelIndex[letter]
level4 = levelIndex[letter]
level5 = levelIndex[letter]
level6 = levelIndex[letter]
level7 = levelIndex[letter]
level8 = levelIndex[letter]

There are a lot of multi-dimensional arrays (slow in SB) so when you get it going, some work to rationalize these a bit may improve performance - good job so far though.

• Marked as answer by Sunday, September 8, 2013 8:32 PM
Sunday, September 8, 2013 9:49 AM
• I did some re-factoring in order to make the data part more compact and modularized.

Hope that helps you out a little.  :-D

`'**********************************************************************************************************'InitDiags()SumDiags()For i = 1 To sumCount  TextWindow.WriteLine(d[i])EndForTextWindow.WriteLine("")'**********************************************************************************************************'Sub InitDiags    'diags[] = "1=;2=;3=;4=;5=;6=;7=;8=;9=;10=;11=;12=;13=;14=;15=;16=;"    diags = "1=42;2=18;3=20;4=44;5=12;6=52;7=50;8=10;9=31;10=7;11=55;12=29;13=61;14=23;15=39;16=63;"  diags = "1=39;2=63;3=61;4=37;5=5;6=29;7=31;8=7;9=50;10=10;11=26;12=52;13=20;14=58;15=42;16=18;"  diags = "1=7;2=31;3=29;4=5;5=37;6=61;7=63;8=39;9=18;10=42;11=58;12=20;13=52;14=26;15=10;16=50;"  diags = "1=10;2=50;3=52;4=12;5=44;6=20;7=18;8=42;9=63;10=39;11=23;12=61;13=29;14=55;15=7;16=31;"  diags = "1=55;2=15;3=13;4=53;5=21;6=45;7=47;8=23;9=2;10=26;11=42;12=4;13=36;14=10;15=58;16=34;"  diags = "1=26;2=2;3=4;4=28;5=60;6=36;7=34;8=58;9=15;10=55;11=39;12=13;13=45;14=7;15=23;16=47;"  diags = "1=58;2=34;3=36;4=60;5=28;6=4;7=2;8=26;9=47;10=23;11=7;12=45;13=13;14=39;15=55;16=15;"  diags = "1=23;2=47;3=45;4=21;5=53;6=13;7=15;8=55;9=34;10=58;11=10;12=36;13=4;14=42;15=26;16=2;"    diagsCount = Array.GetItemCount(diags)  EndSub'**********************************************************************************************************'Sub SumDiags    d = ""    For i = 1 To 8    d = d + diags[i][i]    d = d + diags[i][9-i]    d = d + diags[i][8+i]    d = d + diags[i][17-i]  EndFor    sumCount = Array.GetItemCount(d)  EndSub'**********************************************************************************************************'`

Click on "Propose As Answer" if some post solves your problem or "Vote As Helpful" if some post has been useful to you! (^_^)

• Marked as answer by Sunday, September 8, 2013 8:37 PM
• Edited by Monday, September 9, 2013 3:49 AM More compact!
Sunday, September 8, 2013 9:52 AM
• Daniel,

Do you know how many there should be?

With your algorithm, arrays modified by GoToLoop and using my own way to calculate the 40,320 permutations in code (no files), I get 904 solutions in 45 sec total run time.

Sunday, September 8, 2013 2:19 PM
• Thanks litdev for such a fast response to my problem.  I hadn't thought about indexing the permutation letters in an array variable then assigning indices to the levels.  I will give that a try.
Sunday, September 8, 2013 7:02 PM
• Hi GoToLoop,

Thanks for cleaning up my code and making it more compact.  This will make the program look so much nicer. I knew there had to be a better way of listing all the numerical values of the diagonals in the cube.  Hope you had a chance to play with the code and see that it works.  Though as I have it currently written, you would have to manually change level1 = a, level2 = b, level 3 = c, etc for the eight letter permutation.  abcdefgh will yield a magic cube with all diagonals equaling 260.

Sunday, September 8, 2013 7:08 PM
• Wow litdev!  Thanks again for your great work.  Since each level of the cube is created from the same 180 degree rotation-symmetric closed knight's tour, the entire cube would also be 180 degree rotation-symmetric.  In this case, 50% of the 904 solutions, or 452 solutions, would probably be correct.  That is to say, if all diagonals of the permutation abcdefgh equal 260, then the diagonals in the opposite order of the levels (hgfedcba) would also equal 260.  I guess we could say there are 904 solutions, but reference their reversals.

Would it be possible for you to share your code that includes the accessing of the 40,320 permutations without the use of an external file? I only ask because reading each permutation from an external text file, manipulating and checking the results, then reprinting the solutions to another text file takes forever. I do, however, need an external file with all results listed.

Sunday, September 8, 2013 8:32 PM
• Sure, import MRW335 - un-comment the File command (line 62) to write the output to a file.
Sunday, September 8, 2013 8:37 PM
• Dear me! After checking out MRW335, I've realized I coulda put the 4 diagonal sums into the same For...EndFor loop!  *_*

It's fixed now. And it's actual more compact!  ^_^

In your code I wonder whether "True" or "False" would be better than 1 or 0?

I prefer the boolean String literals, but are they faster?  @_@

Click on "Propose As Answer" if some post solves your problem or "Vote As Helpful" if some post has been useful to you! (^_^)

Monday, September 9, 2013 3:48 AM
• GoToLoop,

I really appreciate your work on this project.  I've added your compact code modifications and litdev's levelIndex addition to the code.  Everything works well with all the correct permutations listed in a file.  This program can be modified and manipulated by other programmers, and probably will be useful for additional combinatorial 3d problems.  By the way, I am a new MSDN forum user.  How do I access the MRW335 code?

Monday, September 9, 2013 12:59 PM
• In the SB interface, hit the Import button on the top, then enter or Copy/Paste the 6 digit import ID.

Same to export a code, using Export button it will give you a code for the uploaded file.

• Marked as answer by Monday, September 9, 2013 5:19 PM
Monday, September 9, 2013 1:13 PM
• Hi litdev.  I have printed copies of all solutions in several different formats now.  I tried to share a gif image of the actual cube that I designed but get the following:

"Message from Webpage"

"Body text cannot contain images or links until we are able to verify your account."

Monday, September 9, 2013 5:13 PM
• You can do this after a few days of 'normal' activity - it is some sort of anti-bot checking (where the exact usage required to verify you is not disclosed) - if you can't do it after a few days, then post to Forum Issues - see here.
Monday, September 9, 2013 5:28 PM
• @ GotoLoop

As you know all variables are Primitive, so performance is probably not better using "True" rather and 1 - I may be wrong or using 1,0 may be faster.

Either way I don't expect a big difference on this.

You are right bool is the best, but typing "True" is more hassle than 1, and my guess is that this is at least as fast.

Monday, September 9, 2013 5:33 PM
• It's just that a variable = "True" doesn't need to be compared == "True"  inside If or While blocks.

Even though "1" is 1 character long, it still needs to be compared == "1"  :D

As you said, typing "True" can be rather a hassle. But I like the idea of boolean variables myself.  ^_^

Click on "Propose As Answer" if some post solves your problem or "Vote As Helpful" if some post has been useful to you! (^_^)

Monday, September 9, 2013 6:25 PM
• Either way - its subjective (assuming no performance differences) and I wouldn't argue what I did was best - from a pure programming angle what you suggest is better - use the correct type - and this is clearly either true or false so I was probably just a little lazy.
Monday, September 9, 2013 6:29 PM
• Interestingly, the following code suggest using "True" "False" is faster than 1 0.  Import ZLS721.
Monday, September 9, 2013 6:56 PM