Удалить дублированный и переключенный случай


27

Цель

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

Пары должны быть заменены слева направо. Например, aAaдолжно стать aaи нет aA.

Примеры

Входы и выходы:

Input:         Output:  
bBaAdD         bad     
NniIcCeE       Nice    
Tt eE Ss tT    T e S t 
sS Ee tT       s E t   
1!1!1sStT!     1!1!1st!
nN00bB         n00b    
(eE.gG.)       (e.g.)  
Hh3lL|@!       H3l|@!
Aaa            Aa
aaaaa          aaaaa
aaAaa          aaaa

Ввод состоит из печатных символов ASCII.

Вы не должны удалять дублирующиеся цифры или другие не буквенные символы.

Подтверждение

Этот вызов противоположен описанному в @nicael «Дублирующему и переключаемому случаю» . Вы можете изменить это?

Спасибо за всех участников из песочницы!

Каталог

Фрагмент стека в нижней части этого поста создает каталог из ответов а) в виде списка кратчайшего решения для каждого языка и б) в качестве общей таблицы лидеров.

Чтобы убедиться, что ваш ответ обнаружен, начните его с заголовка, используя следующий шаблон уценки:

## Language Name, N bytes

где Nразмер вашего представления. Если вы улучшите свой счет, вы можете сохранить старые результаты в заголовке, вычеркнув их. Например:

## Ruby, <s>104</s> <s>101</s> 96 bytes

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

## Perl, 43 + 2 (-p flag) = 45 bytes

Вы также можете сделать имя языка ссылкой, которая будет отображаться во фрагменте кода:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


4
Ха-ха, это NniIcCeE :)
Никель

@nicael Я рад, что вы одобряете :)
aloisdg говорит восстановить Monica

для чего нужен выход abB? abBили ab?
Downgoat

@Downgoat abBдолжен вывестиab
aloisdg говорит восстановить Monica

1
@raznagul с чего бы это? Разделить его: aa; aA; AA, только средняя пара соответствует шаблону и становится a, таким образом aa; a; AA
LLlAMnYP

Ответы:


12

Желе , 8 байт

ṛŒsḟḟȧµ\

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

Как это работает

ṛŒsḟḟȧµ\  Main link. Argument: s (string)

      µ   Convert all links to the left into a chain (unknown arity) and begin a
          new chain.
       \  Do a cumulative reduce by the chain to the left.
          Left argument:   r (previous result or first character)
          Right argument:  c (next character)
ṛ           Set the return value to c.
 Œs         Swap c's case.
    ḟ       Remove c from r (if present).
            This yields an empty string if c and r are identical (repeated letter
            with the same case or non-letter) and r otherwise.
            Note that r will be empty if the previous character has been removed.
   ḟ        Remove the resulting characters (if any) from c with swapped case.
            This yields c with swapped case if the result to the right does not
            contain c; otherwise, it yields the empty string.
     ȧ      Flat logical AND with c.
            Replace swapped case c with c; do not modify an empty string.

Короче, чем Regex, черт побери!
Aloisdg говорит восстановить Монику

2
Удар сетчатки по вызову строки ._.
TuxCrafting

11

Сетчатка , 18 байт

(.)(?!\1)(?i)\1
$1

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

объяснение

Это одиночная (и довольно простая) замена, которая сопоставляет соответствующие пары и заменяет их только первым символом. Пары подбираются путем активации нечувствительности к регистру в середине шаблона:

(.)     # Match a character and capture it into group 1.
(?!\1)  # Use a negative lookahead to ensure that the next character *isn't* the same
        # as the character we just captured. This doesn't advance the position of the
        # regex engine's "cursor".
(?i)    # Now activate case-insensitivity for the remainder of the pattern.
\1      # Match the second character with a backreference to the first. With the i
        # modifier activated, this will match if the two characters only differ
        # by case.

Подстановка просто записывает обратно персонаж, которого мы уже захватили в группе 1.


