Растяни слово

50

Вводимые слова - это строчные буквы, не разделенные пробелами. Новая строка в конце необязательна.

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

Пример ввода:

bonobo

Пример вывода:

bonoobbooo

Применяются стандартные правила ввода / вывода. Самый короткий код в байтах побеждает.

Тесты предоставлены @Neil:

tutu -> tuttuu
queue -> queuuee
bookkeeper -> boookkkeeepeeer
repetitive -> repeetittiiveee
uncopyrightables -> uncopyrightables
abracadabra -> abraacaaadaaaabbrraaaaa
mississippi -> misssiisssssssiiipppiiii
mIllIbyte
источник

Ответы:

36

Желе , 4 байта

;\f"

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

Как это устроено

;\f"  Main link. Argument: S (string)

;\    Cumulatively reduce by concatenation.
      This yields the array of all prefixes of S.
  f"  Vectorized filter.
      Keep only occurrences of the nth letter in the nth prefix.
Деннис
источник
21
Ну, тогда ... Пип Пип.
Аднан,
2
Этот сайт становится конкурсом на лучший универсальный язык игры в гольф ... не то чтобы это плохо.
Шелваку
8
@shelvacu Последнее спорно, 2 друзей я показал PPCG, что сказал что - то вдоль линий «всех лучших ответов только с использованием языков для гольфа» как первое впечатление.
Безумный
@ Insane есть / есть. Кодовый гольф - довольно распространенная вещь. Так что языки объединяются исключительно для этой цели.
Эван Карслэйк
Как это работает?
Эрик Outgolfer
21

Pyth, 6 байт

Спасибо @Doorknob за удаление 1 байта.

Спасибо @Maltysen за удаление 5 байтов.

s@VQ._

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

Как это устроено


Например, возьмите строку "bonobo".

._ составляет список: ['b', 'bo', 'bon', 'bono', 'bonob', 'bonobo']

VQ._означает «предшествующая функция, векторизованная (примененная параллельно) над Qи ._», что означает Q(оцениваемый вход) будет обрабатываться как список: ['b', 'o', 'n', 'o', 'b', 'o']и затем они будут соединены @следующим образом:

     Q      ._         @ (intersect)
0:  'b'     'b'       'b'
1:  'o'     'bo'      'o'
2:  'n'     'bon'     'n'
3:  'o'     'bono'    'oo'
4:  'b'     'bonob'   'bb'
5:  'o'     'bonobo'  'ooo'

Поэтому @VQ._будем производить ['b', 'o', 'n', 'oo', 'bb', 'ooo'].

Затем sон объединяет их все вместе, создавая строку 'bonoobbooo', которая затем неявно распечатывается, чтобы стать bonoobbooo.

Дрянная Монахиня
источник
2
Кенни, ваше объяснение неверно. VQозначает только for N in Qкогда он не внутри функции. В этом случае на самом деле происходит то, что @Vозначает, что @функция векторизована (применяется параллельно) для следующих двух аргументов, Qи ._. Этого нет в документации, поэтому я исправлю это.
Исаак
14

Сетчатка , 34 19 байт

Сэкономьте 15 байт, вдохновившись решением Исаака.

Количество байтов предполагает кодировку ISO 8859-1.


$`¶
(\D)(?!.*\1¶)

Ведущие и конечные пустые строки имеют большое значение.

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

объяснение


$`¶

Это этап замены, который соответствует пустому регулярному выражению (то есть каждой позиции нулевой ширины в строке) и заменяет $`¶его, где $`есть префикс соответствия и вставляет перевод строки. Это в основном вычисляет все префиксы и помещает их в отдельную строку вместе с последним символом этого префикса:

bb
obo
oboo
kbook
kbookk
ebookke
ebookkee
pbookkeep
ebookkeepe
rbookkeeper

Будут некоторые ведущие и конечные переводы строк, но мы можем их игнорировать.

Из каждого из этих префиксов мы хотим сохранить символы, равные последнему символу. Для этого мы используем другой этап замены:

(\D)(?!.*\1¶)

Это соответствует всему, что мы не хотим хранить, и заменяет его ничем. Мы сопоставляем любой символ (используя, \Dтак как мы знаем, что на входе не будет цифр), а затем проверяем, что в конце строки нет другой копии этого символа.

Мартин Эндер
источник
11

Python, 56 байт

Кажется, я застрял с двумя ответами одинаковой длины:

f=lambda x,*y:x and-~y.count(x[0])*x[0]+f(x[1:],x[0],*y)
f=lambda x,y=0:x[y:]and-~x[:y].count(x[y])*x[y]+f(x,y+1)

