Реалізація заповнення вкладки


31

Завершення вкладки - корисна функція, яка автоматично виконує частково написані команди. Ви збираєтесь це реалізовувати.

Наприклад, якби були доступні команди ['apply','apple','apple pie','eat'], тоді aбуде завершено appl, оскільки всі команди, які починаються з, aтакож починаються з appl.

Введення-виведення

Вам потрібно ввести рядок, A і набір рядків, B.

Вам потрібно вивести найдовший загальний префікс з усіх B, який починається з А.

  • Якщо жодна з опцій не починається з A, поверніть A
  • Можна припустити, що B непустий і що всі рядки непусті
  • Ви не можете припустити, що будь-який із варіантів починається з A, а також, що загальний префікс не буде довше A
  • Ви можете бути чутливими до регістру або нечутливими до регістру.
  • Вам потрібно лише обробляти ASCII для друку
  • Вбудовані модулі, які явно виконують це завдання, дозволені

Тестові приклади:

'a'       ['apply','apple','apple pie','eat'] => 'appl'
'a'       ['apple pie']                       => 'apple pie'
'apple'   ['eat','dine']                      => 'apple'
'program' ['programa','programb']             => 'program'
'*%a('    ['*%a()-T>','*%a()-T<','@Da^n&']    => '*%a()-T'
'a'       ['abs','absolute','answer']         => 'a'
'a'       ['a','abs']                         => 'a'
'one to'  ['one to one','one to many']        => 'one to '

Зверніть увагу на пробіл останнього тесту

Це , тому робіть свої відповіді якомога коротшими!



Чи можете ви додати приклад з не алфавітними друкованими символами ASCII для нащадків?
Conor O'Brien

Більше прикладів з не алфавітними символами не зашкодить. Я просто видалив мій відповідь , тому що я зрозумів , що він порвав з входами , що містять \​або '.
Денніс

Не знаєте, як представити 'на прикладі. Якщо я використовую "для рядків, то рядки відрізняються від інших прикладів.
Натан Меррілл

Ось саме ця проблема , моя відповідь була. : P
Денніс

Відповіді:


10

JavaScript (ES6), 75 байт

(s,a)=>/^(.*).*(\n\1.*)*$/.exec(a.filter(e=>e.startsWith(s)).join`
`)[1]||s

Пояснення: Фільтрує всі відповідні префікси, потім з'єднується з новими рядками та збігається з регулярним виразом, який знаходить найдовший загальний префікс усіх рядків. Якщо префіксів немає, то регулярний вираз повертає порожній рядок, і тоді ми просто повертаємо початковий рядок.


Ви можете замінити e.startsWith(s)з e.match("^"+s)на один байт від каррінг збереже інший
Shaun H

@ShaunH Я не можу використовувати matchASCII з довільним друком .
Ніл

О правильний регулярний вираз і контрольні символи. Ви все ще можете здобути (s,a)=>доs=>a=>
Shaun H

7

Желе , 14 12 байт

ḣJ$€ċÐff\ṪṪȯ

Спробуйте в Інтернеті! або перевірити всі тестові випадки .

Як це працює

ḣJ$€ċÐff\ṪṪȯ  Main link. Left argument: B. Right argument: A

  $€          Convert the two links to the left into a monadic chain and apply it
              to each string s in B.
 J              Generate the indices of s, i.e., [1, ..., len(s)].
ḣ               Head; for each index i, take the first i characters of s.
              This generates the prefixes of all strings in B.
     Ðf       Filter; keep prefixes for which the link to the left returns 1.
   ċ            Count the number of times A appears in the prefixes of that string.
       f\     Do a cumulative (i.e., keeping all intermediate values) reduce by
              filter, keeping only common prefixes. f/ is a more obvious choice,
              but it errors on an empty array, i.e., when A isn't a prefix of any
              string in B.
         Ṫ    Tail; take the last prefix array (if any) or return 0.
          Ṫ   Tail; take the last common prefix (if any) or return 0.
           ȯ  Logical OR (flat); replace 0 with A, leave strings untouched.

6

Pyth, 14 13 байт

Завдяки @isaacg за -1 байт

.xe@F/#z._MQz

Програма, яка бере список рядків, а потім рядок, на STDIN і друкує результат.

Перевірте всі тестові випадки

Як це працює

.xe@F/#z._MQz  Program. Inputs: Q, z
        ._MQ   Map prefixes over Q
     /#z       Filter that by count(z)>0, removing the prefixes corresponding to elements
               in Q that do not start with z
   @F          Fold intersection over that. This yields all the common prefixes
  e            Yield the last element of that, giving the longest common prefix, since the
               prefixes are already sorted by length
