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


50

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

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

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

bonobo

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

bonoobbooo

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

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

tutu -> tuttuu
queue -> queuuee
bookkeeper -> boookkkeeepeeer
repetitive -> repeetittiiveee
uncopyrightables -> uncopyrightables
abracadabra -> abraacaaadaaaabbrraaaaa
mississippi -> misssiisssssssiiipppiiii

Ответы:


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.


Я не привык избивать вас своими ответами> <>, я жду ответа 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${<

Черт, это хорошо! Я должен был бы прекратить так сильно полагаться на онлайн-переводчика, я бы никогда не подумал о простом использовании такого огромного кодового поля, и я даже не знал, что официальный переводчик вышел из -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]

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


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.

6

Python 3, 52

def f(s):*s,x=s;return s and f(s)+x+x*s.count(x)or x

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

@ 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 # объединить полученный список в одну строку

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.

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


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(...), но проверка заимствования заставила меня передумать.


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)

Используйте $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}}

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


1

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

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

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

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

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.