Answered by:
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[0] ["num1"] = "42" 'level 1  a8 (using algebraic notation from a chesss board)
diag[0] ["num2"] = "18" 'level 1  b7
diag[0] ["num3"] = "20" 'level 1  c6
diag[0] ["num4"] = "44" 'level 1  d5
diag[0] ["num5"] = "12" 'level 1  e4
diag[0] ["num6"] = "52" 'level 1  f3
diag[0] ["num7"] = "50" 'level 1  g2
diag[0] ["num8"] = "10" 'level 1  h1
diag[0] ["num9"] = "31" 'level 1  a1
diag[0] ["num10"] = "7" 'level 1  b2
diag[0] ["num11"] = "55" 'level 1  c3
diag[0] ["num12"] = "29" 'level 1  d4
diag[0] ["num13"] = "61" 'level 1  e5
diag[0] ["num14"] = "23" 'level 1  f6
diag[0] ["num15"] = "39" 'level 1  g7
diag[0] ["num16"] = "63" 'level 1  h8
diag[1] ["num1"] = "39" 'level 2  a8
diag[1] ["num2"] = "63" 'level 2  b7
diag[1] ["num3"] = "61" 'level 2  c6
diag[1] ["num4"] = "37" 'level 2  d5
diag[1] ["num5"] = "5" 'level 2  e4
diag[1] ["num6"] = "29" 'level 2  f3
diag[1] ["num7"] = "31" 'level 2  g2
diag[1] ["num8"] = "7" 'level 2  h1
diag[1] ["num9"] = "50" 'level 2  a1
diag[1] ["num10"] = "10" 'level 2  b2
diag[1] ["num11"] = "26" 'level 2  c3
diag[1] ["num12"] = "52" 'level 2  d4
diag[1] ["num13"] = "20" 'level 2  e5
diag[1] ["num14"] = "58" 'level 2  f6
diag[1] ["num15"] = "42" 'level 2  g7
diag[1] ["num16"] = "18" 'level 2  h8
diag[2] ["num1"] = "7" 'level 3  a8
diag[2] ["num2"] = "31" 'level 3  b7
diag[2] ["num3"] = "29" 'level 3  c6
diag[2] ["num4"] = "5" 'level 3  d5
diag[2] ["num5"] = "37" 'level 3  e4
diag[2] ["num6"] = "61" 'level 3  f5
diag[2] ["num7"] = "63" 'level 3  g6
diag[2] ["num8"] = "39" 'level 3  h8
diag[2] ["num9"] = "18" 'level 3  a1
diag[2] ["num10"] = "42" 'level 3  b2
diag[2] ["num11"] = "58" 'level 3  c3
diag[2] ["num12"] = "20" 'level 3  d4
diag[2] ["num13"] = "52" 'level 3  e5
diag[2] ["num14"] = "26" 'level 3  f6
diag[2] ["num15"] = "10" 'level 3  g7
diag[2] ["num16"] = "50" 'level 3  h8
diag[3] ["num1"] = "10" 'level 4  a8
diag[3] ["num2"] = "50" 'level 4  b7
diag[3] ["num3"] = "52" 'level 4  c6
diag[3] ["num4"] = "12" 'level 4  d5
diag[3] ["num5"] = "44" 'level 4  e4
diag[3] ["num6"] = "20" 'level 4  f3
diag[3] ["num7"] = "18" 'level 4  g2
diag[3] ["num8"] = "42" 'level 4  h1
diag[3] ["num9"] = "63" 'level 4  a1
diag[3] ["num10"] = "39" 'level 4  b2
diag[3] ["num11"] = "23" 'level 4  c3
diag[3] ["num12"] = "61" 'level 4  d4
diag[3] ["num13"] = "29" 'level 4  e5
diag[3] ["num14"] = "55" 'level 4  f6
diag[3] ["num15"] = "7" 'level 4  g7
diag[3] ["num16"] = "31" 'level 4  h8
diag[4] ["num1"] = "55" 'level 5  a8
diag[4] ["num2"] = "15" 'level 5  b7
diag[4] ["num3"] = "13" 'level 5  c6
diag[4] ["num4"] = "53" 'level 5  d5
diag[4] ["num5"] = "21" 'level 5  e4
diag[4] ["num6"] = "45" 'level 5  f3
diag[4] ["num7"] = "47" 'level 5  g2
diag[4] ["num8"] = "23" 'level 5  h1
diag[4] ["num9"] = "2" 'level 5  a1
diag[4] ["num10"] = "26" 'level 5  b2
diag[4] ["num11"] = "42" 'level 5  c3
diag[4] ["num12"] = "4" 'level 5  d4
diag[4] ["num13"] = "36" 'level 5  e5
diag[4] ["num14"] = "10" 'level 5  f6
diag[4] ["num15"] = "58" 'level 5  g7
diag[4] ["num16"] = "34" 'level 5  h8
diag[5] ["num1"] = "26" 'level 6  a8
diag[5] ["num2"] = "2" 'level 6  b7
diag[5] ["num3"] = "4" 'level 6  c6
diag[5] ["num4"] = "28" 'level 6  d5
diag[5] ["num5"] = "60" 'level 6  e4
diag[5] ["num6"] = "36" 'level 6  f3
diag[5] ["num7"] = "34" 'level 6  g2
diag[5] ["num8"] = "58" 'level 6  h1
diag[5] ["num9"] = "15" 'level 6  a1
diag[5] ["num10"] = "55" 'level 6  b2
diag[5] ["num11"] = "39" 'level 6  c3
diag[5] ["num12"] = "13" 'level 6  d4
diag[5] ["num13"] = "45" 'level 6  e5
diag[5] ["num14"] = "7" 'level 6  f6
diag[5] ["num15"] = "23" 'level 6  g7
diag[5] ["num16"] = "47" 'level 6  h8
diag[6] ["num1"] = "58" 'level 7  a8
diag[6] ["num2"] = "34" 'level 7  b7
diag[6] ["num3"] = "36" 'level 7  c6
diag[6] ["num4"] = "60" 'level 7  d5
diag[6] ["num5"] = "28" 'level 7  e4
diag[6] ["num6"] = "4" 'level 7  f3
diag[6] ["num7"] = "2" 'level 7  g2
diag[6] ["num8"] = "26" 'level 7  h1
diag[6] ["num9"] = "47" 'level 7  a1
diag[6] ["num10"] = "23" 'level 7  b2
diag[6] ["num11"] = "7" 'level 7  c3
diag[6] ["num12"] = "45" 'level 7  d4
diag[6] ["num13"] = "13" 'level 7  e5
diag[6] ["num14"] = "39" 'level 7  f6
diag[6] ["num15"] = "55" 'level 7  g7
diag[6] ["num16"] = "15" 'level 7  h8
diag[7] ["num1"] = "23" 'level 8  a8
diag[7] ["num2"] = "47" 'level 8  b7
diag[7] ["num3"] = "45" 'level 8  c6
diag[7] ["num4"] = "21" 'level 8  d5
diag[7] ["num5"] = "53" 'level 8  e4
diag[7] ["num6"] = "13" 'level 8  f3
diag[7] ["num7"] = "15" 'level 8  g2
diag[7] ["num8"] = "55" 'level 8  h1
diag[7] ["num9"] = "34" 'level 8  a1
diag[7] ["num10"] = "58" 'level 8  b2
diag[7] ["num11"] = "10" 'level 8  c3
diag[7] ["num12"] = "36" 'level 8  d4
diag[7] ["num13"] = "4" 'level 8  e5
diag[7] ["num14"] = "42" 'level 8  f6
diag[7] ["num15"] = "26" 'level 8  g7
diag[7] ["num16"] = "2" 'level 8  h8
'Assign diagonal arrays to letter variables representing individual levels of the cube
a=diag[0]
b=diag[1]
c=diag[2]
d=diag[3]
e=diag[4]
f=diag[5]
g=diag[6]
h=diag[7]
'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[1] = file.ReadLine("c:\users\dan\test.txt",i) 'Test.txt contains all 40,320 permutations to be checked
word = permutation[1] '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 level1level8 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[1] = ""
word = ""
EndFor
Answers

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[1]]
level2 = levelIndex[letter[2]]
level3 = levelIndex[letter[3]]
level4 = levelIndex[letter[4]]
level5 = levelIndex[letter[5]]
level6 = levelIndex[letter[6]]
level7 = levelIndex[letter[7]]
level8 = levelIndex[letter[8]]There are a lot of multidimensional 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 dthomasson Sunday, September 8, 2013 8:32 PM

