RosettaCodeData/Task/Semordnilap/ALGOL-68/semordnilap.alg
2024-10-16 18:07:41 -07:00

55 lines
2.4 KiB
Text

BEGIN # find the semordnilaps (words that are the reverse of another word) #
PR read "files.incl.a68" PR # include file utilities #
[ 1 : 30 000 ]STRING words; # guess that this will be enough words #
INT semordnilap count := 0; # number of semordnilaps found so far #
INT max report = 5; # number of semordnilaps to show #
# returns TRUE if words[ low : high ] comntains s, FALSE otherwise #
PROC is word = ( STRING s, INT low, high )BOOL:
IF high < low THEN FALSE
ELSE INT mid = ( low + high ) OVER 2;
IF words[ mid ] > s THEN is word( s, low, mid - 1 )
ELIF words[ mid ] = s THEN TRUE
ELSE is word( s, mid + 1, high )
FI
FI # is word # ;
# returns text with the characters reversed #
OP REVERSE = ( STRING text )STRING:
BEGIN
STRING reversed := text;
INT start pos := LWB text;
FOR end pos FROM UPB reversed BY -1 TO LWB reversed
DO
reversed[ end pos ] := text[ start pos ];
start pos +:= 1
OD;
reversed
END # REVERSE # ;
# returns FALSE if the reverse of word is in words, TRUE otherwise #
# if the reverse is not present, it is added to words #
# if the reverse is present, it is reported as a seordnilap - if the #
# maximum number hasn't been reported yet #
# count so far will contain the number of words stored so far #
PROC store non semordnilaps = ( STRING word, INT count so far )BOOL:
IF STRING r word = REVERSE word;
is word( r word, 1, count so far )
THEN IF ( semordnilap count +:= 1 ) <= max report
THEN print( ( word, " & ", r word, newline ) )
FI;
FALSE
ELSE words[ count so far + 1 ] := word;
TRUE
FI # store non semordnilaps # ;
# find the semordnilaps - assumes unixdict.txt is sorted #
IF "unixdict.txt" EACHLINE store non semordnilaps < 0
THEN print( ( "Unable to open unixdict.txt", newline ) )
ELSE print( ( whole( semordnilap count, 0 ), " semordnilaps found", newline ) )
FI
END