단어 목록을 백 스페이스로 다시 입력


38

한 문자열에서 다른 문자열로 백 스페이스 및 다시 입력 하는 방법은 다음과 같습니다 .

  1. 첫 번째 문자열부터 시작하십시오.
  2. 결과가 두 번째 문자열 의 접두어 가 될 때까지 끝에있는 문자를 제거하십시오 . (0 단계가 필요할 수 있습니다.)
  3. 결과가 두 번째 문자열과 같아 질 때까지 끝에 문자를 추가하십시오. (이 단계도 0 단계가 걸릴 수 있습니다.)

예를 들어,에서 경로 fooabcfooxyz외모가 좋아 :

fooabc
fooab
fooa
foo
foox
fooxy
fooxyz

태스크

단어 목록이 주어지면 빈 문자열부터 목록의 모든 단어까지 빈 문자열 로 돌아가는 방식으로 백 스페이스 하고 다시 입력하는 프로그램을 작성하십시오 . 모든 중간 문자열을 출력합니다.

예를 들어 input 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 Oops, 이것이 정확히 루프이지만! 계속해서 이것을 복제본이라고하겠습니다.
Lynn

4
@Lynn 정확히 같은 것은 아닙니다. 일반적인 접두사 인식은 포함되지 않으며 항상 한 문자로 내려갑니다.
마틴 엔더

6
테스트 사례 :a,abc,abcde,abc,a,abc,abcde
Zgarb

답변:



9

펄, 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 abc3 회 인쇄 된 후 공백이있었습니다 (실제로 공백이없는 첫 번째 및 세 번째). 나는 그것을 제거했다.
Dada

5

자바 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++));
}

감사의 말

  • CAD97의 람다 제안 덕분에 -38 바이트

class B대신 사용 하는 것이 저렴하지 interface B않습니까? 패키지 전용 클래스에서 실행할 수 있습니다. 또한 Java8을 이미 지정 했으므로 람다를 사용하는 것이 좋습니다.
CAD97

@ CAD97이보다 interface B{static void main짧습니다 class B{public static void main.
케빈 크루이 센

@ CAD97 나는 이것에 람다를 가져올 수있는 방법을 생각할 수 없었지만 어제 그들에 대해서만 알게되었습니다. 어떤 아이디어?
Jakob

1
아, 나는 녹슬었다. 당신은 할 수 있어야하며 a->{/*your code*/}, 이것은 유형의 변수에 할당 될 것 java.util.function.Consumer<String[]>입니다. 그러나 지금은 테스트 할 수 없습니다.
CAD97

1
@JakobCornell 기본적으로 PPCG는 전체 프로그램 또는 기능 제출을 허용합니다. 익명 함수 (lambda)가있는 언어의 경우 자체적으로 익명 함수가 적합합니다 (따라서 변수를 저장할 변수를 포함하지 않아도 됨). (Java 제출에서는 람다 유형을 제공하는 것이 정중합니다.)
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

젤리 , 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

하스켈 , 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
(""!).(++[""])

마지막 줄은 익명 함수이며 문자열 목록을 가져 와서 반환합니다. 온라인으로 사용해보십시오!

설명

내 솔루션은 재귀 적입니다. 먼저 ?도우미 infix 함수입니다. a?b의 첫 length a문자 b또는 bif 의 전체 문자 a가 더 깁니다. 다음으로 infix 함수를 정의합니다 !. 아이디어는 문자열과 문자열 목록 이있는 a!x곳 에서 첫 번째 문자열 의 경로를 생성 하고의 끝까지 반복한다는 것입니다 . 마지막 줄에서 빈 문자열을 추가 하고 빈 문자열과 입력에 적용되는 익명 함수를 정의합니다 .axaxx!

설명 !:

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

파이썬 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에게 파이썬 골프 팁에 대한 글을 보냈고, @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].


whiles를 각각 한 줄에 넣으십시오 . 또한 <1대신에 사용할 수 있습니다 not.
mbomb007

좋은 대답입니다! xnor의 피하는startswith 방법에 대한 유용한 팁이 있습니다 .
Lynn

@Lynn 아, 링크 주셔서 감사합니다! 정말 도움이되었습니다!
HyperNeutrino

@ mbomb007 죄송 합니다만, while한 줄에 s를 넣어서 무슨 뜻인지 알 수 없습니다 . 당신은 같은 의미 while s.find(i):s=s[:-1];print s입니까? 또한에 대한 제안에 감사 <1하지만 파이썬 팁 스레드에 대한 xnor의 팁 중 하나 덕분에 더 짧은 것으로 변경되었습니다.
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),$@)')

또한 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.
  • ~ÿNUL 바이트 대신 문자열을 생성하는 데 사용하여 2 바이트 절약"\0"
  • 다음 문자 $c=$c.ÿ&$w로 접미사 $c를 사용하여 8 바이트를 절약했습니다.$w
  • 단일 루프에서 2 개의 내부 루프의 논리를 결합하여 대량의 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

자바 스크립트 (ES6), 135 바이트

재미있는 도전! 사용법 : g(["abc", "abd", "aefg", "h"]). 이것을 하나의 함수로 작성하여 바이트를 절약 할 수 없었으므로 2입니다. 바이트 수에는 개행이 포함되지 않습니다.

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

자바 스크립트, 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++])}

야콥 항구의 자바 답변

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.