Tạo phím tắt cho menu


10

Phím tắt

Theo truyền thống, các menu người dùng có thể truy cập bằng các phím tắt, chẳng hạn như Alt + (a letter), hoặc thậm chí chỉ cần nhấn chữ cái khi tất cả các hộp văn bản không được tập trung ( kiểu gmail ).

Nhiệm vụ của bạn

Đưa ra các mục menu làm đầu vào, nhiệm vụ của bạn là cấp cho mỗi mục menu một chữ cái tắt thích hợp.

Viết một hàm hoặc một chương trình chấp nhận một tập hợp các từ - các mục trong menu (dưới dạng một chuỗi các chuỗi hoặc tương đương với ngôn ngữ của bạn) và trả về một từ điển hoặc một hashmap, từ một chữ cái cho một mục menu.

Bạn có thể sử dụng một tham số và trả về một giá trị hoặc sử dụng STDIN và xuất kết quả của bạn thành STDOUT. Bạn không được phép giả sử biến toàn cục / phạm vi đã được điền với đầu vào.

Thuật toán để xác định chữ cái thích hợp

  • Về cơ bản nó là chữ cái đầu tiên có sẵn của từ này. Xem các giả định và ví dụ dưới đây.
  • Trong trường hợp tất cả các chữ cái của mục nhập không có sẵn, các phím tắt sẽ có (a letter) + (a number). Những chữ cái bạn chọn từ mục nhập là tùy ý. Số phải bắt đầu từ 0 và được tăng thêm 1 - sao cho tất cả các phím tắt là duy nhất. Xem ví dụ thứ ba dưới đây.

Giả định

  • Đầu vào sẽ là Tập hợp, tức là không lặp lại, mỗi mục nhập là duy nhất.
  • Độ dài của đầu vào có thể là bất kỳ số nguyên không âm nào (tối đa MAX_INT ngôn ngữ của bạn).
  • Phân biệt chữ hoa chữ thường: Đầu vào phân biệt chữ hoa chữ thường, (nhưng sẽ duy nhất khi bỏ qua trường hợp). Các kết quả sẽ chứa các mục gốc với vỏ ban đầu của chúng. Tuy nhiên, các chữ cái tắt đầu ra không phân biệt chữ hoa chữ thường.
  • Tất cả các từ đầu vào sẽ không kết thúc bằng số.
  • Không có "đầu vào xấu" sẽ được kiểm tra. "Đầu vào xấu" là như vậy mà bạn phải tăng bộ đếm của một chữ cái nhất định hơn 10 lần.

Ví dụ

Các ví dụ bên dưới có trong JSON, nhưng bạn có thể sử dụng ngôn ngữ của mình tương đương cho một mảng và Từ điển hoặc - trong trường hợp bạn đang sử dụng STD I / O - mọi định dạng có thể đọc được cho đầu vào và đầu ra của bạn (chẳng hạn như csv hoặc thậm chí là khoảng trắng- các giá trị riêng biệt).

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

Điều kiện chiến thắng

Mã ngắn nhất sẽ thắng. Chỉ cho phép ASCII.


"a" đã được thực hiện bởi mục đầu tiên. Vì vậy, đối với "aa" vì cả hai chữ cái của nó đã được đưa lên, nó được a0. Tương tự với b0-b2.
2014

Điều gì xảy ra khi bạn hết số?
nderscore

@nderscore Điều đó có thực sự cần thiết?
xem

Nên ['ab', 'a']cho {a:'ab', a0:'a'}hay {b:'ab', a:'a'}?
Adám

@ Adám cả hai đều được chấp nhận. Sẽ dễ dàng hơn để thực hiện cái trước vì bạn quét mảng đầu vào theo cách có thứ tự, nhưng nếu vì lý do nào đó bạn thích cái sau hơn - hãy chọn nó.
Jacob

Câu trả lời:


4

Javascript ( ES6 ) 106 105 100

Hàm này lấy đầu vào là một mảng và xuất ra một đối tượng 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

Các kết quả:

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

Ungolfed / Bình luận:

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
}

Thật là đẹp Nó có thể thất bại cho đầu vào xấu ['a', 'aa', 'aaa', 'aaaa', 'aaaaa', 'aaaaaa', 'aaaaaaa', 'aaaaaaaa', 'aaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaaa', 'aaaaaaaaaaaa'], nhưng tôi nghĩ chúng ta có thể bỏ qua các trường hợp cạnh như vậy, phải không?
Jacob

@Jacob Và điều gì xảy ra khi chúng ta đánh 11? Bạn không thể nhấn một phím hai lần trong một phím tắt: P
nderscore

Bạn có một điểm ở đó (mặc dù có thể là có thể, được đưa ra một triển khai chờ cho đến khi kết thúc tổ hợp phím (200ms hoặc hơn)). Nhưng dù sao, tôi sẽ thêm vào các giả định, không có đầu vào xấu nào như vậy sẽ được kiểm tra.
Jacob

2

Python 2.x - 176 170 157 114 byte

Cách tiếp cận rất đơn giản, nhưng ai đó phải đá trò chơi đi.

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)

Ví dụ:

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

Tôi nghĩ rằng lời giải thích duy nhất là mã không được mã hóa. (Đây thực sự là phiên bản gốc)

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

Tôi phải nói lời cảm ơn khiêm tốn đến @Jacob. Các định dạng đầu vào là tuyệt vời.
xem

2

JavaScript (ECMAScript 6) - 107 ký tự

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)

Giải trình:

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

Các xét nghiệm:

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 ký tự

Theo tiêu chuẩn của PHP (chèn sniggers vào đây) , đầu vào không phải là JSON hợp lệ vì nó sử dụng 'thay vì ", vì vậy tôi đã hơi táo tợn và tôi đang sử dụng Đầu vào như một tuyên bố biến thực tế:

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

Sử dụng các ví dụ:

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

Un-golfized nó khá cơ bản:

<?
$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 có khai báo nhảy? Đó là ... những năm 90.
xem

2
Bạn không phải dính vào JSON, tôi chỉ cung cấp các ví dụ trong JSON, nhưng, như đã nêu trong câu hỏi, bạn có thể chọn bất kỳ định dạng có thể đọc nào cho đầu ra hoặc sử dụng ngôn ngữ của bạn tương đương với Từ điển. (Bạn có thể lưu 13 ký tự bằng cách xóa json_encodelời gọi).
Jacob

echokhôngnt làm việc với các mảng; nhưng print_r($c);sẽ làm điều đó, tiết kiệm 9 byte.
Tít

Nhưng đây không phải là trường hợp vô cảm. str_split(strtoupper($w))ucfirst($w[0])có thể giải quyết điều đó (+21); hoặc $s=strtoupper($w);(+18)
Tít

1

PowerShell , 91 83 byte

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

Hãy thử trực tuyến!

Nó ném một ngoại lệ nếu không tìm thấy một phím tắt thích hợp.

Chưa được kiểm soát:

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

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);

chạy với php-r '<code>' <<EOF+ Enter + <word1>+ Enter + <word2>+ Enter + ... + EOF+ Enter

làm việc trên argv cho 155 byte :

$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);

chạy với php -r '<code>' <word1> <word2> ...

(-13 byte với toàn cầu được xác định: foreach($i as$w)thay vì foreach($argv as$i=>$w)if($i))

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.