1
Хороший ответ! Debuggex прекрасно работает с этим!
Aloisdg говорит восстановить Монику

5

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

.v|.l1|hA,?bhB(@uA;A@uB),?bb&~b.hA|?b&~b.h~h?

Brachylog не имеет регулярных выражений.

объяснение

    .v          Input = Output = ""
|               OR
    .l1         Input = Output = string of one character
|               OR
    hA,         A is the first char or the Input
    ?bhB        B is the second char of the Input
    (
        @uA         B uppercased is A
        ;           OR
        A@uB        A uppercased is B
    ),
    ?bb&        Call recursively on Input minus the first two elements
    ~b.hA       Output is the result of that call with A appended before it
|               OR
    b&          Call recursively on Input minus the first element
    ~b.h~h?     Output is the result of that call with the first element of Input appended
                  before it

5

C #, 87 75 байтов

s=>System.Text.RegularExpressions.Regex.Replace(s,@"(.)(?!\1)(?i)\1","$1");

С могущественным регулярным выражением от Мартина Эндера. C # лямбда, где вход и выход string.

Мартин Эндер и TùxCräftîñg сохранили 12 байтов.


C #, 141 134 байта

s=>{var r="";for(int i=0,l=s.Length;i<l;i++){var c=s[i];r+=c;if(char.IsLetter(c)&i+1<l&&(c|32)==(s[i+1]|32)&c!=s[i+1])i++;}return r;};

C # лямбда, где вход и выход string. Алгоритм наивный. Это тот, который я использую в качестве ссылки.

Код:

s=>{
    var r = "";
    for(int i = 0; i < s.Length; i++)
    {
        r+=s[i];
        if (char.IsLetter(s[i]) & i+1 < s.Length)
            if (char.ToLower(s[i])==char.ToLower(s[i+1])
              & char.IsLower(s[i])!=char.IsLower(s[i+1]))
                i += 1;
    }       
    return r;
};

7 байтов благодаря Мартину Эндеру!


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


@ TùxCräftîñg Действительно, но это легко читать, как это. Проверьте мой вариант игры в гольф для менее подробного ответа :)
aloisdg говорит восстановить Monica

4

Perl, 40 24 + 1 = 25 байт

Используйте то же регулярное выражение, что и у Мартина.
Используйте -pфлаг

s/(.)(?!\1)(?i)\1/\1/g

Проверьте это на Ideone


Если вы используете флаг -p, вы можете удалить почти весь ваш код, за исключением s /// для хорошего сохранения!
Дом Гастингс


4

C 66 байтов

l;main(c){for(;~(c=getchar());)l=l^c^32|!isalpha(c)?putchar(c):0;}

3

Pyth, 24 20 байт

4 байта благодаря @Jakube.

Это все еще использует регулярное выражение, но только для токенизации.

shM:zj\|+s_BVGrG1\.1

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

shM:zj\|+s_BVGrG1\.1   input as z
         s_BVGrG1      generate ['aA', 'Aa', 'bB', 'Bb', ..., 'zZ', 'Zz']
        +        \.    add "." to the back of the array
     j\|               insert "|" between every element of the array,
                       forming a new long string, which will be our
                       tokenizer: "aA|Aa|bB|Bb|cC|Cc|...|yY|Yy|zZ|Zz|."
                       the "." at the end is to capture the remaining characters
  :z               1   return all matches of z against that regex
                       this is effectively a tokenizer
 hM                    take the first character of each token
s                      join all the transformed tokens together, and then
                       implicitly print to STDOUT.

3

JavaScript (ES6), 71 68 байт

s=>s.replace(/./g,c=>l=c!=l&&c>'0'&&parseInt(c+l,36)%37<1?'':c,l='')

Объяснение:

s=>s.replace(/./g,c=>   Loop over each character in the string
 l=                     Save result for next loop
  c!=l&&                Check whether characters differ
  c>'@'&&               Check minimum character code
  parseInt(c+l,36)%37<1 Check if characters have same value
  ?'':c,                If so then delete this character
 l='')                  Initial empty previous character

Учитывая c>'@', что единственный способ parseInt(c+l,36)быть кратным 37 - это оба cи lиметь одно и то же значение (они не могут иметь нулевое значение, потому что мы исключили пробел и ноль, и если они не имеют значения, выражение будет оценивать, NaN<1какое ложь) для них должно быть одно и то же письмо. Однако мы знаем, что они не одинаковы с учетом регистра, поэтому они должны быть одинаковыми без учета регистра.

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

Редактировать: 3 байта сохранены благодаря @ edc65.


Используйте замену вместо карты. 68. Но я слишком ленив, чтобы понять, как поместить '`' в комментарий (хороший трюк, мод 37)
edc65

@ edc65 Мне не нужны `s, если я использую replace. (У меня были только они, прежде чем пытаться быть последовательными, но затем я проиграл свой ответ, редактируя его для представления, и снова стал непоследовательным. Вздох ...)
Нил

3

C, 129 127 125 107 106 105 93 92 90 88 85 78 байтов

c;d;f(char*s){for(;putchar(c=*s);)s+=isalpha(c)*(d=*++s)&&(!((c^d)&95)&&c^d);}

AC порт моего C # ответа . Мой C может быть немного плохим. Я больше не пользуюсь языком. Любая помощь приветствуется!

  • 1 байт сохранен благодаря Lowjacker в уловке : a!=b=a^b
  • 1 байт сохранен благодаря Walpen в уловке : a&&b=a*b
  • 12 байтов, спасенных трюком Линн и вдохновленных здесь TùxCräftîñg
  • 1 байт сохранен благодаря трюку Джои Адамса и вдохновлен здесь orlp: Перемещение переменной в глобальный
  • 2 байта сохранены SEJPM, решая мою побитовую (c|32)==(d|32)проблему
  • 5 байтов сохранены Pietu1998

Код:

c;d;f(char*s) {
    for(;putchar(c=*s);)
        s+=isalpha(c)*(d=*++s)&&(!((c^d)&95)&&c^d);
}

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


1
Я думаю, что вы можете увеличить указатель, чтобы сохранить несколько байтов. Я нашел это (не проверено):f(char*s){while(*s) {char c=*s,d=s+1;putchar(c);s+=isalpha(c)&&d&&((c|32)==(d|32)&&c!=d);}}
TuxCrafting

@ TùxCräftîñg Я забыл об этом. Я исправил ваше предложение, основываясь на ответе Линн. Спасибо вам за помощь!
говорит aloisdg Восстановить Монику

1
Я думаю, что вы можете изменить s+++1на ++s.
PurkkaKoodari

@ Pietu1998 Действительно, я могу!
говорит aloisdg Восстановить Монику

1
cи dвсегда будет для печати ASCII, поэтому 95должен работать вместо ~32. Кроме того, я думаю, что c;d;f(char*s){for(;*s;){putchar(c=*s);s+=isalpha(c)*(d=*(++s))&&(!((c^d)&95)&&c^d);}}будет работать (но не проверено).
PurkkaKoodari

3

MATL , 21 байт

"Kk@k=K@XK=>?4XKx}K&h

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

объяснение

Это обрабатывает каждый символ в цикле. Каждая итерация сравнивает текущий символ с предыдущим. Последний хранится в буфере обмена K, который 4по умолчанию инициализируется.

Текущий символ сравнивается с предыдущим дважды: сначала без учета регистра, а затем с учетом регистра. Текущий символ должен быть удален, если и только если первое сравнение было истинным, а второе - ложным. Обратите внимание, что, поскольку буфер обмена K изначально содержит 4, первый символ всегда будет сохранен.

Если текущий символ удален, буфер обмена K должен быть сброшен (поэтому следующий символ будет сохранен); в противном случае он должен быть обновлен текущим символом.

"            % Take input string implicitly. For each char from this string:
  K          %   Push previous char, initiallized to number 4
  k          %   Convert to lower case. For numbers it rounds down
  @          %   Push current char
  k          %   Convert to lower case. 
  =          %   True if current and previous chars are (case-insensitively) equal
  K          %   Push previous char
  @          %   Push current char
  XK         %   Update clipboard K with current char. This doesn't affect the stack
  =          %   True if current and previous chars are (case-sensitively) equal
  >?         %   If first comparison was true and second was false
    4XKx     %     Reset clipboard K to 4
  }          %   Else
    K        %     Push previous char
    &h       %     Concatenate horizontally to gradually build the output string

2

Java 7, 66 байт

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

Использовал регулярное выражение Мартина Эндера из своего ответа на Retina .

Ungolfed & тестовый код:

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

class Main{
  static String c(String i){
    return i.replaceAll("(.)(?!\\1)(?i)\\1", "$1");
  }

  public static void main(String[] a){
    System.out.println(c("bBaAdD"));
    System.out.println(c("NniIcCeE"));
    System.out.println(c("Tt eE Ss tT"));
    System.out.println(c("sS Ee tT"));
    System.out.println(c("1!1!1sStT!"));
    System.out.println(c("nN00bB"));
    System.out.println(c("(eE.gG.)"));
    System.out.println(c("Hh3lL|@!"));
    System.out.println(c("Aaa"));
    System.out.println(c("aaaaa"));
    System.out.println(c("aaAaa"));
  }
}

Выход:

bad
Nice
T e S t
s E t
1!1!1st!
n00b
(e.g.)
H3l|@!
Aa
aaaaa
aaaa

2

JavaScript (ES6), 61 байт , 57 байт

s=>s.replace(/./g,c=>l=c!=l&/(.)\1/i.test(l+c)?'':c,l='')

Спасибо Нилу за сохранение 5 байтов.


1
Плохая новость: вы ошиблись, и это на самом деле 62 байта. Хорошие новости: я могу сэкономить вам пять байтов! s=>s.replace(/./g,c=>l=c!=l&/(.)\1/i.test(l+c)?'':c,l='')
Нил

Ой, извини, я посчитал "code".length, что не понял, что там была последовательность побега. Спасибо
cPu1

Попробуйте использовать (code).toString().length.
Нил

Да, или(code+"").length
cPu1

1

JavaScript (ES6) 70

(s,p,q)=>s.replace(/./g,c=>p!=c&q===(d=parseInt(c,36))?q='':(q=d,p=c))

f=(s,p,q)=>s.replace(/./g,c=>p!=c&q===(d=parseInt(c,36))?q='':(q=d,p=c))

;
[['bBaAdD','bad']
,['NniIcCeE','Nice']
,['Tt eE Ss tT','T e S t']
,['sS Ee tT','s E t']
,['1!1!1sStT!','1!1!1st!']
,['nN00bB','n00b']
,['(eE.gG.)','(e.g.)']
,['Hh3lL|@!','H3l|@!']
,['Aaa','Aa']
,['aaaaa','aaaaa']
,['aaAaa','aaaa']]
.forEach(
  x=>
  {
    var i=x[0],k=x[1],r=f(i)
    console.log(k==r?'OK':'KO',i,r)
  }
)


Хорошо, я укушу Почему то ===?
Нил

0==""но не 0===""@Neil
edc65

1

Выпуклый, 18 байт

V±V.+'.+'|*\ô{0=}%

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

Такой же подход, как и у @Leaky Nun's Pyth answer . Он создает массив ["aA" "bB" ... "zZ" "Aa" "Bb" ... "Zz" '.], объединяет его по '|символу и проверяет входные данные на основе этого регулярного выражения. Затем он берет первый символ каждого матча.

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