生成菜单的键盘快捷键


10

菜单快捷方式

传统上,用户菜单可通过键盘快捷键(例如)访问Alt + (a letter),甚至在所有文本框都未聚焦时(gmail样式)也可以直接按字母。

你的任务

给定菜单项作为输入,您的任务是为每个菜单项授予适当的快捷键。

编写一个接受一组单词的函数或程序-菜单项(以字符串数组或您的语言等效形式),并从单个字母到菜单项返回字典或哈希图。

您可以使用参数并返回值,也可以使用STDIN并将结果输出到STDOUT。您不能假定全局/作用域变量已使用输入填充。

确定正确字母的算法

  • 基本上,这是单词的第一个可用字母。请参见下面的假设和示例。
  • 如果所有条目的字母都不可用,则快捷方式将为(a letter) + (a number)。您从条目中选择哪个字母是任意的。该数字应从0开始并以1递增-这样所有快捷方式都是唯一的。请参阅下面的第三个示例。

假设条件

  • 输入将是一个Set,即没有重复,每个条目都是唯一的。
  • 输入的长度可以是任何非负整数(最多为您的语言的MAX_INT)。
  • 区分大小写:输入区分大小写(但忽略大小写时将保持唯一)。结果应包含原始条目及其原始大小写。但是,输出快捷方式字母不区分大小写。
  • 所有输入的单词都不会以数字结尾。
  • 不会测试“邪恶输入”。“邪恶输入”使您必须将某个字母的计数器增加10倍以上。

例子

下面的示例使用JSON,但是您可以将等效语言用于数组和字典,或者-在使用STD I / O的情况下-输入和输出的任何可读格式(例如csv甚至是空格-分隔值)。

1。

Input:  ['File', 'Edit', 'View', 'Help']
Output: {f:'File', e:'Edit', v:'View', h:'Help'}

2。

Input:  ['Foo', 'Bar', 'FooBar', 'FooBars']
Output: {f:'Foo', b:'Bar', o:'FooBar', a:'FooBars'}

3。

Input:  ['a', 'b', 'aa', 'bb', 'bbq', 'bbb', 'ba']
Output: {a:'a', b:'b', a0:'aa', b0:'bb', q:'bbq', b1:'bbb', b2:'ba'}

获奖条件

最短的代码胜出。仅允许使用ASCII。


第一个条目已经采用了“ a”。因此,对于“ aa”,因为它的两个字母都已被占用,所以得到a0。与b0-b2相同。
mattacular 2014年

如果数字用完了怎么办?
nderscore 2014年

@nderscore真的有必要吗?
seequ 2014年

应该['ab', 'a']{a:'ab', a0:'a'}还是{b:'ab', a:'a'}
亚当

@Adám都可以接受。因为您以有序的方式扫描输入数组,所以实现前者会更容易,但是如果出于某种原因您更喜欢后者,那就去吧。
雅各布

Answers:


4

