Что моя собака действительно слышит


83

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

Rex, I told you not to do this! You're making me angry Rex!

все что он слышит

Rex, * **** *** *** ** ** ****! ***'** ****** ** ***** Rex!

Задача : с учетом входной строки ваша программа должна вывести ту же строку, где все буквенные символы были превращены в звезды, кроме символов в появлении слова Rex, которые должны быть оставлены нетронутыми. Неалфавитные символы также остаются нетронутыми.

Детали : Задача не зависит от регистра, поэтому также rexдолжна быть оставлена ​​нетронутой. Слово Rexможет быть частью другого слова, поэтому, например, anorexicдолжно отображаться как ***rex**.

Обновление : поскольку в первоначальном тексте этого задания не разъяснялось, как следует обращаться с подчеркиванием, цифрами или выделенными символами, я не предъявляю особых требований к этим символам. Таким образом, решение является действительным до тех пор, пока символы в a-zA-Z(а также символы, упомянутые в примерах ,!".) обрабатываются правильно.

Тестовые случаи:

Вход: Rex lives in Rexland.

Выход : Rex ***** ** Rex****.

Вход: To call Rex, just say "Rex".

Выход : ** **** Rex, **** *** "Rex".

Вход: My cat is getting anorexic.

Выход : ** *** ** ******* ***rex**.


27
Тестовый пример: Hello! Isn't this ... a nice challenge?Вы слышите собаку *****! ***'* *** ... * **** *********?? Если это так, то вы могли бы рассмотреть общение в азбуке отныне ...
Стьюи Гриффин

2
Нужно ли нам только поддерживать a-zA-Z, а также 0-9и / или äëïöüÿãõñáéíóúýàèìòùçт. Д. И т. Д.? И не могли бы вы добавить несколько тестов по этому поводу?
Кевин Круйссен

2
@KevinCruijssen Поскольку $ 0-9 $ или акцентированные символы не упоминаются в первоначальном соревновании, не рассматривайте их как часть соревнования.
Эван Деланой

7
Поскольку «собаки не получают разницы между строчными и прописными буквами» , может ли выходной регистр отличаться от входного? (Например: input = "Rex lives in Rexland.", output = "rex ***** ** rex****."; или в качестве альтернативы input = "My cat is getting anorexic.", output = "** *** ** ******* ***Rex**.")
Джонатан Аллан

5
Почему этот вызов использовал звездочки вместо "бла"?
hBy2Py

Ответы:


25

Retina , 24 21 байт

i`(rex)|(\w)
$1$#2$**

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

объяснение

Пропускать rexs проще всего, сопоставляя их, потому что совпадения не могут перекрываться. Поэтому, если мы отдадим приоритет rexнад другими буквами, они будут охвачены в одном совпадении и не затронуты сопоставлениями из отдельных букв.

Но как мы можем делать разные вещи в зависимости от альтернативы, которая использовалась для матча? К сожалению, Retina (пока) не имеет синтаксиса условных подстановок, таких как Boost regex. Но мы можем подделать его, включив обе замены в одну замену и убедившись, что только одна из них не пуста:

  • $1первая группа захвата, то есть (rex). Если мы нашли совпадение, rexэто просто записывает его обратно (так что ничего не делает), но если мы не совпали, rexтогда $1пустая строка исчезает.
  • $#2$**следует читать как ($#2)$*(*). $#2это количество раз группы 2было использовано, то есть (\w). Если мы сопоставили rexэто 0, но если мы сопоставили любое другое отдельное письмо, это так 1. $*повторяет следующий символ столько раз, сколько его левый операнд. Таким образом, эта часть вставляет сингл *для индивидуально-буквенных совпадений и ничего для rex.

Нет сетчатки \aдля [a-z]ZB?
Утренняя монахиня

@ LeakyNun нет. Я должен был бы маркировать регулярное выражение (или даже реализовать свой собственный аромат), чтобы добавить какие-либо функции к самому вкусу регулярного выражения.
Мартин Эндер

163

** REXX 151 148 141 байт **

(Kinda показался уместным)

i=arg(1)
m=i
o=translate(m,'',xrange('A','z'),'*')
p=0
do forever
   p=pos('REX',m,p+1)
   if p=0 then leave
   o=overlay(substr(i,p,3),o,p)
end
say o

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

Примечания для не REXXers:

  1. translate - это функция замены символов (имя происходит из инструкции на ассемблере в IBM MF). Он ищет в строке1 символы в строке3. Каждый раз, когда он находит один, он заменяет его на тот же позиционированный в string2. Если string2 слишком короткая, она дополняется символом pad.

Смотрите здесь для функции перевода

  1. оверлей просто накладывает string1 поверх string2 в указанной позиции.

Смотрите здесь для наложения функции


52
... но собака думала, что он запрограммировал это в REX *.
GuitarPicker

10
Сколько из этих возражений чисто для выбора языка ?! : D
Лохматый

72
@Shaggy По крайней мере, все из них
TheLethalCoder

24

JavaScript (ES6), 42 41 38 байт

s=>s.replace(/rex|\w/gi,m=>m[1]?m:"*")

Попробуй

o.innerText=(f=

s=>s.replace(/rex|\w/gi,m=>m[1]?m:"*")

)(i.value="Rex, I told you not to do this! You're making me angry Rex!")
oninput=_=>o.innerText=f(i.value)
<input id=i><pre id=o>


объяснение

s=>            :Anonymous function that takes the string as an argument via parameter s.
s.replace(x,y) :Replace x in s with y.
/rex|\w/gi     :Case-insenstive regular expression that globally matches all occurrences
                of "rex" or any single letter, number or underscore.
                (numbers & underscores will never be included in the input.)
m=>            :Anonymous function that takes each match as an argument via parameter m.
m[1]?          :If string m has a second character, ...
                (Equivalent to m.charAt(1))
m              :Return m, ...
:"*"           :Otherwise return "*".


1
Хорошее решение!
Стив Беннетт

13

APL (Dyalog Unicode) , 22 байта SBCS

'rex' '\w'R'\0' '*'1

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

Простая замена PCRE R

⍠1устанавливает регистронезависимость. Просто заменяет rexсобой и всеми остальными символами слова звездочки.


\wвключает символ подчеркивания, предполагая, что это RegEx - я не знаю APL.
Лохматый

@ Shaggy Да, Dyalog APL использует PCRE, но из ОП не ясно, что произойдет подчеркивание. Например, цифр не будет.
Адам

Разве мы не должны предполагать, что они могут произойти, если не сказано иное?
Лохматый

@ Shaggy Обычно да, но это, кажется, указывает на то, что то, что не упомянуто, не произойдет. В OP упоминаются только запятая, точка, пробел и восклицательный знак.
Адам

Хм ... Думаю, я подожду подтверждения, что они не произойдут, потому что я оставил этот комментарий о \wнескольких ответах сейчас!
Лохматый

11

Perl 5 , 24 байта

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

Я использовал регулярное выражение Мартина Эндера из его ответа на Retina (который в Perl оказался короче, спасибо \pl), и мне нужно было только адаптировать правую сторону s ///.

s%(rex)|\pl%$1//"*"%gie

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


8

Retina , 32 31 байт

iS`(rex)
%iT`Ll`*`^(?!rex).*
¶

Попробуйте онлайн! Объяснение: разбивает строку на вхождения слова rexи всего остального, но сохраняет совпадения. Затем в строках, которые не начинаются rex(т. Е. «Все остальное»), измените буквы на *s. Наконец, объедините все вместе.


3
По крайней мере, это второй раз, когда я думаю, что режим транслитерации может использовать опцию для транслитерации несоответствий ...
Мартин Эндер

@MartinEnder слишком поздно :-D
Джон Дворжак

8

C, 99 97 92 86 74 73 72 65 байт

f(char*s){*s&&f(s+=strnicmp("Rex",s,3)?!isalpha(*s)||(*s=42):3);}

Среда Pelles IDE предоставляет (компилировать с / Go) функцию strnicmp. Эта функция идентична strncasecmp. Посмотрите, как это работает здесь (с функцией замены).

Выход сохраняется в первом параметре, который является параметром входа / выхода.

Спасибо Johan du Toit за сообщение, что рекурсия немного короче.


Существует среда C, которая предоставляет strncmpi, так что вы можете получить ее в 69. ​​У меня есть это на CD.
Джошуа

1
@ Джошуа Спасибо. Что такое CD?
2501

Borland C ++ 4.5
Джошуа

7

Рубин, 36 35 32 байта

->s{s.gsub(/(rex)|\w/i){$1||?*}}

В качестве теста:

f=->s{s.gsub(/(rex)|\w/i){$1||?*}}

tests = [
  ["Rex, I told you not to do this! You're making me angry Rex!", "Rex, * **** *** *** ** ** ****! ***'** ****** ** ***** Rex!"],
  ["Rex lives in Rexland.", "Rex ***** ** Rex****."],
  ["To call Rex, just say \"Rex\".", %q(** **** Rex, **** *** "Rex".)],
  ["My cat is getting anorexic.", "** *** ** ******* ***rex**."]
] 

tests.each do |input, output|
  if f.call(input) == output
    puts "Fine for #{input.inspect}"
  else
    puts "Problem with :\n#{input.inspect}"
    puts f.call(input)
    puts output
  end
  puts
end

Это выводит:

Fine for "Rex, I told you not to do this! You're making me angry Rex!"

Fine for "Rex lives in Rexland."

Fine for "To call Rex, just say \"Rex\"."

Fine for "My cat is getting anorexic."

6

PHP, 78 байт

<?=preg_replace("#[a-df-qs-wyz]|r(?!ex)|(?<!r)e|e(?!x)|(?<!re)x#i","*",$argn);

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

PHP, 84 байта

<?=preg_replace_callback("#(rex)|\pL#i",function($t){return$t[1]?$t[1]:"*";},$argn);

-1 байт \wвместо этого \plв этом случае подчеркивание и цифры тоже заменяются

\pLкороче как [a-z]или[[:alpha:]]

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


Вы можете использовать \wвместо \pL.
Адам

@ Adám Спасибо, это делает мой более длительный подход только на 1 байт короче и не совсем понятнее, что следует делать в случае подчеркивания или числа
Йорг Хюльсерманн

На входе никогда не будет
символов

@ Adám Я сделал для этого дополнительное замечание и отредактировал более длинный подход, почему я нашел другое улучшение
Йорг Хюльсерманн

5

C (GCC на POSIX), 167 118 93 87 байт

i,j;f(char*s){for(i=0;j=s[i];i++)strncasecmp("Rex",s+i,3)?s[i]=isalpha(j)?42:j:(i+=2);}

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


f(char*s){for(;*s;s++)strncasecmp("Rex",s,3)?putchar(isalpha(*s)?42:*s):write(1,s-2,3,s+=2);}, Что это за колдовство f(s)char*s;{}? Я никогда не видел этот синтаксис раньше.
Кристоф

О, у него был другой параметр, но я забыл его удалить.
betseg

Не работает правильно, потому что работает только первый вызов функции. Смотрите здесь: tio.run/nexus/… Решения в функциональной форме, такие как эта, должны иметь возможность вызываться снова и давать правильные результаты.
2501

@ 2501 спасибо, исправлено.
betseg

5

Python 2 или 3, 75 73 70 байт

import re;f=lambda s:re.sub('(?i)(rex)|\w',lambda x:x.group(1)or'*',s)

В основном так же, как ответ моего Руби .

-2 байта благодаря @Wondercricket.

В качестве теста:

tests = [
  ["Rex, I told you not to do this! You're making me angry Rex!", "Rex, * **** *** *** ** ** ****! ***'** ****** ** ***** Rex!"],
  ["Rex lives in Rexland.", "Rex ***** ** Rex****."],
  ["To call Rex, just say \"Rex\".", "** **** Rex, **** *** \"Rex\"."],
  ["My cat is getting anorexic.", "** *** ** ******* ***rex**."]
]


for test_in, test_out in tests:
    print(test_in)
    print(f(test_in))
    print(f(test_in) == test_out)

1
Вы можете сэкономить 2 байта, удалив интервал междуx.group(1) or '*'
Wondercricket

@Wondercricket: Большое спасибо, это мой первый ответ по гольфу на Python.
Эрик

5

Ява 8, 187 192 168 164 159 138 байт

s->{for(int i=0;i<s.length();System.out.print(s.regionMatches(0<1,i,"rex",0,3)?s.substring(i,i+=3):s.replaceAll("\\w","*").charAt(i++)));}

-28 байт благодаря @ OlivierGrégoire.

Объяснение:

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

s->{                         // Method with String parameter and no return-type
  for(int i=0;i<s.length();  //  Loop over the characters of the input-String
    System.out.print         //   Print:
     s.regionMatches(1>0,i,"rex",0,3)? 
                             //    If we've found "rex" (case-insensitive):
      s.substring(i,i+=3)    //     Print this REX-word (case-sensitive)
     :                       //    Else:
      s.replaceAll("\\w","*").charAt(i++));
                             //     Print the current character,
                             //     or '*' if it's an alpha-numeric character

@ Shaggy Должен быть исправлен сейчас. Это было опубликовано до того, как было указано в комментариях, что 0-9и акцентированные символы не должны быть включены, только a-zA-Zдолжны.
Кевин Круйссен

Не могли бы вы заменить "[a-zA-z]"на /[a-z]/i?
Лохматый

@ Шэгги Да / нет. Java использует немного другой синтаксис регулярных выражений, чем, например, python или C #. Так что да, можно использовать регулярное выражение без учета регистра, но оно будет на один байт длиннее: "[a-zA-Z]"-> "(?i)[a-z]".
Кевин Круйссен

1
Я думаю, что вы должны использовать s.regionMatches(0<1,i,"rex",0,3)вместо s.toLowerCase().substring(i,i+(i>l-3?1:3)).equals("rex").
Оливье Грегуар

1
@KevinCruijssen Возьмите текущий код, который у вас есть (168 байт), удалите переменную lи сохраните 4 байта.
Оливье Грегуар

4

Python 2, 87 байт

import re
print re.sub(r'(?i)[a-df-qs-wyz]|r(?!ex)|(?<!r)e|e(?!x)|(?<!re)x','*',input())

Я думаю, что можно сократить? :)


1
Вы можете избавиться от пробелов после запятых между аргументами на 2 байта.
Mego


3

Гема, 25 знаков

/[rR][eE][xX]/=$0
<L1>=\*

Образец прогона:

bash-4.3$ gema '/[rR][eE][xX]/=$0;<L1>=\*' <<< "Rex, I told you not to do this! You're making me angry Rex!
Rex lives in Rexland.
To call Rex, just say \"Rex\".
My cat is getting anorexic."
Rex, * **** *** *** ** ** ****! ***'** ****** ** ***** Rex!
Rex ***** ** Rex****.
** **** Rex, **** *** "Rex".
** *** ** ******* ***rex**.

Больно факт, что может быть \CRex=$0;<L1>=\*, но, к сожалению, $0содержит шаблон, а не совпадение. ☹


3

Сетчатка , 54 50 49 байтов

Гольф 5 байтов благодаря @MartinEnder

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

i(`[\w-[rex]]
*
(?<!r)e|e(?!x)|r(?!ex)|(?<!re)x
*

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


@Emigna Только что понял, что мое решение не работает dex, оно дает, *e*а ваше дает **x.
Критиси Литос

Если вы группируете оба этапа, ставя (после первого, iвам не нужно настраивать второй этап.
Мартин Эндер

И ваше первое регулярное выражение может быть записано как [a-z-[rex]].
Мартин Эндер

@MartinEnder Спасибо, это первый раз, когда я вижу классы персонажей, где вы можете исключить определенных персонажей
Kritixi Lithos

они существуют в нескольких вариантах, но я считаю, что синтаксис .NET для них уникален.
Мартин Эндер

3

PowerShell, 60 байт

{$args|%{$_-replace'(rex)|\p{L}','$1*'-replace'(x)\*','$1'}}

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


Моя вина. Я заменил \wна \p{L}.
Андрей Одегов

Интересная идея. Обратите внимание, что использование $argsв качестве массива имеет последствия при цитировании, как в одном примере. И если вы все равно используете только первый аргумент, вам не нужно foreach.
Джои

@AndreiOdegov Вы можете вернуться к \w. Примечание: \p{L}действительно ли нужны брекеты ?
Адам

1
очень хороший Regex, "$args"-replace'(rex)|\p{L}','$1*'-replace'(x)\*','$1'намного короче в целом, завершение $argsв кавычки превращает все это в одну строку и экономит вам много.
colsw

@ Adám Требуются фигурные скобки в .NET.
Андрей Одегов


2

MATL , 24 байта

42y3Y2mFGk'rex'Xf!3:q+((

Входные данные - это строка, заключенная в одинарные кавычки.

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

объяснение

Рассмотрим вход 'Rex lives in Rexland.'

42    % Push 42 (ASCII for '*')
      % STACK: 42
y     % Implicit input. Duplicate from below
      % STACK: 'Rex lives in Rexland.', 42, 'Rex lives in Rexland.'
3Y2   % Push string 'ABC...YZabc...yz'
      % STACK: 'Rex lives in Rexland.', 42, 'Rex lives in Rexland.', 'ABC...YZabc...yz'
m     % Ismember
      % STACK: 'Rex lives in Rexland.', 42, [1 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 0]
F     % Push false
      % STACK: 'Rex lives in Rexland.', 42, [1 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 0], 0
Gk    % Push input lower-cased
      % STACK: 'Rex lives in Rexland.', 42, [1 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 0], 0, 'rex lives in rexland'
'rex' % Push this string
      % STACK: 'Rex lives in Rexland.', 42, [1 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 0], 0, 'rex lives in rexland', 'rex'
Xf!   % Strfind and transpose: gives indices of matchings as a column vector
      % STACK: 'Rex lives in Rexland.', 42, [1 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 0], 0, [1; 14]
3:q   % Push [0 1 2]
      % STACK: 'Rex lives in Rexland.', 42, [1 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 0], 0, [1; 14], [0 1 2]
+     % Addition, element-wise with broadcast
      % STACK: 'Rex lives in Rexland.', 42, [1 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 0], 0, [1 2 3; 14 15 16]
(     % Assignment indexing: sets indicated entries to 0
      % STACK: 'Rex lives in Rexland.', 42, [0 0 0 0 1 1 1 1 1 0 1 1 0 0 0 0 1 1 1 1 0]
(     % Assignment indexing: sets indicated entries to 42 (that is, '*'). Implicit display
      % 'Rex ***** ** Rex****.'


2

Perl, 31 байт

s/(rex)|[a-z]/$1||"*"/ieg;print

Вызвать Perl с -nопцией. Например:

echo 'To call rex, just say "Rex".'| perl -ne 's/(rex)|[a-z]/$1||"*"/ieg;print'
** **** rex, **** *** "Rex".

[a-z]теперь может быть заменено на, так \wкак ввод никогда не будет содержать чисел или подчеркиваний.
Лохматый

Вы можете использовать -pвместо -nи удалить;print
wastl

2

Баш , 128 байт

r=REXrex;a=`tr -c $r'",. !
' l<<<$1`;for i in {r,R}{e,E}{x,X};{
a=`echo ${a[@]//$i/$(tr $r f-k<<<$i)}`;}
tr $r l<<<$a|tr f-l $r*

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

Я придерживаюсь tr в моем предыдущем ответе: не функциональная замена массива bash, а не замена preg!

Менее гольф:

    a=`echo $1 |tr -c 'REXrex.,\"! ' 'z'`;        -> a replaces with z chars in input not matching REXrex or punctuation
    for i in {r,R}{e,E}{x,X}; {                   -> iterates over rex .. rEx .. REX
      j=$(tr 'REXrex' 'ABCabc' <<<$i)}            -> holds a for r, A for R, ando so on
      a=`echo ${a[@]//$i/$j`;                     -> replace each combination of rex .. rEx .. REX with abc ... aBc.. ABC
    }
    tr 'REXrex' 'z' <<<$a |tr 'ABCabcz' 'REXrex*' -> replaces each remainig r,e,x,R,E,X with z and finally each ABC with REX and z with *

Пришлось использовать z вместо * из-за расширения


2
выглядит его не правильным инструментом: P
marcosm

1
Вы можете сохранить пару символов, не заключая в trкавычки параметры, если они не содержат ничего расширяемого.
manatwork

Что касается вашего другого ответа bash: не стесняйтесь исправлять, а затем пометьте мод, обращающийся с просьбой об удалении.
Rɪᴋᴇʀ

1
Опять же, есть довольно много рекс для r=REXrexпеременной стоимости.
manatwork

Если вы храните $ r вне строки в кавычках, вам не нужно менять окружение 'на ", поэтому не нужно экранировать литерал ". Конечно, тогда вы пишете дословный перевод строки разрыва строки в этом месте вместо \n: $r'",. !␤'.
manatwork

2

Java 7, 96 98 97 96 байт

+2 байта для пропущенных e, предшествующих r или сопровождаемых x, но не обоими

-1 байт для перехода [a-z&&[^rex]]на(?![rex])\\w

String a(String s){return s.replaceAll("(?i)r(?!ex)|(?<!r)e|e(?!x)|(?<!re)x|(?![rex])\\w","*");}

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

Версия регулярного выражения для замены с использованием Java

Все в этом регулярном выражении заменяется на * (примечание в Java \ w должно быть экранировано как \\ w)

(?i)r(?!ex)|(?<!r)e|e(?!x)|(?<!re)x|(?![rex])\w

(?i)                                                   // Case Insensitive
    r(?!ex)                                            // Any r not followed by ex
           |(?<!r)e                                    // Or any e not preceded by r
                   |e(?!x)                             // Or any e not followed by x
                          |(?<!re)x                    // Or any x not preceded by re
                                   |(?![rex])\w        // Or any other word character

2

C #, 93 90 байт

s=>System.Text.RegularExpressions.Regex.Replace(s,"(?i)rex|\w",m=>m.Length>1?m.Value:"*");

Поверьте, это первый раз, когда я использовал регулярное выражение в ответе на C # из-за длинного пространства имен System.Text.RegularExpressions.


Я не осознавал этого, когда писал свой ответ, но это, похоже, версия C # ответа @ Shaggy's JavaScript .


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

@ Shaggy Ах, спасибо, не знал, что это было обновлено
TheLethalCoder

1

CJam , 39 байт

q{_3<_el"rex"=3{elc_'{,97>&'*@?1}?\o>}h

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

Как это устроено

q           e# Read the input.
{           e# Do:
 _3<        e#  Copy the string and get its first three characters.
 _el"rex"=  e#  Check case-insensitively if they equal "rex".
  3         e#   If they do, push 3.
  {         e#   If they don't:
   elc_     e#    Take the first character of the three, and make it lowercase.
   '{,97>&  e#    Take its set intersection with the lowercase alphabet. Returns a non-empty
            e#      string (truthy) if it's a letter or an empty string (falsy) if not.
   '*@?     e#    Push a * if the char is a letter, or itself if it's not.
   1        e#    Push 1.
  }?        e#  (end if)
 \o         e#  Print the second-from-the-top stack item.
 >          e#  Slice the string after the first 3 or 1 characters, depending on previous outcome.
}h          e# Repeat the above until the string is empty.

1

VimScript, 34 байта

s/\v(rex|r@<=ex|(re)@<=x)@!\w/*/gi

И вот интересная замена, которая почти работает:

s/\vr(ex)@!|<e|<x|[rex]@!\w/*/gi

Представьте, что вы выполняете это несколько раз в строке. Rex, dex, I told you not to do this! You're making me angry Rex!После первой строки, строка будет Rex, *ex, * **** *** *** ** ** ****! ***'*e ****** *e ***** Rex!Второй проход закончится Rex, **x, * **** *** *** ** ** ****! ***'** ****** ** ***** Rex!, и третий проход завершит его. Любые последующие проходы не изменят строку. Однако для этого может потребоваться более 3 подстановок, например, для строки xxxxxxxx. Таким образом, если бы существовал простой способ выполнить вышеуказанную замену, пока она не перестала что-либо менять, или столько раз, сколько длина ввода, это было бы другим решением. Могу поспорить, что это может быть сделано в V, но это, вероятно, будет длиннее, чем 34 байта.


Спасибо за идею! Вот V ответ . :)
DJMcMayhem

1

Желе , 23 байта

В течение 24 часов нет ответа на мой вопрос по делу , поэтому я опубликую эти предварительные 23 байта.

“rex”
Œlœṣ¢µØaW;”*yµ€j¢

Смотрите тестовые примеры на сайте Try it online!

Как?

“rex” - Link 1, get "rex": no arguments
“rex” - literal "rex"

Œlœṣ¢µØaW;”*yµ€j¢ - Main link: string s (or list of characters)
Œl                - convert s to lowercase
    ¢             - call the last link (1) as a nilad (get "rex")
  œṣ              - split left (s) at sublists equal to right ("rex")
     µ            - call the result t
             µ€   - for each word, w, in t:
      Øa          -   literal: lowercase alphabet
        W         -   wrap it in a list
          ”*      -   literal: '*'
         ;        -   concatenate the wrapped alphabet with the asterisk
            y     -   translate: replace all lowercase letters with asterisks.
                ¢ - call the last link (1) as a nilad (get "rex")
               j  - join left (translated, split text) with copies of right ("rex")

Я не уверен, что это действительно. Это не соответствует тестовым случаям.
Okx

Смотрите мою записку справа вверху и мой вопрос к ОП.
Джонатан Аллан

(хотя, к сожалению, комментарий, который я связал с тем, что ОП сказал, что «собаки не понимают разницы между строчными и прописными буквами», теперь пропал)
Джонатан Аллан

1

CJam , 26 байт (в верхнем регистре) / 36 байт (с учетом регистра)

qeu"REX":R/{__el-'*@?}f%R*

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

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

q_32f&:i\eu"REX":R/{__el-'*@?}f%R*.|

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

Кстати, при написании этого ответа я обнаружил то, что я бы посчитал ошибкой проектирования в CJam: побитовые операторы &и |они не определены между двумя значениями символов, поэтому я не могу использовать .|для получения побитового ИЛИ двух строк. Решение, которое в итоге обошлось мне в два дополнительных байта, состоит в том, чтобы сначала преобразовать одну из строк :iв массив целых чисел, который затем можно ORed с другой строкой. (На самом деле это стоило мне трех байтов, потому что, если бы &работало между двумя символами, я мог бы также использовать Sf&вместо того, 32f&чтобы сохранить информацию о регистре букв.)

С другой стороны, я обнаружил, что он {...}f%действительно работает, как и ожидалось, для перебора символов в массиве строк. Приятно.

В любом случае, вот (слегка) закомментированная версия 36-байтового кода:

q                                       "read input";
 _32f&:i\                               "save the case bit of each input char";
         eu"REX":R/                     "uppercase input and split it on 'REX'";
                   {                    "start code block:"
                    __el-'*@?           "c = (c != lowercase(c) ? '*' : c)";
                             }f%        "apply block to chars in each substring";
                                R*      "join the substrings with 'REX' again";
                                  .|    "bitwise OR the case bits back in";

Трюк с сохранением регистра работает, потому что регистр букв ASCII определяется исключительно пятым битом кода ASCII: этот бит равен 0 для прописных букв и 1 для строчных букв. Таким образом, взятие поразрядного И для символа кода с 32 = 2 5 извлекает бит регистра, а побитовое ИЛИ с использованием букв в верхнем регистре восстанавливает их первоначальный регистр.

Конечно, неалфавитные символы могут иметь произвольные значения для пятого бита (хотя из-за того, как организованы символы ASCII, большинство символов пунктуации имеют пятый бит, установленный в 1), но это не имеет значения, поскольку эти символы остаются в любом случае, не затрагивается заглавными буквами и циклом цензуры букв, и если OR для символа с его собственным пятым битом не изменит его. Кроме того, удобно, что у *персонажа уже установлен пятый бит, поэтому он также остается неизменным в финале .|.


1

Пип , 21 19 байт

qR-`(rex)|\w`{b|'*}

Принимает ввод из stdin, выводит в stdout. Попробуйте онлайн!

объяснение

q                    Read a line of stdin
 R                   and replace
   `(rex)|\w`          a regex matching `rex` or any single alphanumeric character,
  -                    case-insensitive
             {    }  with this callback function:
              b|'*     If the 1st capture group (rex) matched, return it, else asterisk
                       The result of the replacement is auto-printed

1

V , 27 , 24 байта

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

27 байт

òÓãr¨ex©À!ü¼eü¼xü[rex]À!÷/*

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

Спасибо Брайану Маккатону за его идею сделать это в V

HexDump:

00000000: f2d3 e372 a865 78a9 c021 fcbc 65fc bc78  ...r.ex..!..e..x
00000010: fc5b 7265 785d c021 f72f 2a              .[rex].!./*

Объяснение:

ò                           " Until the output stops changing...
 Óãr¨ex©À!ü¼eü¼xü[rex]À!÷/* " Run the compressed vim regex:

:s/\vr(ex)@!|<e|<x|[rex]@!\w/*/gi

24 байта

Óãrex/ò&ò
HòÓ÷/*/e
jjòÍî

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

Ó           " Substitute
 ã          "   (case-insensitive)
  rex       "   'rex'
     /      " with
       &    "   'rex'
      ò ò   "   Surrounded in new lines
ò           " Recursively...
 Ó          "   Substitute...
  ÷         "     A word character
   /        "   with
    *       "     An asterisk
     /e     "     (don't break if there are 0 matches)
jj          "   Move down 2 lines
  ò         " end the recursive loop
   Íî       " Remove all newlines
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.