Довжина-кодуйте рядок


18

Припустимо, ми використовуємо наступні правила для витягання однієї рядка з іншої рядка, яка містить лише символи для друку ASCII і називається- *string. Якщо рядок закінчується до того, як процес зупиниться, це помилка, і результат процесу не визначений у такому випадку:

  1. Починати з d=1, s=""
  2. Щоразу, коли ви стикаєтесь з a *, помножте dна 2. Щоразу, коли ви зустрінете іншого символу, з'єднайте його в кінець sі відніміть 1 з d. Якщо зараз d=0, зупиніть і повернітьсяs

Визначені приклади :

d->d
769->7
abcd56->a
*abcd56->ab
**abcd56->abcd
*7*690->769
***abcdefghij->abcdefgh

Не визначені приклади : (зауважте, що порожній рядок також буде одним із таких)

*7
**769
*7*
*a*b
*

Ваше завдання - взяти рядок і повернути найкоротший *рядок, який виробляє цю нитку.

Приклади програми :

7->7
a->a
ab->*ab
abcd->**abcd
769->*7*69

Ваша програма повинна обробляти будь-яку рядок, що містить принаймні один символ та лише *символи, що не надруковані ASCII для друку. Ніколи не можна повертати рядки, для яких процес не визначений, оскільки за визначенням вони не можуть створювати БУДЬ-яких рядків.

Застосовуються стандартні лазівки та правила вводу / виводу.


Чи можна припустити, що вхід не містить *?
Луїс Мендо

3
@DonMuesli "Тільки символи, що не друкуються ASCII"
FryAmTheEggman

Відповіді:


3

Pyth ( 36 27 байт)

Дякую Якубе за покращення в 9 байт! Наразі не так добре, як відповідь каламутника , але все одно

KlzJ1VzWgKyJp\*=yJ)pN=tK=tJ

Тестовий сюїт

Переклад на python:

                            | z=input() #occurs by default
Klz                         | K=len(z)
   J1                       | J=1
     Vz                     | for N in z:
       WgKyJ                |   while K >= J*2:
            p\*             |     print("*", end="")
               =yJ          |     J=J*2
                  )         |     #end inside while
                   pN       |   print(N, end="")
                     =tK    |   K=K-1
                        =tJ |   J=J-1

1
Мадяни, схоже, загинули ...
1616

5

JavaScript (ES6), 61 байт

f=(s,d=2)=>s?d>s.length?s[0]+f(s.slice(1),d-2):'*'+f(s,d*2):s

Рекурсивна функція, яка виконує наступні дії:

  • Якщо dменше або дорівнює іншій довжині рядка, розділеній на 2:

    Додайте *до виводу та помножте dна 2

  • Ще:

    Зсуньте рядок і додайте до виводу, відніміть 1 d.

Дивіться це в дії:

f=(s,d=2)=>s?d>s.length?s[0]+f(s.slice(1),d-2):'*'+f(s,d*2):s

input.oninput = e => output.innerHTML = f(input.value);
<input id="input" type="text"/>
<p id="output"></p>


1
Збережіть 2 байти, працюючи з подвійним значенням d плюс більший байт, скасувавши умову:f=(s,d=2)=>s?d>s.length?s[0]+f(s.slice(1),d-2):'*'+f(s,d*2):s
Ніл


2

C, 125 байт

main(int q,char**v){++v;int i=1,n=strlen(*v);while(n>(i*=2))putchar(42);for(i-=n;**v;--i,++*v)!i&&putchar(42),putchar(**v);}

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

По суті, у вас завжди будуть 2^floor(log_2(length))зірки на початку виводу, а кінцева зірка після 2^ceil(log_2(length)) - lengthсимволів (якщо це може бути принаймні 1 символом).

Версія (злегка) без вогонь наступна

main(int q,char**v){
   ++v;                         // refer to the first command line argument
   int i=1, n=strlen(*v);       // set up iteration variables

   while(n > (i*=2))            // print the first floor(log2(n)) '*'s
      putchar(42);

   for(i-=n;  **v;  --i, ++*v)  // print the string, and the final '*'
      !i&&putchar(42),putchar(**v);
}

1

JavaScript (ES6), 88 77 байт

f=(s,l=s.length,p=2)=>l<2?s:p<l?"*"+f(s,l,p*2):s.slice(0,p-=l)+"*"+s.slice(p)

Спочатку я думав, що abcdeце має бути, *a**bcdeале виявилося, що це **abc*deпрацює так само добре. Це означає, що вихід легко будується за допомогою провідних зірок підлоги (log₂ (s.length)) плюс додаткова зірка для струн, довжина яких не має потужності дві.

Редагувати: Збережено 8 байт шляхом обчислення кількості провідних зірок рекурсивно. Збережено ще 3 байти за допомогою рядків зі спеціальним кожухом довжиною 1, щоб я міг розглядати рядки, довжина яких потужністю 2, як додаткові провідні зірки.


0

Хаскелл, 68 байт

f d[]=""
f d xs|length xs>=d*2='*':f(d*2)xs
f d(x:xs)=x:f(d-1)xs

Точно так само, як і інші відповіді. Якщо EOF, виведіть порожній рядок. Якщо залишилася довжина більше двох разів d, виведіть зірку та подвійну d. В іншому випадку виведіть наступний символ і відніміть його d.

Безголівки:

f d (  [])                    = ""
f d (  xs) | length xs >= d*2 = '*' : f (d*2) xs
f d (x:xs)                    =  x  : f (d-1) xs
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.