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


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

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

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]при добавлении к входу.


Поместите 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 байтов путем объединения логики двух внутренних циклов в одном цикле.
  • Исправлена ​​ошибка с тест-кейсом из комментариев, без изменения количества байтов

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.