.x             But if that throws an exception since no elements of Q start with z:
            z  Yield z instead
               Implicitly print

1
f}zT=>/#z
isaacg

5

PowerShell v3 +, 112 байт

param($a,$b)if($c=@($b-like"$a*")){([char[]]$c[0]|%{($i+="$_")}|?{($c-like"$_*").count-eq$c.count})[-1]}else{$a}

Приймає дані як рядок $aі масив рядків $b. Використовує -likeоператор для витягування цих елементів із $bцього (нечутливого до регістру) починається з $a, явно виводить їх як масив @(...)(оскільки результат може бути одним збігом як скалярний; у цьому випадку індексація пізніше не вдається), і зберігати цей масив у $c.

Це формулює ifзастереження. Якщо нічого немає $c(тобто нічого не починається з $a, тому масив порожній), тоді виводиться $aз else. Інакше ...

Ми передаємо перший елемент $cяк- charмасив і цикл через кожен елемент, з'єднуючи рядок з попереднім $iі розміщуючи струни на трубопроводі за допомогою інкапсуляції паронів. Вони фільтруються через |?{...}( Where-Objectпункт), щоб переконатися, що значення .countof $cне відповідає -eqрівню .countречей, $cщо є -likeпідрядком (тобто, підрядка відповідає всім в $ c). Оскільки ми будуємо наші підрядки для того, щоб вони були найкоротшими та довшими, нам потрібен останній [-1]з результативних рядків.

Випробування

PS C:\Tools\Scripts\golfing> $tests=@('a',@('apply','apple','apple pie','eat')),@('a',@('apple pie')),@('apple',@('eat','dine')),@('program',@('programa','programb')),@('one to',@('one to one','one to many')),@('*%a(',@('*%a()-T>', '*%a()-T<', '@Da^n&'))

