Більше корівника…!


42

Ви забезпечуєте технічну підтримку в Брюс Dickenson , як він проводить запис сеансу Blue Oyster Cult. Коли він попросить більше коров’ячої капусти , ви можете дати йому це.

Ваше завдання

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

Скільки ковбачків містить рядок?

Кількість стрибків, що містять рядок, дорівнює максимальній кількості чітко виражених копій "каучук", які можна отримати, перевівши символи рядка. Так , наприклад, "bbbccceeellllllooowwwwwwwww"містить 3 дзвіночки, в той час , "bbccceeellllllooowwwwwwwww"і "bbbccceeelllllooowwwwwwwww"кожен з яких містить 2 дзвіночки, і "cowbel"містить 0 дзвіночки.

Як результат повинен бути пов'язаний із входом?

Вихід повинен складатися з конкатенації в такому порядку вхідного рядка та найкоротшого префіксу вхідного рядка, необхідного для збільшення кількості обмоток.

Наприклад, "bbbccceeelllllooowwwwwwwww"потрібен лише один додатковий, "l"щоб містити 3 корівника замість 2; найкоротший префікс, який містить, що "l"є "bbbccceeel". Тому, якщо вхід є "bbbccceeelllllooowwwwwwwww", то вихід повинен бути "bbbccceeelllllooowwwwwwwwwbbbccceeel".

Технічні характеристики

  • Ви можете припустити, що вхід містить лише друковані символи ASCII. Якщо є один або два символи, які дратують обробку рядків у вашій мові (наприклад, нові рядки або \), ви можете припустити, що вхідні дані не містять їх - просто згадайте це обмеження.
  • Ви також можете припустити, що алфавітні символи у введеному регістрі - це всі малі літери або всі великі регістри. Якщо ви вирішите не брати на себе жодне з них, порахуйте коров'ячих дзвонів невідчутливо.
  • Далі Ви можете припустити , що введення містить , щонайменше , одну копію кожного з персонажів b, c, e, l, o, і w. Це еквівалентно припущенню, що якийсь префікс рядка може бути приєднаний до нього, щоб створити рядок, що містить більше каучукових звуків. (Зверніть увагу, що сам рядок введення не повинен містити обмоту.)
  • Якщо у вашій мові є вбудований елемент, який вирішує цю проблему ... тоді повністю використовуйте її, серйозно, наскільки приголомшливо це.

Золоті підгузники

Оскільки час запису в студії дорогий, код повинен бути максимально коротким. Запис з найменшими байтами - переможець!

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

( посилання на пастину для більш простого копіювання / вставки)

Тестовий вхід №1: "christopher walken begs for more cowbell!"

Тестовий вихід №1: "christopher walken begs for more cowbell!christopher wal"

Тестовий вхід №2: "the quick brown fox jumps over the lazy dog"

Тестовий вихід №2: "the quick brown fox jumps over the lazy dogthe quick brown fox jumps over the l"

Тестовий вхід №3: "cowbell"

Тестовий вихід №3: "cowbellcowbell"

Тестовий вхід №4: "cowbell cowbell cowbell"

Тестовий вихід №4: "cowbell cowbell cowbellcowbell"

Тестовий вхід №5: "cowbell cowbell cowbel"

Тестовий вихід №5: "cowbell cowbell cowbelcowbel"

Тестовий вхід №6: "bcelow"

Тестовий вихід № 6: "bcelowbcel"

Тестовий вхід №7: "abcdefghijklmnopqrstuvwxyz"

Тестовий вихід № 7: "abcdefghijklmnopqrstuvwxyzabcdefghijkl"

Тестовий вхід № 8: "cccowwwwbbeeeeelllll"

Тестовий вихід № 8: "cccowwwwbbeeeeelllllccco"

Тестовий вхід №9: "be well, programming puzzles & code golf"

Тестовий вихід №9: "be well, programming puzzles & code golfbe well, programming puzzles & c"

Тестовий вхід №10: "lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. wow!"

Тестовий вихід №10: "lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. wow!lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut lab"

Тестовий вхід № 11:

"c-c-b-c

