Проблема з кодовим гольфом, добре


51

Містер Маккі - персонаж Саута- Парку, відомий тим, що додав "м'кай" у все, що він каже.

Напишіть програму або функцію, яка перетворює рядок тексту в те, що сказав містер Макей.

Добре розміщення

  • m'kayмає випадковий 50% шанс того , щоб бути доданий після пунктуації ,, ., ?і! . Якщо це так, за ним піде той самий розділовий знак, який передує йому та пробіл.

    Наприклад, у реченні Test, test.є два місця, куди m'kayможна додати: після коми і після періоду, з 50% шансом на кожне місце. Можливі результати були б Test, m'kay, test. або Test, test. M'kay.або Test, m'kay, test. M'kay..

  • Завжди має бути принаймні один m'kayдоданий . Більше того, воно не завжди може бути на одному і тому ж місці, і кожне дійсне місце, куди його m'kayможна було б додати, має відбуватися з однаковою ймовірністю. Тобто, ви не можете додавати m'kayзавжди в кінці рядка, якщо через випадковість ви ніколи не додавали жодної m'kay. Якщо є лише один m'kay, він повинен мати однакову ймовірність появи у кожній дійсній позиції, навіть незважаючи на його наявність.

  • Якщо m'kayпісля ?, .або !, mобов'язково слід передбачити великі регістри.

  • Кількість mв m'kayмає бути одноманітно вибрана між 1 і 3. Тобто m'kay, mm'kayі mmm'kayце всі можливі варіанти, кожен з вірогідністю 0,33 ... Якщо він повинен бути великим, (див. Вище правило), усі mповинні бути великими.

Входи, виходи

  • Вхідні дані - це рядки ASCII, що містять символи від ASCII Dec 32 (пробіл) до ASCII Dec 126 (Tilde ~). У вході немає перерив рядків. Ви можете припустити, що будь-який вхід буде містити принаймні один із , . ? !.

  • Ви можете припустити, що m'kayу вході немає жодного або будь-якого з його варіантів.

    Введення даних може бути взято з STDIN, аргументів функції, командного рядка чи будь-чого подібного.

  • Вихід може бути через STDOUT, повернення функції чи щось подібне.

Тестові справи

  • Вхід: Test.

Можливий вихід: Test. M'kay.

  • Вхід: Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Можливий вихід: Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. MMM'kay. It's 100% free, mm'kay, no registration required.

  • Вхід: Drugs are bad, so, if you do drugs, you're bad, because drugs are bad. They can hurt your body, cause drugs are bad.

Можливий вихід: Drugs are bad, m'kay, so, if you do drugs, you're bad, m'kay, because drugs are bad. They can hurt your body, m'kay, cause drugs are bad. M'kay.

  • Вхід: Do you understand? Really? Good!

Можливий вихід: Do you understand? MM'kay? Really? Good! MMM'kay!

Оцінка балів

Це , тому найкоротший код у байтах виграє, правда?


10
+1, добре, але нам потрібен виклик Cartman!
Рівень р. Св.

16
@steveverrill не впевнений, що мова у виклику Картмана буде на жаль прийнятною тут: P
Fatalize

1
Я хочу побачити відповідь в Оок! MM''кей! Але ви, ймовірно, захочете використовувати цей алгоритм для генератора псевдовипадкових чисел .
mbomb007

3
@Fatalize: У всьому винна мама Кайла.
marinus

4
" M'kayмає випадковий 50% шанс бути доданим після пунктуацій ,,.,? і! ", здається, несумісний із " Завжди має бути принаймні один m'kayдоданий ". Будь ласка, уточнюйте це
Луїс Мендо

Відповіді:


13

CJam, 65 52 49 байт

l{_{_",.?!"#:IW>)mr{SI'M'm?3mr)*"'kay"3$}&}%_@=}g

Спробуйте його в Інтернеті в інтерпретаторі CJam .

Як це працює

l            e# Read a line from STDIN.
{            e# Do:
  _          e#   Duplicate the line.
  {          e#   For each of its characters:
    _",.?!"# e#     Find its index in that string.
    :IW>     e#     Save the index in I and check if it's greater than -1.
    )        e#     Add 1 to the resulting Boolean.
     mr      e#     Pseudo-randomly select a non-negative integer below that sum.
             e#     If I == -1 the result will always be 0.
    {        e#     If the result is 1:
      S      e#       Push a space.
      I'M'm? e#       Select 'm' if I == 0 (comma) and 'M' otherwise.
      3mr)   e#       Pseudo-randomly select an integer in [1 2 3].
      *      e#       Repeat the M that many times.
      "'kay" e#       Push that string. MMM'kay.
      3$     e#       Copy the proper punctuation.
    }&       e#
  }%         e#
  _          e#   Copy the resulting array.
  @=         e#   Compare it to the copy from the beginning.
}g           e# Repeat the loop while the arrays are equal.
             e# This makes sure that there's at least one m'kay. M'kay.

