Programeer opdrachtenOpdracht : opdr5b_dirk.txt

Terug naar de inzendingen
Opdracht 5b, Dirk Gerrits
10 April 2005
 Ik heb een halve oplossing voor deel A in Prolog (dat wil zeggen, hij kan wel
 paden vinden via Prolog's backtracking, maar ik heb nog geen kortste pad
 algoritme geĆÆmplementeerd). Ik weet niet of ik hem nog af ga maken, want hij
 is nu zo heerlijk kort. Wink (12 regels om de 6 steden en 6 wegen te
 definiĆ«ren, 9 regels om een route te vinden, 3 regels commentaar, 2 regels
 whitespace)
 
 Hier is deel B in Forth, zoals gevraagd.
 
 Opmerkingen in het Nederlands:
 
  * Ik heb net als de opdrachtbeschrijving de term "T9" gebruikt, maar dat
  * is volgens mij niet wat dit is. Het idee achter T9 is om een woordenboek
  * te gebruiken zodat je juist NIET meerdere keren per letter op een knop
  * hoeft te drukken.
 
  * Alle karakters die geen letter zijn worden als spatie gezien.
 
  * Ik zoek letters niet op in een tabel, maar voer een berekening uit op
  * hun ASCII waarde. Niet netjes, wel kort. (En ik ben niet zo goed met
  * datastructuren in Forth.)
 
  * Het is niet mogelijk een regel langer dan 256 karakters in te geven.
 1 
 *****t9.fs*****
  
 2\ Copyright (c) 2005, Dirk H.P. Gerrits 
 3\
 4\ Permission is hereby granted, free of charge, to any person obtaining a
 5\ copy of this software and associated documentation files (the "Software"),
 6\ to deal in the Software without restriction, including without limitation
 7\ the rights to use, copy, modify, merge, publish, distribute, sublicense,
 8\ and/or sell copies of the Software, and to permit persons to whom the
 9\ Software is furnished to do so, subject to the following conditions:
 10\
 11\ The above copyright notice and this permission notice shall be included in
 12\ all copies or substantial portions of the Software.
 13\
 14\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 15\ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 16\ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 17\ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 18\ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 19\ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 20\ DEALINGS IN THE SOFTWARE.
 21\
 22\ Summary
 23\ ---------------------------------------------------------------------------
 24\ This program reads a string from standard input and tells you for each
 25\ character how many times you have to press which numbers on a mobile phone
 26\ to type them.
 27\
 28\ Notes
 29\ ---------------------------------------------------------------------------
 30\ * I used the term "T9" as per the assignment description, but AFAIK that's
 31\   not what this actually is.  The idea behind T9 is to use a dictionary so
 32\   that you do NOT need multiple keypresses per letter.
 33\ * All non-letters are treated as spaces.
 34\ * Arithmetic is used rather than table lookup; not pretty, but concise.
 35\   (I'm not very well-versed in Forth data structure usage.)
 36\ * It's not possible to enter a line longer than 256 characters.
 37\
 38\ Usage:
 39\ ---------------------------------------------------------------------------
 40\ Run the file with your favorite Forth implementation.  With GNU Forth
 41\ (http://www.gnu.org/software/gforth/gforth.html) this can be done as
 42follows:
 43\
 44\ $ gforth t9.fs -e 'bye'
 45\
 46\ This should ask for a string and then print the corresponding T9 keypresses.
 47\
 48\ ---------------------------------------------------------------------------
 49
 50: ?UPPER-LETTER  ( c -- t=c-is-an-uppercase-letter)
 51    [CHAR] A   [CHAR] Z 1+   WITHIN ;
 52: ?LOWER-LETTER  ( c -- t=c-is-a-lowercase-letter)
 53    [CHAR] a   [CHAR] z 1+   WITHIN ;
 54: UPCASE  ( c -- C)
 55    DUP  ?LOWER-LETTER IF 32 XOR THEN ;
 56
 57: ?A-L  ( c -- t=c-is-[A-L])
 58    [CHAR] A   [CHAR] L 1+   WITHIN ;
 59: ?M-Z  ( c -- t=c-is-[M-Z])
 60    [CHAR] M   [CHAR] Z 1+   WITHIN ;
 61
 62: T9-NUMBERS:A-L  ( c=[A-L] -- n)  \ 3 letters per number
 63    65 -   3 /MOD   2 + SWAP 1+ SWAP ;
 64: T9-NUMBERS:M-Z  ( c=[M-Z] -- n)  \ 3 1/2 letters per number
 65    4 +   2 7 */MOD   SWAP 2/ 1+   SWAP 17 - ;
 66: T9-NUMBERS  ( c -- n)
 67    UPCASE  DUP  ?A-L IF T9-NUMBERS:A-L ELSE
 68            DUP  ?M-Z IF T9-NUMBERS:M-Z ELSE
 69                         DROP   1 0
 70                      THEN THEN ;
 71
 72: T9.  ( number #presses --) \ prints T9 keypresses
 73    10 *  +   0 <#  #  [CHAR] . HOLD  #  #>   TYPE ;
 74: T9-EMIT   ( c -- ) \ print a character and its T9 keypresses
 75    DUP  EMIT   BL EMIT   T9-NUMBERS T9. ;
 76: T9-TYPE   ( c-addr u -- )  \ print a string as lines of T9 keypresses
 77    OVER + SWAP   DO  CR  I C@ T9-EMIT  LOOP  CR ;
 78
 79CREATE LINEBUF 256 CHARS ALLOT
 80: READLINE   ( -- c-addr u)  \ read a line of input from the user
 81    LINEBUF DUP 256   ACCEPT ;
 82
 83\ read a line of input from the user and print it as lines of T9 keypresses
 84S" String to convert to T9 keypresses: " TYPE   READLINE   T9-TYPE -- INSERT
 
 
Mijn commentaar
 
 Dirk,
 Mij is wederom volslagen duidelijk waarom Forth nooit erg populair is
 geworden.
 Het kost mij wel wat hoofdbrekens om het verloop van het programma bij te
 houden.
 Mijn laatste ervaring met Forth is in.l. al meer dan 20 jaar geleden.
 Ook ik had gekozen voor een oplossing waarin de karakters berekend worden ipv
 ze op te zoeken in een tabel.
 Daardoor loop je wel het risico karacters te missen.
 Denk daarbij aan de letters voorzien van leestekens als umlaut, of accent
 aegu.
 Verder wel cool dat je het op deze manier gedaan hebt.