Знову і введіть список слів


38

Ось як повернути назад і повторно ввести один рядок в інший:

  1. Почніть з першого рядка.
  2. Видаліть символи в кінці, поки результат не буде префіксом другого рядка. (Це може зайняти 0 кроків.)
  3. Додайте символи в кінці, поки результат не дорівнює другому рядку. (Це може також зробити 0 кроків.)

Наприклад, шлях від fooabcдо fooxyzвиглядає так:

fooabc
fooab
fooa
foo
foox
fooxy
fooxyz

Завдання

Давши список слів, напишіть програму, яка повертає назад і повторно повторює шлях із порожнього рядка, до всіх слів у списку послідовно, назад до порожнього рядка. Виведіть усі проміжні рядки.

Наприклад, враховуючи список вхідних даних ["abc", "abd", "aefg", "h"], вихід повинен бути:

a
ab
abc
ab
abd
ab
a
ae
aef
aefg
aef
ae
a

h

Правила

Ви можете повернути або роздрукувати список рядків або одну рядок з вибраним роздільником. Ви можете необов'язково включати початкові та заключні порожні рядки. Гарантоване введення містить щонайменше одне слово, а кожне слово гарантує лише малі літери ASCII ( a- z). Редагувати: послідовні рядки на вході гарантовано не дорівнюватимуть одна одній.

Це ; найкоротший код в байтах виграє.

Довідкова реалізація в Python 3: Спробуйте в Інтернеті!


4
@ rahnema1> написати програму, яка повертає назад і повторює свій шлях із порожнього рядка
Kritixi Lithos

3
Яким буде вихід ["abc","abc"]?
Kritixi Lithos

1
@Emigna На жаль, це саме те, але в циклі! Тому я збираюся йти вперед і скажу, що це дублікат цього.
Лінь

4
@Lynn Це не зовсім те саме. Цей не включає розпізнавання загальних префіксів, він завжди зводиться до одного символу.
Мартін Ендер

6
Тестовий випадок:a,abc,abcde,abc,a,abc,abcde
Згарб

Відповіді:



9

Perl, 43 байти

42 байти коду + -nпрапори.

chop$@,say$@while!s/^$@//;s/./say$@.=$&/ge

Щоб запустити його:

perl -nE 'chop$@,say$@while!s/^$@//;s/./say$@.=$&/ge' <<< "abc
abd
aefg
h"

це друкує abc 3 рази
izabera

@izabera Після пропуску було abcнадруковано 3 рази (але насправді перший і третій раз було без пробілу). Я її зняв.
Дада

5

Java 8, 144 байти

Ця схожа на еталонну реалізацію, але поєднує дві whileпетлі. Це лямбда-вираз, що приймає String[]параметр.

a->{String c="";int l=0,i;for(String w:a)while((i=w.indexOf(c))!=0||!c.equals(w))System.out.println(c=i!=0?c.substring(0,--l):c+w.charAt(l++));}

Безумовно

a -> {
    String c = "";
    int l = 0, i;
    for (String w : a)
        while ((i = w.indexOf(c)) != 0 || !c.equals(w))
            System.out.println(c = i != 0 ? c.substring(0, --l) : c + w.charAt(l++));
}

Подяка

  • -38 байт завдяки лямбдаській пропозиції CAD97

Хіба це не дешевше використовувати class Bзамість interface B? Ви можете бігти з класу пакет-приватний. Крім того, подумайте про використання лямбда, як ви вже вказали Java8.
CAD97