I did some refactoring 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])
EndFor
TextWindow.WriteLine("")
'**********************************************************************************************************'
Sub InitDiags
'diags[] = "1=;2=;3=;4=;5=;6=;7=;8=;9=;10=;11=;12=;13=;14=;15=;16=;"
diags[1] = "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[2] = "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[3] = "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[4] = "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[5] = "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[6] = "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[7] = "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[8] = "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[1] = d[1] + diags[i][i]
d[2] = d[2] + diags[i][9i]
d[3] = d[3] + diags[i][8+i]
d[4] = d[4] + diags[i][17i]
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 dthomasson Sunday, September 8, 2013 8:37 PM
 Edited by GoToLoopEditor Monday, September 9, 2013 3:49 AM More compact!

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 dthomasson Monday, September 9, 2013 5:19 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[1]]
level2 = levelIndex[letter[2]]
level3 = levelIndex[letter[3]]
level4 = levelIndex[letter[4]]
level5 = levelIndex[letter[5]]
level6 = levelIndex[letter[6]]
level7 = levelIndex[letter[7]]
level8 = levelIndex[letter[8]]There are a lot of multidimensional 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 dthomasson Sunday, September 8, 2013 8:32 PM

I did some refactoring 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])
EndFor
TextWindow.WriteLine("")
'**********************************************************************************************************'
Sub InitDiags
'diags[] = "1=;2=;3=;4=;5=;6=;7=;8=;9=;10=;11=;12=;13=;14=;15=;16=;"
diags[1] = "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[2] = "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[3] = "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[4] = "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[5] = "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[6] = "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[7] = "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[8] = "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[1] = d[1] + diags[i][i]
d[2] = d[2] + diags[i][9i]
d[3] = d[3] + diags[i][8+i]
d[4] = d[4] + diags[i][17i]
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 dthomasson Sunday, September 8, 2013 8:37 PM
 Edited by GoToLoopEditor Monday, September 9, 2013 3:49 AM More compact!



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.

Wow litdev! Thanks again for your great work. Since each level of the cube is created from the same 180 degree rotationsymmetric closed knight's tour, the entire cube would also be 180 degree rotationsymmetric. 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.


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! (^_^)
 Edited by GoToLoopEditor Monday, September 9, 2013 3:52 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?

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 dthomasson Monday, September 9, 2013 5:19 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."


@ 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.

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! (^_^)

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.