i have a cow, i have a bell.
uh! bell-cow!
i have a cow, i have a cowbell.
uh! cowbell-cow!

bell-cow, cowbell-cow.
uh! cow-cowbell-bell-cow.
cow-cowbell-bell-cow!
"

Тестовий вихід № 11:

"c-c-b-c

i have a cow, i have a bell.
uh! bell-cow!
i have a cow, i have a cowbell.
uh! cowbell-cow!

bell-cow, cowbell-cow.
uh! cow-cowbell-bell-cow.
cow-cowbell-bell-cow!
c-c-b-c

i have a cow, i have a bell"

23
Кожен, хто відповість на тему COW, отримує десять балів в Інтернеті.
Павло

3
Я думаю, що людям було б набагато простіше обробляти справи введення / виводу, якби ви їх відформатували в одному блоці коду. Поки він займає багато місця і не дуже копіює пасту.
FryAmTheEggman

Для копіювання / вставлення додано посилання Pastebin. Якщо є спосіб приховати / згортати / показати тестові випадки в цій публікації, заощаджуючи таким чином вертикальний простір, я б хотів це вивчити.
Грег Мартін

2
Добре зазвичай люди використовують test case -> resultв одному великому попередньо відформатованому блоці коду. Набагато приємніше естетично і простіше копіювати пасту.
FlipTack

1
@MatthewRoh Окрім того, що Lу слові є два s, це не те, що задає проблема.
Мартін Ендер

Відповіді:


13

Піп , 50 42 38 байт

T$<(MN{_NaM"lcowbe"}//^2M[aYa@<i])++iy

Передайте рядок як аргумент командного рядка, при необхідності цитуючи його. Спробуйте в Інтернеті!

Пояснення

Я збираюся пояснити це у двох частинах: функція каучука та повна програма. По-перше, ось функція, яка обчислює кількість обмотки в рядку:

MN{_NaM"lcowbe"}//^2

{...}визначає функцію. Багато операторів Pip при застосуванні до функції повертають іншу функцію; наприклад, -{a+1}те саме, що {-(a+1)}. Отже, вищесказане рівнозначно

{MN(_NaM"lcowbe")//^2}

яка працює наступним чином:

{                    }  Function, in which a is the 1st argument (the string)
    _Na                 Lambda fn: returns number of times its argument occurs in a
       M"lcowbe"        Map that function to the characters of "lcowbe"
                   ^2   A devious way to get [2]: split the scalar 2 into characters
   (            )//     Int-divide the list of character counts by [2]
                        Since the lists are not the same length, this divides the first
                          element (# of l's) by 2 and leaves the others alone
 MN                     Take the min of the resulting list

Тепер, коли у нас це є, ось повна програма:

T$<(MN{_NaM"lcowbe"}//^2M[aYa@<i])++iy
                                        a is 1st cmdline arg, i is 0 (implicit)
T                                       Loop till condition is true:
                            a@<i        Slice leftmost i characters of a
                           Y            Yank that into y variable
                         [a     ]       List containing a and that value
                        M               To that list, map...
    MN{_NaM"lcowbe"}//^2                ... the cowbell function
                                        Result: a list containing the amount of cowbell
                                        in the original string and the amount in the slice
 $<(                             )      Fold on less-than: true if the first element is
                                        less than the second, otherwise false
                                  ++i   In the loop, increment i
                                     y  Once the loop exits, print y (the latest slice)

Я вступив, cowbell cowbell cowbeeі вихід був, cowbellcowbelcowbelале я, можливо, використовую IDE неправильно (нове для PIP)
Альберт Реншо

@AlbertRenshaw Я отримую cowbell cowbell cowbeecowbell( спробуйте в Інтернеті ). Використовуєте TIO або локальну копію?
DLosc

О, гарно! Я проставляв його під полем "введення", а не під аргументом додати. +1
Альберт Реншо

Дійсно вищий клас. Я переніс його на javascript.
edc65

6

C, 511 488 474 470 463 454

void f(char*a){char*s;int i=-1,c,o,w,b,e=b=w=o=c=1,l=3,n,r,z=i;for(;s=a[++i];c+=s==67,o+=s==79,w+=s==87,b+=s==66,e+=s==69,l+=s==76);r=~-l/2;n=c<o?c:o;n=w<n?w:n;n=b<n?b:n;n=e<n?e:n;n=r<n?r:n;c=c==n;o=o==n;w=w==n;b=b==n;e=e==n;if(l=r==n?l:0)if(l%2)l=2;else l=1,c=o=w=b=e=0;else l+=l%2;n=c+o+w+b+e+l;for(printf("%s",a);s=n?a[++z]:0;s==67&&c?n--,c--:0,s==79&&o?n--,o--:0,s==87&&w?n--,w--:0,s==66&&b?n--,b--:0,s==69&&e?n--,e--:0,s==76&&l?n--,l--:0,putchar(s));}

Спробуйте в Інтернеті


Читальний формат + пояснення:

void f(char*a){
//a = input

    char*s;

    int i=-1,c,o,w,b,e=b=w=o=c=1,l=3,n,r,z=i;//c,o,w,b,e all start at 1; L starts at 3

    for(;s=a[++i];c+=s==67,o+=s==79,w+=s==87,b+=s==66,e+=s==69,l+=s==76);
    //loop to obtain number of times each character C,O,W,B,E,L is found in string (using the ASCII numeric values of each letter)

    //to get an extra cowbell we need to increment C,O,W,B,E by 1 and L by 2 (two Ls in cowbell); except we don't have to because we already did that by starting them at c=1, o=1, w=1, b=1, e=1, L=3 when we declared them. 

    r=~-l/2;
    //r is half of (1 less the number of times L is in string (+ init value))

    n=c<o?c:o;n=w<n?w:n;n=b<n?b:n;n=e<n?e:n;n=r<n?r:n;
    //n is the number of times that the least occouring character appears in the string, (use R instead of L since cowbell has two L's in it and we just need ~-l/2)

    c=c==n;o=o==n;w=w==n;b=b==n;e=e==n;
    //convert c,o,w,b,e to BOOL of whether or not we need 1 more of that letter to create one more cowbell (logic for L handled below since it's trickier)

    if(l=r==n?l:0)//if L-1/2 is [or is tied for] least occurring character do below logic, else set l to 0 and skip to `else`
        if(l%2)//if l is divisible by 2 then we need 2 more Ls
            l=2;
        else //otherwise we just need 1 more l and no other letters
            l=1,c=o=w=b=e=0;
    else //add 1 to L if it's divisible by 2 (meaning just 1 more L is needed in addition to possibly other C,O,W,B,E letters) (*Note: L count started at 3, so a count of 4 would be divisible by 2 and there is only 1 L in the string)
        l+=l%2;

    n=c+o+w+b+e+l;
    //n = number of specific characters we need before we reach 1 more cowbell

    for(printf("%s",a);s=n?a[++z]:0;s==67&&c?n--,c--:0,s==79&&o?n--,o--:0,s==87&&w?n--,w--:0,s==66&&b?n--,b--:0,s==69&&e?n--,e--:0,s==76&&l?n--,l--:0,putchar(s));
    //loop starts by printing the original string, then starts printing it again one character at a time until the required number of C,O,W,B,E,L letters are reached, then break (s=n?a[++z]:0) will return 0 when n is 0. Each letter subtracts from n only when it still requires letters of its type (e.g. b?n--,b--:0)

}

Деякі використані цікаві хитрощі:

• Під час перевірки символів я 'w'набираю значення char w, що становить 3 байти, але для символів, 'c'і 'b'я можу вводити їх ASCII значення 99 та 98 відповідно, щоб кожен раз зберігати байт. (Редагувати: Завдяки @Titus я знаю, що роблю це з усіма літерами COWBELL, використовуючи лише великі великі літери, які є усіма двобайтовими числовими значеннями ascii)

r=~-l/2в r=(l-1)/2використанні bitshifts

a[++i]Я отримую символ в індексі (i) і повторюю індекс одночасно. Я просто починаю iз i=-1замість i=0(роблю те саме zі запускаю, z=iщоб зберегти ще один байт)


1
Збережіть 8 байтів з великого введення: всі коди ASCII нижче 100.
Тит

@Titus Блискуче! Дякую Титусу, редагуючи зараз
Альберт Реншов

1
Наразі у нас є питання щодо вашого твердження "Другий визначений int (у даному випадку c) завжди встановлюється як 1 [...]". Ми будемо раді вашій заяві щодо того, чому ви так думаєте там, тому що для когось із нас це просто дивно.
cadaniluk

@Albert Можливо, ваша програма просто покладається на c,o,w,b,eініціалізацію до того самого значення, а не на 1? Тому що ваш підказ №2, здається, не відповідає дійсності, як мінімум, не знаю для ІП. Ви можете уточнити? ТАК питання
Фелікс Домбек

1
@FelixDombek дякую за те, що він також вказав на це! Це деф. невизначена поведінка, я просто моделював її (циклічно) на багатьох IDE, і, здається, завжди init int є 0. Я, мабуть, міг би залишити це все-таки, хоча моя логіка була розроблена так, щоб вони були встановлені на 1; факт, що тестові випадки працюють з ним на 0, я думаю, що це збіг. Ура
Альберт Реншоу

5

Python 2, 125 113 112 байт

n=lambda s:min(s.count(c)>>(c=='l')for c in "cowbel")
def f(s,i=0):
 while n(s)==n(s+s[:i]):i+=1
 return s+s[:i]

n підраховує кількість корів


-12 байт завдяки @Rod
-1 байт завдяки @Titus


Вам не потрібно []для розуміння списку , коли це єдиний параметр, також ви можете впасти enumerate: min(s.count(c)/-~(c=='l')for c in"cowbel")де -~(n=='l')коротший спосіб запису1+(n=='l')
Rod

1
Не >>було б коротше /-~?
Тіт

@Titus ти маєш рацію
ов

Була спроба редагування, яка видалила б байт, замінивши останній простір нового рядка на один крапку з комою.
Пшеничний майстер

@ Möbius Чи не був returnби тоді цикл while?
ов

5

Perl 6 , 91 байт

{my &c={.comb.Bag.&{|.<c o w b e>,.<l>div 2}.min}
first *.&c>.&c,($_ X~[\,](.comb)».join)}

Передбачає введення з малого регістру.

Як це працює

Усередині лямбда визначається інша лямбда для підрахунку кількості корів у рядок як така:

my &c={                                        }  # Lambda, assigned to a variable.
       .comb                                      # Split the string into characters.
            .Bag                                  # Create a Bag (maps items to counts).
                .&{                       }       # Transform it into:
                   |.<c o w b e>,                 #   The counts of those letters, and
                                 .<l>div 2        #   half the count of "l" rounded down.
                                           .min   # Take the minimum count.

Решта коду використовує цю внутрішню лямбда, &cщоб знайти результат, наприклад такий:

                     [\,](.comb)».join   # All prefixes of the input,
               ($_ X~                 )  # each appended to the input.
first         ,                          # Return the first one for which:
      *.&c>                              #   The cowbell count is greater than
           .&c                           #   the cowbell count of the input.

4

MATL , 38 37 байт

1 байт вимкнено завдяки ідеї @ DLosc використовувати рядок шаблону lcowbeзамістьcowbel

n`Gt@q:)hXK!'lcowbe'=s32BQ/kX<wy-Q]xK

Символи введення - це малі літери. Якщо вхід містить нові рядки, символ нового рядка потрібно вводити як його ASCII-код, з'єднаний із звичайними символами (див. Останній вхід у посиланні з усіма тестовими випадками).

Спробуйте в Інтернеті! Або перевірити всі тестові випадки .


3

JavaScript (ES6), 106 107 113 126 141

Перенесення на javascript відповіді Pip від @DLosc. Мені знадобився певний час, щоб повністю зрозуміти це, і це геніально.

Відредагуйте -15 байт за підказкою @Titus, безпосередньо додаючи символи до вхідного рядка aта уникаючи раннього повернення (так, ні for/if)

Редагувати 2, перераховуючи значення 6 для функції Min, зберігає інші 13 байт

Знову змінити 3 зміни функції c. Я думав, що багатослівний lengthі splitбуде занадто довгим. Я помилявся.

Припускаючи введення малих літер

a=>[...a].some(z=>c(a+=z)>b,c=a=>Math.min(...[...'lcowbe'].map((c,i)=>~-a.split(c).length>>!i)),b=c(a))&&a

Менше гольфу

a=>{
  c=a=>{ // cowbell functions - count cowbells
    k = [... 'lcowbe'].map((c,i) => 
          (a.split(c).length - 1) // count occurrences of c in a
           / (!i + 1) // divide by 2 if first in list ('l')
    );
    return Math.min(...k);
  };
  b = c(a); // starting number of cowbells
  [...a].some(z => ( // iterate for all chars of a until true
    a += z,
    c(a) > b // exit when I have more cowbells
  ));
  return a;
}

Тест

f=
a=>[...a].some(z=>c(a+=z)>b,c=a=>Math.min(...[...'lcowbe'].map((c,i)=>~-a.split(c).length>>!i)),b=c(a))&&a

;["christopher walken begs for more cowbell!"
,"the quick brown fox jumps over the lazy dog"
,"cowbell"
,"cowbell cowbell cowbell"
,"cowbell cowbell cowbel"
,"bcelow"
,"abcdefghijklmnopqrstuvwxyz"
,"cccowwwwbbeeeeelllll"
,"be well, programming puzzles & code golf"
,"lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. wow!"
,`c-c-b-c
 
i have a cow, i have a bell.
uh! bell-cow!
i have a cow, i have a cowbell.
uh! cowbell-cow!
 
bell-cow, cowbell-cow.
uh! cow-cowbell-bell-cow.
cow-cowbell-bell-cow!
`].forEach(x=>console.log(x+'\n\n'+f(x)))


Я думаю, що k[x]++це не вдасться через undefined. Але я впевнений, що це for(i=0;c(a)==c(a+=a[i++]);),aпрацює.
Тит

@Titus Я не впевнений, що розумію. Спробую
edc65

@Titus wow 15 байт збережено, спасибі багато
edc65

>>!iекономить 3 байти. Чому ви не використовуєте c(a+=z)?
Тит

@Titus я використовую c(a+=z). Не в менш гольф- версії, як це, бачите, менш гольф. Використання >>!iзаощаджує 1 байт (у версії для гольфу). Ще раз
дякую

2

Утиліти Bash + Unix, 184 байти

f()(tr -cd cowbel<<<"$1"|sed 's/\(.\)/\1\
/g'|sort|uniq -c|awk '{print int($1/(($2=="l")?2:1))}'|sort -n|head -1)
for((m=1;`f "$1${1:0:m}"`!=$[`f "$1"`+1];m++)){ :;}
echo "$1${1:0:$m}"

Спробуйте в Інтернеті!

Дякуємо @AlbertRenshaw для гри в гольф на 2 байти.


Це можна пограти в гольф, наприклад, просто вилучивши пробіли до і після!=
Альберт Реншо

1
@AlbertRenshaw Дякую - я думав, що я спробував це і отримав синтаксичну помилку, але ти маєш рацію. Частина awk може бути ще й гольфувальною; Я не дуже знайомий з awk.
Мітчелл Спектор

Так, я наївно намагався видалити інші пробіли та рядки у вашому коді, і отримував синтаксичні помилки, але на цьому він працював ¯_ (ツ) _ / ¯
Альберт Реншо

2

JavaScript (ES6), 124 114 байт

Завдяки Нілу за збереження кількох байт

a=>eval("for(c=0,d=a;(A=$=>Math.min([...'cowbel'].map(_=>($.split(_).length-1)>>(_=='l'))))(a)==A(d+=a[c++]););d")

Оскільки це сильно відрізняється від вже існуючої відповіді на JavaScript, і я вкладав досить багато часу на це, я вирішив створити відповідь сам.

Використання

f=a=>eval("for(c=0,d=a;(A=$=>Math.min([...'cowbel'].map(_=>($.split(_).length-1)>>(_=='l'))))(a)==A(d+=a[c++]););d")
f("cowbell")

Вихідні дані

"cowbellcowbell"

.sort()[0]- дивовижна ідея. evalє зло. : D
Тіт

Дякую ;-) Я спочатку використовував Math.min(), але це коштувало багато символів, і я вважав, що буде коротший шлях. І так, evalце справді приємно для гольфу.
Лука

Якби це .sort()[0]працювало, це коштувало б лише 10 байт, але це не так, а .sort((a,b)=>a-b)[0]коштує 20 байт, а Math.min(...)коштує лише 13.
Ніл,

2

Октава, 80 87 97 байт

s=input('');k=1;do;until(x=@(A)min(fix(sum('cowbel'==A')./('111112'-48))))(b=[s s(1:++k)])>x(s);b

Спробуйте в Інтернеті!


1
Це не спрацьовує, коли нам потрібно два lс, щоб виконати додатковий каучук. Наприклад, при введенні cowbellвін неправильно повертається, cowbellcowbelа не cowbellcowbell. (Сподіваюся, ви зможете це виправити. Мені подобається нетиповий алгоритм!)
Грег Мартін

@GregMartin Дякую! Я буду його чекати!
rahnema1

2

CJam, 37

q___S\+{+"cowbel"1$fe=)2/+:e<\}%()#)<

Спробуйте в Інтернеті

Якщо я можу виключити символи "та \символи, то…

35 байт

q___`{+"cowbel"1$fe=)2/+:e<\}%()#)<

Спробуйте в Інтернеті

Пояснення

Код послідовно додає кожен символ рядка до початкового рядка (переходить від початкового до подвоєного), визначає кількість ковзанок для кожної струни (підраховуючи кількість зустрічань кожного символу в "cowbel" і ділить на "l" на 2, потім приймаючи мінімум), знаходить положення першої струни, де кількість обмоток збільшується на 1, потім бере відповідний префікс введення і ставить його після рядка введення.

Для того щоб також включити оригінальну рядок (без доданого символу), код додає нейтральний символ до рядка, який повторюється. Перша версія передбачає пробіл, а друга версія використовує рядкове представлення, тобто рядок між подвійними лапками.

q___          read input and make 3 more copies: one for output, one for prefix,
               one for appending and one for iterating
S\+           prepend a space to the iterating string
              or
`             get the string representation
{…}%          map each character of the string
  +           append the character to the previous string
  "cowbel"    push this string
  1$          copy the appended string
  fe=         get the number of occurrences of each "cowbel" character
  )2/+        take out the last number, divide by 2 and put it back
  :e<         find the minimum
  \           swap with the appended string
(             take out the first number (cowbells in the initial string)
)#            increment and find the index of this value in the array
)             increment the index (compensating for taking out one element before)
<             get the corresponding prefix
              another copy of the input is still on the stack
              and they are both printed at the end

Я добре з вами, виключаючи символи "і \!"
Грег Мартін,

1

PHP, 133 байт

порту PHP в порту JavaScript @ edc65 на відповідь DLosc Pip.

function f($s){for(;$c=lcowbe[$i];)$a[$c]=substr_count($s,$c)>>!$i++;return min($a);}for($s=$argv[1];f($s)==f($s.=$s[$i++]););echo$s;

бере аргументи з нижнього регістру з аргументу командного рядка. Бігайте з -nr.

зламатися

// function to count the cowbells:
function f($s)
{
    for(;$c=lcowbe[$i];)            # loop through "cowbel" characters
        $a[$c]=substr_count($s,$c)  # count occurences in $s
            >>!$i++;                # divide by 2 if character is "l" (first position)
        return min($a);             # return minimum value
}
for($s=$argv[1];    # copy input to $s, loop:
    f($s)               # 1. count cowbells in $s
    ==                  # 3. keep looping while cowbell counts are equal
    f($s.=$s[$i++])     # 2. append $i-th character of $s to $s, count cowbells
;);
echo$s;             # print $s
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.