22

APL (66)

{∊⍉⍵⍪⍉⍪(¯1+⌈?2×⍵∊',.!?')/¨{' ',⍵,⍨'''kay',⍨'mM'[1+⍵≠',']/⍨?3}¨⍵}⍣≢

Результат 10 пробіжок:

      ↑ ({∊⍉⍵⍪⍉⍪(¯1+⌈?2×⍵∊',.!?')/¨{' ',⍵,⍨'''kay',⍨'mM'[1+⍵≠',']/⍨?3}¨⍵}⍣≢)¨ 10/⊂'Test, test. Test! Test?'
Test, m'kay, test. Test! Test?                  
Test, test. M'kay. Test! MMM'kay! Test? M'kay?  
Test, mm'kay, test. Test! MM'kay! Test? MM'kay? 
Test, mmm'kay, test. Test! Test? M'kay?         
Test, mm'kay, test. Test! Test? M'kay?          
Test, test. MM'kay. Test! Test? MMM'kay?        
Test, test. MMM'kay. Test! MMM'kay! Test? M'kay?
Test, test. Test! MM'kay! Test?                 
Test, mm'kay, test. M'kay. Test! Test?          
Test, test. MM'kay. Test! MM'kay! Test?   

Пояснення:

  • {... }⍣≢: застосувати функцію до входу, поки значення не зміниться
    • Створіть M'kayдля кожного символу:
    • {... }¨⍵: для кожного символу у введенні:
      • 'mM'[1+⍵≠',']/⍨?3: генеруйте від 1 до 3 mс або Mс залежно від того, символ був комою чи ні.
      • '''kay',⍨: додайте рядок 'kay.
      • ⍵,⍨: додайте символ
      • ' ',: додайте пробіл.
    • (¯1+⌈?2×⍵∊',.!?')/¨: для кожного M'kay", якщо його відповідний символ є одним із .,!?, виберіть його з 50% шансом, інакше виберіть його з 0% шансом.
    • ⍉⍵⍪⍉⍪: співставити кожен вибір з його характером,
    • : список усіх простих елементів (символів) по порядку.


Гаразд, як це нав'язує, що завжди додається один?
Джеррі Єремія

6
@JerryJeremiah: ⍣≢повторно застосовує цю функцію, поки вхід не відповідає результату. Отже, якщо один доданий, вихід змінюється, він зупиняється і повертає результат, а якщо його не додається, вихід залишається незмінним і він запускається знову, поки не буде доданий.
marinus

Я це якось пропустив. Це дуже розумно.
Джеррі Єремія

2
@DmitryGrigoryev: якщо ви використовуєте традиційне кодування APL, воно дійсно займає лише 1 байт.
marinus

9

K5, 99 90 байт

{f::0;{x;~f}{,/{f::f|r:(*1?2)&#&",.?!"=x;x,("";" ",((1+1?3)#"Mm"@x=","),"'kay",x)@r}'x}/x}

Що ж, комусь потрібно було розпочати це!

Збережено 9 байт за допомогою менш фантазійного методу верхнього обмацування M.

Пояснення

{                                                                                        }  Define a function
 f::0;                                                                                      Set `f` (used to determine when to stop) to 0.
      {x;~f}{                                                                         }/x   While `f` is 0 (no "m'kay"s have been inserted), loop over the string argument
               {                                                                   }'x      For each character in the string
                       (*1?2)&#&",.?!"=x                                                    If we are at a punctuation character, generate a random number between 0 and 1
                     r:                                                                     and assign it to `r`
                f::f|                                                                       If the number is one, an "m'kay" will be inserted, so the outer while loop should exit after this
                                                            "Mm"@x=","                      If the punctuation is a comma, then use a lowecase `m`, otherwise use `M`
                                                    (1+1?3)#                                Repeat the `m` between 1 and 3 times
                                               " ",(                  ),"'kay",x            Join the "m'kay" string to the punctuation and prepend a space
                                         x,("";                                 )@r         If the random number is 1, append the "m'kay" string, to the current string
             ,/                                                                             Join the resulting string

99-байтна версія

{f::0;{x;~f}{,/{f::f|r:(*1?2)&#&",.?!"=x;x,("";" ",((1+1?3)#`c$(-32*~","=x)+"m"),"'kay",x)@r}'x}/x}

7

Джулія, мм''кай, 115 114 байт

f(s)=(R=replace(s,r"[,.?!]",r->r*(" "*(r==","?"m":"M")^rand(1:3)*"'kay"*r)^rand(0:1));ismatch(r"m'kay"i,R)?R:f(R))

Це створює рекурсивну функцію, яка приймає рядок і повертає рядок.

Недоліки + пояснення:

function f(s)
    # Replace occurrences of punctuation using random repeats
    R = replace(s, r"[,.?!]", r -> r*(" " * (r == "," ? "m" : "M")^rand(1:3) * "'kay" * r)^rand(0:1))

    # Check whether anything was replaced
    if ismatch(r"m'kay"i, R)
        # If so, return the replaced string
        R
    else
        # Otherwise recurse
        f(R)
    end
end

Мені не подобається Південний Парк, але трепет від гольфу був занадто привабливим, щоб передати це. Дякуємо KRyan за те, що спростив регулярний вираз, економив 1 байт.


6

JavaScript ES6, 79 86 108 байт

Виявляється, Mповтор займає багато байтів.

(s,z=Math.random)=>s.replace(/([!?.,])/g,l=>z(t=t+1)>=.5||t?` ${(l==','?'m':'M').repeat(0|z()*3+1)}'kay`+l:l)

Стара версія (не повторюється) (86 байт)

(s,t=1)=>s.replace(/([!?.,])/g,l=>Math.random()>=.5||--t?` ${l==','?'m':'M'}'kay`+l:l)

Старіша версія (не повторюється, не вимагає хоча б одного м'кея) (79 байт) :

s=>s.replace(/([!?.,])/g,l=>~~(Math.random()*2)?l+` ${l==','?'m':'M'}'kay`+l:l)

Найстаріша версія:

s=>(r=t=>t.replace(/([!?.])/,"$1 M'kay$1").replace(/,/,", m'kay,"),r(s),[for(i of s)~~(Math.random()*2)?r(i):i].join``)

В останній версії є ReferenceError: t не визначено
Ніл

Тільки найстаріша версія насправді працює на Test.вході.
Ніл

@Ніл, що не повинно відбуватися, для мене працює чудово. Чи можете ви додати код, який ви використовуєте в консолі
Downgoat

Я загортаю ваше подання в дужки, а потім суфікс ("Test.")до нього.
Ніл


4

C, 170 байт

Перша тріщина в ньому:

n;main(r,v,p)char**v,*p;{for(srand(time(0)),p=v[1];r=rand(),*p;p++)if(strchr(".,?!",putchar(*p))&&r%2||(!*(p+1)&&!n))n=printf(" %.*s'kay%c",r/2%3+1,*p%4?"MMM":"mmm",*p);}

Безголівки:

n;
main(r,v,p)
char**v,*p;
{
    for(srand(time(0)), p=v[1]; r=rand(), *p; p++) /* loop through string */
        if(strchr(".,?!",putchar(*p)) /* print the char, check if punctuation */
            && r % 2 /* should we say it? */
            || (!*(p+1) && !n)) /* If this is the end of the string and we haven't M'kay'd, then do it now */
            n=printf(" %.*s'kay%c", r/2%3+1, *p%4 ? "MMM" : "mmm", *p); /* say it! */
}

4

Скала, 191 байт

var(r,s,a,o)=(util.Random,readLine,1>2,"")
while(!a){o=""
for(c<-s)o+=(if(",.?!".contains(c)&&r.nextBoolean){a=2>1
s"$c ${(if(c==46)"M"else"m")*(1+r.nextInt(3))}'kay$c"}else s"$c")}
print(o)

3

Математика, 202 байти

i=0;r=Random;x=r[];
h=" "<>If[#==",","m","M"]~Table~{Ceiling[3r[]]}<>"'kay"<>#&;
(ee/.a:>(If[e~Count~a@__==i&&#==Floor[x*i],h@#2,""]&))@
StringReplace[#,x:","|"."|"?"|"!":>x~~RandomChoice@{i++~a~x,h@x}]&

Додано рядкові рядки для читабельності. Оцінює анонімну функцію, беручи рядок як аргумент. ( це скорочення для \[Function].)

Безголівки:

h[x_]:=" " <> Table[
    If[x==",", "m", "M"],
    { Ceiling[3 Random[]] }
] <> "'kay" <> x;

hприймає знаки пунктуації напівкоксу і робить його " m'kay,", " mm'kay,"і т.д. випадковим чином і капіталізовані відповідним чином .

f[s_] := (i = 0;
   StringReplace[s, 
    x : "," | "." | "?" | "!" :> 
     x ~~ RandomChoice[{a[i++, x], h[x]}]]);

fбере рядок і шукає будь-який розділовий символ x; коли він знаходить це, він застосовує з 50% ймовірністю відповідний h[x]і 50% вираз, як a[3, x]. Він також оновлює iзагальну кількість замінених пунктуацій (з обома відмінками). Так f["X, x."]може оцінити

"X," ~~ h[","] ~~ " x." ~~ a[1, "."]           ...which might expand to
"X, mmm'kay, x." ~~ a[1, "."]                  , and i would equal 2

Нарешті, gрозберемося з aросійськими.

g[expr_] := (r = Random[]; 
  expr /. a -> (If[Count[expr, a[__]] == i && # == Floor[r*i], h[#2], ""] &))

Countпорахуватиме, скільки aми помістимо туди; якщо вона дорівнює iзагальній кількості розділових знаків, ми не додавали жодних м'кайсів. У цьому випадку ми матимемо вирази на зразок a[0, _] ... a[i-1, _], і ми визначаємо aтак, що він поверне m'kay точно для одного з 0..i-1.


2

Пітон, 173 168 156

from random import randint as R
    m,k,s,C="mM","'kay",input(),0
    while C<1:
        S=""
        for c in s:r=R(0,c in",.!?");C+=r;S+=c+(' '+m[c!=","]*R(1,3)+k+c)*r
    print(S)

Безголівки:

from random import randint
m, kay = "mM", "'kay"
string = input()
count = 0
while count < 1: #at least one occurrence
    newString= ""
    for char in s:
        rm  = randint(1,3) #number of "m"
        rmk = randint(0, char in ",.!?") #occurrence of "m'kay"
        count += rmk
        newString += char + (' ' + m[c != ","] * rm + kay + char) * rmk
print(newString)

Здається, ваш відступ досить заплутаний: /
jazzpi

Я знаю, вкладки автоматично перетворюються на пробіли.
Trang Oul

2

> <>, 150 байт

i:0(?v
r0&v >
?v~>:0(?v::o1[:::",.?!"{=${=+${=+r=+]
>x~^    >&:0)?;&"."14.
v>&1+&1[:","=&"yak'"&84**"M"+
 >  >84*v
>x::^>22 .
 >: ^]
ol0=?^  >

13 марних байтів, але мені стало нудно, намагаючись змінити його. Крім того, рандомізація у Funge важко гольфу -.-


2

Perl, 93 89 88 байт

$_=$0=<>;s/[.?!]|(,)/$&.($".($1?"m":M)x(1+rand 3)."'kay$&")[rand 2]/ge while$0eq$_;print

Однозначно можна пограти ще трохи!

4 байти відрізано завдяки Дому Гастінгсу


2

C ++ 290

Моє рішення

void M(string x){
srand(rand());
string p(",.?!");
char c=0,m='m',n='M';
int r=0;
size_t z=0;
for(size_t i=0;i<x.size();i++)
{
c=x[i];cout<<c;
z=p.find(c);
r=rand()%2;
if(z!=string::npos&&r)
{
cout<<' ';
c=(z?n:m);
r=rand()%3+1;
while(r--){cout<<c;}
cout<<"\'kay";
}
}
}

Пояснення змінної z визначає, який розділовий знак і z = 0 вказує на використання 'm', а не 'M'.

Тест

int main()
{
int x=5;
while(x--){
string S("Do you understand? Really? Good! Yes, I do.");
M(S);
cout<<endl;
}
return 0;
}

string::npos=> -1або ~0. Вибір ~0дозволяє використовувати -замість !=; так що умовне стає if(z-~0&&r), економлячи 11 байт.
Схизм

1

JavaScript ES6, 121 байт

(s,r=Math.random,f=t=>t==s?f(s.replace(/[!?.,]/g,m=>r()<.5?m:m+" "+(m==","?"mmm":"MMM").slice(r()*3)+"'kay"+m)):t)=>f(s)

Збиває, якщо даний рядок не містить відповідних розділових знаків.


1

Луа, 162 160 байт

r=math.random;s,m=io.read()repeat m=s:gsub("([,.?!])",function(p)return p..(r()>.5 and" "..(p==","and"m"or"M"):rep(r(1)).."'kay"..p or"")end)until s~=m;print(m)

Ви коли-небудь чули трагедію Дарта Плагей Мудрого? MM''кей? Я думав, що ні. MMM'''кей. Це не історія, яку б вам розповіли джедаї. Гаразд. Це ситська легенда. Дарт Плуге був темним лордом сіттів, добре, такий потужний і такий мудрий, що міг застосувати Силу, щоб впливати на міхлоріан, щоб створити життя ... Він мав такі знання про темну сторону, що міг навіть утримати тих, кого його піклували. приблизно від вмирання. ММ 'гаразд. Темна сторона Сили - це шлях до багатьох здібностей, які деякі вважають неприродними. ММ 'гаразд. Він став настільки потужним ... єдине, чого він боявся - втратити владу, ммм''кай, що, врешті-решт, добре, звичайно, добре, він зробив. Гаразд. На жаль, він навчив свого учень усьому, що знав, тоді його учень вбив його уві сні. Гаразд. Іронічний. Він міг врятувати інших від смерті,

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.