Повільно перетворіть рядок в іншу


31

Змагання

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

Можна припустити, що рядки завжди будуть починатися з того самого символу.

Приклад

Input:
"Test", "Testing"

Output:
Test
Tes
Te
T
Te
Tes
Test
Testi
Testin
Testing

Спочатку виводите перше слово:

Test

Потім ви продовжуєте видаляти одну букву, поки рядок не буде одним символом:

Tes
Te
T

Потім продовжуйте додавати одну букву другого слова, поки це не закінчено:

Te
Tes
Test
Testi
Testin
Testing

(якщо обидва рядки є одним символом, просто виведіть один з них один раз.)

Випробування

"Hello!", "Hi."
Hello!
Hello
Hell
Hel
He
H
Hi
Hi.

"O", "O"

O

"z", "zz"

z
zz

".vimrc", ".minecraft"

.vimrc
.vimr
.vim
.vi
.v
.
.m
.mi
.min
.mine
.minec
.minecr
.minecra
.minecraf
.minecraft

"     ", "   "

SSSSS
SSSS
SSS
SS
S
SS
SSS

"0123456789", "02468"

0123456789
012345678
01234567
0123456
012345
01234
0123
012
01
0
02
024
0246
02468

(Примітка: на пробілі / четвертому тестовому випадку замініть S пробілами)

Правила

  • Це , тому найкоротша відповідь у байтах виграє! Tiebreaker - це найбільш популярна посада. Переможець буде обраний 10.09.2016.

  • Стандартні лазівки заборонені.


Чи буде дозволено 2 чистих нових рядків (один видимий порожній рядок після послідовності) чи ні?
seshoumara

Відповіді:


11

Pyth, 9 байт

j+_._Et._

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

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

Як це працює

j+_._Et._  Program. Inputs: Q, E
   ._E     Yield prefixes of E as a list
  _        Reverse the above
       ._  Yield prefixes of Q as a list (implicit input fill)
      t    All but the first element of above
 +         Merge the two lists
j          Join on newlines
           Implicitly print

14

V , 14 байт

òYp$xhòjòÄ$xhh

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

Пояснення:

ò     ò     "Recursively:
 Yp         "  Yank the current line and paste it
   $        "  Move to the end of the current line
    x       "  Delete one character
     h      "  Move One character to the right.
            "  Because of the way loops work in V, this will throw an error if there
            "  Is only one character on the current line.

Тепер буфер виглядає приблизно так:

0123456789
012345678
01234567
0123456
012345
01234
0123
012
01
0

Нам просто потрібно зробити те ж саме, щоб зробити наступний рядок:

j           "Move down one line
 ò     ò    "Recursively (The second ò is implicit)
  Ä         "  Duplicate this line up
   $        "  Move to the end of the current line
    x       "  Delete one character
     hh     "  Move two characters to the right.
            "  Because of the way loops work in V, this will throw an error if there
            "  Is only two characters on the current line.

Більш цікаве альтернативне рішення :

òÄ$xhòç^/:m0
ddGp@qd

3
Це як vim завжди правильний інструмент для роботи
Downgoat

@Downgoat Рівно. Ось чому вам потрібно почати займатися гольфом у V.: P
DJMcMayhem

9

Пітон, 93 байти

f=lambda a,b,r='',i=2:a and f(a[:-1],b,r+a+'\n')or(len(b)>=i and f(a,b,r+b[:i]+'\n',i+1)or r)

Починається з порожнього рядка r, додає aі новий рядок, і видаляє останній символ з aтих пір, поки aпорожній, потім додає необхідні частини bта новий рядок, зберігаючи лічильник i, який починається з 2тих пір, поки довжина не bбуде перевищена, а потім повертається r. Має зворотний рядок.

Всі тести на ideone


2 речі. 1) Я вважаю, що ви неправильно рахували символів, і це насправді 93 і 2) Вам не потрібно говорити r="". Простий rвсе одно працював.

Дякую @JackBates 1. Правильно та оновлено - я, мабуть, забув f=. 2. Без r=''справжнього f('test','testing')не вийшло б; так f('test','testing',''), але ми повинні слідувати технічним умовам.
Джонатан Аллан

Пробач мені. Я просто дивився на код, а не на приклади.


7

Сітківка, 50 41 26 байт

Дякую Мартіну Ендеру за збереження 15 (!) Байтів.

M&!r`.+
Om`^.¶[^·]+|.+
A1`

Здійснює введення двома рядками, розділеними новим рядком:

Test
Testing

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

Пояснення

M&!r`.+

Перший рядок генерує "кроки" обох слів:

Testing
Testin
Testi
Test
Tes
Te
T
Test
Tes
Te
T

Mпризначений для режиму матчу, &враховує збіги, що збігаються, і !друкує відповідність замість їх кількості. Причина, коли вона перевернута, - це rпараметр «ліворуч» вліво: двигун починає шукати відповідники в кінці рядка і продовжує до початку.

Om`^.¶[^·]+|.+

Це набирає все в правильному порядку: це Orts всі збіги наступного регулярного виразів: Персонаж у своєму власному рядку та кожен символ (включаючи нові рядки) після нього, який відповідає всій другій половині як один шматок, або інакше лінія символів , що відповідає кожному окремому рядку. Потім ці зіставлення сортуються за кодовою точкою, тому T, за яким слідує новий рядок, йде спочатку, за ним слідують лінії, що збільшуються по довжині.

A1`

Тепер у нас просто перша лінія символів зверху, тому ми використовуємо Aрежим ntigrep, щоб відкинути першу відповідність регулярного вираження за замовчуванням .+.

Стара версія

M&!r`.+
O`\G..+¶
s`(.*)¶.¶(.*)
$2¶$1
¶.$

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

Пояснення

Перший рядок той самий, тому дивіться пояснення до цього вище.

O`\G..+¶

Це повертає рядки першої половини (друге вхідне слово). Це насправді s Orts рядки, і регулярний вираз обмежує відповідність: це повинен бути рядок з двох або більше символів ( ..+), а потім новий рядок ( ), який починається там, де останній відійшов ( \G). У наведеному вище прикладі сингл Tпосередині не збігається, тому нічого після цього не може.

Te
Tes
Test
Testi
Testin
Testing
T
Test
Tes
Te
T

Тепер у нас є правильні два компоненти, але в неправильному порядку.

s`(.*)¶.¶(.*)
$2¶$1

¶.¶відповідає самотній T посередині, який нам не потрібен, але розділяє дві частини. Двоє (.*)захоплюють все до і після, включаючи нові рядки завдяки sрежиму ввімкненої лінії. Дві знімки заміщені в правильному порядку новою лінією між ними.

Тепер ми закінчили, якщо рядки вводу не мають одного символу, і в цьому випадку введення не змінилося. Щоб позбутися дубліката, ми замінюємо ¶.$(коли останній рядок рядка - один символ) нічим.


4

Python 2, 88 82 байт

x,y=input(),input()
for i in x:print x;x=x[:-1]
s=y[0]
for i in y[1:]:s+=i;print s

Бере два входи, кожен оточений лапками.

Дякуємо @JonathanAllan за збереження деяких байтів та вказівку на помилку.


1
Немає необхідності len(x)в x=x[:len(x)-1]тому, що працює нарізка негативного зміщення - ви можете просто написати x=x[:-1]. Єдина проблема - ваш код не " ", " "дуже добре поводиться з тестовим випадком.
Джонатан Аллан

1
Ви можете кинути другий input()і використовувати формат введення на кшталт"<str1>", "<str2>"
LevitatingLion

Ви можете змінити другий рядок на for i in range(x):print x[-i:], а четвертий - на for i in range(1,y):print y[:-i]. Не впевнений, що це буде працювати, хоча.
клісмік

4

Perl, 34 28 байт

Включає +2для-0n

Виконайте рядки на окремих рядках на STDIN:

perl -M5.010 -0n slow.pl
Test
Testing
^D

slow.pl:

/(^..+|
\K.+?)(?{say$&})^/

Нехай зворотне відстеження regex виконує роботу ...



3

Брахілог , 32 байти

:1aLtT,Lhbr:Tc~@nw
:2fb
~c[A:B]h

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

Пояснення

У Brachylog немає вбудованого префікса, тому ми отримаємо префікси, використовуючи concatenate(Див. Предикат 2): префікс S, Pякщо Pприєднується до Q(що б це не було), призводить до S.

  • Основний предикат:

    :1aL                  L is all prefixes of both elements of the input (see predicate 1)
       LtT,               T is the second element of L
           Lhbr           Remove the first prefix of the first list of L and reverse it
               :Tc        Concatenate with T
                  ~@n     Join with newlines
                     w    Write to STDOUT
    
  • Предикат 1:

    :2f                   Find all prefixes of the input string (see predicate 2)
       b                  Remove the first one (empty string)
    
  • Предикат 2:

    ~c[A:B]               Input is the result of concatenating A to B
           h              Output is A
    

3

Javascript, 103 81 байт

f=(x,y,n=1)=>x?`
`+x+f(x.slice(0,-1),y):n++<y.length?`
`+y.slice(0,n)+f(x,y,n):''

Приклад: f("Test", "Testing")

Вихід:

Test
Tes
Te
T
Te
Tes
Test
Testi
Testin
Testing

Оригінальна відповідь

f=(x,y,n=1)=>x?(console.log(x),f(x.slice(0,-1),y)):n++<y.length?(console.log(y.slice(0,n)),f(x,y,n)):''

3

Ява, 188 179 байт

interface E{static void main(String[]a){int i=a[0].length();while(i>1)System.out.println(a[0].substring(0,i--));while(i<=a[1].length())System.out.println(a[1].substring(0,i++));}}

Оновлення

  • Видалена змінна s, збережено 9 байт

Безумовно :

interface E {

    static void main(String[] a) {
        int i = a[0].length();
        while (i > 1) {
            System.out.println(a[0].substring(0, i--));
        }
        while (i <= a[1].length()) {
            System.out.println(a[1].substring(0, i++));
        }
    }
}

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

$ java E 'test' 'testing'
test
tes
te
t
te
tes
test
testi
testin
testing

3

Haskell, 54 53 47 байт

t[]=[]
t x=x:t(init x)
(.reverse.t).(++).init.t

Приклад використання: ((.reverse.t).(++).init.t) "Hello" "Hi!"->["Hello","Hell","Hel","He","H","Hi","Hi!"] .

Якась безглузда магія. Це те саме, що f x y = (init(t x))++reverse (t y)там, де tскладається список усіх початкових підрядків, наприклад t "HI!"-> ["H","HI","HI!"].


Гм t=reverse.tail.inits,?
Бергі

@Bergi: впевнений, але initsпотребує import Data.List.
німі


3

GNU sed, 57 45 + 2 (rn прапори) = 47 байт

:;1{/../p};2G;2h;s/.(\n.*)?$//;/./t;g;s/.$//p

Виконати:

echo -e "Test\nTesting" | sed -rnf morphing_string.sed

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

Цикл :видаляє один символ з кінця рядка ітеративно. Вихід пов'язаний з першого рядка друкується безпосередньо, за винятком першого символу: 1{/../p}. Виведення другого рядка зберігається у просторі утримування у зворотному порядку ( 2G;2h) під час видалення та друкується в кінці.


3

C (gcc) , 102 97 95 93 байт

n;f(char*a,char*b){for(n=strlen(a);n;puts(a))a[n--]=0;for(a=b+1;*a++;*a=n)n=*a,*a=0,puts(b);}

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

Перший цикл перезаписує рядок на 0 байтів, починаючи з кінця, і використовує puts()для друку рядка. Другий цикл не може просто перезаписати спочатку, він повинен зберігати старе значення, щоб він міг повернути його назад; 0 байт просто йде до кінця.

Дякуємо @homersimpson та @ceilingcat за кожне гоління по 2 байти!


1
Ви можете заощадити пару байт, оголошуючи в nякості глобального міжнар як: n;f(char*a,char*b){n=strlen(a).... І ви, ймовірно, можете виконувати це n=*a=0як приковане завдання в тілі вашого циклу.
homersimpson

Дякую @homersimpson. Але n = * a = 0 - це не те саме, що n = * a, * a = 0.
Г. Сліпен

2

Пітон 3, 104 байти

Мех.

n='\n';lambda x,y:x+n+n.join(x[:-i]for i in range(1,len(x)-1))+n+n.join(y[:i]for i in range(1,len(y)+1))

Дякуємо @DJMcMayhem за те, що виграли 21 байт.

Ідей це!


1
Ви можете взяти 5 байт, якщо ви робите, n='\n'а замість n використовувати n'\n' . Ви можете зняти ще 8, якщо замість друку використовували лямбда:n='\n';lambda x,y:n.join(x+n+n.join(x[:-i]for i in range(1,len(x)-1))+n+n.join(y[:i]for i in range(1,len(y)+1)))
DJMcMayhem

2

REPL / Javascript, 109 байт

Використовує помилковий рядок, щоб зменшити вихідний рядок

Зловживає підрядком із більшими числами для зростання другого, зупиняється, коли він збирається надрукувати те саме слово, що і минулого разу.

(a,b)=>{l=console.log;z='substring';for(c=a.length;d=a[z](0,c--);){l(d)}for(c=2;d!=(n=b[z](0,c++));){l(d=n)}}

Демонстрація:

> ((a,b)=>{l=console.log;z='substring';for(c=a.length;d=a[z](0,c--);){l(d)}for(c=2;d!=(n=b[z](0,c++));){l(d=n)}})("asdf","abcd")
[Log] asdf
[Log] asd
[Log] as
[Log] a
[Log] ab
[Log] abc
[Log] abcd

1
це на 1 байт коротше, a=>b=>...а функцію зателефонувати за допомогою (a) (b)
Zwei

2

Brainfuck, 38 55 байт

>++++++++++>,[>,]<[<]>>[[.>]<[-]<[<]>.>],.[[<]>.>[.>],]

Редагувати: включені нові лінії у висновок


Я не можу змусити твій код працювати. Чи вхід розділений новим рядком? Якого перекладача ви використовуєте?
акроліт

2

Діалог APL , 20 13 байт

↑(⌽,\⍞),1↓,\⍞

матрифікувати

(⌽,\⍞)зворотна ( ) кумулятивна конкатенація ( ,\) введення символів ( )

, претендував на

1↓ один елемент випав із

,\⍞ сукупне конкатенація введення символів

СпробуйтеAPAP онлайн!


2

Ракетка 193 байт

(define(f l)
(let*((s(list-ref l 0))
(x(string-length s)))
(for((n x))
(println(substring s 0(- x n))))
(set! s(list-ref l 1))
(for((n(range 1(string-length s))))
(println(substring s 0(add1 n))))))

Тестування:

(f(list "Test" "Testing"))

"Test"
"Tes"
"Te"
"T"
"Te"
"Tes"
"Test"
"Testi"
"Testin"
"Testing"


(f(list "Hello!" "Hi."))

"Hello!"
"Hello"
"Hell"
"Hel"
"He"
"H"
"Hi"
"Hi."

Він повинен видалити останній символ із вхідного рядка, а не перший.
агілоб

2

Флороїд , 69 байт

a,b=L.J
c=1
NZ(a)!=1:z(a);a=a[:-1]
z(a)
NZ(a)!=Z(b):c+=1;a=b[:c];z(a)

Це початок. Бере вхід від STDIN.

Тестові шафи

Input: Test Testing
Output:
Test
Tes
Te
T
Te
Tes
Test
Testi
Testin
Testing

Input: O O
Output: O

1

JavaScript (ES6), 92 байти

(s,t)=>s.replace(/./g,`
$\`$&`).split`
`.slice(2).reverse().join`
`+t.replace(/./g,`
$\`$&`)

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

(s,t)=>s.replace(/./g,`
$\`$&\n`).split(/^/m).slice(1).reverse().join``+t.replace(/./g,`
$\`$&\n`)

1

C, 142 байти

#define _(x,y) while(y)printf("%.*s\n",d,x-c);
f(char*a,char*b){int c=1,d=strlen(a)+1;while(*++a==*++b)c++;_(a,--d>=c)d++;_(b,d++<strlen(b-c))}

Надати f(char* str1, char* str2).


1

TI-Basic, 56 байт

Prompt Str1,Str2
Str1
While 1<length(Ans
Disp Ans
sub(Ans,1,length(Ans)-1
End
For(I,1,length(Str2
Disp sub(Str2,1,I
End

Приклад використання

Str1=?Test
Str2=?Testing
Test
Tes
Te
T
Te
Tes
Test
Testi
Testin
Testing

Str1=?O
Str2=?O
O

Str1=?z
Str2=?zz
z
zz

1

Java, 168 136 байт

(s,d)->{int i=s.length()+1;while(i-->1)System.out.println(s.substring(0,i));while(i++<d.length())System.out.println(d.substring(0,i));};

Програма тестування без вогків

public static void main(String[] args) {

    BiConsumer<String, String> biconsumer = (s, d) -> {
        int i = s.length() + 1;
        while (i-- > 1) {
            System.out.println(s.substring(0, i));
        }
        while (i++ < d.length()) {
            System.out.println(d.substring(0, i));
        }
    };

    biconsumer.accept("Test", "Testing123");

}

1

(Ламбдабот) Haskell - 41 байт

f=(.drop 2.inits).(++).reverse.tail.inits

Більш читабельний, але на два байти довше:

a!b=(reverse.tail$inits a)++drop 2(inits b)


Вихід:

f "Hello" "Hi!"
["Hello","Hell","Hel","He","H","Hi","Hi!"]

1

J, 18 байт

]\@],~[:}:[:|.]\@[

Безголовки:

]\@] ,~ [: }: [: |. ]\@[

Це 7-поїзд:

]\@] ,~ ([: }: ([: |. ]\@[))

Найпотаємніший поїзд [: |. ]\@[складається з ковпачка [:зліва, тому ми застосовуємо |.(зворотний) до результату ]\@[, який є]\ (префіксами) над[ (лівий аргумент).

Ось як це виглядає на testing, testвході:

   'testing' ([: |. ]\@]) 'test'
test
tes
te
t

Це дає нам майже першу порцію. 5-поїзд поза цим є ([: }: ([: |. ]\@[)), який застосовується }:(косити, видалити останній елемент) до вищевказаного виразу:

   'testing' ([: }: [: |. ]\@]) 'test'
test
tes
te

(Це тому, що ми не можемо мати дубліката середини.)

Нарешті зовнішня частина:

]\@] ,~ ([: }: ([: |. ]\@[))

Складається з ]\@](префікси лівого аргументу) та,~ (додайте те, що ліворуч, а те, що праворуч), залишаючи нам бажаний результат:

   'testing' (]\@] ,~ ([: }: ([: |. ]\@[))) 'test'
testing
testin
testi
test
tes
te
t
te
tes
test

Тестові справи

   k =: ]\@] ,~ ([: }: ([: |. ]\@[))
   'o' k 'o'
o
   k~ 'o'
o
   'test' k 'test'
test
tes
te
t
te
tes
test
   k~ 'test'
test
tes
te
t
te
tes
test
   '. . .' k '...'
. . .
. .
. .
.
.
..
...
   'z' k 'zz'
z
zz

Ви можете змінити його до 14 байтів , використовуючи(,~}:@|.)&(]\)
миль

1

PHP, 117 109 байт

for($i=strlen($a=$argv[1]);$i>1;)echo" ".substr($a,0,$i--);
for(;$j<strlen($b=$argv[2]);)echo" ".$c.=$b[$j++];

for($i=strlen($a=$argv[1]);$i>1;)echo substr($a,0,$i--)." ";
for(;$i<=strlen($b=$argv[2]);)echo substr($b,0,$i++)." ";

PHP, 107 байт (не працює з рядками, що містять 0)

for($a=$argv[1];$a[$i];)echo substr($a.a,0,-++$i)." ";
for($b=$argv[2];$b[$j];)echo substr($b,0,++$j+1)." ";

1

C, 111 байт

f(char*a, char*b){int l=strlen(a),k=1;while(*a){printf("%s\n",a);a[--l]=0;}while(b[k]) printf("%.*s\n",++k,b);}

Тест без вольфів

#include <stdio.h>
#include <string.h>

f(char*a, char*b) {
  int l=strlen(a), k=1;
  while(*a) {
    printf("%s\n",a);
    a[--l]=0;
  }
  while(b[k])
    printf("%.*s\n",++k,b);
}

int main() {
  char a[10] = {0};
  char b[10] = {0};

  for (int i=0; i<5; ++i) {
    a[i] = 'a' + i;
    b[i] = 'a' + i*2;
  }

  f(&(a[0]), &(b[0]));
}

1

мозковий ебать, 162 байти

,[>,]++++++++++[[-<]>[->]<]++++++++++[<[+<]<[+<]>[+>]>[+>]<---]<[<]<[<]>[[.>]++++++++++.----------<[-]<[[->+<]<]>>]>[<+>-]>[[<+>-]<[<]>[.>]++++++++++.---------->]

Спробуйте тут

Введення приймає два рядки, розділені прямим підведенням.

Перша програма з brianfuck та гольф першого коду, тому я впевнений, що потрібно зробити багато оптимізації. Було весело робити це, хоча.

Безумовно

,[>,] Read all input
++++++++++ Flag for 10
[                   Subtract 10 from each cell to flag space for blank
    [-<]            
    >
        [->]
        <
]
++++++++++ Flag for 10
[                   Add 10 back to each cell with value in it
    <[+<]<[+<]
    >[+>]>[+>]<---
]
<[<]<[<]>               goto first cell in first string string      

[                           Print first word subtracting one each time
    [.>]                    Print first string
    ++++++++++.----------   Print new line
    <[-]                    Kill last letter of first string
    <                       Back one
    [                       Move each first string character up one
          [->+<]
          <
    ]>>
]
>[<+>-]>                    Move to first letter of scond string back one goto second letter
[                               
    [<+>-]                  Move next letter back
    <[<]>                   Move to start of string
    [.>]                    Print string
    ++++++++++.----------   Print new line
    >
]

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