PS C:\Tools\Scripts\golfing> $tests|%{""+$_[0]+" ("+($_[1]-join',')+") -> "+(.\implement-tab-completion.ps1 $_[0] $_[1])}
a (apply,apple,apple pie,eat) -> appl
a (apple pie) -> apple pie
apple (eat,dine) -> apple
program (programa,programb) -> program
one to (one to one,one to many) -> one to 
*%a( (*%a()-T>,*%a()-T<,@Da^n&) -> *%a()-T

4

Python 2, 122 байти

s=input();l=[x for x in input()if x[:len(s)]==s]or[s];i=len(l[0])
while len(l)>1:i-=1;l=set(x[:i]for x in l)
print l.pop()

Повна програма; бере строки та списки з stdin точно так, як зазначено в прикладах, за винятком того, що входи повинні бути в окремих рядках.

Перевірте всі тестові випадки


Чому l.pop()замість l[-1]?
Cyoce

@Cyoce Тому що lзазвичай є setв цій точці, яка не дозволяє індексувати (не упорядковано). (На щастя, підтримує і набори, і списки pop().)
DLosc

3

Perl, 54 байти

Включає +2 для -Xp(можна комбінувати -e) та +3 для -i(не можна поєднувати)

Дайте словник на STDIN та слово після -iпараметра, наприклад:

perl -ia -Xpe '/^\Q$^I\E.*?(?{$F[$a{$&}++]=$&})^/}{$_=pop@F||$^I'
apply
apple
apple pie
eat
^D

Просто код:

/^\Q$^I\E.*?(?{$F[$a{$&}++]=$&})^/}{$_=pop@F||$^I

3

Perl, 61 байт

Включає +2 для -0p

Виконати з першим словом, за яким слід слова словника на STDIN:

tabcompletion.pl
a
apply
apple
apple pie
eat
^D

tabcompletion.pl:

#!/usr/bin/perl -0p
/^(.+)
((?!\1).*
)*(\1.*).*
((?!\1).*
|\3.*
)*$|
/;$_=$3||$`

2

Python 2, 112 байт

lambda n,h:[a.pop()for a in[{s[:-i]for s in h if s.find(n)==0}for i in range(-len(`h`),0)]+[{n}]if len(a)==1][0]

2

Haskell, 67 байт

(a:b)?(c:d)|a==c=a:(b?d)
_?_=""
s%l=foldr1(?)$max[s][x|x<-l,x?s==s]

Допоміжна функція ?знаходить найдовший загальний префікс з двох рядків шляхом рекурсивного прийому першого символу, доки він однаковий для обох рядків і рядки не порожні.

Основна функція %спочатку зберігає лише ті рядки у списку, які починаються із заданого s, перевірені найдовшим загальним префіксом sбуття s. Щоб вирішити те, що немає дійсних змагань, це додає sпорожній результат через max. Потім він знаходить найдовший загальний приставку, склавши двійкову функцію ?.


2

Python 2, 75 байт

import os
lambda s,x:os.path.commonprefix([t for t in x if s<=t<s+'ÿ'])or s

Дякуємо @xnor за те, що він запропонував вбудований, який спочатку використовував @BetaDecay у цій відповіді .

Для оцінки балів ÿможна замінити байт DEL. Перевірте це на Ideone .


1

D, 88 байт

S f(S)(S p,S[]q){try p=q.filter!(a=>a.startsWith(p)).fold!commonPrefix;catch{}return p;}

Використання:

assert(f("a", ["apply","apple","apple pie","eat"]) ==  "appl");

Код просто видаляє всі елементи, з qяких не починається p, а потім обчислює найбільшу загальну початкову підпорядкованість решти елементів.

Шаблонні параметри рятують нас від двох повторень stringта одного з auto. Неправильне використання винятків дозволяє нам уникати тимчасової змінної та умовної, яка в іншому випадку була б необхідною для обробки випадку, коли немає елементів для qпочатку p.


1

Python 2, 107 102 байт

s,x=input();r='';q=1
for c in zip(*[t for t in x if s<=t<s+'ÿ']):q/=len(set(c));r+=c[0]*q
print r or s

Для оцінки балів ÿможна замінити байт DEL. Перевірте це на Ideone .

Дякуємо @xnor за збереження 5 байт!


З , os.path.commonprefix як бета - розпад знайдений , ви можете це зробити для вас роботу.
xnor

Нічого собі, це економить багато байтів. Ви впевнені, що не хочете опублікувати це самостійно?
Денніс

Я не відчував би себе правильним розміщувати це повідомлення, оскільки це виключно ідея Beta Decay у поєднанні з вашою відповіддю.
xnor

Для вашого рішення воно виглядає трохи коротше, щоб його повторити for c in ...безпосередньо та закінчити з помилкою після друку, як if len(set(c))>1:print r or s;_.
xnor

Я думаю, що це не вдасться, якщо x є однотонним масивом.
Денніс

1

PHP, 167 160 157 152 байт

<?for($r=preg_grep("$^".preg_quote($s=$_GET[s])."$",$a=$_GET[a]);$r[0]>$s&&preg_grep("$^".preg_quote($t=$s.$r[0][strlen($s)])."$",$a)==$r;)$s=$t;echo$s;

Я міг би зберегти ще 3 байти, призначивши змінні за допомогою preg_grepі preg_quote, але так.

зламатися

for(
    // find items in $a that start with $s
    $r=preg_grep("$^".preg_quote($s=$_GET[s])."$",$a=$_GET[a]);
    // while the first match is longer than $s
    $r[0]>$s
    // and appending the next character of the first match
    &&preg_grep("$^".preg_quote($t=$s.$r[0][strlen($s)])."$",$a)
    // does not change the matches
    ==$r
;)
    // keep appending
    $s=$t;
return$s;

1

PHP, 156 байт

з великою допомогою Тита. Дякую

<?foreach($_GET[t]as$v)if(strstr($v,$s=$_GET[s])==$v)$r[]=$z=$v;for(;$i++<strlen($z);){$s=substr($z,0,$i);foreach($r as$x)if($x[$i]!=$z[$i])break 2;}echo$s;

PHP, 199 байт

32 байти зберігає Тит за допомогою array_unique

<?foreach($_GET[t]as$v)if(strstr($v,$s=$_GET[s])==$v)$r[]=$v;for(;$i++<strlen($r[0]);$a=[]){foreach($r as$x)$a[]=substr($x,0,$i);if(count($r)==count($a)&count(array_unique($a))<2)$s=$a[0];}echo$s;

Я знаю, що рішення Регекса від Тіта було коротше, поки Тіт допоможе мені покращити свій шлях. Можливо спосіб, який я знайшов, цікавий для вас


1
1) Замініть $zна, $sщоб виправити apple, [eat,dine]справу. 2) $l=застарілий; Ви не використовуєте цю змінну. (-2) 3) $i++<$mкоротше, ніж ++$i<=$m. (-1) 4) substr($x,0,$i);коротше, ніж str_split($x,$i)[0]. (-3) 5) Ви можете помістити $r[]=$vвсередину струни. (-5)
Тіт

1
6) <2коротше, ніж ==1. (-1) 7) Ви можете використовувати strstrв першому циклі: strstr($v,$s)==$v. (-3)
Тіт

1
Дозвольте мені перефразувати: 5) Ви можете комбінувати , $r[]=$v;$m=max($m,strlen($v));щоб $m=max($m,strlen($r[]=$v));і падіння curlys. Це не стосується умови.
Тіт

1
По-друге, вам це $mзовсім не потрібно . Все, що вам потрібно, це щось, що становить> = мінімальна довжина заміни. Новий 5) Замініть {$r[]=$v;$m=max($m,strlen($v));}на $r[]=$v;}і <$mз <strlen($r[0])(-13)
Тіт

1
Чудово! І я щойно знайшов ще один гольф: 9) $r[]=$z=$v;у першій петлі, а {$s=substr($z,0,$i);foreach($r as$x)if($x[$i]!=$z[$i])break 2;}у другому (-3)
Тіт

1

Сітківка, 60 байт

^(.*)(\n(?!\1).*)*(\n(\1.*)).*(\n((?!\1)|\4).*)*$
$4
s`\n.*

Новий рядок дуже важливий. Приймає введення як рядок у рядку, а потім кожне слово в окремому рядку (але жодного нового рядка немає!). Працює аналогічно моїй відповіді на JavaScript, шляхом зіставлення найдовшого загального префіксу всіх рядків, що починаються з рядка в першому рядку. Якщо він не знайде його, він просто видаляє всі слова.


0

Scala, 119 байт

def f(s:String,a:Seq[Char]*)=a filter(_ startsWith s)reduceOption(_ zip _ takeWhile(t=>t._1==t._2)map(_._1))getOrElse s

Безголовки:

def tabComplete(input: String, options: Seq[Char]*) = {
  options.
  filter((x: String) => x.startsWith(input)).
  reduceOption((x: Seq[Char], y: Seq[Char]) =>
    x.zip(y).
    takeWhile((t: (Char, Char)) => t._1 == t._2).
    map((t: (Char, Char)) => t._1)
  ).getOrElse(input)
}

Пояснення:

def g(s:String,a:Seq[Char]*)= //define a method g with a string and a vararg array of strings as parameter
  a filter(_ startsWith s)    //filter the options to contains only elements starting with the input
  reduceOption(               //if the filtered array is nonempty, reduce it: 
    _ zip _                     //zip two elements together
    takeWhile(t=>t._1==t._2)    //take the tuples while they contain the same char
    map(_._1)                   //take the first element from each tuple
  )getOrElse s                //else return the input


0

05AB1E , 14 байт

ʒIÅ?}€ηøʒË}‚˜θ