Изменить: см . Ответ @ pacholik для более короткого, альтернативного подхода Python.

Sp3000
источник
Я не привык избивать вас своими ответами> <>, я жду ответа Gol> <>, чтобы это исправить;)
Аарон,
@Aaron Жаль, я на самом деле буду бить вас обратно с> <>: P
Sp3000
Линейный шум в Python? Какая ересь !
кот
Что делает ~? Я знаю, что это побитовое НЕ с последующим отрицанием, но что вы пытаетесь сделать, чтобы сэкономить несколько байтов?
Ник Хартли
2
@QPaysTaxes Это инкремент +1с достаточно высоким приоритетом, так что парены не нужны
Sp3000
10

Haskell, 39 байт

f""=""
f x=f(init x)++filter(==last x)x

Пример использования: f "bonobo"-> "bonoobbooo".

Достаточно отличается от ответа @ Damien . Создает строку справа, извлекая все вхождения последнего символа из строки и добавляя рекурсивный вызов со всеми, кроме последнего символа.

Ними
источник
9

> <> , 27 байт

>i:0g1+:\
:{-1v!?:<}o
/p${/

Требуется официальный интерпретатор, который выходит с ошибкой при попытке напечатать кодовую точку -1. Попробуйте онлайн!

Код читает входные данные по одному символу за раз и использует первую строку кодового окна в виде большого массива, в котором хранится количество раз, которое каждый символ просматривался до сих пор (> <> инициализирует непрограммные ячейки равными 0). Вторая строка представляет собой цикл для вывода символа несколько раз.

Кроме того, вот версия, которая выходит чисто (37 байт, не правильно гольф):

>i:0(?;:0g1+:\
}o:{-1v!?:   <
v  p${<
Sp3000
источник
Черт, это хорошо! Я должен был бы прекратить так сильно полагаться на онлайн-переводчика, я бы никогда не подумал о простом использовании такого огромного кодового поля, и я даже не знал, что официальный переводчик вышел из -1 печати
Аарон
2
@ Аарон Да, это следствие ошибки Python при попытке сделать это chr(-1). Анимационный переводчик отлично подходит для визуализации, но, к сожалению, некоторые расхождения с официальным переводчиком немного раздражают: /
Sp3000
9

JavaScript (ES6), 48 45 байт

s=>s.replace(n=/./g,c=>c.repeat(n[c]=-~n[c]))

Редактировать: 3 байта сохранены благодаря @ user81655.

Нил
источник
8

Haskell, 50 42 41 байт

Сохранено 8 байтов благодаря Линн

f t=[c|(i,c)<-zip[1..]t,x<-take i t,c==x]
Damien
источник
1
Как насчет:f t=[c|(i,c)<-zip[0..]t,j<-[0..i],c==t!!j]
Линн
8

MATL , 8 байт

tt!=RsY"

Попробуйте онлайн! Или проверьте все тестовые случаи одновременно .

объяснение

t    % take input string implictly. Duplicate
t!   % duplicate and transpose into a column
=    % test for equality with broadcast. Gives an NxN array, where N is
     % input string length
R    % upper triangular part: set entries below the diagonal to 0
s    % sum of each column. For each postion in the input, gives how many
     % times that letter has appeared up to that position
Y"   % replicate elements (run-length decoding). Display implicitly
Луис Мендо
источник
8

Лабиринт , 54 25 байт

<#; "#: ={},>
 }=}(.);("@

Другой сотрудни с @ MartinBüttner, который на самом деле сделал большинство почти все игры в гольф для этого. Переработав алгоритм, нам удалось значительно сократить размер программы!

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

объяснение

Быстрый лабринтный учебник:

  • Лабиринт - это двумерный язык на основе стека. Есть два стека, основной и вспомогательный, и выталкивание из пустого стека дает ноль.

  • На каждом перекрестке, где есть несколько путей перемещения указателя инструкции вниз, проверяется вершина основного стека, чтобы увидеть, куда идти дальше. Отрицательный - поворот налево, ноль - прямой, а положительный поворот направо.

Два стека целых чисел произвольной точности не очень гибки с точки зрения параметров памяти. Чтобы выполнить подсчет, эта программа фактически использует два стека в качестве ленты, смещая значение из одного стека в другой, сродни перемещению указателя памяти влево / вправо по ячейке. Это не совсем то же самое, поскольку нам нужно тащить счетчик петель с собой по пути вверх.

введите описание изображения здесь

Во-первых, <и >на каждом конце вставьте смещение и поверните строку кода, которая смещена на единицу влево или вправо. Этот механизм используется для того, чтобы код выполнялся в цикле - он <выталкивает ноль и поворачивает текущую строку влево, помещая IP-адрес справа от кода, а >выталкивает еще один ноль и фиксирует строку обратно.

Вот что происходит на каждой итерации по отношению к диаграмме выше:

[Section 1]
,}    Read char of input and shift to aux - the char will be used as a counter
      to determine how many elements to shift

[Section 2 - shift loop]
{     Shift counter from aux
"     No-op at a junction: turn left to [Section 3] if char was EOF (-1), otherwise
      turn right
(     Decrement counter; go forward to [Section 4] if zero, otherwise turn right
=     Swap tops of main and aux - we've pulled a value from aux and moved the
      decremented counter to aux, ready for the next loop iteration

[Section 3]
@     Terminate

[Section 4]
;     Pop the zeroed counter
)     Increment the top of the main stack, updating the count of the number of times
      we've seen the read char
:     Copy the count, to determine how many chars to output

[Section 5 - output loop]
#.    Output (number of elements on stack) as a char
(     Decrement the count of how many chars to output; go forward to [Section 6]
      if zero, otherwise turn right
"     No-op

[Section 6]
}     Shift the zeroed counter to aux

[Section 7a]
This section is meant to shift one element at a time from main to aux until the main
stack is empty, but the first iteration actually traverses the loop the wrong way!

Suppose the stack state is [... a b c | 0 d e ...].

=     Swap tops of main and aux               [... a b 0 | c d e ...]
}     Move top of main to aux                 [... a b | 0 c d e ...]
#;    Push stack depth and pop it (no-op)
=     Swap tops of main and aux               [... a 0 | b c d e ...]
      Top is 0 at a junction - can't move
      forwards so we bounce back
;     Pop the top 0                           [... a | b c d e ... ]

The net result is that we've shifted two chars from main to aux and popped the
extraneous zero. From here the loop is traversed anticlockwise as intended.

[Section 7b - unshift loop]

#     Push stack depth; if zero, move forward to the <, else turn left
}=    Move to aux and swap main and aux, thus moving the char below (stack depth)
      to aux
