Пусть первый будет с тобой


19

Напишите программу для замены всех вхождений «force» на «first» и всех вхождений «first» на «force», сохраняя исходный регистр для всех позиций символов:

"ForcefoRcefOrcE" -> "FirstfiRstfIrsT"
"FirstfiRstfIrsT" -> "ForcefoRcefOrcE"

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

"thirst of forces" -> "thirst of firsts" -> "thirst of forces"

Ваша программа должна работать с любой начальной строкой. Так что в качестве подсказки лучше избегать использования магических символов в качестве промежуточного представления, потому что, если вы попробуете трехпроходную замену ( "force" -> "zzzzz", "first" -> "force", "zzzzz" -> "first"), она потерпит неудачу на содержащих строки "zzzzz".

Вы должны поддерживать полный диапазон символов, разрешенных в определении String вашим языком программирования (в большинстве случаев это Unicode). Пример использования представления в стиле JSON для непечатаемых символов (\ u + 4 цифры):

"\u0000\u0001\u0002\u0003the Force of the firsT"
                     |
                     V
"\u0000\u0001\u0002\u0003the First of the forcE"

1
Атта мальчик. Напомните людям, что у тега есть критерий выигрыша »
Кристофер

1
@ Challenger5 Нет, я так не думаю, потому что если нет ведущей [Ff], то вы не должны заменить слово.
Эрик Outgolfer

2
Пусть май сначала будет с тобой. (Комментарий 1 мая)
Esolanging Fruit

19
Разве это не должно быть "может быть четвертый с тобой"?
wizzwizz4

3
@ mbomb007 «четвертый» и «форсированный» не имеют одинакового количества букв, что делает его несовместимым для сохранения одинакового регистра символов.
Cœur

Ответы:


6

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

