You are not logged in. You can browse in the PowerBASIC Community, but you must click Login (top right) before you can post. If this is your first visit, check out the FAQ or Sign Up.

#INCLUDE "win32api.inc"
FUNCTION ShowDate (month AS LONG, day AS LONG, year AS LONG) AS STRING
LOCAL st As SYSTEMTIME, szDF AS ASCIIZ * 48, szDate As ASCIIZ * 48
st.wYear = year
st.wMonth = month
st.wDay = day
szDf = "MM'/'dd'/'yyyy" ' for MM/DD/CCYY
GetDateFormat BYVAL %NULL, BYVAL %NULL ,st, szDf, szDate, SIZEOF (szDate)
FUNCTION = szDate
END FUNCTION

There are 26 letters in our alphabet. The nearest binary count value would be 32 (00000b to 111111b). To represent five letters consecutively in a single numeric value, you would need a total of 25 bits. Even six characters can be squeezed into 30 bits, and we can easily represent integers of 32 bits.

Arranging the bits so that no two words create an identical total is easy. Say that your word is placed in a string called AB$. Then you can create a unique total using (ASC(ab$,1)-65)*32^5+(ASC(ab$,2)-65)*32^4+(ASC(ab$,3)-65)*32^3+(ASC(ab$,4)-65)*32^2+(ASC(ab$,5)-65)*32^1

This could also be done using a FOR loop:

b=0
FOR a=1 to LEN(ab$)
b=b*32+ASC(ab$,a)-65
NEXT

Because 6 combinations in the possibilities of a 2^5 (or 32 count) bit representation are unused, you may find some unique uses for these as well.
But to exhaust all the possibilities of character combinations from AAAAA to ZZZZZ would mean 11,881,376 spelling possibilities, of which only a comparatively few would be valid. Yet with 30 bits of encoding, (five bits for each character), we have a grand total of 33,554,432 possibilities for our range, again with only a comparatively small number representing valid words. So constructing a table with either value as an index would be very wasteful of memory or disk storage.

There are ways you can reduce this amount. Since each index could point to an individual byte, and each byte is composed of 8 bits, you could set a bit if a certain spelling is valid and leave it clear if it were invalid or if the combination is not used. Then you could take the 33,554,432 and divide it by 8 to point at the right byte, then use the remainder (using the MOD operator) to select the specific bit and test to see it if is valid or not. That would reduce the index range to an effective 4,194,304 reference to bytes of memory.

However, we can go smaller. Instead of five bits, we can just use the 26 character possibilities and rewrite our expression this way:

Now we are down to using the 11,881,376 possibilities that are actually required. Again, using the byte reference method described next, we can reduce this value to 1,485,172 byte references, then use the MOD of the actual count to find which bit to query for a valid word.

If that number is unacceptable, you can attempt a study of the written word and see if you can find any hard and fast rules about what letter combinations never occur together. For instance, "qz" might be suspect, or "vb". Maybe you can work on minimizing the two-letter combinations from AA to ZZ, which is 26^2, to something much smaller.

Or, you can consider a hashing approach. In a hashing approach, you try to reduce the total to something much smaller, but accept that some combinations will be duplicates. For instance, you could remove the vowels from consideration, and just encode the remaining letters. The vowels are A, E, I, O, and U, and the remaining letter represent only 21 possibilities. Including Y as a vowel could reduce this to 20 possibilities. Since every word has to have at least one vowel, you could see that five letters can be reduced to four or less if you do this. This means that the word "SOAR" now becomes "SR", which might also match "SIRE" or "SURE". These collisions are where the art of hashing comes in, because you must point the way to where each can be validated via a secondary method.

So while you may have found a place where hashing can be used beneficially, you also are at a place where you have to figure out how to implement it. Hashing is an approach to reducing the scale of a data reference, not a technique or method that works the same way in all circumstances.

I should mention that for the purpose of this discussion, I am assuming that all characters are upper case. If not, you need to force them to upper case, or you will end up with 52 character values instead of just 26.

FWIW, this problem is called the "decimal print" routine and for a long time was the subject of many "mine's smaller than yours" contests. (Measurements taken in 'instructions')

You might try a search on "decimal print" if you want more ideas.

