메뉴의 키보드 단축키 생성


10

메뉴 바로 가기

일반적으로 사용자 메뉴는와 같은 키보드 단축키로 액세스 Alt + (a letter)하거나 모든 텍스트 상자의 초점이 맞지 않을 때 문자를 누르기 만하면됩니다 ( gmail 스타일).

당신의 작업

메뉴 항목을 입력으로 지정하면 각 메뉴 항목에 적절한 단축키를 부여해야합니다.

메뉴 항목 (문자열 배열 또는 해당 언어의 언어로 된 단어)을 수용하고 단일 문자에서 메뉴 항목으로 사전 또는 해시 맵을 리턴하는 함수 또는 프로그램을 작성하십시오.

매개 변수를 사용하고 값을 리턴하거나 STDIN을 사용하여 결과를 STDOUT에 출력 할 수 있습니다. 전역 / 범위 변수가 이미 입력으로 채워져 있다고 가정 할 수 없습니다 .

적절한 글자를 결정하는 알고리즘

  • 기본적으로 단어의 첫 번째 사용 가능한 문자입니다. 아래의 가정과 예를 참조하십시오.
  • 모든 항목의 문자를 사용할 수없는 경우 바로 가기는입니다 (a letter) + (a number). 항목에서 선택하는 문자는 임의적입니다. 숫자는 0에서 시작하여 1 씩 증가해야합니다. 모든 단축키는 고유합니다. 아래의 세 번째 예를 참조하십시오.

가정

  • 입력은 세트가 될 것입니다. 즉, 반복이 없습니다. 모든 엔트리는 고유합니다.
  • 입력 길이는 음이 아닌 정수 (언어의 최대 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'}

삼.

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

숫자가 부족하면 어떻게됩니까?
nderscore

@nderscore 정말 필요한가요?
seequ

또는 ['ab', 'a']제공 해야합니까 ? {a:'ab', a0:'a'}{b:'ab', a:'a'}
Adám

@ Adám 모두 허용됩니다. 순서대로 입력 배열을 스캔하기 때문에 전자를 구현하는 것이 더 쉽지만 어떤 이유로 든 후자를 선호하는 경우가 있습니다.
Jacob

답변:


4

자바 ( ES6 ) 106 105 100

이 함수는 입력을 배열로 가져 와서 자바 스크립트 객체를 출력합니다.

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']있지만, 우리는 그러한 우연한 경우를 무시할 수 있다고 생각합니다.
Jacob

@Jacob 그리고 우리가 맞았을 때 어떻게됩니까 11? 키보드 단축키에서 하나의 키를 두 번 누를 수 없습니다 : P
nderscore

당신은 거기에 요점이 있습니다 (키 스트로크가 끝날 때까지 기다리는 구현이 가능할 수도 있지만 (200ms 정도)). 어쨌든, 그런 악의적 인 입력은 테스트되지 않을 것이라는 가정에 덧붙일 것입니다.
Jacob

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'}

필요한 유일한 설명은 ungolfed 코드라고 생각합니다. (이것은 실제로 원본 버전입니다)

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

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 표준에 따르면 (여기에 스니퍼 삽입) 입력은 '대신 JSON을 사용할 때 유효한 JSON이 아니므 "로 약간 건 방해졌으며 입력을 실제 변수 선언으로 사용하고 있습니다.

<?
$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

2
JSON을 고수 할 필요는 없으며 JSON으로 예제 만 제공했지만 질문에 명시된 것처럼 읽을 수있는 형식을 선택하거나 사전에 해당하는 언어를 사용할 수 있습니다. ( json_encode호출 을 제거하여 13자를 저장할 수 있습니다 ).
Jacob

echo배열에서는 작동하지 않습니다. 그러나 print_r($c);9 바이트를 절약하면됩니다.
Titus

그러나 이것은 대소 문자를 구분하지 않습니다. str_split(strtoupper($w))ucfirst($w[0])(+21)를 그 해결; 또는 $s=strtoupper($w);(+18)
Titus

1

PowerShell , 91 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+ + 입력 <word1>+ 입력 + <word2>+ 입력 + ... + EOF입력 +

155 바이트의 argv 작업 :

$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> ...

(- foreach($i as$w)대신 정의 된 전역 : -13 바이트 foreach($argv as$i=>$w)if($i))

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.