Abbreviations, easy
This task is an easier (to code) variant of the Rosetta Code task: Abbreviations, simple.
For this task, the following command table will be used:
Add ALTer BAckup Bottom CAppend Change SCHANGE CInsert CLAst COMPress COpy COUnt COVerlay CURsor DELete CDelete Down DUPlicate Xedit EXPand EXTract Find NFind NFINDUp NFUp CFind FINdup FUp FOrward GET Help HEXType Input POWerinput Join SPlit SPLTJOIN LOAD Locate CLocate LOWercase UPPercase LPrefix MACRO MErge MODify MOve MSG Next Overlay PARSE PREServe PURge PUT PUTD Query QUIT READ RECover REFRESH RENum REPeat Replace CReplace RESet RESTore RGTLEFT RIght LEft SAVE SET SHift SI SORT SOS STAck STATus TOP TRAnsfer Type Up
Notes concerning the above command table:
- it can be thought of as one long literal string (with blanks at end-of-lines)
- it may have superfluous blanks
- it may be in any case (lower/upper/mixed)
- the order of the words in the command table must be preserved as shown
- the user input(s) may be in any case (upper/lower/mixed)
- commands will be restricted to the Latin alphabet (A ──► Z, a ──► z)
- A valid abbreviation is a word that has:
- at least the minimum length of the number of capital letters of the word in the command table
- compares equal (regardless of case) to the leading characters of the word in the command table
- a length not longer than the word in the command table
- ALT, aLt, ALTE, and ALTER are all abbreviations of ALTer
- AL, ALF, ALTERS, TER, and A aren't valid abbreviations of ALTer
- The number of capital letters in ALTer indicates that any abbreviation for ALTer must be at least three letters
- Any word longer than five characters can't be an abbreviation for ALTer
- o, ov, oVe, over, overL, overla are all acceptable abbreviations for Overlay
- if there isn't any lowercase letters in the word in the command table, then there isn't an abbreviation permitted
- Task
-
- The command table needn't be verified/validated.
- Write a function to validate if the user "words" (given as input) are valid (in the command table).
- If the word is valid, then return the full uppercase version of that "word".
- If the word isn't valid, then return the lowercase string: *error* (7 characters).
- A blank input (or a null input) should return a null string.
- Show all output here.
- An example test case to be used for this task
For a user string of:
riG rePEAT copies put mo rest types fup. 6 poweRin
the computer program should return the string:
RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT
- Related tasks
Kotlin
<lang scala>// version 1.1.4-3
val r = Regex("[ ]+")
val table =
"Add ALTer BAckup Bottom CAppend Change SCHANGE CInsert CLAst COMPress COpy " + "COUnt COVerlay CURsor DELete CDelete Down DUPlicate Xedit EXPand EXTract Find " + "NFind NFINDUp NFUp CFind FINdup FUp FOrward GET Help HEXType Input POWerinput " + "Join SPlit SPLTJOIN LOAD Locate CLocate LOWercase UPPercase LPrefix MACRO " + "MErge MODify MOve MSG Next Overlay PARSE PREServe PURge PUT PUTD Query QUIT " + "READ RECover REFRESH RENum REPeat Replace CReplace RESet RESTore RGTLEFT " + "RIght LEft SAVE SET SHift SI SORT SOS STAck STATus TOP TRAnsfer Type Up "
fun validate(commands: List<String>, minLens: List<Int>, words: List<String>): List<String> {
if (words.isEmpty()) return emptyList<String>() val results = mutableListOf<String>() for (word in words) { var matchFound = false for ((i, command) in commands.withIndex()) { if (minLens[i] == 0 || word.length !in minLens[i] .. command.length) continue if (command.startsWith(word, true)) { results.add(command.toUpperCase()) matchFound = true break } } if (!matchFound) results.add("*error*") } return results
}
fun main(args: Array<String>) {
val commands = table.trimEnd().split(r) val minLens = MutableList(commands.size) { commands[it].count { c -> c.isUpperCase() } } val sentence = "riG rePEAT copies put mo rest types fup. 6 poweRin" val words = sentence.trim().split(r) val results = validate(commands, minLens, words) print("user words: ") for (j in 0 until words.size) print("${words[j].padEnd(results[j].length)} ") print("\nfull words: ") for (j in 0 until results.size) print("${results[j]} ") println()
}</lang>
- Output:
user words: riG rePEAT copies put mo rest types fup. 6 poweRin full words: RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT
Perl 6
Demonstrate that inputting an empty string returns an empty string in addition to the required test input.
<lang perl6>my @commands = < Add ALTer BAckup Bottom CAppend Change SCHANGE CInsert CLAst COMPress COpy COUnt COVerlay CURsor DELete CDelete Down DUPlicate Xedit EXPand EXTract Find NFind NFINDUp NFUp CFind FINdup FUp FOrward GET Help HEXType Input POWerinput Join SPlit SPLTJOIN LOAD Locate CLocate LOWercase UPPercase LPrefix MACRO MErge MODify MOve MSG Next Overlay PARSE PREServe PURge PUT PUTD Query QUIT READ RECover REFRESH RENum REPeat Replace CReplace RESet RESTore RGTLEFT RIght LEft SAVE SET SHift SI SORT SOS STAck STATus TOP TRAnsfer Type Up > ~~ m:g/ (<.:Lu>+) (<.:Ll>*) /;
my %abr = $/.map( {
my $abbrv = $_[0].Str.lc ~ $_[1].Str.lc; |map { $abbrv.substr( 0, $_ ) => $abbrv.uc }, $_[0].Str.chars .. $abbrv.chars;
} );
sub abbr-easy ( $str ) { $str ?? ( my $cmd = %abr{$str.fc} ) ?? $cmd !! '*error*' !! }
- Testing
for 'riG rePEAT copies put mo rest types fup. 6 poweRin', -> $str {
put ' Input: ', $str; put 'Output: ', join ' ', $str.words.map: *.&abbr-easy;
}</lang>
- Output:
Input: riG rePEAT copies put mo rest types fup. 6 poweRin Output: RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT Input: Output:
REXX
<lang>/*REXX program validates a user "word" against a "command table" with abbreviations.*/ parse arg uw /*obtain optional arguments from the CL*/ if uw= then uw= 'riG rePEAT copies put mo rest types fup. 6 poweRin' say 'user words: ' uw
@= 'Add ALTer BAckup Bottom CAppend Change SCHANGE CInsert CLAst COMPress COpy' ,
'COUnt COVerlay CURsor DELete CDelete Down DUPlicate Xedit EXPand EXTract Find' , 'NFind NFINDUp NFUp CFind FINdup FUp FOrward GET Help HEXType Input POWerinput' , 'Join SPlit SPLTJOIN LOAD Locate CLocate LOWercase UPPercase LPrefix MACRO' , 'MErge MOve MODify MSG Next Overlay PARSE PREServe PURge PUT PUTD Query QUIT' , 'READ RECover REFRESH RENum REPeat Replace CReplace RESet RESTore RGTLEFT' , 'RIght LEft SAVE SET SHift SI SORT SOS STAck STATus TOP TRAnsfer Type Up'
say 'full words: ' validate(uw) /*display the result(s) to the terminal*/ exit /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ validate: procedure expose @; arg x; upper @ /*ARG capitalizes all the X words. */
$= /*initialize the return string to null.*/ do j=1 to words(x); _=word(x, j) /*obtain a word from the X list. */ do k=1 to words(@); a=word(@, k) /*get a legitimate command name from @.*/ L=verify(_, 'abcdefghijklmnopqrstuvwxyz', "M") /*maybe get abbrev's len.*/ if L==0 then L=length(_) /*0? Command name can't be abbreviated*/ if abbrev(a, _, L) then do; $=$ a; iterate j; end /*is valid abbrev?*/ end /*k*/ $=$ '*error*' /*processed the whole list, not valid. */ end /*j*/ return strip($) /*elide the superfluous leading blank. */</lang>
- output when using the default input:
user words: riG rePEAT copies put mo rest types fup. 6 poweRin full words: RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT
Ruby
Abbrev in the standard library builds a hash from the command table. <lang ruby>require "abbrev"
command_table =
"Add ALTer BAckup Bottom CAppend Change SCHANGE CInsert CLAst COMPress COpy COUnt COVerlay CURsor DELete CDelete Down DUPlicate Xedit EXPand EXTract Find NFind NFINDUp NFUp CFind FINdup FUp FOrward GET Help HEXType Input POWerinput Join SPlit SPLTJOIN LOAD Locate CLocate LOWercase UPPercase LPrefix MACRO MErge MODify MOve MSG Next Overlay PARSE PREServe PURge PUT PUTD Query QUIT READ RECover REFRESH RENum REPeat Replace CReplace RESet RESTore RGTLEFT RIght LEft SAVE SET SHift SI SORT SOS STAck STATus TOP TRAnsfer Type Up".split.map(&:upcase)
userstrings = "riG rePEAT copies put mo rest types fup. 6 poweRin".split.map(&:upcase)
abbrevs = command_table.abbrev abbrevs.default = "*error*" puts userstrings.map {|us| abbrevs[us] }.join(" ") </lang>
- Output:
RIGHT REPEAT *error* PUT *error* RESTORE *error* *error* *error* POWERINPUT
zkl
Rather more brute force than I'd like but hashing the command table is just too much code. And the table is so small... <lang zkl>commands:=Data(0,String, // "Add\0ALTer\0..."
- <<<
"Add ALTer BAckup Bottom CAppend Change SCHANGE CInsert CLAst COMPress COpy
COUnt COVerlay CURsor DELete CDelete Down DUPlicate Xedit EXPand EXTract Find NFind NFINDUp NFUp CFind FINdup FUp FOrward GET Help HEXType Input POWerinput Join SPlit SPLTJOIN LOAD Locate CLocate LOWercase UPPercase LPrefix MACRO MErge MODify MOve MSG Next Overlay PARSE PREServe PURge PUT PUTD Query QUIT READ RECover REFRESH RENum REPeat Replace CReplace RESet RESTore RGTLEFT RIght LEft SAVE SET SHift SI SORT SOS STAck STATus TOP TRAnsfer Type Up "
.split());
- <<<
testText:=" riG rePEAT copies put mo rest types " "fup. 6 poweRin";
testText.split().apply('wrap(word){
sz,w := word.len(),word + "*"; foreach c in (commands){ // rather inelegant but gotta ignore case // check for length requirement and, if there, verify if(c.matches(w) and sz>=(c-"abcdefghijklmnopqrstuvwxyz").len())
return(c.toUpper());
} "*error*"
.concat(" ").println();</lang>
- Output:
RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT