Молитовні головоломки та пасинки: конденсуйте струну


25

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

  • Почніть з конденсації 0 , тобто шукайте першу (ліву) пару тих самих символів з 0 іншими символами між ними. Якщо така пара знайдена, видаліть один із двох символів і перезапустіть алгоритм, виконавши ще одну конденсацію 0 . Якщо такої пари не знайдено, перейдіть до наступного кроку. Приклади:
    programming-C0-> programing
    aabbcc-C0-> abbcc
    test-C0->test

  • Потім виконайте 1-конденсацію , тобто знайдіть першу пару однакових символів із ще одним символом між ними. Якщо така пара знайдена, видаліть один із них та всі символи між ними та перезапустіть 0-конденсацією . Якщо такої пари не знайдено, перейдіть до наступного кроку. Приклади:
    abacac-C1-> acac
    java-C1->ja

  • Продовжуйте 2-конденсацію і так далі до n-конденсації, причому n - довжина вихідної струни, щоразу перезапускаючись після конденсації, видаляючи деякі літери. Приклади:
    programing-C2-> praming
    abcdafg-C3->afg

Отриманий рядок називається скороченим і містить кожен символ максимум одночасно.


Вхід:

Нижній регістр друкованих символів ascii.

Вихід:

Конденсують рядки в відповідно до зазначених вище правилами.

Приклади:

examples     -> es
programming  -> praming
puzzles      -> puzles
codegolf     -> colf
andromeda    -> a
abcbaccbabcb -> acb
if(x==1):x++ -> if(x+
fnabnfun     -> fun
abcdefae     -> abcde

Детальні приклади, щоб уточнити, як працює алгоритм:

fnabnfun -C0-> fnabnfun -C1-> fnabnfun -C2-> fnfun -C0-> fnfun -C1-> fun -C0-> fun 
 -C1-> fun -C2-> ... -C8-> fun

abcbaccbabcb -C0-> abcbacbabcb -C0-> abcbacbabcb -C1-> abacbabcb -C0-> abacbabcb 
 -C1-> acbabcb -C0-> acbabcb -C1-> acbcb -C0-> acbcb -C1-> acb -C0-> acb 
 -C1-> ... -C12-> acb

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


Дякуємо @Linus за корисні коментарі з пісочниці!


Тестовий випадок @MartinEnder Райлі все ще необхідний, оскільки це єдине рішення, на яке не працює моє сітківка.
mbomb007

@ mbomb007 Ах, бачу. Влучне зауваження.
Мартін Ендер

Чи буде введений рядок коли-небудь містити символи, які не можна друкувати, як пробіли?
mbomb007

@ mbomb007 Ні, припускати, що друкуються лише символи ascii, це добре.
Лайконі

@ Mbomb007 Однак, наскільки мені відомо, простір буде вважатися для друку символів ASCII, наприклад , тут .
Лайконі

Відповіді:


6

JavaScript (ES6), 74 байти

f=
(s,n=0,m=s.match(`(.).{${n}}\\1`))=>s[n]?m?f(s.replace(...m)):f(s,n+1):s
;
<input oninput=o.textContent=f(this.value)><pre id=o>


Дуже приємно, коротше, ніж я б подумав.
ETHproductions

5

Perl, 38 31 30 29 байт

Це повинно залишити мови для гольфу далеко позаду ...

-1 за $-[0]подяку Райлі

-1 за @{-}подяку Даді

Включає +1 для -p

Введіть дані про STDIN

condense.pl:

#!/usr/bin/perl -p
s/(.)\K.{@{-}}\1// while/./g

Ця 27-байтна версія повинна працювати, але це не так, оскільки perl не інтерполюється @-в регулярний вираз (див. Https://stackoverflow.com/questions/39521060/why-are-etc-not-interpolated-in-strings )

#!/usr/bin/perl -p
s/(.)\K.{@-}\1// while/./g

Як працює @{\@-}деталь? Я думав, що @-утримує індекси кожного матчу, і як це "підраховувати" за кожну ітерацію. Крім того, якщо ви друкуєте @{\@-}до та після кожної заміни, вона надрукує лише 1 або 2.
Райлі

1
@Riley /./gПрогресує на 1 в рядку щоразу, за винятком випадків, коли рядок змінюється, то вона скидається до 0. Якщо ви надрукуєте @-після, /./gале раніше, s///ви побачите, що вона піднімається (використовуйте тест, де решта рядка достатньо велика)
Тон Євангелія

Друк $-[0]дає цифри, які я б очікував. Чи @{\@-}діє так, як $-[0]через контекст регулярних виразів, але не друкується чомусь? $-[0]- байт коротший, ніж @{\@-}якщо вони однакові.
Райлі

"@{\@-}"не те саме, що @{\@-}(без ").
Райлі

@Riley Ні, але "@{\@-}"це те саме, що "@-". І це також має бути справедливим для заміни регулярних виразів, але це не так. Симулятор $-[0]повинен працювати, але ні. PS: Ви, мабуть, якось застосували скалярний контекст, @-коли ви робили друк, тому у вас завжди було 1 або 2
Евангеліє Тон


2

Python 2, 117 104 101 байт

Рекурсивно виконуйте необхідні заміни. Я будую регулярний вираз.

import re
def f(s,i=0):t=re.sub(r"(.)%s\1"%("."*i),r"\1",s);e=s==t;return i>len(t)and t or f(t,i*e+e)

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


Дві зворотні лінії можуть бути згущені return i>len(t) and t or s!=t and f(t) or f(t,i+1)для мережі в 4 байти
Quelklef

Ще 2 байти можна поголити, змінивши його наreturn t if i>len(t)else s!=t and f(t)or f(t,i+1))
Quelklef

Ще більше e=s==t;return i>len(t)and t or f(t,i*e+e)і тоді ви можете видалити i=0визначення функції, але вам доведеться зателефонувати з 0 запуском.
Quelklef

Я припускаю, що чотири пробіли існують не тому, що ви використовуєте чотири пробіли, а тому, що SE автоматично розширює їх. Якщо це не так, ви можете змінити всі свої пробіли на вкладки або на один пробіл на -9 байт.
Фонд позову Моніки

@Quelklef Мета забороняє приймати додаткові параметри.
mbomb007

1

Перл 53 52

Включає +1 для -p

for($i=0;$i<length;){$i=(s/(.).{$i}\1/\1/)?0:$i+1;}

Спробуйте це на ideone .


1

Математика, 101 байт

NestWhile[i=0;StringReplace[#,a_~~_~RepeatedNull~i++~~a_:>a,1]&,#,SameQ,2,ByteCount@#]&~FixedPoint~#&

Повинен бути спосіб зробити це коротшим ...


1

PHP, 90 байт

for($s=$argv[$c=1];$s[$i=++$i*!$c];)$s=preg_replace("#(.).{{$i}}\\1#","$1",$s,1,$c);echo$s;

або 92 байт

for($s=$argv[1];$s[$i];$i=++$i*!$c)$s=preg_replace("#(.).{".+$i."}\\1#","$1",$s,1,$c);echo$s;   

1
1) перша версія: +$iзамість $i+=0(-2). 2) forцикл замість whileможе зберегти два байти і дозволить видалити фігурні (-4). 3) $i=++$i*!$cзамість $i=$c?0:$i+1(-1). 4) \\2не потрібен, видаліть дужки (-2). 5) Ви можете дозволити обмеження 9замість 1швидкості (+0)
Тіт

@Titus дуже хороші ідеї. Я не бачив цього дякую
Йорг Гюльсерманн,

Тепер, коли я знову думаю ... це +$iне працює в кожному випадку. Спробуйте hammer. PHP не скаржиться на порожні дужки в регулярній виразці; але це не відповідає так, як хотілося. До речі: я рахую 91, а не 90. Але спробуйте нове 1)for($s=$argv[$c=1];$s[$i=++$i*!$c];)
Тіт

@Titus Так, я справді повернусь $i+=0і спробую вашу пропозицію згодом. Що означає молоток?
Йорг Гюльсерманн

@Titus гаразд та сама проблема, якщо puzzleщось інше, (.)//1але це нормально з вашою пропозицією або з$i´=0
Йорг Гюльсерманн,

1

Ruby, 75 64 57 байт

(56 байт коду + pваріант командного рядка.)

Використання рядкової інтерполяції всередині регулярного вираження для контролю довжини відповідних збігів.

i=0
~/(.).{#{i}}\1/?sub($&,$1)&&i=0: i+=1while i<$_.size

Тест:

$ ruby -p condense.rb <<< fnabnfun
fun

1

Haskell , 97 88 байт

(0?)
(a:s)!(b:t)|a==b=a:t|1<3=a:s!t
s!_=s
m?s|length s<m=s|a<-s!drop m s=sum[m+1|a==s]?a

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


Старий 97-байтний Берсіон:

(a:s)!(b:t)|a==b=a:t|1<3=a:s!t
s!_=s
m?s|length s==m=s|a<-s!drop m s=(last$0:[m+1|a==s])?a
c=(0?)

Спробуйте це на ideone .

Пояснення:

(a:s)!(b:t)|a==b = a:t         --perform condensation
           |1<3  = a:s!t       --recursively compare further
 s   ! _         = s           --no condensation performed

(!)Функція виконує один п-конденсація , коли дана рядок раз цілого і один раз з перших п символами видаляють, наприклад , abcdbeі cdbeдля 2-конденсації, шляхом рекурсивного порівняння двох провідних персонажів.

m?s|length s==m   = s         --stop before performing length-s-condensation
   |a <- s!drop m s           --a is the m-condensation of s
    = (last$0:[m+1|a==s])?a   --disguised conditional:
                              -- if a==s       if the m-condensation did not change s
                              -- then (m+1)?a  then perform m+1-condensation
                              -- else 0?a      else restart with a 0-condensation

c=(0?)                        -- main function, initialise m with 0
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.