使用Javascript(ES6106 105 100

此函数将输入作为一个数组并输出一个javascript对象。

f=i=>i.map(a=>{for(b of c=a.toLowerCase(d=0)+d+123456789)d<!o[e=b>=0?c[0]+b:b]&&(o[d=e]=a)},o={})&&o

结果:

f(['File', 'Edit', 'View', 'Help']);
// {"f":"File","e":"Edit","v":"View","h":"Help"}

f(['Foo', 'Bar', 'FooBar', 'FooBars']);
// {"f":"Foo","b":"Bar","o":"FooBar","a":"FooBars"}

f(['a', 'b', 'aa', 'bb', 'bbq', 'bbb', 'ba']);
// {"a":"a","b":"b","a0":"aa","b0":"bb","q":"bbq","b1":"bbb","b2":"ba"}

取消高尔夫/评论:

f=i=>{
  o={};                                        // initialize an object for output
  i.map(a=>                                    // loop through all values in input
    for(b of c=a.toLowerCase(d=0)+d+123456789) // loop through all characters of the string with 0123456789 appended to the end
                                               // and initialize d as 0 to be used as a flag 
      e=b>=0?c[0]+b:b                          // if b is a number, set e to the first character + the number, otherwise b
      if(d<!o[e])                              // if the flag hasn't been triggered and o doesn't have a property e
        o[d=e]=a                               // then store the value at e and trigger the d flag
  )
  return o                                     // return the output object
}

这很漂亮。对于邪恶的输入['a', 'aa', 'aaa', 'aaaa', 'aaaaa', 'aaaaaa', 'aaaaaaa', 'aaaaaaaa', 'aaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaaa', 'aaaaaaaaaaaa'],它可能会失败,但是我认为我们可以忽略这样的极端情况,不是吗?
2014年

@Jacob当我们击中时会发生什么11?您不能在键盘快捷键中按两次一个键:P
nderscore 2014年

您在这里有一个要点(尽管有可能实现,因为实现要等到击键结束(大约200毫秒左右))。无论如何,我将增加一个假设,即不会测试这种邪恶的输入。
2014年

2

Python 2.x- 176170157114字节

很简单的方法,但是必须有人继续比赛。

r={}
for i in input():a=list(i.upper());r[([c for c in a+[a[0]+`x`for x in range(10)]if c not in r])[0]]=i
print r

Edit 1: Reversed the checking operation and made it set the result only once.
Edit 2: Removed branching.
Edit 3: Removed unnecessary dictionary. (thanks to the added assumption)

例子:

Input:  ['File', 'Edit', 'View', 'Help']
Output: {'H': 'Help', 'V': 'View', 'E': 'Edit', 'F': 'File'}

Input:  ['Foo', 'Bar', 'FooBar', 'FooBars']
Output: {'A': 'FooBars', 'B': 'Bar', 'O': 'FooBar', 'F': 'Foo'}

Input:  ['a', 'b', 'aa', 'bb', 'bbq', 'bbb', 'ba']
Output: {'A': 'a', 'B': 'b', 'Q': 'bbq', 'A0': 'aa', 'B0': 'bb', 'B1': 'bbb', 'B2': 'ba'}

我认为唯一需要说明的是非高尔夫代码。(这实际上是原始版本)

items = input() # ['File', 'Edit', 'View', 'Help']
chars = map(chr,range(65,91))
numbers = {}.fromkeys(chars,0)
result = {}
for item in items:
    try:
        key = [c for c in item.upper() if c in chars][0] # causes an exception when no items match
        result[key] = item
        chars.remove(key)
    except:
        key = item[0].upper()
        result[key+`numbers[key]`] = item
        numbers[key] += 1
print result

我必须对@Jacob表示谦卑的感谢。输入格式很棒。
seequ 2014年

2

JavaScript(ECMAScript 6)-107个字符

f=a=>(o={},p={},[o[[c for(c of l=w.toLowerCase())if(!o[c])][0]||(k=l[0])+(p[k]=p[k]+1|0)]=w for(w of a)],o)

说明:

f=a=>(
  o={},                              // The dictionary to output
  p={},                              // Stores record of numbers appended after duplicate
                                     // menu keys
  [                                  // Use array comprehension for each word w of input a
   (unmatchedCharacters
     =[c                             // Use array comprehension for each character c of
      for(c of l=w.toLowerCase())    //   the lower case of word w but only get
      if(!o[c])                      //   those characters which are not already a key in o.
     ],
    key=unmatchedCharacters[0]       // Take the first of those characters
     ||                              // Or if all characters are already in o
     (k=l[0])                        // Take the first character of the lower-case word
     +(p[k]=p[k]+1|0),               //   concatenated with the increment of the digit stored
                                     //   in p (or zero). 
   o[key]=w)                         // Set o to map from this key to the word
   for(w of a)
  ],
  o)                                 // return o

测试:

f(['File', 'Edit', 'View', 'Help']);
{f: "File", e: "Edit", v: "View", h: "Help"}

f(['Foo', 'Bar', 'FooBar', 'FooBars']);
{f: "Foo", b: "Bar", o: "FooBar", a: "FooBars"}

f(['a', 'b', 'aa', 'bb', 'bbq', 'bbb', 'ba']);
{a: "a", b: "b", a0: "aa", b0: "bb", q: "bbq", b1: "bbb", b2: "ba"}

1

PHP> = 5.4-149个字符

根据PHP的标准(在此处插入snigger),输入不是有效的JSON,因为它使用'而不是",所以我有些不客气,并且将Input用作实际的变量声明:

<?
$i = ['a', 'b', 'aa', 'bb', 'bbq', 'bbb', 'ba'];
$c=[];foreach($i as$w){foreach(str_split($w) as$j)if(!$c[$j]){$x=$j;goto f;}$n=0;do{$x=$w[0].$n++;}while($c[$x]);f:$c[$x]=$w;}echo json_encode($c);

使用示例:

Input:  ['File', 'Edit', 'View', 'Help']
Output: {"F":"File","E":"Edit","V":"View","H":"Help"}

Input:  ['Foo', 'Bar', 'FooBar', 'FooBars']
Output: {"F":"Foo","B":"Bar","o":"FooBar","a":"FooBars"}

Input:  ['a', 'b', 'aa', 'bb', 'bbq', 'bbb', 'ba']
Output: {"a":"a","b":"b","a0":"aa","b0":"bb","q":"bbq","b1":"bbb","b2":"ba"}

取消涂胶是很基本的:

<?
$i = ['a', 'b', 'aa', 'bb', 'bbq', 'bbb', 'ba'];
$c = [];
foreach($i as $w)
{
    foreach(str_split($w) as $j)
        if(!$c[$j])
        {
            $x = $j;
            goto f;
        }
    $n = 0;
    do
    {
        $x = $w[0] . $n++;
    }
    while($c[$x]);
    f: $c[$x] = $w;
}
echo json_encode($c);

PHP有跳转声明吗?就是这样... 90年代。
seequ 2014年

2
您不必坚持使用JSON,我仅提供了JSON中的示例,但是,正如问题中所述,您可以选择任何可读的格式进行输出,或者将等效的语言用于Dictionary。(您可以通过删除json_encode调用来保存13个字符)。
2014年

echo不适用于数组;但print_r($c);这样做可以节省9个字节。
泰特斯(Titus)

但这并不区分大小写。str_split(strtoupper($w))ucfirst($w[0])可以解决(+21); 或$s=strtoupper($w);(+18)
泰特斯

1

PowerShell91 83字节

$r=@{}
$args|%{$r[($_|% *wer|% t*y|%{$c=$_;,''+0..9|%{$c+$_}|?{!$r.$_}})[0]]=$_}
$r

在线尝试!

如果找不到正确的快捷方式,它将引发异常。

展开:

$result=@{}
$args|%{
    $shortcuts = $_|% toLower|% toCharArray|%{
        $c=$_
        ,''+0..9|%{$c+$_}|?{!$result.$_}    # output shortcuts are not exist in the result
    }
    $properShortcut = $shortcuts[0]         # throws an exception if a proper shortcut not found
    $result[$properShortcut]=$_
}
$result

0

PHP,153字节

for($c=[];$w=trim(fgets(STDIN));$c[reset(array_diff(str_split($s),array_keys($c)))?:$y]=$w){$s=strtoupper($w);for($n=0;$c[$y=$s[0].$n++];);}print_r($c);

php-r '<code>' <<EOF+ Enter + <word1>+ Enter + <word2>+ Enter + ... + EOF+ Enter运行

在argv上工作155个字节

$c=[];foreach($argv as$i=>$w)if($i){$s=strtoupper($w);for($n=0;$c[$y=$s[0].$n++];);$c[reset(array_diff(str_split($s),array_keys($c)))?:$y]=$w;}print_r($c);

php -r '<code>' <word1> <word2> ...

(-13字节,带有已定义的global:foreach($i as$w)而不是foreach($argv as$i=>$w)if($i)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.