Praming Puzles & Colf: конденсировать струну


25

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

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

  • Затем выполните 1-конденсацию , то есть найдите первую пару одинаковых символов с 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 Райли по-прежнему необходим, потому что он единственный, с которым не работает мое решение Retina.
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.
Riley

1
@Riley /./gПрогрессирует на 1 в строке каждый раз, за ​​исключением случаев, когда строка изменяется, а затем сбрасывается на 0. Если вы печатаете @-после, /./gно до того, как s///вы увидите, что она идет вверх (используйте тест, где оставшаяся строка достаточно велика)
Тон Хоспел

Печать $-[0]дает числа, которые я ожидал. Имеет ли @{\@-}действие , как $-[0]из - за регулярные выражения контекста , но не при печати по какой - то причине? $-[0]на байт короче, чем @{\@-}если бы они были одинаковыми.
Райли

"@{\@-}"это не то же самое, что @{\@-}(без ").
Райли

@ Райли Нет, но так "@{\@-}"же, как "@-". И это также должно быть верно для замены регулярных выражений, но это не так. Одновременно $-[0]должно работать, но не работает. PS: Вы, вероятно, каким-то образом применили скалярный контекст, @-когда делали свой отпечаток, так что вы всегда получаете 1 или 2
Тон Хоспел

3

CJam , 35 байт

rL{_,{{(_@_@#I={I)>]sj}*}h]s}fI}j

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


rL{                            }j   | run recursion on input
   _,{                      }fI     | for I from 0 to length(input)
      {                 }h]s        | one pass & clean up
       (_@                          | slice and store leading element A
          _@#I={      }*            | if next A is I steps away
                I)>                 | slice off I+1 element
                   ]sj              | clean up & recursion

Вы можете увидеть отдельные уплотнения, вставивed


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))
сократить,

Более того, e=s==t;return i>len(t)and t or f(t,i*e+e)вы можете удалить i=0из определения функции, но вам придется вызывать с 0 start.
Quelklef,

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

@Quelklef Мета запрещает принимать дополнительные параметры.
mbomb007

1

Perl 53 52

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

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

Попробуйте это на Ideone .


1

Mathematica, 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и попробую ваше предложение позже. Что значит с молотком?
Йорг Хюльсерманн

@ Титус, хорошо, та же проблема, если puzzleили что-то еще, (.)//1но это нормально с твоим предложением или$i´=0
Jörg Hülsermann,

1

Рубин, 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.