Возврат и перепечатка списка слов

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
@ Линн Это не совсем то же самое. Это не включает распознавание общих префиксов, оно всегда сводится к одному символу.
Мартин Эндер
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 Был пробел после того, как 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++));}

Ungolfed

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
Jakob
источник
Разве это не дешевле использовать 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

Mathematica, 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

Сетчатка , 39 байт

Число байтов предполагает кодировку ISO 8859-1.

M!&r`.+
%)`\G.
¶$`$&
+`((.*).¶)\2¶\1
$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.
Zgarb
источник
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 за предложение поместить whiles в одну строку. Я также исправил ошибку, изменив s.find(i)на i.find(s).

Редакция 4: -4 байта. Благодарю @xnor за понимание того, что мне не нужно хранить входные данные в переменной.

Редакция 5: -1 байт. Благодарю меня за то, что я понял, что ['']это то же самое, что и [s]при добавлении к входу.

HyperNeutrino
источник
Поместите whileкаждый в одну строку. Также вы можете использовать <1вместо not.
mbomb007
Хороший ответ! Есть хороший совет от xnor о том, как этого избежатьstartswith .
Линн
@ Линн О, спасибо за ссылку! Я нашел это действительно полезным!
HyperNeutrino
@ mbomb007 Извините, я не совсем понимаю, что вы имеете в виду, помещая whiles в одну строку. Вы имеете в виду как while s.find(i):s=s[:-1];print s? Кроме того, спасибо за предложение <1, но я изменился на что-то еще более короткое благодаря одному из советов xnor в ветке Python tips.
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 байта, заменив второй аргумент substrfrom 0на пустую строку, но это приведет к большому количеству предупреждений о stderr.

Ungolfed:

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.

Tweaks

  • Сохранено 5 байтов с помощью trim($c^$w,"\0")проверки соответствия подстроки вместо $c&&strpos($w,$c)!==0.
  • Сохранено 2 байта с использованием ~ÿдля получения строки с байтом NUL вместо"\0"
  • Сохранено 8 байтов с помощью $c=$c.ÿ&$wсуффикса $cсо следующим символом$w
  • Сохранение массивных 18 байтов путем объединения логики двух внутренних циклов в одном цикле.
  • Исправлена ​​ошибка с тест-кейсом из комментариев, без изменения количества байтов
aross
источник
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> ....

Titus
источник
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 ответ

SuperStormer
источник