@ CAD97 interface B{static void mainкоротше, ніж class B{public static void main.
Кевін Кройсейсен

@ CAD97 Я не міг придумати спосіб залучення лямбдів до цього, але я лише вчора дізнався про них. Якісь ідеї?
Якоб

1
Ах, я іржавий. Ви повинні мати змогу зробити це a->{/*your code*/}, яке призначить змінної типу java.util.function.Consumer<String[]>. На даний момент я не можу перевірити.
CAD97

1
@JakobCornell За замовчуванням PPCG дозволяє повністю подати програми чи функції. Для мов з анонімними функціями (лямбда) анонімна функція сама по собі є прийнятною відповіддю (тому вам не потрібно включати змінну, щоб зберігати її). (Хоча в Java
заявах

4

Математика, 149 байт

Reap[Fold[n=NestWhile;s=StringMatchQ;r=StringReplace;n[k=#2;Sow@r[k,#~~a_~~___:>#<>a]&,n[Sow@r[#,a___~~_:>a]&,#,!s[k,#~~___]&],k!=#&]&,"",#]][[2,1]]&


3

Желе , 31 29 26 байт

⁷œ|;\
ÇṚðfḢṭḟ;ḟ@ḊðÇ}
⁷;ç2\

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

Як це працює

⁷;ç2\           Main link. Argument: A (string array)

⁷;              Prepend a linefeed to A. 
                This is cheaper than prepending an empty string.
  ç2\           Reduce all overlapping pairs by the second helper link.


ÇṚðfḢṭḟ;ḟ@ḊðÇ}  Second helper link. Arguments: s, t (strings)

Ç               Call the first helper link with argument s.
 Ṛ              Reverse the results.
            Ç}  Call the first helper link with argument t.
  ð        ð    Combine everything in between into a dyadic chain, and call it
                with the results to both sides as arguments.
                Let's call the arguments S and T.
   f            Filter; get the common strings of S and T.
    Ḣ           Head; select the first one.
      ḟ         Filterfalse; get the strings in S that do not appear in T.
     ṭ          Tack; append the left result to the right one.
        ḟ@      Filterfalse swap; get the strings in T that do not appear in S.
       ;        Concatenate the results to both sides.
          Ḋ     Dequeue; remove the first string.


⁷œ|;\           First helper link. Argument: s (string)

⁷œ|             Linefeed multiset union; prepend a linefeed to s unless it already
                has a linefeed in it (the first string does).
   ;\           Concatenate cumulative reduce; generate all prefixes of the result.

2

Haskell , 102 93 91 90 байт

(?)=take.length
a!x@(b:c)|a==b=b!c|a/=a?b=a:init a!x|d<-'?':a=a:d?b!x
_!x=x
(""!).(++[""])

Останній рядок - це анонімна функція, яка приймає та повертає список рядків. Спробуйте в Інтернеті!

Пояснення

Моє рішення є рекурсивним. По-перше, ?це допоміжна функція інфікування: a?bдає перші length aсимволи bабо ціле число, bякщо aдовше. Далі я визначаю функцію інфіксації !. Ідея полягає в тому a!x, що , де aє рядок і xсписок рядків, створює шлях від aпершої струни до xі повторюється до хвоста x. У заключному рядку я визначаю анонімну функцію, яка додає порожню рядок, потім застосовується !до порожнього рядка та вводу.

Пояснення !:

a!x@(b:c)        -- a!x, where x has head b and tail c:
  |a==b          -- If a equals b,
    =b!c         -- recurse to x.
  |a/=a?b        -- If a is not a prefix of b,
    =a:          -- produce a and
    init a!x     -- continue with one shorter prefix of a.
  |              -- Otherwise a is a proper prefix of b.
   d<-'?':a      -- Let d be a with an extra dummy element,
    =a:          -- produce a and
    d?b!x        -- continue with one longer prefix of b.
_!x=x            -- If x is empty, return x.

2

Python 2, 118 107 103 97 93 92 байт

s=''
for i in input()+[s]:
 while i.find(s):s=s[:-1];print s
 while i>s:s+=i[len(s)];print s

Введення задається як ['abc', 'abcdef', 'abcfed'], або як [ "abc", "abcdef", "abcfed"].

Версія 1: -11 байт. Кредит належить @xnor за його посаду на підказках щодо гольфу в Python, а також @Lynn за те, що він знайшов підказку для мене та для мене за розумність. Були внесені дві зміни: Замість цього not s.startswith(i)я використав s.find(i), а замість цього i!=sвикористав i>s.

Версія 2: -4 байти. Кредит йде на мене, розуміючи, що я зробив дійсно тупу помилку. Замість того, щоб використовувати відступи з одними та двома вкладками, я застосував відступи з одним пробілом та з двома вкладками.

Версія 3: -6 байт. Кредит надходить до @ mbomb007 за те, що він пропонує поставити вітрів в одну лінію. Я також виправив помилку, змінивши s.find(i)на i.find(s).

Версія 4: -4 байти. Кредит переходить до @xnor за те, що він зрозумів, що мені не потрібно зберігати дані у змінній.

Версія 5: -1 байт. Я вважаю, що я розумію, що ['']це те саме, що і [s]при додаванні його до вхідних даних.


Розмістіть whiles кожного на одному рядку. Також ви можете використовувати <1замість not.
mbomb007

Гарна відповідь! Xnor має гарну пораду, як цього уникнутиstartswith .
Лінь

@Lynn О, дякую за посилання! Я вважаю це дійсно корисним!
HyperNeutrino

@ mbomb007 Вибачте, я не зовсім розумію, що ви маєте на увазі, поставивши whiles на одну лінію. Ви маєте на увазі, як while s.find(i):s=s[:-1];print s? Також дякую за пропозицію щодо <1, але я змінив щось ще коротше завдяки одному із порад xnor у потоці підказок Python.
HyperNeutrino

@AlexL. Так, покладіть час так.
mbomb007

1

GNU M4, 228 або 232 байт¹

(¹ залежно від того, закінчувати файл dnl\nчи ні - я все ще новачок у гольфінгу та M4)

define(E,`ifelse(index($2,$1),0,`T($1,$2)',`$1
E(substr($1,0,decr(len($1))),$2)')')define(T,`ifelse($1,$2,,`$1
T(substr($2,0,incr(len($1))),$2)')')define(K,`ifelse($2,,$1,`E($1,$2)K(shift($@))')')define(M,`K(substr($1,0,1),$@)')

Крім того, 3 байти можна зберегти, замінивши другий аргумент на substrз 0на порожній рядок, але це призведе до багатьох попереджень про stderr.

Безголовки:

define(erase_til_prefix, `dnl arguments: src dst; prints src and chops one char off of it until src == dst, at which point it calls type_til_complete instead
ifelse(dnl
index($2, $1), 0, `type_til_complete($1, $2)',dnl
`$1
erase_til_prefix(substr($1, 0, decr(len($1))), $2)dnl
')')dnl
define(type_til_complete, `dnl arguments: src dst; types src, does not type `dst' itself
ifelse(dnl
$1, $2, ,dnl
`$1
type_til_complete(substr($2, 0, incr(len($1))), $2)'dnl
)')dnl
define(main_, `dnl
ifelse(dnl
$2, , $1, dnl no arguments left
`erase_til_prefix($1, $2)main_(shift($@))'dnl
)')dnl
define(main, `main_(substr($1, 0, 1), $@)')dnl

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

$ m4 <<<"include(\`backspace-golfed.m4')M(abc, abd, aefg, abcdefg, h)"

1

PHP, 116 111 101 83 байт

Примітка: використовується кодування Windows-1252.

for(;$w=$argv[++$i];)for(;$c!=$w;)echo$c=($c^$c^$w)==$c?$c.ÿ&$w:substr($c,0,-1),~õ;

Бігайте так:

php -r 'for(;$w=$argv[++$i];)for(;$c!=$w;)echo$c=($c^$c^$w)==$c?$c.ÿ&$w:substr($c,0,-1),~õ;' -- abc abd aefg h 2>/dev/null
> a
> ab
> abc
> ab
> abd
> ab
> a
> ae
> aef
> aefg
> aef
> ae
> a
>
> h

Пояснення

for(                       # Outer loop.
  ;
  $w=$argv[++$i];          # Loops over the input words.
)
  for(                     # Second inner loop.
    ;
    $c!=$w;                # Loop until the word was output.
  )
    echo $c=
      ($c^$c^$w)==$c?      # Check if last output string is a substring
                           # match with the next word to output.
        $c.ÿ&$w:           # ... If yes, suffix the string with the next
                           # char of the word, and output the result.
        substr($c,0,-1),   # ... If not, remove a char and output.
      ~õ;                  # Output newline.

Налаштування

  • Збережено 5 байт, використовуючи trim($c^$w,"\0")для перевірки відповідності підрядків замість $c&&strpos($w,$c)!==0.
  • Збережено 2 байти, використовуючи ~ÿдля отримання рядка з байтом NUL замість"\0"
  • Збережено 8 байт, використовуючи $c=$c.ÿ&$wсуфікс $cіз наступним символом$w
  • Збережено масивні 18 байт, об’єднавши логіку двох внутрішніх циклів в одну петлю
  • Виправлена ​​помилка з тестовою скринькою з коментарів, без зміни кількості байтів

1

Пакетна, 296 291 байт

@echo off
set f=
set t=%1
:t
set f=%f%%t:~,1%
set t=%t:~1%
echo(%f%
if not "%t%"=="" goto t
shift
set t=%1
set s=%f%
set p=
:h
if %s:~,1%==%t:~,1% set p=%p%%t:~,1%&set s=%s:~1%&set t=%t:~1%&goto h
:b
set f=%f:~,-1%
echo(%f%
if not "%f%"=="%p%" goto b
if not "%1"=="" goto t

Обчислення загального префікса було громіздким.


0

PHP, 153 байти

жахливо довго :(

for($s=$argv[$k=1];$t=$argv[++$k];){for(;$s>""&&strstr($t,$s)!=$t;$s=substr($s,0,-1))echo"$s
";for($i=strlen($s);$s<$t;$s.=$t[$i++])echo"$s
";echo"$s
";}

Бігайте з php -nr '<ode>' <text1> <text2> ....


0

JavaScript (ES6), 135 байт

Цікавий виклик! Використання: g(["abc", "abd", "aefg", "h"]). Я не міг би зберегти жоден байт, записавши це як одну функцію, тож це два. Нові рядки, не включені до числа байтів

f=a=>console.log(([,...z]=[x,y]=a)[0])||
y?f(a=(x==y.slice(0,-1))?z:([y.match(x)
?x+y[x.length]:x.slice(0,-1),...z])):1;
g=a=>f(['',...a])

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


0

Javascript, 98 байт

a=>{c="",l=0;for(w of a)while((i=w.indexOf(c))!=0||c!=w)alert(c=i!=0?c.substring(0,--l):c+w[l++])}

Порт Якова відповідь Java

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.