Кодирование длины строки


18

Предположим, мы используем следующие правила для извлечения одной строки из другой строки, содержащей только печатаемые символы ASCII и называемой *-string. Если строка заканчивается до остановки процесса, это является ошибкой, и результат процесса в этом случае не определен:

  1. Начать с d=1, s=""
  2. Всякий раз, когда вы сталкиваетесь с *, умножьте 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 байт)

Спасибо Jakube за 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
Грязная рыба, кажется, умерла
Rɪᴋᴇʀ

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

  • Else:

    Сдвиньте строку и добавьте к выводу, вычтите 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

Haskell, 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.

Ungolfed:

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.