Bir menü için klavye kısayolları oluşturma


10

Menü Kısayolları

Geleneksel olarak, kullanıcı menülerine, Alt + (a letter)tüm metin kutuları odaklanmamışken ( gmail stili) klavye kısayollarıyla veya hatta harflere dokunarak erişilebilir .

Senin görevin

Menü girişleri giriş olarak verildiğinde, göreviniz her menü girişine uygun bir kısayol harfi vermektir.

Bir sözcük grubunu kabul eden bir işlev veya program yazın - menü girişleri (dizeler dizisi veya dil eşdeğeri olarak) ve tek bir harften bir menü girişine bir sözlük veya hashmap döndürür.

Bir parametre kullanabilir ve bir değer döndürebilir veya STDIN'i kullanabilir ve sonuçlarınızı STDOUT'a gönderebilirsiniz. Sen edilir değil zaten giriş doldurulur küresel / kapsam değişkeni varsaymak izin verdi.

Uygun mektubu belirleme algoritması

  • Temel olarak kelimenin ilk harfidir. Aşağıdaki varsayımlara ve örneklere bakın.
  • Tüm girdilerin harfleri mevcut değilse, kısayol kullanılacaktır (a letter) + (a number). Girişten hangi harfi seçeceğiniz keyfi olur. Sayı 0'dan başlamalı ve 1 ile artırılmalıdır - böylece tüm kısayollar benzersizdir. Aşağıdaki üçüncü örneğe bakın.

Varsayımlar

  • Giriş bir Set olacaktır, yani tekrarlama olmaz, her giriş benzersizdir.
  • Girişin uzunluğu herhangi bir negatif olmayan tamsayı olabilir (dilinizin MAX_INT kadarı).
  • Büyük / küçük harf duyarlılığı: Giriş büyük / küçük harfe duyarlıdır (ancak büyük / küçük harf göz ardı edilirken benzersiz kalır). Sonuçlar orijinal muhafazaları ile birlikte orijinal girişleri içermelidir. Ancak, çıkış kısayol harfleri büyük / küçük harfe duyarlı değildir.
  • Tüm giriş sözcükleri sayılarla bitmez.
  • Hiçbir "kötü girdi" test edilmeyecektir. "Kötülük girdisi" belli bir harfin sayacını 10 kattan fazla artırmanız gerektiği şekildedir.

Örnekler

Aşağıdaki örnekler JSON'dadır, ancak bir dizi ve Sözlük için dil eşdeğerini kullanabilirsiniz veya - STD G / Ç kullanıyorsanız - giriş ve çıktınız için okunabilir herhangi bir biçim (csv, hatta boşluk gibi) ayrılmış değerler).

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

Kazanma koşulları

En kısa kod kazanır. Yalnızca ASCII'ye izin verilir.


"a" ilk girdi tarafından zaten alınmış. Yani "aa" için, her iki harfi de zaten alınmış olduğundan, a0 alır. B0-b2 ile aynı.
mattacular

Rakamlar bittiğinde ne olur?
nderscore

@nderscore Bu gerçekten gerekli mi?
seequ

Meli ['ab', 'a']vermek {a:'ab', a0:'a'}veya {b:'ab', a:'a'}?
ADAM

@ Adám her ikisi de kabul edilebilir. Girdi dizisini düzenli bir şekilde taradığınız için ilkini uygulamak daha kolay olurdu, ancak herhangi bir nedenle ikincisini tercih ederseniz, bunun için gidin.
Jacob

Yanıtlar:


4

JavaScript ( ES6 ) 106 105 100

Bu işlev girişi bir dizi olarak alır ve bir javascript nesnesi çıkarır.

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

Sonuçlar:

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 / Comments:

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
}

Bu güzel. Kötü girdi için başarısız olabilir ['a', 'aa', 'aaa', 'aaaa', 'aaaaa', 'aaaaaa', 'aaaaaaa', 'aaaaaaaa', 'aaaaaaaaa', 'aaaaaaaaaa', 'aaaaaaaaaaa', 'aaaaaaaaaaaa'], ama bence bu gibi uç durumları görmezden gelebiliriz, değil mi?
Jacob

@Jacob Peki vurduğumuzda ne olur 11? Klavye kısayolunda bir tuşa iki kez
basamazsınız

Orada bir noktanız var (tuş vuruşlarının sonuna kadar bekleyen bir uygulama göz önüne alındığında (mümkün olsa da, 200 ms)). Her neyse, varsayımlara böyle kötü girdilerin test edilmeyeceğini ekleyeceğim.
Jacob

2

Python 2.x - 1761701515114 bayt

Çok basit bir yaklaşım, ama birisi oyunu tekmelemek zorunda.

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)

Örnekler:

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

Sanırım gerekli olan tek açıklama çözümsüz kod. (Bu aslında orijinal sürüm)

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'a mütevazı teşekkürler demeliyim. Giriş formatı harika.
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)

Açıklama:

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

Testler:

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 karakter

PHP standartlarına göre (buraya sniggers ekleyin) , giriş 'yerine kullanıldığı gibi geçerli JSON değil ", bu yüzden biraz arsız oldum ve gerçek bir değişken bildirimi olarak Input kullanıyorum:

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

Örnekleri kullanarak:

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

Golfsiz, oldukça basit:

<?
$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 sıçrama bildirimleri var? Öyle ki ... 90'lar.
seequ

2
JSON'a bağlı kalmanıza gerek yok, sadece JSON'daki örnekleri sağladım, ancak soruda belirtildiği gibi, çıktı için herhangi bir okunabilir formatı seçebilir veya bir Sözlük için dil eşdeğerini kullanabilirsiniz. ( json_encodeÇağrıyı kaldırarak 13 karakter kaydedebilirsiniz ).
Jacob

echodizilerle çalışmaz; ama print_r($c);9 baytlık tasarruf sağladı.
Titus

Ancak bu durum duyarsız değildir. str_split(strtoupper($w))ve ucfirst($w[0])bunu çözebilir (+21); veya $s=strtoupper($w);(+18)
Titus

1

PowerShell , 91 83 bayt

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

Çevrimiçi deneyin!

Uygun bir kısayol bulunmazsa bir istisna atar.

unrolled:

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

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

ile çalıştırmak php-r '<code>' <<EOF+ Enter <word1>+ Enter + <word2>+ Enter + ... + EOF+ Enter

155 bayt için argv üzerinde çalışıyor :

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

ile koş php -r '<code>' <word1> <word2> ...

(Tanımlı bir global ile -13 bayt: foreach($i as$w)yerine foreach($argv as$i=>$w)if($i))

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.