iT`\OC\E\ocetsiTSI`Ro`first|force

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

Изменить: Сохранено 5 байтов благодаря @MartinEnder за указание, что Roделает.


Да, собирался опубликовать как только ОП ответит на мой комментарий. Вы можете сохранить несколько байтов, переупорядочив первый набор так, чтобы второй был Ro.
Мартин Эндер

@MartinEnder Документация смутила меня, уделив слишком много внимания Rвлиянию диапазонов; например, я бы никогда не понял, что REэто эквивалентно, 86420если бы ты не указал на это.
Нейл

Спасибо, что дали мне знать. Я постараюсь прояснить это в документах.
Мартин Эндер

9

JavaScript (ES6), 93 88 байт

f=
s=>s.replace(/force|first/gi,s=>s.replace(/./g,c=>s[s.search(c)^1]||c,s="oicsetOICSET"))
<textarea oninput=o.textContent=f(this.value)></textarea><pre id=o>

Редактировать: Сохранение 5 байтов путем оптимизации неизменного регистра букв.


5

APL (Dyalog) , 61 байт

Требуется ⎕IO←0по умолчанию во многих системах. Может быть на четыре символа короче, используя символ Unicode вместо ⎕OPT .

(t'force' 'first')⎕R{(m∊⎕A)c¨t⊃⍨~t⍳(c819⌶)⊂m←⍵.Match}⎕OPT 1

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


4

PHP, 88 байт

Онлайн версии

<?=preg_replace_callback("#first|force#i",function($t){return$t[0]^first^force;},$argn);

PHP, 110 байт

<?=preg_replace_callback("#first|force#i",function($t){return strtr($t[0],iIsStToOcCeE,oOcCeEiIsStT);},$argn);

3
Вы можете сохранить несколько байтов $t[0]^first^forceвместо strtr().
user63956

@ user63956 Спасибо за усилия по обучению
Йорг Хюльсерманн

4

Perl 5 , 52 байта

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

s%first|force%$&=~y/oceOCEistIST/istISToceOCE/r%eig

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

Ничего слишком сумасшедшего не происходит. Найдите вхождения forceи firstбез учета регистра ( s%force|first%%gi), а затем транслитерируйте символы для преобразования одного в другое.


3

CJam, 66 байт

qY5m*_"force"{f{_eu}3/:z{~?}f%}:K~\"first"K.{[\]:P~@\/\f/P~@\f*\*}

Проходит через каждый вариант вариации «first» и «force» и пытается разделить его. Если это возможно, он затем присоединяется к нему с обратными словами.

псевдокод:

input_chars = list(read_all_input()) # CJam: q
power = cartesian_power(2, 5) # CJam: Y4m*_
def case_variations(s): # CJam: {...}:K
    temp0 = [[i, j, upper(j)] for i, j in zip(power, s)] # CJam: f{_eu}3/
    temp1 = map(transpose, temp0) # CJam: :z
    ret = []
    for i in ret:
        for j in i: # CJam: {...}f%
            ret.append(j[1] if j[0] else j[2]) # CJam: ~?
    return ret
force_var = K("force") # CJam: "force"{...}:K~
first_var = K("first") # CJam: \"first"K
for force, first in zip(force_var, first_var): # CJam: .{...}
    current = [force, first] # CJam: [\]:P~
    input_chars = list_split(input_chars, force) # CJam: @\/
    input_chars = [list_split(i, first) for i in input_chars] # CJam: \f/
    input_chars = [list_join(i, force) for i in input_chars] # CJam: P~@\f*
    input_chars = list_split(input_chars, first) # CJam: \*

Конечно, fэто важно, чтобы избежать изменения thirstв thorceили divorceв divirst?
Нейл

@Neil Правда, отредактировано.
Esolanging Fruit


3

Java 7, 318 310 байт

String c(String s){String x=s.toLowerCase();int i=x.indexOf("force")+1,j=x.indexOf("first")+1,t=i>0&j>i?0:j>0?1:0;return i>0|j>0?s.substring(0,t>0?(i=j):i)+(char)(s.charAt(i++)-(t>0?-6:6))+s.charAt(i++)+(char)(s.charAt(i++)+(t>0?-16:16))+(char)(s.charAt(i++)+(t>0?-15:15))+c(s.length()>i?s.substring(i):""):s;}

Хорошо, это было довольно сложно в Java ..

Объяснение:

String c(String s){                       // Method with String parameter and String return-type
  String x=s.toLowerCase();               //  Temp String as lowercase of the input
  int i=x.indexOf("force")+1,             //  Index of "force" + 1 (becomes 0 if NOT present; >=1 if it is present)
      j=x.indexOf("first")+1,             //  Index of "first" + 1 (becomes 0 if NOT present; >=1 if it is present)
      t=i>0&j>i?0:j>0?1:0;                //  Temp integer: 0 if "force" is found first; 1 if "first" is found first
  return i>0|j>0?                         //  If either "force" or "first" is found:
    s.substring(0,t>0?(i=j):i)            //   Return the substring before that (if any) + ('f' or 'F')
     +(char)(s.charAt(i++)-(t>0?-6:6))    //   + 'i' <-> 'o', or 'I' <-> 'O'
     +s.charAt(i++)                       //   + 'r' or 'R'
     +(char)(s.charAt(i++)+(t>0?-16:16))  //   + 's' <-> 'c', or 'S' <-> 'C'
     +(char)(s.charAt(i++)+(t>0?-15:15))  //   + 't' <-> 'e', or 'T' <-> 'E'
     +c(s.length()>i?s.substring(i):"")   //   + a recursive call for the rest of the input-String (if any)
   :                                      //  Else:
    s;                                    //   Return the input-String
}                                         // End of method

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

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

class M{
  static String c(String s){String x=s.toLowerCase();int i=x.indexOf("force")+1,j=x.indexOf("first")+1,t=i>0&j>i?0:j>0?1:0;return i>0|j>0?s.substring(0,t>0?(i=j):i)+(char)(s.charAt(i++)-(t>0?-6:6))+s.charAt(i++)+(char)(s.charAt(i++)+(t>0?-16:16))+(char)(s.charAt(i++)+(t>0?-15:15))+c(s.length()>i?s.substring(i):""):s;}

  public static void main(String[] a){
    System.out.println(c("Force"));
    System.out.println(c("First"));
    System.out.println(c("foRce"));
    System.out.println(c("fiRst"));
    System.out.println(c("fOrcE"));
    System.out.println(c("fIrsT"));
    System.out.println(c("\u0000\u0001\u0002\u0003the Force of the firsT"));
    System.out.println(c("May the first be with you"));
    System.out.println(c(c("May the first be with you"))); // 2x
    System.out.println(c("The fIrSt of the First of the fORCE of the FIRST of the FoRCe"));
  }
}

Выход:

First
Force
fiRst
foRce
fIrsT
fOrcE
 ���the First of the forcE
May the force be with you
May the first be with you
The fOrCe of the Force of the fIRST of the FORCE of the FiRSt

1
Я ценю, что вы привели симметричный пример c(c("..."))!
Cœur

3

Желе , 37 36 байт

Есть ли способ использовать уменьшение для срезов длиной 5 вместо?

®‘©ị“Ɓu“¡Ḣƭ»
Œlœṣ¢œṣ€¢j€¢j¢Œu⁸=ŒuT¤¦

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

Как?

®‘©ị“Ɓu“¡Ḣƭ» - Link 1 helper that fetches the next word to use: no arguments
®            - recall value from register (initially zero)
 ‘           - increment
  ©          - place the result into the register
    “Ɓu“¡Ḣƭ» - literal dictionary compressed string list ["first","force"]
   ị         - index into (1-indexed and modular)
             - so this link first yields "first", then "force", then "first" and so on.

Œlœṣ¢œṣ€¢j€¢j¢Œu⁸=ŒuT¤¦ - Main link: list of characters, S
Œl                      - convert S to lower case
  œṣ                    - split on sublists equal to:
    ¢                   -   call the last link (1) as a nilad ("first")
     œṣ€                - split €ach on sublists equal to:
        ¢               -   call the last link (1) as a nilad ("force")
         j€             - join €ach with:
           ¢            -   call the last link (1) as a nilad ("first")
            j           - join with:
             ¢          -   call the last link (1) as a nilad ("force")
                      ¦ - apply a link to sparse indices:
              Œu        -   convert to upper case
                     ¤  -   nilad followed by link(s) as a nilad:
                ⁸       -     chain's left argument, S
                  Œu    -     convert to upper case
                 =      -     equal to S? (vectorises)
                    T   -     truthy indexes (indexes at which input is upper case)

Pyth и Jelly равны: o
Leaky Nun

Должен быть путь в гольф: D
Джонатан Аллан

Да, и я только что нашел это: D
Leaky Nun

2

MATL , 47 байт

5W:qB!"o['first';'force']@!32*-cZ}_Zt5M_6MoZt|c

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

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



2

Flex (лексер), 72 байта

%%
 #define x(a) yytext[a]^=
(?i:first|force) x(1)6;x(3)16;x(4)17;ECHO;

Чтобы скомпилировать и запустить:

flex first.l
gcc lex.yy.c -lfl # -ll on Macs, apparently
./a.out

first.l:3: EOF encountered inside an action(о, неважно: в конце требуется
Cœur

ld: library not found for -lfl(о, неважно, команда gcc lex.yy.c -llна macOS)
Cœur

Проверено и одобрено.
Cœur

2

Python 2, 171 байт

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

import re,string as g
def f(s):f="istISTECOeco";l=re.split("(first|force)",s,0,re.IGNORECASE);l[1::2]=[t.translate(g.maketrans(f,f[::-1]))for t in l[1::2]];print"".join(l)

Я думаю, что совершенно ясно, что я здесь делаю. Разбейте строку на экземпляры first и force (без учета регистра), замените эти экземпляры версиями, переведенными с помощью str.translate, и снова соедините ее обратно в строку.

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


2

Python 2.7, 173 165 байт

8 байтов, сохраненных Quintopia

Этот получил брутто:

lambda S:`[(t[0],t[0].upper())[t[1]]for t in zip("".join("first".join(s.replace("first","force")for s in S.lower().split("force"))),[l.isupper() for l in S])]`[2::5]

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

Разбивая это шаг за шагом:

  1. S.lower().split("force"): взять строку, объединить в нижний регистр, разбить на подстроки, разделенные "force"
  2. s.replace("first","force")for s in <STEP 1>: Заменить все "first"на"force"
  3. _`.join("first".join(<STEP 2>)`[2::5]`_: заменить все "force"на с "first"помощью рекомбинирования "force"выделенных подстрок с"first" и воссоединиться в одну строку (подчеркивания добавлены, чтобы получить правильные метки)
  4. zip(<STEP 3>,[(2,1)[l.isupper()]for l in S]): заархивируйте каждый символ заменяемой фразы в регистр исходной строки (2 в нижнем регистре, 1 в верхнем регистре)
  5. _`[(t[0],t[0].upper())[t[1]==1]for t in <STEP 4>]`[2::5]`_: Восстановить исходный регистр, преобразовать список в строку (подчеркивание добавлено, чтобы получить правильные метки)

Вы можете сэкономить 8 байтов, кодируя верхний как True, а нижний как False: попробуйте онлайн!
Quintopia

2

C (лязг) , 201 183 226 214 байтов

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

(сохранено 12 благодаря возрастанию Cat)

char*s,*p,*q;main(i,v)char**v;{puts(s=v[1]);do{p=strcasestr(s,"first");q=strcasestr(s,"force");if(p&&(!q|p<q))p[1]+=6,p[3]-=16,p[4]-=15;else if(q)q[1]-=6,q[3]+=16,q[4]+=15;s=p&&(!q|p<q)?p:q;}while(s++);puts(v[1]);}

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



1

C # 273 байта

string c(string s){var x=s.ToLower();int i=x.IndexOf("force")+1,j=x.IndexOf("first")+1,t=i>0&j>i?0:j>0?1:0;return i>0|j>0?s.Substring(0,t>0?(i=j):i)+(char)(s[i++]-(t>0?-6:6))+s[i++]+(char)(s[i++]+(t>0?-16:16))+(char)(s[i++]+(t>0?-15:15))+c(s.Length>i?s.Substring(i):""):s;}

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

Прямой порт Java-ответа Кевина Круйссена , оказывается, когда дело доходит до получения символа в строке по заданному индексу, C # намного лучше, чем Java ( s[i++]вместо s.charAt(i++))



1

C #, 235 символов

string a(string s){var l=s.ToLower();int f=l.IndexOf("first"),F=l.IndexOf("force"),m=f<F&f>-1?f:F>-1?F:f;return ++m>0?s.Substring(0,m)+(char)(s[m]^6)+s[m+1]+(char)(s[m+2]^16)+(char)(s[m+3]^17)+(s.Length-m>5?c(s.Substring(m+4)):""):s;}


0

Java, 382 байта не соответствует

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

String f(String t){String s="";for(String w:t.split(" "))if(w.equalsIgnoreCase("force")|w.equalsIgnoreCase("first"))s+=" "+w.charAt(0)+(char)(w.charAt(1)+(w.charAt(1)=='o'|w.charAt(1)=='O'?-6:6))+w.charAt(2)+(char)(w.charAt(3)+(w.charAt(3)=='c'|w.charAt(3)=='C'?16:-16))+(char)(w.charAt(4)+(w.charAt(4)=='e'|w.charAt(4)=='E'?15:-15));else s+=" "+w;return s.substring(1,s.length());}

3
Хм, это работает, только если все слова разделены пробелами, но как насчет запятых или странных строк вроде "The first, force,|first'forced!" ? Кроме того, вы можете немного изменить свой текущий код: if(w.equalsIgnoreCase("force")|w.equalsIgnoreCase("first"))-> ,zпосле String s=""и z=w.toLowerCase();if(z.equals("force")|z.equals("first")). Кроме того, 'O'может быть 79, 'C'может быть 67и 'E'может быть 69. А то if elseможно заменить одним большим троичным, если оба так и есть s+=.
Кевин Круйссен

Я подтверждаю, что это решение не подпадает под определение, поскольку оно не работает, например, в «Forceforce».
Cœur

@ Cœur, который я добавил non competentв заголовке
Khaled.K

0

C # (269 байт)

string s(string z){var u=z.ToUpper();var a=new[]{"FIRST","FORCE"};return String.Join("",u.Split(a,StringSplitOptions.None).Aggregate((c,n)=>c+(u.Substring(c.Length,5)==a[0]?a[1]:a[0])+n).Select((c,i)=>Char.IsLower(z[i])?Char.ToLower(c):c));}

еще одно решение на C #, только второе наименьшее, потому что я объявил две переменные и поэтому не могу использовать лямбда-синтаксис. да ладно, мне было весело. :)

объяснение:

  • переместить оригинальную строку вверх, затем разделить на «FORCE» и «FIRST».

  • агрегируйте результаты и при каждом разбиении найдите подстроку из пяти символов, которая использовалась для разбиения исходной строки, используя длину агрегируемой строки. если это было «силой», сделайте это «первым» и наоборот

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