退格并重新输入单词列表


38

以下是从一个字符串退格并重新键入的方法

  1. 从第一个字符串开始。
  2. 最后删除字符,直到结果是第二个字符串的前缀。(这可能需要0步。)
  3. 在末尾添加字符,直到结果等于第二个字符串。(这也可能需要0步。)

例如,从fooabc到的路径fooxyz如下所示:

fooabc
fooab
fooa
foo
foox
fooxy
fooxyz

任务

给定一个单词列表,编写一个程序,该程序从空字符串到列表中的所有单词依次退格并重新键入,然后返回到空字符串。输出所有中间字符串。

例如,给定输入list ["abc", "abd", "aefg", "h"],输出应为:

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

h

规则

您可以返回或打印字符串列表,也可以返回带有某些定界符的单个字符串。您可以选择包括初始和最终的空字符串。确保输入至少包含一个单词,并且每个单词只能包含小写ASCII字母(az)。编辑:保证输入中的连续字符串彼此不相等。

这是;以字节为单位的最短代码获胜。

Python 3中的参考实现:在线尝试!


4
@ rahnema1>编写一个程序,从空字符串
Kritixi Lithos

3
输出将如何["abc","abc"]
Kritixi Lithos

1
@Emigna糟糕,这确实是一个循环!所以我要继续说这是重复的。
林恩

4
@Lynn这不是一回事。那不包括识别公共前缀,它总是下降到一个字符。
马丁·恩德

6
测试案例:a,abc,abcde,abc,a,abc,abcde
Zgarb

Answers:



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[]参数的lambda表达式。

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的lambda建议

class B代替它便宜interface B吗?您可以从程序包专用类运行。另外,请考虑使用lambda,因为您已经指定了Java8。
CAD97

@ CAD97 interface B{static void main比短class B{public static void main
凯文·克鲁伊森

@ CAD97我想不出一种方法来引入lambda,但是昨天我才刚刚了解它们。有任何想法吗?
雅各布

1
啊,我生锈了。您应该能够做a->{/*your code*/},这将分配给type变量java.util.function.Consumer<String[]>。但是,目前我无法测试。
CAD97

1
@JakobCornell默认情况下,PPCG允许完整的程序或功能提交。对于具有匿名函数(lambda)的语言,匿名函数本身就是一个可以接受的答案(因此您不必包括将其存储到的变量)。(尽管在Java提交中,提供lambda的类型是有礼貌的。)
CAD97

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

Haskell102 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
(""!).(++[""])

最后一行是匿名函数,它接收并返回字符串列表。 在线尝试!

说明

我的解决方案是递归的。首先,?是一个辅助函数infix函数:a?b给出的第一个length a字符b,或者整个bif a更长。接下来,我定义一个infix函数!。这个想法是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个字节。感谢xxnor意识到我不需要将输入存储在变量中。

修订版5:-1字节。归功于我意识到[''][s]将其添加到输入中时是一回事。


whiles放在一行中。另外,您可以使用<1代替not
mbomb007 '01

好答案!xnor有一个很好的技巧来说明如何避免startswith
林恩

@Lynn哦,谢谢您的链接!我发现它真的很有帮助!
HyperNeutrino

@ mbomb007对不起,将whiles放在一行上并不能完全理解您的意思。你是说喜欢while s.find(i):s=s[:-1];print s吗?另外,感谢您对的建议<1,但是由于xnor在Python技巧线程上的技巧之一,我的语言变得更短了。
HyperNeutrino

@AlexL。是的,放一会儿就是这样。
mbomb007 '01

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),$@)')

另外,通过将第二个参数替换为substrfrom 0到空字符串可以节省3个字节,但是这会在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.

调整

  • 通过trim($c^$w,"\0")检查子字符串匹配而不是来节省5个字节$c&&strpos($w,$c)!==0
  • 通过使用~ÿ产生2个字节的NUL字节而不是字符串来节省2个字节"\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++])}

Jakob的Java移植端口

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.