;     Pop the stack depth
Sp3000
источник
7

Perl, 17

(16-байтовый код, +1 для -p)

s/./${$&}.=$&/ge

Использование:

perl -pe 's/./${$&}.=$&/ge' <<< 'bonobo'
bonoobbooo
Дом Гастингс
источник
7

Pyth, 7 байт

s@Led._

Тестирование

Тестовый набор благодаря DenkerAffe

Объяснение:

s@Led._
     ._    All prefixes, implicitly applied to the input.
 @L        Filter each prefix for characters equal to
   ed      the last character of the prefix
s          Concatenate and implicitly print.
isaacg
источник
6

Python 3, 52

def f(s):*s,x=s;return s and f(s)+x+x*s.count(x)or x
pacholik
источник
4
Ах, идти с конца имеет гораздо больше смысла! Вы можете сделать это короче в лямбде, без необходимости в Python 3, а именно:f=lambda s:s and f(s[:-1])+s[-1]*s.count(s[-1])
Sp3000
Я думал, что так можно и сделать. Но я не люблю подписку на Python: P
pacholik
5

PowerShell v2 +, 52 47 байт

$b=@{};-join([char[]]$args[0]|%{"$_"*++$b[$_]})

Создает пустую хеш-таблицу, сохраняет ее в $b. Это наш «счетчик» того, какие буквы мы видели. Затем мы берем входные данные $args[0], приводим их как массив символов и отправляем через цикл. На каждой итерации мы берем текущий символ "$_"и умножаем его на предварительно увеличенный счетчик с заданным значением, что приведет к умножению первого вхождения 1, второго на 2и так далее. Мы инкапсулируем это -joinтак, чтобы выводилось все одно слово.

Благодаря TessellatingHeckler мы сохранили 5 байтов , используя вместо массива хеш-таблицу, поэтому нам не нужно уменьшать символ ASCII, 97чтобы получить соответствующий индекс. Это работает, потому что предварительное увеличение индекса хеша неявно вызывает .Add()в фоновом режиме, если этот индекс не существует, поскольку хеш-таблицы являются изменяемыми.

PS C:\Tools\Scripts\golfing> .\stretch-the-word.ps1 tessellatingheckler
tessseelllattingheeeckllleeeer
AdmBorkBork
источник
@ TessellatingHeckler Действительно - спасибо!
AdmBorkBork
5

Дьялог АПЛ , 6 байтов

∊,\∩¨⊢

TryAPL!

Четыре функции наверху (2 поезда) вилки (3 поезда):

┌──┴──┐  
∊ ┌───┼─┐
  \   ¨ ⊢
┌─┘ ┌─┘  
,   ∩    

Сначала (справа - без операции) в данной строке, давая'bonobo'

Затем ,\(сканирование конкатенации) на строку, давая'b' 'bo' 'bon' 'bono' 'bonob' 'bonobo'

Два разветвляются вместе с (дано как правый и левый аргументы) ∩¨(пересечение каждого), то ('b'∩'b') ('bo'∩'o') ('bon'∩'n') ('bono'∩'o') ('bonob'∩'b') ('bonobo'∩'o')есть'b' 'o' 'n' 'oo' 'bb' 'ooo'

Наконец, (enlist) применяется к результату, чтобы сгладить его, давая'bonoobbooo'

Эй, по крайней мере, это соответствует Pyth ! Очевидно, что Jelly короче, так как это версия J для гольфа, которая, в свою очередь, представляет собой продвинутый диалект APL с 2 символами на функцию.

Адам
источник
4

Pyth, 11 байт

s.e*b/<Qhkb

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

объяснение

se * b / <Qhkb # Q = ввод

 .e # отображать входные данные с b в качестве значения и k в качестве индекса (Q добавляется в конце неявно)
      <Qhk # взять первые k + 1 символов Q
     / b # подсчитать вхождения b там
   * b # повторить b столько раз
s # объединить полученный список в одну строку
Denker
источник
4

J 11 байт

#~+/@(={:)\

Это монадический глагол. Попробуй это здесь. Использование:

   f =: #~+/@(={:)\
   f 'tutu'
'tuttuu'

объяснение

#~+/@(={:)\
     (   )\  For each non-empty prefix:
       {:      Take last element,
      =        compare for equality to the others and itself
  +/@          and take sum (number of matches).
#~           Replicate original elements wrt the resulting array.
Zgarb
источник
4

05AB1E , 10 байтов

Код:

$vy«Dy¢y×?

Объяснение:

$           # Push the number 1 and input
 v          # Map over the input string
  y«        # Concat the letter to the previous string (initial 1)
    D       # Duplicate this string
     y¢     # Count the occurences of the current character in the string
       y×   # Multiply this number with the current character
         ?  # Pop and print without a newline

Использует кодировку CP-1252 . Попробуйте онлайн!

Аднан
источник
3

CJam, 14

q:A,{)A<_)--}/

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

Объяснение:

q:A      read the input and store in A
,        get the string length
{…}/     for each number from 0 to length-1
  )      increment the number
  A<     get the prefix of A with that length
  _      duplicate it
  )      separate the last character
  -      remove it from the rest of the prefix
  -      remove all the remaining characters (different from the last one)
          from the prefix
aditsu
источник
2

Perl 6, 37 байт

{.split('').map({$_ x++%.{$_}}).join}
Вен
источник
2

> <> , 52 байта

i:0(?;&l:?!v1-$:&:&=?\}70.>
6f+0.00o:&~/         \:o

Он складывает каждое прочитанное письмо, печатает их один раз и снова для каждого подобного письма в стопке.
Он использует &регистр, потому что необходимость обрабатывать 3 переменные в стеке (текущая буква чтения, позиция в стеке, буква в этой позиции) - это боль.

Вы можете попробовать это здесь !

Аарон
источник
2

Ржавчина, 176 байт

fn s(w:&str)->String{let mut m=std::collections::HashMap::new();w.chars().map(|c|{let mut s=m.remove(&c).unwrap_or(String::new());s.push(c);m.insert(c,s.clone());s}).collect()}

Это использует карту для хранения строки для каждого символа на входе. Для каждого символа строка будет удалена с карты, соединена с символом, вставлена ​​обратно в карту и добавлена ​​к выходным данным.

Я хотел бы использовать get(...)вместо remove(...), но проверка заимствования заставила меня передумать.

ECS
источник
2

Mathcad, 66 байт

К сожалению, Mathcad не обладает особенно хорошей обработкой строк, поэтому я преобразовал входную строку в вектор, а затем использовал вектор (индексированный код символа), чтобы отслеживать количество встречений символа, добавляя символ, который количество раз, чтобы вектор результата. Наконец, вектор результата преобразуется обратно в строку. Довольно долго, к сожалению.

введите описание изображения здесь

Обратите внимание, что Mathcad использует двумерный интерфейс «белой доски» со смесью обычного текста и операторов; операторы обычно вводятся с помощью панели инструментов или сочетания клавиш; например, ctl- # вводит оператор цикла for, который содержит ключевое слово for, символ element-of и 3 пустых "заполнителя" для переменной итерации, выражений range и body соответственно. Typing [после того, как имя переменной входит в режим индекса массива, Typing 'вводит пару подходящих скобок (в основном ... есть исключения в зависимости от того, что еще находится в окружающем выражении )

Стюарт Бруфф
источник
2

Javascript ES6 44 байта

q=>q.replace(/./g,a=>x[a]=(x[a]||'')+a,x=[])

старый ответ

Javascript ES6 46 байтов

q=>(x=[...q]).map(a=>x[a]=(x[a]||'')+a).join``

//thanks user81655 for -1 byte
Чарли Винн
источник
1
Вы можете сохранить байт, перейдя xво входной массив ->q=>(x=[...q]).map(a=>x[a]=(x[a]||'')+a).join``
user81655
2

Юлия, 38 35 байт

!s=[]==s?s:[!s[1:end-1];ss[end]]

I / O находится в массивах символов. Попробуйте онлайн!

Как это устроено

Мы (пере) определяем монадический оператор ! для наших целей.

Когда ! вызывается, он проверяет, является ли его аргумент s пустым. Если это так, он возвращает свой аргумент.

Если s не пусто, мы пересекаем s с последним символом ( s[end]), который возвращает все вхождения этого символа в s . Этот результат объединяется с возвращаемым значением рекурсивного вызова ! с s минус последний символ ( s[1:end-1]) в качестве аргумента.

Деннис
источник
2

PHP, 54 51 50 47 байт

for(;$C=$argn[$X++];)echo str_repeat($C,++$$C);

Запустите так:

echo abracadabra | php -nR 'for(;$C=$argn[$X++];)echo str_repeat($C,++$$C); echo"\n";'

Tweaks

  • Сохранено 3 байта с помощью переменных переменных. Изменены используемые переменные в верхний регистр, чтобы предотвратить столкновение
  • Сохраненные байты, удаляя приведение типа nullв intстроку смещения, как строка смещения отливают междунар все равно
  • Сохранено 3 байта при использовании $argnвместо $argv(thx Titus)
aross
источник
Используйте $argnс, -Rчтобы сохранить еще три байта.
Тит
О, и -nдолжен сделать то же самое, что и your -d error_reporting: nозначает no config file, что в конфигурации по умолчанию уведомления отключены; так -nr(соответственно -nR) должно хватить.
Тит
@Titus 2 года ответ, но все равно ТНХ :)
aross
1

Mathematica, 57 байт

StringReplace[Clear@c;c@_=0;#,x_:>x~StringRepeat~++c[x]]&

Мы используем c[x]в качестве справочной таблицы, как часто персонаж xуже встречался. Это увеличивается каждый раз, когда это извлекается в x~StringRepeat~++c[x]. К сожалению, чтобы сделать функцию многократно используемой, нам нужно каждый раз сбрасывать таблицу поиска Clear@c;c@_=0;, что довольно дорого.

Мартин Эндер
источник
1

awk, 72 байта

BEGIN{FS=""}{for(i=1;i<=NF;i++){a[$i]++;for(j=0;j<a[$i];j++)printf $i}}

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

rexkogitans
источник
1

Луч, 32 33 42 байта

Это должно было быть меньше, но я потерял несколько байтов, инициализируя слоты памяти равными 0. Замена некоторых направлений потока позволила устранить много пустого пространства.

 >+\
vus/
>rnH
  >g'\
(@v's/
^`<

Попробуйте это в этом фрагменте

Общее объяснение.

  • Установите все слоты памяти от 0-255 до 0
  • Считайте во входном значении ascii в луч
  • Если луч останавливается на 0 (луч = магазин)
  • Получить значение памяти [луч] в хранилище, увеличить его и сохранить обратно
  • Уменьшите магазин до 0, распечатав символ луча
  • Повторение
MickyT
источник
1

Python, 66 62 байта

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

Golfed

def s(w,o=[],n=""):
 for x in w:o+=x;n+=x*o.count(x)
 return n

Ungolfed

def stretch(word):
    occurrences = []
    newWord = ""
    for w in word:
        occurrences.append(w)
        newWord += w * occurrences.count(w)
    return newWord
Арженис Гарсия
источник