สร้างแป้นพิมพ์ลัดสำหรับเมนู


10

ปุ่มลัดเมนู

ตามเนื้อผ้าเมนูผู้ใช้สามารถเข้าถึงได้โดยใช้แป้นพิมพ์ลัดเช่นAlt + (a letter)หรือแม้แต่กดปุ่มตัวอักษรเมื่อกล่องข้อความทั้งหมดไม่มีการโฟกัส ( สไตล์gmail )

งานของคุณ

เมื่อได้รับรายการเมนูเป็นอินพุตงานของคุณคืออนุญาตให้แต่ละรายการเมนูมีตัวอักษรลัดที่เหมาะสม

เขียนฟังก์ชั่นหรือโปรแกรมที่รับชุดคำ - รายการเมนู (เป็นอาร์เรย์ของสตริงหรือเทียบเท่าภาษาของคุณ) และส่งคืนพจนานุกรมหรือ hashmap จากตัวอักษรตัวเดียวไปยังรายการเมนู

คุณสามารถใช้พารามิเตอร์และส่งคืนค่าหรือใช้ STDIN และส่งออกผลลัพธ์ของคุณไปยัง STDOUT คุณไม่ได้รับอนุญาตให้สันนิษฐานว่าตัวแปรโกลบอล / ขอบเขตได้รับการป้อนข้อมูลเรียบร้อยแล้ว

อัลกอริทึมเพื่อกำหนดตัวอักษรที่เหมาะสม

  • โดยทั่วไปมันเป็นตัวอักษรตัวแรกของคำ ดูสมมติฐานและตัวอย่างด้านล่าง
  • (a letter) + (a number)ในกรณีที่ตัวอักษรของรายการทั้งหมดจะไม่สามารถใช้ทางลัดจะ ตัวอักษรใดที่คุณเลือกจากรายการนั้นเป็นกฎเกณฑ์ ตัวเลขควรเริ่มต้นจาก 0 และเพิ่มขึ้นทีละ 1 - เช่นนั้นทางลัดทั้งหมดจะไม่ซ้ำกัน ดูตัวอย่างที่สามด้านล่าง

สมมติฐาน

  • การป้อนข้อมูลจะเป็นชุดคือไม่มีการซ้ำทุกรายการไม่ซ้ำกัน
  • ความยาวของอินพุตอาจเป็นจำนวนเต็มใด ๆ ที่ไม่เป็นลบ (มากถึง MAX_INT ของภาษาของคุณ)
  • การพิจารณาตัวพิมพ์เล็กและตัวพิมพ์ใหญ่: อินพุตเป็นตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ (แต่จะไม่ซ้ำกันเมื่อไม่สนใจขนาดตัวพิมพ์) ผลลัพธ์ควรมีรายการต้นฉบับพร้อมเคสต้นฉบับ อย่างไรก็ตามตัวอักษรช็อตคัตเอาท์พุทไม่คำนึงถึงขนาดตัวพิมพ์
  • คำที่ป้อนทั้งหมดจะไม่ลงท้ายด้วยตัวเลข
  • จะไม่มีการทดสอบ "อินพุตที่ชั่วร้าย" "การป้อนข้อมูลที่ชั่วร้าย" เป็นสิ่งที่คุณต้องเพิ่มตัวนับจำนวนจดหมายมากกว่า 10 ครั้ง

ตัวอย่าง

ตัวอย่างด้านล่างนี้อยู่ใน JSON แต่คุณสามารถใช้ภาษาของคุณเทียบเท่ากับอาร์เรย์และพจนานุกรมหรือ - ในกรณีที่คุณใช้ STD I / O - รูปแบบที่สามารถอ่านได้สำหรับอินพุตและเอาต์พุตของคุณ (เช่น csv หรือแม้แต่ space- ค่าที่แยกจากกัน)

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
matt

เกิดอะไรขึ้นเมื่อคุณไม่มีตัวเลข?
nderscore

@ ตัวเลขที่จำเป็นจริงๆเหรอ?
seequ

ควร['ab', 'a']ให้{a:'ab', a0:'a'}หรือ{b:'ab', a:'a'}?
Adám

@ Adámทั้งสองเป็นที่ยอมรับ มันจะง่ายกว่าที่จะใช้อดีตตั้งแต่คุณสแกนอาร์เรย์อินพุตในลักษณะที่สั่ง แต่ถ้าด้วยเหตุผลบางอย่างที่คุณต้องการหลัง - ไปหามัน
จาค็อบ

คำตอบ:


4

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

Ungolfed / แสดงความคิดเห็น:

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 - 176 170 157 114 ไบต์

วิธีการง่ายมาก แต่มีคนที่จะเตะเกมไป

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

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 (แทรก sniggers ที่นี่)อินพุตไม่ถูกต้อง 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's
seequ

2
คุณไม่ต้องติดกับ JSON ฉันให้เฉพาะตัวอย่างใน JSON แต่ตามที่ระบุในคำถามคุณสามารถเลือกรูปแบบที่อ่านได้สำหรับเอาท์พุทหรือใช้ภาษาของคุณเทียบเท่ากับพจนานุกรม (คุณสามารถบันทึกได้ 13 ตัวอักษรโดยลบการjson_encodeเรียกใช้)
จาค็อบ

echoไม่ทำงานกับอาร์เรย์ แต่print_r($c);จะทำเช่นนั้นประหยัด 9 ไบต์
ติตัส

แต่นี่ไม่ใช่กรณีตาย str_split(strtoupper($w))และucfirst($w[0])สามารถแก้ปัญหานั้น (+21); หรือ$s=strtoupper($w);(+18)
ติตัส

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+ 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 ไบต์ที่มีการกำหนดทั่วโลก: foreach($i as$w)แทนforeach($argv as$i=>$w)if($i))

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.