Buat pintasan keyboard untuk menu

10

Pintasan Menu

Secara tradisional, menu pengguna dapat diakses dengan cara pintas keyboard, seperti Alt + (a letter), atau bahkan hanya menekan huruf ketika semua kotak teks tidak fokus ( gaya gmail ).

Tugas Anda

Mengingat entri menu sebagai input, tugas Anda adalah memberikan setiap entri menu surat jalan pintas yang tepat.

Tulis fungsi atau program yang menerima serangkaian kata - entri menu (sebagai array string, atau padanan bahasa Anda), dan mengembalikan kamus, atau hashmap, dari satu huruf ke entri menu.

Anda bisa menggunakan parameter dan mengembalikan nilai, atau menggunakan STDIN dan output hasilnya ke STDOUT. Anda tidak boleh berasumsi bahwa variabel global / lingkup sudah diisi dengan input.

Algoritma untuk menentukan huruf yang tepat

  • Pada dasarnya ini adalah huruf pertama yang tersedia. Lihat asumsi dan contoh di bawah ini.
  • Jika semua huruf entri tidak tersedia, pintasannya akan (a letter) + (a number). Surat mana yang Anda pilih dari entri adalah arbitrer. Angka harus dimulai dari 0 dan bertambah 1 - sehingga semua pintasan unik. Lihat contoh ketiga di bawah ini.

Asumsi

  • Input akan menjadi Set, yaitu tanpa pengulangan, setiap entri adalah unik.
  • Panjang input dapat berupa bilangan bulat non-negatif (hingga MAX_INT bahasa Anda).
  • Sensitivitas kasus: Input peka huruf besar-kecil, (tetapi akan tetap unik saat mengabaikan huruf besar-kecil). Hasilnya harus berisi entri asli dengan casing aslinya. Namun, huruf pintasan keluaran tidak peka huruf besar-kecil.
  • Semua kata input tidak akan diakhiri dengan angka.
  • Tidak ada "input jahat" yang akan diuji. "Input jahat" adalah sedemikian rupa sehingga Anda harus menambah penghitung surat tertentu lebih dari 10 kali.

Contohnya

Contoh di bawah ini dalam JSON, tetapi Anda dapat menggunakan padanan bahasa Anda untuk array dan Kamus, atau - jika Anda menggunakan STD I / O - format yang dapat dibaca untuk input dan output Anda (seperti csv, atau bahkan space- nilai yang dipisahkan).

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

Kondisi menang

Kode terpendek menang. Hanya ASCII yang diizinkan.

Yakub
sumber
"a" sudah diambil oleh entri pertama. Jadi untuk "aa" karena kedua suratnya sudah diambil, ia mendapat a0. Sama dengan b0-b2.
mattacular
Apa yang terjadi ketika Anda kehabisan angka?
nderscore
@nderscore Apakah itu benar-benar perlu?
seequ
Haruskah ['ab', 'a']memberi {a:'ab', a0:'a'}atau {b:'ab', a:'a'}?
Adám
@ Adám keduanya dapat diterima. Akan lebih mudah untuk mengimplementasikan yang pertama karena Anda memindai array input dengan cara yang teratur, tetapi jika karena alasan tertentu Anda lebih suka yang terakhir - lakukan saja.
Yakub

Jawaban:

4

Javascript ( ES6 ) 106 105 100

Fungsi ini mengambil input sebagai array dan menampilkan objek 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

Hasil:

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

Tidak Terkumpul / Berkomentar:

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
}
nderscore
sumber
Ini indah. Ini mungkin gagal untuk input jahat ['a', 'aa', 'aaa', 'aaaa', 'aaaaa', 'aaaaaa', 'aaaaaaa', 'aaaaaaaa', 'aaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaaa', 'aaaaaaaaaaaa'], tapi saya pikir kita bisa mengabaikan kasus tepi seperti itu, bukan?
Yakub
@ Jacob Dan apa yang terjadi ketika kita menekan 11? Anda tidak dapat menekan satu tombol dua kali dalam pintasan keyboard: P
nderscore
Anda memiliki titik di sana (meskipun mungkin, mengingat implementasi yang menunggu hingga akhir penekanan tombol (sekitar 200 ms atau lebih)). Bagaimanapun, saya akan menambah asumsi tidak ada input jahat seperti itu akan diuji.
Yakub
2

Python 2.x - 176 170 157 114 byte

Pendekatan yang sangat sederhana, tetapi seseorang harus memulai permainan.

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)

Contoh:

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

Saya pikir satu-satunya penjelasan yang diperlukan adalah kode yang tidak diklik. (Ini sebenarnya adalah versi asli)

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
seequ
sumber
Saya harus mengucapkan terima kasih kepada @Jacob. Format inputnya bagus.
seequ
2

JavaScript (ECMAScript 6) - 107 Karakter

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)

Penjelasan:

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

Tes:

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"}
MT0
sumber
1

PHP> = 5,4 - 149 karakter

Menurut standar PHP (masukkan sniggers di sini) , input tersebut bukan JSON yang valid seperti yang digunakan 'alih-alih ", jadi saya sedikit kurang ajar dan saya menggunakan Input sebagai deklarasi variabel aktual:

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

Menggunakan contoh-contoh:

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-golfified itu cukup mendasar:

<?
$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);
TuanLore
sumber
PHP memiliki deklarasi lompat? Itu sangat ... 90-an.
seequ
2
Anda tidak harus tetap menggunakan JSON, saya hanya memberikan contoh-contoh di JSON, tetapi, sebagaimana dinyatakan dalam pertanyaan, Anda dapat memilih format apa pun yang dapat dibaca untuk output atau menggunakan bahasa Anda yang setara untuk Kamus. (Anda dapat menyimpan 13 karakter dengan menghapus json_encodedoa).
Yakub
echotidak bekerja dengan array; tetapi print_r($c);akan melakukannya, menghemat 9 byte.
Titus
Tapi ini bukan kasus tidak sensitif. str_split(strtoupper($w))dan ucfirst($w[0])dapat menyelesaikannya (+21); atau $s=strtoupper($w);(+18)
Titus
1

PowerShell , 91 83 byte

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

Cobalah online!

Ini melempar pengecualian jika pintasan yang tepat tidak ditemukan.

Belum dibuka:

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

jalankan dengan php-r '<code>' <<EOF+ Enter + <word1>+ Enter + <word2>+ Enter + ... + EOF+ Enter

bekerja pada argv untuk 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);

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

(-13 byte dengan global yang ditentukan: foreach($i as$w)alih-alih foreach($argv as$i=>$w)if($i))

Titus
sumber