Спробуйте в Інтернеті або перевірте всі тестові випадки .

Пояснення:

ʒ   }           # Filter the (implicit) input-list
 IÅ?            #  Does it start with the (second) input-string
                #   i.e. ["codex","bla","codegolf"] and "c" → ["codex","codegolf"]
     €η         # Then take the prefixes of every remaining string
                #  → [["c","co","cod","code","codex"],
                #     ["c","co","cod","code","codeg","codego","codegol","codegolf"]]
       ø        # Zip/transpose; swapping rows/columns
                #  → [["c","c"],["co","co"],["cod","cod"],["code","code"],["codex","codeg"]]
        ʒ }     # Filter:
         Ë      #  Only keep sublists which only contain the same substrings
                #   → [["c","c"],["co","co"],["cod","cod"],["code","code"]]
               # Pair it with the (second implicit) input
                #  → ["c",["c","c"],["co","co"],["cod","cod"],["code","code"]]
                # (workaround if nothing in the input-list starts with the input-string)
            ˜   # Flatten this list
                #  → ["c","c","c","co","co","cod","cod","code","code"]
             θ  # And only leave the last item (which is output implicitly as result)
                #  → "code"

0

Гая , 12 байт

e…¦&⊢…Ė⁇_+ₔ)

Спробуйте в Інтернеті!

Приймає введення як B, тоді A.

e		| eval B as list of strings
 …¦		| take prefixes of each string
   &⊢		| reduce by set intersection
     …		| take list prefixes of each.
      Ė⁇	| Keep only those with A as an element
	_	| flatten
	 +ₔ	| add A to the beginning of the list
	   )	| take the last element
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.