#COMPILE EXE '#CC 4.04#
#DIM ALL
'______________________________________________________________________________
FUNCTION ShowDateA(BYVAL Month AS LONG, BYVAL Day AS LONG, BYVAL Year AS LONG) AS STRING
LOCAL sString AS STRING * 10
LOCAL pChar AS BYTE POINTER
LOCAL Looper AS LONG
pChar = VARPTR(sString) + 9
FOR Looper = 1 TO 10
SELECT CASE Looper
CASE 1 TO 4 : @pChar = (Year MOD 10) + 48 : Year = Year \ 10
CASE 5, 8 : @pChar = 47
CASE 6, 7 : @pChar = (Day MOD 10) + 48 : Day = Day \ 10
CASE 9, 10 : @pChar = (Month MOD 10) + 48 : Month = Month \ 10
END SELECT
DECR pChar
NEXT
FUNCTION = sString
END FUNCTION
'______________________________________________________________________________
FUNCTION ShowDateB(BYVAL Month AS LONG, BYVAL Day AS LONG, BYVAL Year AS LONG) AS STRING
LOCAL sString AS STRING * 10
LOCAL pChar AS BYTE POINTER
pChar = VARPTR(sString)
@pChar[9] = (Year MOD 10) + 48 : Year = Year \ 10
@pChar[8] = (Year MOD 10) + 48 : Year = Year \ 10
@pChar[7] = (Year MOD 10) + 48 : Year = Year \ 10
@pChar[6] = (Year MOD 10) + 48
@pChar[5] = 47
@pChar[4] = (Day MOD 10) + 48 : Day = Day \ 10
@pChar[3] = (Day MOD 10) + 48
@pChar[2] = 47
@pChar[1] = (Month MOD 10) + 48 : Month = Month \ 10
@pChar[0] = (Month MOD 10) + 48
FUNCTION = sString
END FUNCTION
'______________________________________________________________________________
FUNCTION PBMAIN AS LONG
LOCAL Month AS LONG
LOCAL Day AS LONG
LOCAL Year AS LONG
Month = 12
Day = 01
Year = 1989
PRINT ShowDateA(Month, Day, Year)
PRINT ShowDateB(Month, Day, Year)
PRINT : PRINT "Press any key or click to continue..." : MOUSE ON : MOUSE 3, UP : WAITKEY$
END FUNCTION
'______________________________________________________________________________
'

#COMPILE EXE
#DIM ALL
DECLARE FUNCTION ShowDate(month AS LONG, day AS LONG, year AS LONG) AS STRING
FUNCTION PBMAIN AS LONG
LOCAL month, day, year AS LONG
DIM s AS STRING
s = "00/00/0000"
month = 12
day = 1
year = 1989
? ShowDate(month, day, year)
WAITKEY$
END FUNCTION
FUNCTION ShowDate (month AS LONG, day AS LONG, year AS LONG) AS STRING
LOCAL s AS STRING
LOCAL remains AS LONG
LOCAL digit AS LONG
LOCAL nextdigit AS LONG
LOCAL nextcharacter AS LONG
s = "00/00/0000"
ASC(s,1) = month \10 +48
ASC(s,2) = month MOD 10 + 48
ASC(s,4) = day\10 + 48
ASC(s,5) = day MOD 10 + 48
Remains&=year
FOR digit& = 10 TO 7 STEP -1 'changed from 4 to 1 to 10 to 7
NextDigit&=Remains& MOD 10
Remains&=Remains& \ 10
NextCharacter&=NextDigit& + 48
ASC(s,digit) = NextCharacter 'no longer need to add 6
NEXT
FUNCTION = s
END FUNCTION

FUNCTION PBMAIN () AS LONG
InitialValue&=1234567890
Remains&=InitialValue&
FOR digit& = 1 TO 10
NextDigit&=Remains& MOD 10
Remains&=Remains& \ 10
NextCharacter&=NextDigit& + 48
PRINT NextDigit& , NextCharacter&, CHR$(NextCharacter&)
NEXT
WAITKEY$
END FUNCTION

How do you get the ascii value of each digit of a long?
Trying to get the values without using the string handling routines.

Code:

#COMPILE EXE
#DIM ALL
DECLARE FUNCTION ShowDate(month AS LONG, day AS LONG, year AS LONG) AS STRING
FUNCTION PBMAIN AS LONG
LOCAL month, day, year AS LONG
DIM s AS STRING
s = "00/00/0000"
month = 11
day = 12
year = 9473
? ShowDate(month, day, year)
WAITKEY$
END FUNCTION
FUNCTION ShowDate (month AS LONG, day AS LONG, year AS LONG) AS STRING
LOCAL s AS STRING
s = "00/00/0000"
ASC(s,1) = month \10 +48
ASC(s,2) = month MOD 10 + 48
ASC(s,4) = day\10 + 48
ASC(s,5) = day MOD 10 + 48
ASC(s,7) = year\1000 +48
'ASc(s,8) =
'asc(s,9) =
'asc(s,10) =
FUNCTION = s
END FUNCTION

We process personal data about users of our site, through the use of cookies and other technologies, to deliver our services, and to analyze site activity. For additional details, refer to our Privacy Policy.

By clicking "I AGREE" below, you agree to our Privacy Policy and our personal data processing and cookie practices as described therein. You also acknowledge that this forum may be hosted outside your country and you consent to the collection, storage, and processing of your data in the country where this forum is hosted.

## Leave a comment: