I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

Abbreviations, easy

From Rosetta Code
Task
Abbreviations, easy
You are encouraged to solve this task according to the task description, using any language you may know.

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



ALGOL 68[edit]

Works with: ALGOL 68G version Any - tested with release 2.8.3.win32

Uses Algol 68G specific is lower and to upper procedures. Does not use a hash table.

# "Easy" abbreviations                                                 #
# table of "commands" - upper-case indicates the mminimum abbreviation #
STRING 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";
 
# returns the next word from text, updating pos #
PRIO NEXTWORD = 1;
OP NEXTWORD = ( REF INT pos, STRING text )STRING:
BEGIN
# skip spaces #
WHILE IF pos > UPB text THEN FALSE ELSE text[ pos ] = " " FI DO pos +:= 1 OD;
# get the word #
STRING word := "";
WHILE IF pos > UPB text THEN FALSE ELSE text[ pos ] /= " " FI DO
word +:= text[ pos ];
pos +:= 1
OD;
word
END # NEXTWORD # ;
# returns text converted to upper case #
OP TOUPPER = ( STRING text )STRING:
BEGIN
STRING result := text;
FOR ch pos FROM LWB result TO UPB result DO
IF is lower( result[ ch pos ] ) THEN result[ ch pos ] := to upper( result[ ch pos ] ) FI
OD;
result
END # TOUPPER # ;
# returns the minimum abbreviation length of command #
OP MINABLENGTH = ( STRING command )INT:
BEGIN
INT ab min := LWB command;
WHILE IF ab min > UPB command THEN FALSE ELSE is upper( command[ ab min ] ) FI DO ab min +:= 1 OD;
ab min - LWB command
END # MINABLENGTH # ;
# searches for word in command table and returns the full command #
# matching the possible abbreviation or *error* if there is no match #
PRIO EXPAND = 1;
OP EXPAND = ( STRING command table, word )STRING:
IF word = ""
THEN # empty word #
""
ELSE # non-empty word #
INT word len = ( UPB word + 1 ) - LWB word;
STRING upper word := TOUPPER word;
STRING result := "*error*";
INT pos := LWB command table;
WHILE STRING command := pos NEXTWORD command table;
IF command = ""
THEN # end of command table #
FALSE
ELIF word len < MINABLENGTH command OR word len > ( ( UPB command + 1 ) - LWB command )
THEN # word is too short or too long - try the next command #
TRUE
ELIF upper word = TOUPPER command[ LWB command : ( LWB command - 1 ) + word len ]
THEN # found the command #
result := TOUPPER command;
FALSE
ELSE # word doexn't match - try the next command #
TRUE
FI
DO SKIP OD;
result
FI # EXPAND # ;
# tests the EXPAND operator #
PROC test expand = ( STRING words, command table )VOID:
BEGIN
STRING results := "", separator := "";
INT pos := LWB words;
WHILE STRING word = pos NEXTWORD words; word /= "" DO
results +:= separator + ( command table EXPAND word );
separator := " "
OD;
print( ( "Input: ", words, newline ) );
print( ( "Output: ", results, newline ) )
END # test expand # ;
 
# task test cases #
test expand( "riG rePEAT copies put mo rest types fup. 6 poweRin", command table );
test expand( "", command table )
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:

AutoHotkey[edit]

; Setting up command table as one string
str =
(
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
)
str := StrReplace(str,"`n")
 
; comTable turns the command table string into an array
; comTableCapsCount creates an array with the count of capital values for each word
comTable := StrSplit(RegExReplace(str, "\s+", " "), " ")
comTableCapsCount := []
for cmds in comTable
comTableCapsCount.push(StrLen(RegExReplace(comTable[cmds], "[a-z]")))
 
; Take and process user input into an array of abbreviations
InputBox, abbrev, Command, Type in your command(s).`n If you have several commands`, leave spaces between them.
abbrev := Trim(abbrev)
StringLower, lowerCaseAbbrev, abbrev
abbrev := StrSplit(RegExReplace(abbrev, "\s+", " "), " ")
 
; Double loop compares abbreviations to commands in command table
Loop % abbrev.MaxIndex() {
count := A_Index
found := false
for cmds in comTable {
command := SubStr(comTable[cmds], 1, StrLen(abbrev[count]))
StringLower, lowerCaseCommand, command
if (lowerCaseCommand = abbrev[count]) and (StrLen(abbrev[count]) >= comTableCapsCount[cmds]) {
StringUpper, foundCmd, % comTable[cmds]
found := true
}
}
if (found)
result .= " " foundCmd
else
result .= " *error*"
}
MsgBox % Trim(result)
 
Output:
 input: riG   rePEAT copies  put mo   rest    types   fup.    6       poweRin
output: RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT

C[edit]

#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
const char* 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";
 
typedef struct command_tag {
char* cmd;
size_t length;
size_t min_len;
struct command_tag* next;
} command_t;
 
// str is assumed to be all uppercase
bool command_match(const command_t* command, const char* str) {
size_t olen = strlen(str);
return olen >= command->min_len && olen <= command->length
&& strncmp(str, command->cmd, olen) == 0;
}
 
// convert string to uppercase
char* uppercase(char* str, size_t n) {
for (size_t i = 0; i < n; ++i)
str[i] = toupper((unsigned char)str[i]);
return str;
}
 
size_t get_min_length(const char* str, size_t n) {
size_t len = 0;
while (len < n && isupper((unsigned char)str[len]))
++len;
return len;
}
 
void fatal(const char* message) {
fprintf(stderr, "%s\n", message);
exit(1);
}
 
void* xmalloc(size_t n) {
void* ptr = malloc(n);
if (ptr == NULL)
fatal("Out of memory");
return ptr;
}
 
void* xrealloc(void* p, size_t n) {
void* ptr = realloc(p, n);
if (ptr == NULL)
fatal("Out of memory");
return ptr;
}
 
char** split_into_words(const char* str, size_t* count) {
size_t size = 0;
size_t capacity = 16;
char** words = xmalloc(capacity * sizeof(char*));
size_t len = strlen(str);
for (size_t begin = 0; begin < len; ) {
size_t i = begin;
for (; i < len && isspace((unsigned char)str[i]); ++i) {}
begin = i;
for (; i < len && !isspace((unsigned char)str[i]); ++i) {}
size_t word_len = i - begin;
if (word_len == 0)
break;
char* word = xmalloc(word_len + 1);
memcpy(word, str + begin, word_len);
word[word_len] = 0;
begin += word_len;
if (capacity == size) {
capacity *= 2;
words = xrealloc(words, capacity * sizeof(char*));
}
words[size++] = word;
}
*count = size;
return words;
}
 
command_t* make_command_list(const char* table) {
command_t* cmd = NULL;
size_t count = 0;
char** words = split_into_words(table, &count);
for (size_t i = 0; i < count; ++i) {
char* word = words[i];
command_t* new_cmd = xmalloc(sizeof(command_t));
size_t word_len = strlen(word);
new_cmd->length = word_len;
new_cmd->min_len = get_min_length(word, word_len);
new_cmd->cmd = uppercase(word, word_len);
new_cmd->next = cmd;
cmd = new_cmd;
}
free(words);
return cmd;
}
 
void free_command_list(command_t* cmd) {
while (cmd != NULL) {
command_t* next = cmd->next;
free(cmd->cmd);
free(cmd);
cmd = next;
}
}
 
const command_t* find_command(const command_t* commands, const char* word) {
for (const command_t* cmd = commands; cmd != NULL; cmd = cmd->next) {
if (command_match(cmd, word))
return cmd;
}
return NULL;
}
 
void test(const command_t* commands, const char* input) {
printf(" input: %s\n", input);
printf("output:");
size_t count = 0;
char** words = split_into_words(input, &count);
for (size_t i = 0; i < count; ++i) {
char* word = words[i];
uppercase(word, strlen(word));
const command_t* cmd_ptr = find_command(commands, word);
printf(" %s", cmd_ptr ? cmd_ptr->cmd : "*error*");
free(word);
}
free(words);
printf("\n");
}
 
int main() {
command_t* commands = make_command_list(command_table);
const char* input = "riG rePEAT copies put mo rest types fup. 6 poweRin";
test(commands, input);
free_command_list(commands);
return 0;
}
Output:
 input: riG   rePEAT copies  put mo   rest    types   fup.    6       poweRin
output: RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT

C++[edit]

#include <algorithm>
#include <cctype>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
 
const char* 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";
 
class command {
public:
command(const std::string&, size_t);
const std::string& cmd() const { return cmd_; }
size_t min_length() const { return min_len_; }
bool match(const std::string&) const;
private:
std::string cmd_;
size_t min_len_;
};
 
// cmd is assumed to be all uppercase
command::command(const std::string& cmd, size_t min_len)
: cmd_(cmd), min_len_(min_len) {}
 
// str is assumed to be all uppercase
bool command::match(const std::string& str) const {
size_t olen = str.length();
return olen >= min_len_ && olen <= cmd_.length()
&& cmd_.compare(0, olen, str) == 0;
}
 
// convert string to uppercase
void uppercase(std::string& str) {
std::transform(str.begin(), str.end(), str.begin(),
[](unsigned char c) -> unsigned char { return std::toupper(c); });
}
 
size_t get_min_length(const std::string& str) {
size_t len = 0, n = str.length();
while (len < n && std::isupper(static_cast<unsigned char>(str[len])))
++len;
return len;
}
 
class command_list {
public:
explicit command_list(const char*);
const command* find_command(const std::string&) const;
private:
std::vector<command> commands_;
};
 
command_list::command_list(const char* table) {
std::vector<command> commands;
std::istringstream is(table);
std::string word;
while (is >> word) {
// count leading uppercase characters
size_t len = get_min_length(word);
// then convert to uppercase
uppercase(word);
commands_.push_back(command(word, len));
}
}
 
const command* command_list::find_command(const std::string& word) const {
auto iter = std::find_if(commands_.begin(), commands_.end(),
[&word](const command& cmd) { return cmd.match(word); });
return (iter != commands_.end()) ? &*iter : nullptr;
}
 
std::string test(const command_list& commands, const std::string& input) {
std::string output;
std::istringstream is(input);
std::string word;
while (is >> word) {
if (!output.empty())
output += ' ';
uppercase(word);
const command* cmd_ptr = commands.find_command(word);
if (cmd_ptr)
output += cmd_ptr->cmd();
else
output += "*error*";
}
return output;
}
 
int main() {
command_list commands(command_table);
std::string input("riG rePEAT copies put mo rest types fup. 6 poweRin");
std::string output(test(commands, input));
std::cout << " input: " << input << '\n';
std::cout << "output: " << output << '\n';
return 0;
}
Output:
 input: riG   rePEAT copies  put mo   rest    types   fup.    6       poweRin
output: RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT


Euphoria[edit]

 
include std/text.e -- for upper conversion
include std/console.e -- for display
include std/sequence.e
 
sequence ct = """
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
"
""
ct = upper(split(join(split(ct,"\n")," ")," "))
 
object input = remove_all("\n",upper(remove_all("",split(gets(0)))))
display(validate(input))
 
-------------------------------
function validate(object words)
-------------------------------
object results = repeat("*error*",length(words)) -- build an output list;
integer x
for i = 1 to length(words) do
words[i] = remove_all('\n',words[i]) -- final word in input line (may) have \n, get rid of it;
for j = 1 to length(ct) do
x = match(words[i],ct[j])
if x = 1 then
results[i] = ct[j] -- replace this slot in the output list with the "found" word;
exit -- and don't look further into the list;
end if
end for
end for
return flatten(join(results," ")) -- convert sequence of strings into one string, words separated by a single space;
end function
 
Output:
 riG   rePEAT copies  put mo   rest    types   fup.    6       poweRin
 RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT

Factor[edit]

USING: arrays ascii assocs combinators.short-circuit io kernel
literals math qw sequences sequences.extras splitting.extras ;
IN: rosetta-code.abbreviations-easy
 
CONSTANT: commands qw{
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 }
 
CONSTANT: user-input $[ "riG rePEAT copies put mo rest "
"types fup. 6 poweRin" append ]
 
: starts-with? ( cand com -- ? ) [ >upper ] [email protected] start 0 = ;
: capitals ( str -- n ) [ LETTER? ] count ;
: min-len? ( candidate command -- ? ) capitals swap length <= ;
: not-longer? ( candidate command -- ? ) [ length ] [email protected] <= ;
: permitted? ( candidate command -- ? ) dup [ letter? ] count 0
> [ [ >upper ] [email protected] = ] dip or ;
 
: valid-abbr? ( candidate command -- ? )
{
[ permitted? ]
[ starts-with? ]
[ min-len? ]
[ not-longer? ]
} 2&& ;
 
: find-command ( candidate -- command/f )
commands swap [ swap valid-abbr? ] curry find nip ;
 
: process-candidate ( candidate -- abbr/error )
find-command [ >upper ] [ "*error*" ] if* ;
 
: process-user-string ( str -- seq ) dup "" = [ drop "" ]
[ " " split-harvest [ process-candidate ] map ] if ;
 
: .abbr ( input -- )
[ " " split-harvest ] [ process-user-string ] bi zip
[ first2 32 pad-longest 2array ] map
[ keys ] [ values ] bi
[ " " join ] [email protected]
[ "User words: " write print ]
[ "Full words: " write print ] bi* ;
 
: main ( -- ) user-input "" [ .abbr ] [email protected] ;
 
MAIN: main
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
User words:
Full words:

Go[edit]

Translation of: Kotlin
package main
 
import (
"fmt"
"strings"
)
 
var 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 "
 
func validate(commands, words []string, minLens []int) []string {
results := make([]string, 0)
if len(words) == 0 {
return results
}
for _, word := range words {
matchFound := false
wlen := len(word)
for i, command := range commands {
if minLens[i] == 0 || wlen < minLens[i] || wlen > len(command) {
continue
}
c := strings.ToUpper(command)
w := strings.ToUpper(word)
if strings.HasPrefix(c, w) {
results = append(results, c)
matchFound = true
break
}
}
if !matchFound {
results = append(results, "*error*")
}
}
return results
}
 
func main() {
table = strings.TrimSpace(table)
commands := strings.Fields(table)
clen := len(commands)
minLens := make([]int, clen)
for i := 0; i < clen; i++ {
count := 0
for _, c := range commands[i] {
if c >= 'A' && c <= 'Z' {
count++
}
}
minLens[i] = count
}
sentence := "riG rePEAT copies put mo rest types fup. 6 poweRin"
words := strings.Fields(sentence)
results := validate(commands, words, minLens)
fmt.Print("user words: ")
for j := 0; j < len(words); j++ {
fmt.Printf("%-*s ", len(results[j]), words[j])
}
fmt.Print("\nfull words: ")
fmt.Println(strings.Join(results, " "))
}
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

Haskell[edit]

 
import Data.Maybe (fromMaybe)
import Data.List (find, isPrefixOf)
import Data.Char (toUpper, isUpper)
 
isAbbreviationOf :: String -> String -> Bool
isAbbreviationOf abbreviation command =
minimumPrefix `isPrefixOf` normalizedAbbreviation
&& normalizedAbbreviation `isPrefixOf` normalizedCommand
where
normalizedAbbreviation = map toUpper abbreviation
normalizedCommand = map toUpper command
minimumPrefix = takeWhile isUpper command
 
 
expandAbbreviation :: String -> String -> Maybe String
expandAbbreviation commandTable abbreviation = do
command <- find (isAbbreviationOf abbreviation) (words commandTable)
return $ map toUpper command
 
 
commandTable = unwords [
"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"]
 
 
main :: IO ()
main = do
input <- getLine
let abbreviations = words input
let commands = map (fromMaybe "*error*" . expandAbbreviation commandTable) abbreviations
putStrLn $ unwords results
 

J[edit]

Using the expand definition as well as its dependencies from Abbreviations, simple#J we convert this command table into the form with the abbreviation length given as a number.

 
COMMAND_TABLE=: noun define
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
)
 
'CAPA CAPZ'=:a.i.'AZ'
CT =: (, 3 ": [: +/ (CAPA&<: *. <:&CAPZ)@:(a.&i.))&.>&.:;: CRLF -.~ COMMAND_TABLE
user_words =: 'riG rePEAT copies put mo rest types fup. 6 poweRin'
CT expand user_words
RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT
 

Java[edit]

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
 
public class AbbreviationsEasy {
private static final Scanner input = new Scanner(System.in);
private static final String COMMAND_TABLE
= " Add ALTer BAckup Bottom CAppend Change SCHANGE CInsert CLAst COMPress COpy\n" +
" COUnt COVerlay CURsor DELete CDelete Down DUPlicate Xedit EXPand EXTract Find\n" +
" NFind NFINDUp NFUp CFind FINdup FUp FOrward GET Help HEXType Input POWerinput\n" +
" Join SPlit SPLTJOIN LOAD Locate CLocate LOWercase UPPercase LPrefix MACRO\n" +
" MErge MODify MOve MSG Next Overlay PARSE PREServe PURge PUT PUTD Query QUIT\n" +
" READ RECover REFRESH RENum REPeat Replace CReplace RESet RESTore RGTLEFT\n" +
" RIght LEft SAVE SET SHift SI SORT SOS STAck STATus TOP TRAnsfer Type Up";
 
public static void main(String[] args) {
String[] cmdTableArr = COMMAND_TABLE.split("\\s+");
Map<String, Integer> cmd_table = new HashMap<String, Integer>();
 
for (String word : cmdTableArr) { //Populate words and number of caps
cmd_table.put(word, countCaps(word));
}
 
System.out.print("Please enter your command to verify: ");
String userInput = input.nextLine();
String[] user_input = userInput.split("\\s+");
 
for (String s : user_input) {
boolean match = false; //resets each outer loop
for (String cmd : cmd_table.keySet()) {
if (s.length() >= cmd_table.get(cmd) && s.length() <= cmd.length()) {
String temp = cmd.toUpperCase();
if (temp.startsWith(s.toUpperCase())) {
System.out.print(temp + " ");
match = true;
}
}
}
if (!match) { //no match, print error msg
System.out.print("*error* ");
}
}
}
 
private static int countCaps(String word) {
int numCaps = 0;
for (int i = 0; i < word.length(); i++) {
if (Character.isUpperCase(word.charAt(i))) {
numCaps++;
}
}
return numCaps;
}
}
 
Output:
Please enter your command to verify:  
riG   rePEAT copies  put mo   rest    types   fup.    6       poweRin

RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT

Julia[edit]

Works with: Julia version 0.6
Translation of: Kotlin
const 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 "
 
function validate(commands::AbstractVector{<:AbstractString},
minlens::AbstractVector{<:Integer}, words::AbstractVector{<:AbstractString})
r = String[]
for word in words
matchfound = false
for (i, command) in enumerate(commands)
if iszero(minlens[i]) || length(word) ∉ minlens[i]:length(command)
continue
end
if startswith(lowercase(command), lowercase(word))
push!(r, uppercase(command))
matchfound = true
break
end
end
 !matchfound && push!(r, "*error*")
end
return r
end
 
commands = split(strip(table))
minlens = count.(isupper, commands)
sentence = "riG rePEAT copies put mo rest types fup. 6 poweRin"
words = split(sentence)
result = validate(commands, minlens, words)
println("User words: ", join(lpad.(words, 11)))
println("Full words: ", join(lpad.(result, 11)))
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

Kotlin[edit]

// 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()
}
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 

Lua[edit]

#!/usr/bin/lua
 
local list1 = [[
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 ]]
 
 
local indata1 = [[riG rePEAT copies put mo rest types
fup. 6 poweRin]]
 
local indata2 = [[ALT aLt ALTE ALTER AL ALF ALTERS TER A]]
local indata3 = [[o ov oVe over overL overla]]
 
local function split(text)
local result = {}
for w in string.gmatch(text, "%g+") do
result[#result+1]=w
-- print(#result,w,#w)
end
return result
end
 
 
local function print_line( t )
for i = 1,#t do
io.write( string.format("%s ", t[i] ) )
end
print()
end
 
 
local function is_valid(cmd,abbrev)
--print(abbrev,cmd,"##")
 
local sm = string.match( cmd:lower(), abbrev:lower() )
if sm == nil then return -1 end
 
-- test if any lowercase in "cmd"
if false then do -- NOTE!: requirement spec error .. put not equal PUT
local lowcase = string.match(cmd,"%l+")
if lowcase == nil then return -2 end
if #lowcase < 1 then return -3 end
end
end
 
-- test if abbrev is too long
if #abbrev > #cmd then return -4 end
 
--- num caps in "cmd" is minimum length of abbrev
local caps = string.match(cmd,"%u+")
if #abbrev < #caps then return -5 end
 
local s1 = abbrev:sub(1,#caps)
local s2 = cmd:sub(1,#caps)
if s1:lower() ~= s2:lower() then return -6 end
 
return 1
end
 
local function start()
local t1 = {}
local t2 = {}
local result = {}
t1 = split(list1)
t2 = split(indata1)
print_line(t2);
 
for i = 1,#t2 do
good = 0
for j = 1,#t1 do
local abbrev = t2[i]
local cmd = t1[j]
good = is_valid(cmd,abbrev)
if good==1 then do
result[#result+1] = t1[j]:upper()
break end
end --if
end --for j
if good < 1 then result[#result+1] = "*error*" end
end --for i
print_line(result)
end
 
start() -- run the program
 
Output:
Please enter your command to verify:  
riG   rePEAT copies  put mo   rest    types   fup.    6       poweRin

RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT

Nanoquery[edit]

Translation of: Java
import map
 
COMMAND_TABLE = " Add ALTer BAckup Bottom CAppend Change SCHANGE CInsert CLAst COMPress COpy\n" +\
" COUnt COVerlay CURsor DELete CDelete Down DUPlicate Xedit EXPand EXTract Find\n" +\
" NFind NFINDUp NFUp CFind FINdup FUp FOrward GET Help HEXType Input POWerinput\n" +\
" Join SPlit SPLTJOIN LOAD Locate CLocate LOWercase UPPercase LPrefix MACRO\n" +\
" MErge MODify MOve MSG Next Overlay PARSE PREServe PURge PUT PUTD Query QUIT\n" +\
" READ RECover REFRESH RENum REPeat Replace CReplace RESet RESTore RGTLEFT\n" +\
" RIght LEft SAVE SET SHift SI SORT SOS STAck STATus TOP TRAnsfer Type Up"
 
def countCaps(word)
if len(word) < 1
return 0
end
 
numCaps = 0
for i in range(0, len(word) - 1)
if word[i] = upper(word[i])
numCaps += 1
end
end
return numCaps
end
 
cmdTableArr = COMMAND_TABLE.split("\\s+")
cmd_table = new(map)
 
for word in cmdTableArr
cmd_table.put(word, countCaps(word))
end
 
print "Please enter your command to verify: "
user_input = input().split("\\s+")
 
for s in user_input
match = false
for i in range(0, len(cmd_table.keys) - 1)
if (len(s) >= cmd_table.get(cmd_table.keys[i])) and (len(s) <= len(cmd_table.keys[i]))
temp = upper(cmd_table.keys[i])
if temp .startswith. upper(s)
print temp + " "
match = true
end
end
end
 
if !match
print "*error* "
end
end
Output:
Please enter your command to verify: riG   rePEAT copies  put mo   rest    types   fup.    6       poweRin           RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT

Nim[edit]

Translation of: Kotlin

This is a translation of Kotlin solution with some modifications.

 
import sequtils
import strutils
 
const 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"
 
#---------------------------------------------------------------------------------------------------
 
proc validate(words, commands: seq[string]; minLens: seq[int]): seq[string] =
 
if words.len == 0:
return
 
for word in words:
var matchFound = false
for i, command in commands:
if word.len notin minLens[i]..command.len:
continue
if command.toUpper.startsWith(word.toUpper):
result.add(command.toUpper)
matchFound = true
break
if not matchFound:
result.add("*error*")
 
#---------------------------------------------------------------------------------------------------
 
var commands = Commands.splitWhitespace()
var minLens = newSeq[int](commands.len) # Count of uppercase characters.
for idx, command in commands:
minLens[idx] = command.countIt(it.isUpperAscii)
 
while true:
 
try:
stdout.write "Input? "
let words = stdin.readline().strip().splitWhitespace()
let results = words.validate(commands, minLens)
stdout.write("\nUser words: ")
for i, word in words:
stdout.write(word.alignLeft(results[i].len) & ' ')
stdout.write("\nFull words: ")
for result in results:
stdout.write(result & ' ')
stdout.write("\n\n")
 
except EOFError:
echo ""
break
 
Output:
Input?  riG   rePEAT copies  put mo   rest    types   fup.    6       poweRin

User words: riG   rePEAT copies  put mo   rest    types   fup.    6       poweRin    
Full words: RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT 

Input? 

User words: 
Full words: 

Input? 

OCaml[edit]

let cmds = "\
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"

 
let user =
"riG rePEAT copies put mo rest types fup. 6 poweRin"
 
let char_is_uppercase c =
match c with
| 'A'..'Z' -> true
| _ -> false
 
let get_abbr s =
let seq = String.to_seq s in
let seq = Seq.filter char_is_uppercase seq in
(String.of_seq seq)
 
let () =
let cmds = Str.split (Str.regexp "[ \r\n]+") cmds in
let cmds =
List.map (fun s ->
get_abbr s,
String.uppercase_ascii s
) cmds
in
let user = Str.split (Str.regexp "[ \r\n]+") user in
let r =
List.map (fun ucmd ->
let n = String.length ucmd in
let find_abbr (abbr, cmd) =
let na = String.length abbr in
let nc = String.length cmd in
if n < na || nc < n then false else
let sub = String.sub cmd 0 n in
(sub = String.uppercase_ascii ucmd)
in
match List.find_opt find_abbr cmds with
| Some (_, found) -> found
| None -> "*error*"
) user
in
print_endline (String.concat " " r)
Output:
$ ocaml str.cma abbr.ml
RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT

Perl[edit]

Translation of: Raku
@c = (join ' ', qw<
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 Replace REPeat CReplace RESet RESTore RGTLEFT
RIght LEft SAVE SET SHift SI SORT SOS STAck STATus TOP TRAnsfer Type Up
>) =~ /([A-Z]+)([a-z]*)(?:\s+|$)/g;
 
my %abr = ('' => '', ' ' => '');
for ($i = 0; $i < @c; $i += 2) {
$sl = length($s = $c[$i] );
$ll = length($l = uc $c[$i+1]);
$abr{$s} = $w = $s.$l;
map { $abr{substr($w, 0, $_)} = $w } $sl .. $ll;
$abr{$w} = $w; # full command should always work
}
 
$fmt = "%-10s";
$inp = sprintf $fmt, 'Input:';
$out = sprintf $fmt, 'Output:';
for $str ('', qw<riG rePEAT copies put mo rest types fup. 6 poweRin>) {
$inp .= sprintf $fmt, $str;
$out .= sprintf $fmt, $abr{uc $str} // '*error*';
}
 
print "$inp\n$out\n"
Output:
Input:              riG       rePEAT    copies    put       mo        rest      types     fup.      6         poweRin
Output:             RIGHT     REPEAT    *error*   PUT       MOVE      RESTORE   *error*   *error*   *error*   POWERINPUT

Phix[edit]

constant abbrtxt = """
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
""",
input = "riG rePEAT copies put mo rest types fup. 6 poweRin"
 
function set_min_lengths(sequence a)
sequence res = {}
for i=1 to length(a) do
string ai = a[i], uai = upper(ai)
for j=-length(ai) to 0 do
if j=0 or ai[j]!=uai[j] then
res = append(res,{ai,length(ai)+j})
exit
end if
end for
end for
return res
end function
 
constant abbrevs = set_min_lengths(split(substitute(abbrtxt,"\n"," "),no_empty:=true))
constant inputs = split(input,no_empty:=true)
 
for i=1 to length(inputs) do
string ii = inputs[i],
res = "*error*"
for j=1 to length(abbrevs) do
{string aj, integer l} = abbrevs[j]
if length(ii)>=l
and match(ii,aj,case_insensitive:=true)==1 then
res = upper(aj)
exit
end if
end for
puts(1,res&" ")
end for
puts(1,"\n")
Output:
RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT

PowerShell[edit]

 
<#Start with a string of the commands#>
$cmdTableStr = "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"
 
<#String of inputs#>
$userWordStr = "riG rePEAT copies put mo rest types fup. 6 poweRin"
 
$outputStr = $null <#Set this string to null only so all variables are intialized#>
 
$cmdTabArray = @() <#Arrays for the commands and the inputs#>
$userWordArray = @()
 
<#Split the strings into arrays using a space as the delimiter. This also removes "blank" entries, which fits the requirement "A blank input (or a null input) should return a null string."#>
$cmdTabArray = $cmdTableStr.Split(" ", [System.StringSplitOptions]::RemoveEmptyEntries)
$userWordArray = $userWordStr.Split(" ", [System.StringSplitOptions]::RemoveEmptyEntries)
 
<#Begins a loop to iterate through the inputs#>
foreach($word in $userWordArray)
{
$match = $false #Variable set to false so that if a match is never found, the "*error*" string can be appended
foreach($cmd in $cmdTabArray)
{
if($cmd -like "$word*" -and ($word.Length -ge ($cmd -creplace '[a-z]').Length)) <#This test: 1) ensures inputs match the leading characters of the command 2) are abbreviations of the command 3) the abbreviations is at least the number of capital characters in the command#>
{
$outputStr += $cmd.ToUpper() + " " #Adds the command in all caps to the output string
$match = $true #sets the variable so that "*error*" is not appended
break #break keep the loop from continuing and wasting time once a match was found
}
}
 
if($match -eq $false){$outputStr += "*error* "} #appends error if no match was found
}
#below lines display the input and output
$userWordStr
""
$outputStr
 

Python[edit]

Works with: Python version 3.6
 
 
command_table_text = """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"""

 
user_words = "riG rePEAT copies put mo rest types fup. 6 poweRin"
 
 
def find_abbreviations_length(command_table_text):
""" find the minimal abbreviation length for each word by counting capital letters.
a word that does not have capital letters
gets it's full lengths as the minimum.
"""

command_table = dict()
for word in command_table_text.split():
abbr_len = sum(1 for c in word if c.isupper())
if abbr_len == 0:
abbr_len = len(word)
command_table[word] = abbr_len
return command_table
 
 
def find_abbreviations(command_table):
""" for each command insert all possible abbreviations"""
abbreviations = dict()
for command, min_abbr_len in command_table.items():
for l in range(min_abbr_len, len(command)+1):
abbr = command[:l].lower()
abbreviations[abbr] = command.upper()
return abbreviations
 
 
def parse_user_string(user_string, abbreviations):
user_words = [word.lower() for word in user_string.split()]
commands = [abbreviations.get(user_word, "*error*") for user_word in user_words]
return " ".join(commands)
 
 
command_table = find_abbreviations_length(command_table_text)
abbreviations_table = find_abbreviations(command_table)
 
full_words = parse_user_string(user_words, abbreviations_table)
 
print("user words:", user_words)
print("full words:", full_words)
 

Racket[edit]

#lang racket
 
(define command-string
"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")
 
(define input-string
"riG rePEAT copies put mo rest types fup. 6 poweRin")
 
(define (make-command command)
(cons (string-upcase command)
(list->string (takef (string->list command) char-upper-case?))))
 
(define commands (map make-command (string-split command-string)))
 
(string-join
(for/list ([s (in-list (string-split input-string))])
(define up (string-upcase s))
(or (for/or ([command (in-list commands)])
(match-define (cons full-command abbrev) command)
(and (string-prefix? up abbrev)
(string-prefix? full-command up)
full-command))
"*error*"))
" ")
Output:
"RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT"

Raku[edit]

(formerly Perl 6)

Works with: Rakudo version 2017.08

Demonstrate that inputting an empty string returns an empty string in addition to the required test input.

<
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.fc;
|map { $abbrv.substr( 0, $_ ) => $abbrv.uc },
.[0][0].Str.chars .. $abbrv.chars
};
 
sub abbr-easy ( $str ) { %abr{$str.trim.fc} // '*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;
}
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[edit]

/*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. */
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[edit]

#!/usr/bin/env ruby
 
cmd_table = File.read(ARGV[0]).split
user_str = File.read(ARGV[1]).split
 
user_str.each do |abbr|
candidate = cmd_table.find do |cmd|
cmd.count('A-Z') <= abbr.length && abbr.casecmp(cmd[0...abbr.length]).zero?
end
 
print candidate.nil? ? '*error*' : candidate.upcase
 
print ' '
end
 
puts
 
Output:
$ ./abbreviations_easy.rb cmd_table user_str
RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT

Rust[edit]

use std::collections::HashMap;
 
fn main() {
let 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 \
";
let split = commands.split_ascii_whitespace();
let count_hashtable: HashMap<&str, usize> = split.map(|word| {
(word, word.chars().take_while(|c| c.is_ascii_uppercase()).count())
}).collect();
 
let line = "riG rePEAT copies put mo rest types fup. 6 poweRin";
let mut words_vec: Vec<String> = vec![];
for word in line.split_ascii_whitespace() {
let split = commands.split_ascii_whitespace();
let abbr = split.filter(|x| {
x.to_ascii_lowercase().starts_with(&word.to_ascii_lowercase()) &&
word.len() >= *count_hashtable.get(x).unwrap()
}).next();
words_vec.push(match abbr {
Some(word) => word.to_ascii_uppercase(),
None => String::from("*error*"),
});
}
let corrected_line = words_vec.join(" ");
println!("{}", corrected_line);
}
 
Output:
RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT

Scala[edit]

 
object Main extends App {
implicit class StrOps(i: String) {
def isAbbreviationOf(target: String): Boolean = {
@scala.annotation.tailrec
def checkPAsPrefixOfM(p: List[Char], m: List[Char]): Boolean = (p, m) match {
case (Nil, _) => true //prefix empty
case (_, Nil) => false //main string empty
case (ph :: pt, mh :: mt) if ph.toUpper == mh.toUpper => checkPAsPrefixOfM(pt, mt) //case insensitive match of head characters
case _ => false
}
i.length >= target.count(_.isUpper) && checkPAsPrefixOfM(i.toList, target.toList)
}
}
 
val 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
"
"".stripMargin.replace("\n", " ").trim.split(" ")
 
val input = "riG rePEAT copies put mo rest types fup. 6 poweRin".split(" ").filter(!_.isEmpty)
 
val resultLine = input.map{ i =>
commands.find(c => i.isAbbreviationOf(c)).map(_.toUpperCase).getOrElse("*error*")
}.mkString(" ")
 
println(resultLine)
}
 
Output:
RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT

Tcl[edit]

 
proc appendCmd {word} {
# Procedure to append the correct command from the global list ::cmds
# for the word given as parameter to the global list ::result.
# If a matching word has been found and appended to ::result, this procedure
# behaves like a "continue" statement, causing the loop containing it to
# jump over the rest of the body.
set candidates [lsearch -inline -all -nocase -glob $::cmds "${word}*"]
foreach cand $candidates {
if {[string length $word] >= $::minLen($cand)} {
lappend ::result [string toupper $cand]
return -code continue
}
}
}
 
set cmds {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}
 
# Find the minimum lengths necessary for each command.
foreach c $cmds {
regexp {^[A-Z]+} $c match
set minLen($c) [string length $match]
}
 
set words {riG rePEAT copies put mo rest types fup. 6 poweRin}
set result {}
 
foreach w $words {
appendCmd $w
lappend result *error*
}
 
puts $result
 
Output:
RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT

VBA[edit]

Private Function ValidateUserWords(userstring As String) As String
Dim s As String
Dim user_words() As String
Dim command_table As Scripting.Dictionary
Set command_table = New Scripting.Dictionary
Dim abbreviations As Scripting.Dictionary
Set abbreviations = New Scripting.Dictionary
abbreviations.CompareMode = TextCompare
Dim commandtable() As String
Dim commands As String
s = s & "Add ALTer BAckup Bottom CAppend Change SCHANGE CInsert CLAst COMPress COpy "
s = s & "COUnt COVerlay CURsor DELete CDelete Down DUPlicate Xedit EXPand EXTract Find "
s = s & "NFind NFINDUp NFUp CFind FINdup FUp FOrward GET Help HEXType Input POWerinput "
s = s & "Join SPlit SPLTJOIN LOAD Locate CLocate LOWercase UPPercase LPrefix MACRO "
s = s & "MErge MODify MOve MSG Next Overlay PARSE PREServe PURge PUT PUTD Query QUIT "
s = s & "READ RECover REFRESH RENum REPeat Replace CReplace RESet RESTore RGTLEFT "
s = s & "RIght LEft SAVE SET SHift SI SORT SOS STAck STATus TOP TRAnsfer Type Up "
commandtable = Split(s, " ")
Dim i As Integer
For Each word In commandtable
If Len(word) > 0 Then
i = 1
Do While Mid(word, i, 1) >= "A" And Mid(word, i, 1) <= "Z"
i = i + 1
Loop
command_table.Add Key:=word, Item:=i - 1
End If
Next word
For Each word In command_table
For i = command_table(word) To Len(word)
On Error Resume Next
abbreviations.Add Key:=Left(word, i), Item:=UCase(word)
Next i
Next word
user_words() = Split(userstring, " ")
For Each word In user_words
If Len(word) > 0 Then
If abbreviations.exists(word) Then
commands = commands & abbreviations(word) & " "
Else
commands = commands & "*error* "
End If
End If
Next word
ValidateUserWords = commands
End Function
Public Sub program()
Dim guserstring As String
guserstring = "riG rePEAT copies put mo rest types fup. 6 poweRin"
Debug.Print "user words:", guserstring
Debug.Print "full words:", ValidateUserWords(guserstring)
End Sub
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 

Vedit macro language[edit]

// Command table:
Buf_Switch(#10=Buf_Free)
Ins_Text("
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
"
)
 
// Example input:
Buf_Switch(#11=Buf_Free)
Ins_Text("riG rePEAT copies put mo rest types fup. 6 poweRin ")
BOF
 
// Main program
#20 = Reg_Free() // Text register for the word to be converted
Repeat(ALL) {
Buf_Switch(#11) // Buffer for example input
Search("|!|X", ERRBREAK) // Find next non-space character
#30 = Cur_Pos // #30 = begin of a word
Search("|X", NOERR+NORESTORE) // Find whitespace (end of the word)
Reg_Copy_Block(#20, #30, Cur_Pos) // Get the word to text register #20
Call("acronym_to_word") // Convert acronym to full word
Reg_Type(#20) // Display the full word
Type_Char(' ') // Display a space character
}
Buf_Switch(#10) Buf_Quit(OK) // Clean-up
Buf_Switch(#11) Buf_Quit(OK)
Reg_Empty(#20)
Return
 
// Convert an acronym to full word in uppercase
// Input: @(#20) = the acronym
// Return: @(#20) = the full word
//
:acronym_to_word:
if (Reg_Size(#20) == 0) { // If zero length input,
return // return zero length string
}
Buf_Switch(#10) // Switch to command table
BOF
While (!At_EOF) {
if (Search("|S|@(#20)", NOERR)) { // Find (the first part of) the word
Char // Skip the separator
#31 = Cur_Pos // #31 = Begin of the acronym
Char(Reg_Size(#20)) // Check if the acronym is log enough
if (Cur_Char < 'A' || Cur_Char > 'Z') { // Not a capital letter, verified
Search("|X") // Find the end of the word
Reg_Copy_Block(#20, #31, Cur_Pos) // Get the word into text register #20
Buf_Switch(Buf_Free) // Convert to upper case using tmp buffer
Reg_Ins(#20)
Case_Upper_Block(0, Cur_Pos)
Reg_Copy_Block(#20, 0, Cur_Pos)
Buf_Quit(OK)
break // Word found, exit loop
}
} else { // Not found
Reg_Set(#20, "*error*")
break
}
}
Return
Output:
RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT 

Wren[edit]

Translation of: Go
Library: Wren-fmt
Library: Wren-str
import "/fmt" for Fmt
import "/str" for Str
 
var 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"
 
var validate = Fn.new { |commands, words, minLens|
var results = []
if (words.count == 0) return results
for (word in words) {
var matchFound = false
var wlen = word.count
for (i in 0...commands.count) {
var command = commands[i]
if (minLens[i] != 0 && wlen >= minLens[i] && wlen <= command.count) {
var c = Str.upper(command)
var w = Str.upper(word)
if (c.startsWith(w)) {
results.add(c)
matchFound = true
break
}
}
}
if (!matchFound) results.add("*error*")
}
return results
}
 
var commands = table.split(" ")
// get rid of empty entries
for (i in commands.count-1..0) if (commands[i] == "") commands.removeAt(i)
var clen = commands.count
var minLens = [0] * clen
for (i in 0...clen) {
var count = 0
for (c in commands[i].codePoints) {
if (c >= 65 && c <= 90) count = count + 1 // A to Z
}
minLens[i] = count
}
var sentence = "riG rePEAT copies put mo rest types fup. 6 poweRin"
var words = sentence.split(" ")
// get rid of empty entries
for (i in words.count-1..0) if (words[i] == "") words.removeAt(i)
var results = validate.call(commands, words, minLens)
System.write("user words: ")
for (j in 0...words.count) {
System.write("%(Fmt.s(-results[j].count, words[j])) ")
}
System.write("\nfull words: ")
System.print(results.join(" "))
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

Yabasic[edit]

data "Add ALTer  BAckup Bottom  CAppend Change SCHANGE  CInsert CLAst COMPress COpy"
data "COUnt COVerlay CURsor DELete CDelete Down DUPlicate Xedit EXPand EXTract Find"
data "NFind NFINDUp NFUp CFind FINdup FUp FOrward GET Help HEXType Input POWerinput"
data "Join SPlit SPLTJOIN LOAD Locate CLocate LOWercase UPPercase LPrefix MACRO"
data "MErge MODify MOve MSG Next Overlay PARSE PREServe PURge PUT PUTD Query QUIT"
data "READ RECover REFRESH RENum REPeat Replace CReplace RESet RESTore RGTLEFT"
data "RIght LEft SAVE SET SHift SI SORT SOS STAck STATus TOP TRAnsfer Type Up"
data ""
 
dim abrev$(1)
 
do
read a$
if a$ = "" break
s$ = s$ + " " + a$
loop
 
size = token(s$, abrev$())
 
do
input "Input abbreviation: " a$
l1 = len(a$)
 
if l1 = 0 break
test = false
for i = 1 to size
l2 = uppers(abrev$(i))
if lower$(left$(abrev$(i), l1)) = lower$(left$(a$, l1)) and l1 >= l2 then
print upper$(abrev$(i))
test = true
end if
next
if not test print "*error*"
loop
 
sub uppers(s$)
local l, i, c$, n
 
l = len(s$)
for i = 1 to l
c$ = mid$(s$, i, 1)
if c$ >= "A" and c$ <= "Z" n = n + 1
next
return n
end sub
 

zkl[edit]

Rather more brute force than I'd like but hashing the command table is just too much code. And the table is so small...

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();
Output:
RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT