Недедуплицирующие строки


33

Введение

Давайте посмотрим на следующую строку:

AABBCCDDEFFGG

Вы можете видеть, что каждое письмо было продублировано , за исключением письма E. Это означает, что письмо Eбыло дублировано . Таким образом, единственное, что нам нужно сделать здесь, это обратить этот процесс вспять, что дает нам следующую недедуплицированную строку:

AABBCCDDEEFFGG

Давайте рассмотрим более сложный пример:

AAAABBBCCCCDD

Вы можете видеть, что число последовательных символов Bразличается, что означает, что один из них BBбыл дублирован из исходной строки. Нам нужно только де-дублировать это письмо, которое дает нам:

AAAABBBBCCCCDD


Соревнование

Если задана непустая дедуплицированная строка, состоящая только из буквенных символов (либо только в верхнем, либо только в нижнем регистре), вернуть нед дедуплицированную строку. Вы можете предположить, что в строке всегда будет хотя бы один дедуплицированный символ.


Контрольные примеры

AAABBBCCCCDDDD    -->    AAAABBBBCCCCDDDD
HEY               -->    HHEEYY
AAAAAAA           -->    AAAAAAAA
N                 -->    NN
OOQQO             -->    OOQQOO
ABBB              -->    AABBBB
ABBA              -->    AABBAA

Это , поэтому выигрывает самая короткая действительная подача в байтах!


@ mbomb007 Да, это приведет к AABBBB.
Аднан

1
Я не уверен, что понимаю проблему. Почему ABBBкарта AABBBB, а не AABBBBBB?
Деннис

2
@Dennis Если вы разделите каждую группу символов в группы 2, вы получите следующее: A BB B. Символы, которые не сопряжены (и, следовательно, не дублированы), должны быть продублированы, в результате AA BB BBчего получается недедуплицированная строка.
Аднан

8
Итак: Убедитесь, что каждый цикл символов имеет четное количество элементов, добавив в него не более одного элемента?
Безумный физик

1
@MadPhysicist Да, это правильно
Аднан

Ответы:


20

MATL , 7 байт

Y'to+Y"

Попробуйте онлайн! Или проверьте все тестовые случаи .

Давайте возьмем в 'ABBA'качестве примера ввод.

Y'   % Implicit input. Run-length decoding
     % STACK: 'ABA', [1 2 1]
t    % Duplicate top of the stack
     % STACK: 'ABA', [1 2 1], [1 2 1]
o    % Modulo 2
     % STACK: 'ABA', [1 2 1], [1 0 1]
+    % Add, element-wise
     % STACK: 'ABA', [2 2 2]
Y"   % Run-length encoding. Implicit display
     % STACK: 'AABBAA'


8

Perl, 16 байт

15 байтов кода + -pфлаг.

s/(.)\1?/$1$1/g

Чтобы запустить это:

perl -pe 's/(.)\1?/$1$1/g' <<< 'HEY'

7

Haskell, 36 байт

u(a:b:c)=a:a:u([b|a/=b]++c)
u x=x++x

Пример использования: u "OOQQO"-> "OOQQOO".

Если строка содержит хотя бы 2 элемента, возьмите две копии первого и добавьте рекурсивный вызов с помощью

  • второй элемент остальное, если первые два элемента отличаются или
  • просто отдых

Если имеется менее двух элементов (один или ноль), возьмите две копии списка.


6

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

@b:{~b#=.l#e,|}ac

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

объяснение

Example input: "ABBB"

@b                  Blocks: Split into ["A", "BBB"]
  :{          }a    Apply the predicate below to each element of the list: ["AA", "BBBB"]
                c   Concatenate: "AABBBB"

    ~b#=.             Output is the input with an additional element at the beginning, and
                        all elements of the output are the same (e.g. append a leading "B")
        .l#e,         The length of the Output is an even number
             |        Or: Input = Output (i.e. do nothing)


4

JavaScript (ES6), 37 30 байт

Сэкономили 7 байт, используя гораздо более эффективный «$ 1 $ 1», как это сделали [другие] [ответы]

s=>s.replace(/(.)\1?/g,'$1$1')

Контрольные примеры


4

Mathematica, 41 байт

s=StringReplace;s[s[#,a_~~a_->a],b_->b~~b]&

Безымянная функция, которая вводит строку и выводит строку. Полностью дедуплицирует, затем полностью недедуплицирует. Не очень коротко, но я не мог сделать лучше сейчас.


4

Befunge 98 , 24 байта

#@~#;:::#@,~-:!j;$,;-\,;

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

$может быть легко заменено на -, а 2-е - @на ;.

Я думаю, что это может быть дальше в гольфе из- -за в начале обоих -,(или $,выше) и -\,.

Как?

Stack notation:  bottom [A, B, C, D] top

#@~     Pushes the first character onto the stack (C henceforth) and ends if EOF
#;      No-op to be used later
:::     Now stack is [C, C, C, C]

#@,~    Prints C, and if EOF is next (odd consecutive Cs), prints again and ends
        Lets call the next character D

-       Now stack is [C, C, C-D]
:!j;    If C == D, go to "$," Else, go to "-\,"

===(C == D)===

$,      C == D (i.e. a pair of Cs) so we discard top and print C (Stack is now [C])
;-\,;   Skipped, IP wraps, and loop starts again

===(C != D)===

-       Stack is [C, C-(C-D)]  By expanding: [C, C - C + D] or just [C, D]
\,      Prints C (Stack is now [D])

;#@~#;  This is skipped, because we already read the first character of a set of Ds,
        and this algorithm works by checking the odd character in a set of
        consecutive similar characters. We already read D, so we don't
        need to read another character.

3

Java 7, 58 байт

String c(String s){return s.replaceAll("(.)\\1?","$1$1");}

Ungolfed:

String c(String s){
  return s.replaceAll("(.)\\1?", "$1$1");
}

Тестовый код:

Попробуй это здесь.

class M{
  static String c(String s){return s.replaceAll("(.)\\1?","$1$1");}

  public static void main(String[] a){
    System.out.println(c("AABBCCDDEFFGG"));
    System.out.println(c("AAAABBBCCCCDD"));
    System.out.println(c("AAABBBCCCCDDDD"));
    System.out.println(c("HEY"));
    System.out.println(c("AAAAAAA"));
    System.out.println(c("N"));
    System.out.println(c("OOQQO"));
    System.out.println(c("ABBB"));
    System.out.println(c("ABBA"));
  }
}

Выход:

AABBCCDDEEFFGG
AAAABBBBCCCCDD
AAAABBBBCCCCDDDD
HHEEYY
AAAAAAAA
NN
OOQQOO
AABBBB
AABBAA

2

PHP, 65 байт, без регулярных выражений

while(""<$c=($s=$argv[1])[$i])if($c!=$s[++$i]||!$k=!$k)echo$c.$c;

принимает входные данные из аргумента командной строки. Беги с -r.

регулярное выражение? В PHP регулярное выражение, используемое большинством ответов, дублирует каждый символ. будет 44 байта:

<?=preg_replace("#(.)\1?#","$1$1",$argv[1]);

2

Brain-Flak 69 Bytes

Включает +3 для -c

{((({}<>))<>[({})]<(())>){((<{}{}>))}{}{(<{}{}>)}{}}<>{({}<>)<>}<>

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

Объяснение:

Part 1:
{((({}<>))<>[({})]<(())>){((<{}{}>))}{}{(<{}{}>)}{}}<>

{                                                  }   # loop through all letters
 (   {}     [ {} ]<(())>){((<{}{}>))}{}                # equals from the wiki   
                                                       # but first:
  ((  <>))<>                                           # push the top letter on the other 
                                                       # stack twice  
             (  )                                      # push the second letter back on
                                       {        }      # if they were equal:
                                        (<    >)       # push a 0 to exit this loop
                                          {}{}         # after popping the 1 from the 
                                                       # comparison and the next letter
                                                       # (the duplicate)
                                                 {}    # pop the extra 0
                                                    <> # switch stacks

Part 2 (at this point, everything is duplicated in reverse order):
{({}<>)<>}<>

{        }   # for every letter:
 ({}<>)      # move the top letter to the other stack
       <>    # and switch back
          <> # Finally switch stacks and implicitly print


1

V 10 байтов

ͨ.©±½/±±

TryItOnline

Просто найдите и замените регулярное выражение, как и все остальные в теме. Единственное отличие состоит в том, что я могу заменить все, что потребует \перед ним символ с тем же значением ascii, но с установленным старшим битом. (Итак (, 00101000 становится ¨, 10101000)


1

Perl 6 , 17 байт

s:g/(.)$0?/$0$0/

с ключом командной строки -p

Пример:

$ perl6 -pe 's:g/(.)$0?/$0$0/' <<< 'AAABBBCCCCDDDD
> HEY
> AAAAAAA
> N
> OOQQO
> ABBB
> ABBA'
AAAABBBBCCCCDDDD
HHEEYY
AAAAAAAA
NN
OOQQOO
AABBBB
AABBAA

1

Ракетка 261 байт

(let((l(string->list s))(r reverse)(c cons)(e even?)(t rest)(i first))(let p((l(t l))(ol(c(i l)'())))
(cond[(empty? l)(list->string(if(e(length ol))(r ol)(r(c(i ol)ol))))][(or(equal?(i ol)(i l))(e(length ol)))
(p(t l)(c(i l)ol))][(p(t l)(c(i l)(c(i ol)ol)))])))

Ungolfed:

(define (f s)
  (let ((l (string->list s)))
    (let loop ((l (rest l))
               (ol (cons (first l) '())))
      (cond
        [(empty? l)
         (list->string(if (even? (length ol))
                          (reverse ol)
                          (reverse (cons (first ol) ol))))]
        [(or (equal? (first ol) (first l)) 
             (even? (length ol)))
         (loop (rest l) (cons (first l) ol))]
        [else
         (loop (rest l) (cons (first l) (cons (first ol) ol)))] ))))

Тестирование:

(f "ABBBCDDEFFGGG")

Выход:

"AABBBBCCDDEEFFGGGG"

1

05AB1E , 10 байтов

.¡vy¬ygÉ×J

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

объяснение

.¡           # split string into groups of the same char
  v          # for each group
   y         # push the group
    ¬        # push the char the group consists of
     yg      # push the length of the group
       É     # check if the length of the group is odd
        ×    # repeat the char is-odd times (0 or 1)
         J   # join to string

1

Python3, 102 94 байта

from collections import*
lambda s:"".join(c*(s.count(c)+1&-2)for c in OrderedDict.fromkeys(s))

Спасибо xnor за сохранение 8 байт! -> Битхак.


Это не держит буквы в правильном порядке.
xnor

@xnor Спасибо за упоминание! Исправлена.
Yytsi

Выглядит хорошо. Вы можете написать выражение x+x%2как x&-2.
xnor

@xnor Я попытался, s.count(c)&-2и он вернул пустую строку ...: / Есть мысли?
Yytsi

1
О, вы правы, и я ошибся. Я думаю, x+1&-2должен сделать это. Четвёртые идут на себя, а шансы округляются до четных.
xnor

1

R, 81 байт

r=rle(el(strsplit(scan(,""),"")));cat(do.call("rep",list(r$v,r$l+r$l%%2)),sep="")

Читает строку из stdin, разделяется на вектор символов и выполняет кодирование длины строки (rle). Затем повторите каждое значение из rle, сумму длин и мод длины 2.

Если мы можем прочитать ввод, разделенный пробелом (неявно как вектор / массив символов), тогда мы можем пропустить разделительную часть, и программа уменьшит до 64 байтов:

r=rle(scan(,""));cat(do.call("rep",list(r$v,r$l+r$l%%2)),sep="")

1

> <> (Рыба) 39 байт

0v ;oo:~/:@@:@=?!voo
 >i:1+?!\|o !:  !<

Я уверен, что это можно сыграть в гольф, используя другую технику.

Он принимает входные данные и сравнивает их с текущим элементом стека; если он отличается, он напечатает первый элемент стека дважды, если он одинаковый, то они оба будут напечатаны.

Стек, когда пустой, получает 0, который ничего не печатает, поэтому может быть добавлен в любое время.


1

Pyth, 15 байт

Vrz8p*+hN%hN2eN

Проверьте все контрольные примеры здесь.

Спасибо Луису Мендо за методологию.

объяснение

Vrz8p*+hN%hN2eN    z autoinitializes to the input
 rz8               run-length encode the input, returned as list of tuples (A -> [[1,"A"]])
V                  for every element N in this list
      +hN          add the head element of N (the number in the tuple)
         %hN2      to the head element of N mod 2
     *       eN    repeat the tail element of N that many times (the letter in the tuple)
    p              print repeated character without trailing newline

Как это часто бывает, я чувствую, что это может быть короче. Я думаю, что должен быть лучший способ извлечь элементы из списка, чем то, что я использую здесь.


1

PowerShell , 28 байт

$args-replace'(.)\1?','$1$1'

Попробуйте онлайн! (включает все тестовые случаи)

Порт сетчатки ответ . Единственное замечание, которое мы получили $argsвместо обычного $args[0](поскольку мы -replaceбудем выполнять итерацию по каждому элементу во входном массиве, мы можем выйти из индекса), и '$1$1'необходимо использовать одинарные кавычки, чтобы они были заменены регулярным выражением. переменные, а не рассматриваются как переменные PowerShell (что произошло бы, если бы они были в двойных кавычках).


1

C 67 байт

i;f(char*s,char*d){i=*s++;*d++=i;*d++=i;*s?f(i-*s?s:++s,d):(*d=0);}

Звоните с:

int main()
{
    char *in="AAABBBCCCCDDDD";
    char out[128];
    f(in,out);
    puts(out);
}

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.