Stretch the word

50

5

The input is a word of lowercase letters not separated by whitespace. A newline at the end is optional.

The same word must be output in a modified version: For each character, double it the second time it appears in the original word, triple it the third time etc.

Example input:

bonobo

Example output:

bonoobbooo

Standard I/O rules apply. The shortest code in bytes wins.

Tests provided by @Neil :

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

mIllIbyte

Posted 2016-04-04T11:32:04.670

Reputation: 1 129

Answers

36

Jelly, 4 bytes

;\f"

Try it online!

How it works

;\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.

Dennis

Posted 2016-04-04T11:32:04.670

Reputation: 196 637

21Well then... rip Pyth. – Adnan – 2016-04-04T14:16:17.270

2This site is becoming a competition for the best general-purpose golfing language... not that that's a bad thing. – Shelvacu – 2016-04-04T23:34:52.083

8@shelvacu The latter is debatable, 2 friends I've shown PPCG to have said something along the lines of "all the top answers are just using golf languages" as a first impression. – Insane – 2016-04-05T06:37:20.673

@Insane there is/ are. Code golf is a pretty common thing. So languages are put together for that purpose, exclusively. – Evan Carslake – 2016-04-06T23:53:04.590

How does this.... work? – Erik the Outgolfer – 2016-10-04T15:22:50.330

21

Pyth, 6 bytes

Thanks to @Doorknob for taking off 1 byte.

Thanks to @Maltysen for taking off 5 bytes.

s@VQ._

Try it online!

How it works


For example, take the string "bonobo".

._ makes a list: ['b', 'bo', 'bon', 'bono', 'bonob', 'bonobo']

VQ._ means "the preceding function vectorized (applied in parallel) over Q and ._", which means Q (the input evaluated) will be treated as a list: ['b', 'o', 'n', 'o', 'b', 'o'], and then they will be paired by the @ like this:

     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'

Therefore, @VQ._ will produce ['b', 'o', 'n', 'oo', 'bb', 'ooo'].

The s then joins them all together, creating a string 'bonoobbooo', which is then implicitly printed out to become bonoobbooo.

Leaky Nun

Posted 2016-04-04T11:32:04.670

Reputation: 45 011

2Kenny, your explanation is wrong. VQ only means for N in Q when it is not inside a function. In this case, what's actually going on is that @V means the @ function vectorized (applied in parallel) over its next two arguments, Q and ._. This is missing from the docs, so I'll fix it. – isaacg – 2016-04-05T06:11:49.507

14

Retina, 34 19 bytes

Saved 15 bytes by taking some inspiration from isaacg's solution.

Byte count assumes ISO 8859-1 encoding.


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

The leading and trailing empty lines are significant.

Try it online!

Explanation


$`¶

This is a replace stage which matches the empty regex (i.e. every zero-width position in the string) and substitutes $`¶ for it, where $` is the prefix of the match and inserts a linefeed. This basically computes all the prefixes and puts them on a separate line together with the last character of that prefix:

bb
obo
oboo
kbook
kbookk
ebookke
ebookkee
pbookkeep
ebookkeepe
rbookkeeper

There will be some leading and trailing linefeeds, but we can ignore them.

From each of these prefixes we want to keep the characters that are equal to the last character. For that we use another replace stage:

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

This matches everything we don't want to keep and replaces it with a nothing. We match any character (using \D since we know there won't be digits in the input) and then make sure that there isn't another copy of that character at the end of the line.

Martin Ender

Posted 2016-04-04T11:32:04.670

Reputation: 184 808

11

Python, 56 bytes

I seem to be stuck with two answers of the same length:

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)

Edit: See @pacholik's answer for a shorter, alternative Python approach.

Sp3000

Posted 2016-04-04T11:32:04.670

Reputation: 58 729

I'm not used to beating you with my ><> answers, I'm waiting for a Gol><> answer to fix that ;) – Aaron – 2016-04-04T12:48:50.780

@Aaron Too bad, I was actually going to beat you back with ><> :P – Sp3000 – 2016-04-04T13:01:06.957

Line noise in Python? What heresy! – cat – 2016-04-06T13:27:27.793

What does -~ do? I know it's bitwise NOT followed by negation, but what are you trying to do that it saves a few bytes on? – Fund Monica's Lawsuit – 2016-04-07T20:30:26.867

2@QPaysTaxes It's increment +1 with high enough precedence so that parens aren't necessary – Sp3000 – 2016-04-07T20:38:37.163

@Q Similarly, ~- will decrement. – mbomb007 – 2016-04-22T18:49:03.333

10

Haskell, 39 bytes

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

Usage example: f "bonobo" -> "bonoobbooo".

Different enough from @Damien's answer. Builds the string from the right by extracting all occurrences of the last character from the string and prepending a recursive call with all but the last character.

nimi

Posted 2016-04-04T11:32:04.670

Reputation: 34 639

9

JavaScript (ES6), 48 45 bytes

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

Edit: Saved 3 bytes thanks to @user81655.

Neil

Posted 2016-04-04T11:32:04.670

Reputation: 95 035

9

><>, 27 bytes

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

Requires the official interpreter which exits with an error when trying to print code point -1. Try it online!

The code reads input one char at a time and uses the first row of the codebox as a large array which stores the number of times each char has been seen so far (><> initialises non-program cells to 0). The second row is a loop for outputting a char multiple times.

Alternatively, here's a version which exits cleanly (37 bytes, not properly golfed):

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

Sp3000

Posted 2016-04-04T11:32:04.670

Reputation: 58 729

Damn that's good ! I should stop relying so heavily on the online interpreter, I would never have thought about simply using such a huge codebox, and I didn't even knew the official interpreter exited on -1 print – Aaron – 2016-04-04T13:11:54.960

2@Aaron Yeah, it's a corollary of Python erroring when trying to do chr(-1). The animated interpreter's great for visualisations, but unfortunately some of the discrepancies with the official interpreter are a bit annoying :/ – Sp3000 – 2016-04-04T13:15:02.957

8

Haskell, 50 42 41 bytes

Saved 8 bytes thanks to Lynn

f t=[c|(i,c)<-zip[1..]t,x<-take i t,c==x]

Damien

Posted 2016-04-04T11:32:04.670

Reputation: 2 407

1How about: f t=[c|(i,c)<-zip[0..]t,j<-[0..i],c==t!!j] – Lynn – 2016-04-04T12:23:00.943

8

MATL, 8 bytes

tt!=RsY"

Try it online! Or verify all test cases at once.

Explanation

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

Luis Mendo

Posted 2016-04-04T11:32:04.670

Reputation: 87 464

8

Labyrinth, 54 25 bytes

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

Another collab with @MartinBüttner, who actually did most almost all of the golfing for this one. By revamping the algorithm, we've managed to cut down the program size by quite a bit!

Try it online!

Explanation

A quick Labrinth primer:

  • Labyrinth is a stack-based 2D language. There are two stacks, a main and auxiliary stack, and popping from an empty stack yields zero.

  • At each junction, where there are multiple paths for the instruction pointer to move down, the top of the main stack is checked to see where to go next. Negative is turn left, zero is straight ahead and positive is turn right.

The two stacks of arbitrary-precision integers isn't much flexibility in terms of memory options. To perform the counting, this program actually uses the two stacks as a tape, with shifting a value from one stack to the other being akin to moving a memory pointer left/right by a cell. It's not quite the same as that though, since we need to drag a loop counter with us on the way up.

enter image description here

First off, the < and > on either end pop an offset and rotate the row of code that offset away by one either left or right. This mechanism is used to make the code run in a loop - the < pops a zero and rotates the current row left, putting the IP at the right of the code, and the > pops another zero and fixes the row back.

Here's what happens each iteration, in relation to the diagram above:

[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

Posted 2016-04-04T11:32:04.670

Reputation: 58 729

7

Perl, 17

(16 bytes code, +1 for -p)

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

Usage:

perl -pe 's/./${$&}.=$&/ge' <<< 'bonobo'
bonoobbooo

Dom Hastings

Posted 2016-04-04T11:32:04.670

Reputation: 16 415

7

Pyth, 7 bytes

s@Led._

Test suite

Test suite thanks to DenkerAffe

Explanation:

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

Posted 2016-04-04T11:32:04.670

Reputation: 39 268

6

Python 3, 52

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

pacholik

Posted 2016-04-04T11:32:04.670

Reputation: 490

4Ah, going from the end makes so much more sense! You can do this shorter in a lambda, without the need for Python 3 specifically: f=lambda s:s and f(s[:-1])+s[-1]*s.count(s[-1]) – Sp3000 – 2016-04-04T13:11:56.173

I though it could be done that way. But I don't like subscripting in Python :P – pacholik – 2016-04-04T13:19:24.083

5

PowerShell v2+, 52 47 bytes

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

Constructs an empty hashtable, stores it in $b. This is our "counter" of what letters we've seen. We then take input $args[0], cast it as a char-array, and send it through a loop. Each iteration, we take the current character "$_" and multiply it by the pre-incremented counter at the given value, which will make the first occurrence be multiplied by 1, the second by 2 and so on. We encapsulate that with a -join so it's all one word being output.

Saved 5 bytes thanks to TessellatingHeckler by using a hashtable instead of an array, so we didn't need to decrement the ASCII character by 97 to reach the appropriate index. This works because pre-incrementing the hash index implicitly calls .Add() in the background if that index doesn't exist, since hashtables are mutable.

PS C:\Tools\Scripts\golfing> .\stretch-the-word.ps1 tessellatingheckler
tessseelllattingheeeckllleeeer

AdmBorkBork

Posted 2016-04-04T11:32:04.670

Reputation: 41 581

@TessellatingHeckler Indeed - thanks! – AdmBorkBork – 2016-04-08T12:28:25.097

5

Dyalog APL, 6 bytes

∊,\∩¨⊢

TryAPL!

4 functions is an atop (2-train) of a fork (3-train):

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

First (right – a no-op) on the given string, giving 'bonobo'

Then ,\ (concatenation scan) on the string, giving 'b' 'bo' 'bon' 'bono' 'bonob' 'bonobo'

The two are forked together with (given as right and left arguments to) ∩¨ (intersection each), i.e. ('b'∩'b') ('bo'∩'o') ('bon'∩'n') ('bono'∩'o') ('bonob'∩'b') ('bonobo'∩'o'), which is 'b' 'o' 'n' 'oo' 'bb' 'ooo'

Finally, (enlist) is applied to the result to flatten it, giving 'bonoobbooo'

Hey, at least it matches Pyth! Obviously Jelly is shorter as it is a golf version of J, which in turn is an advanced 2-character-per-function dialect of APL.

Adám

Posted 2016-04-04T11:32:04.670

Reputation: 37 779

4

Pyth, 11 bytes

s.e*b/<Qhkb

Try it here!

Explanation

s.e*b/<Qhkb    # Q = input

 .e            # map over input with b as value and k as index (Q get appended at the end inplicitly)
      <Qhk     # take the first k+1 chars of Q
     /    b    # count occurences of b in there
   *b          # repeat b that many times
s              # join resulting list into one string

Denker

Posted 2016-04-04T11:32:04.670

Reputation: 6 639

4

05AB1E, 10 bytes

Code:

$vy«Dy¢y×?

Explanation:

$           # 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

Uses the CP-1252 encoding. Try it online!

Adnan

Posted 2016-04-04T11:32:04.670

Reputation: 41 965

4

J, 11 bytes

#~+/@(={:)\

This is a monadic verb. Try it here. Usage:

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

Explanation

#~+/@(={:)\
     (   )\  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

Posted 2016-04-04T11:32:04.670

Reputation: 39 083

3

CJam, 14

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

Try it online

Explanation:

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 quit because SE is EVIL

Posted 2016-04-04T11:32:04.670

Reputation: 22 326

2

Perl 6, 37 bytes

{.split('').map({$_ x++%.{$_}}).join}

Ven

Posted 2016-04-04T11:32:04.670

Reputation: 3 382

2

PHP, 54 51 50 47 bytes

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

Run like this:

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

Tweaks

  • Saved 3 bytes by using variable variables. Changed used variables to uppercase to prevent collision
  • Saved a byte by removing type cast null to int for string offset, as string offset is cast to int anyway
  • Saved 3 bytes by using $argn instead of $argv (thx Titus)

aross

Posted 2016-04-04T11:32:04.670

Reputation: 1 583

Use $argn with -R to save three more bytes. – Titus – 2018-05-02T08:41:41.313

Oh, and -n should do the same as your -d error_reporting: n stands for no config file, and notices are off in the default config; so -nr (respectively -nR) should suffice. – Titus – 2018-05-02T08:57:17.850

@Titus 2 year old answer, but thx anyway :) – aross – 2018-05-02T09:20:44.883

2

><>, 52 bytes

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

It stacks every letter read, prints them once and once again for every similar letter in the stack.
It uses the & register, because having to handle 3 variables on the stack (current read letter, position in the stack, letter at this position) is a pain.

You can try it here!

Aaron

Posted 2016-04-04T11:32:04.670

Reputation: 3 689

2

Rust, 176 Bytes

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()}

This uses a map to store a string for every character in the input. For each character, the string will be removed from the map, concatenated with the character, inserted back into the map and appended to the output.

I would have liked to use get(...) instead of remove(...), but the borrow checker had me change my mind.

ECS

Posted 2016-04-04T11:32:04.670

Reputation: 361

2

Javascript ES6 44 bytes

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

old answer

Javascript ES6 46 bytes

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

//thanks user81655 for -1 byte

Charlie Wynn

Posted 2016-04-04T11:32:04.670

Reputation: 696

1You could save a byte by moving x to the input array -> q=>(x=[...q]).map(a=>x[a]=(x[a]||'')+a).join\`` – user81655 – 2016-04-08T04:03:30.233

2

Mathcad, 66 bytes

Unfortunately, Mathcad doesn't have particularly good string handling, so I've converted the input string to a vector and then used a (character code indexed) vector to keep track of the number of times a character is encountered, adding the character that number of times to a result vector. Finally, the result vector is converted back to a string. Quite lenghty unfortunately.

enter image description here

Note that Mathcad uses a 2D "whiteboard" interface, with a mix of normal text and operators; operators are normally entered via a toolbar or keyboard shortcut; for example, ctl-# enters the for loop operator, which comprises the keyword for, the element-of symbol and 3 empty "placeholders" for the iteration variable, range and body expressions respectively. Typing [ after a variable name enters array index mode, Typing ' enters a matched pair of parentheses (mostly ... there are exceptions depending upon what else is in the surrounding expression)

Stuart Bruff

Posted 2016-04-04T11:32:04.670

Reputation: 501

2

Julia, 38 35 bytes

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

I/O is in the from of character arrays. Try it online!

How it works

We (re)define the monadic operator ! for our purposes.

When ! is called, it checks if its argument s is empty. If it is, it returns its argument.

If s is non-empty, we intersect s with its last character (s[end]), which yields all occurrences of that character in s. This result is concatenated with the return value of a recursive call to ! with s minus its last character (s[1:end-1]) as argument.

Dennis

Posted 2016-04-04T11:32:04.670

Reputation: 196 637

1

Mathematica, 57 bytes

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

We use c[x] as a lookup table of how often character x has already occurred. This is incremented each time it's retrieved in x~StringRepeat~++c[x]. Unfortunately, to make the function reusable, we need to reset the lookup table each time with Clear@c;c@_=0;, which is quite expensive.

Martin Ender

Posted 2016-04-04T11:32:04.670

Reputation: 184 808

1

awk, 72 bytes

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

The idea is to store the count of the appearing character in an associative array and print the character this count times.

rexkogitans

Posted 2016-04-04T11:32:04.670

Reputation: 589

1

Python, 66 62 bytes

Try it here

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

Argenis García

Posted 2016-04-04T11:32:04.670

Reputation: 223

1

Beam, 32 33 42 bytes

This should have been smaller, but I lost some bytes initializing the memory slots to 0. Swapping some flow directions managed to eliminate a lot of empty space.

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

Try it in this snippet

General explanation.

  • Set all the memory slots from 0-255 to 0
  • Read in the input ascii value into the beam
  • If beam is 0 halt (beam = store)
  • Get the memory[beam] value into the store, increment it and save back
  • Decrement the store to 0 printing out the beam character
  • Repeat

MickyT

Posted 2016-04-04T11:32:04.670

Reputation: 11 735

0

PHP, 46 bytes

for(;--$X||($C=$argn[$K++])&&$X=++$$C;)echo$C;

Run as pipe with -nR or try it online.

These 42 bytes print the same, but the loop is infinite (which results in a timeout error):

for(;--$X||$X=++${$C=$argn[$K++]};)echo$C;

printf solution, 47 bytes:

for(;$C=$argn[$K++];)printf("%'$C".++$$C.s,"");

Side note: PHP used to yield notices for undefined constants and cast them to string for decades. PHP 7.2 yields warnings with a hint that, in future versions, they will throw fatal errors.

End of an era. :-/ I wonder if they will do the same to undefined variables.

Titus

Posted 2016-04-04T11:32:04.670

Reputation: 13 814

0

Kotlin, 60 bytes

{s:String->s.fold(""){a,c->a+"$c".repeat(a.count{it==c}+1)}}

Try it online!

snail_

Posted 2016-04-04T11:32:04.670

Reputation: 1 982

0

Ruby, 50 48 bytes

Anonymous function.

->s{i=0
s.chars.map{|c|c*s[0,i+=1].count(c)}*''}

Value Ink

Posted 2016-04-04T11:32:04.670

Reputation: 10 608

0

Go, 142 bytes

No awards, but a neat exercise.

import(."fmt"
."strings")
func f(s string){m:=map[rune]int{}
for _,c:=range s{if _,ok:=m[c];!ok{m[c]=1}
Print(Repeat(string(c),m[c]))
m[c]++}}

You can save 1 byte by changing for _,c to for i,c and changing string(c) to s[i:i+1], but then it works only with ASCII.

EMBLEM

Posted 2016-04-04T11:32:04.670

Reputation: 2 179

0

Factor, 120 bytes

[ dup dup length iota [ head* ] with map reverse zip [ first2 over [ = ] curry count swap <array> >string ] map concat ]

Ungolfed, explained:

! "bonobo" -> { "b" "bo" "bon" "bono" "bonob" "bonobo" }
: ascend-string ( string -- string ascending-seq )
    dup dup length iota [ head* ] with map reverse ;

: stretch-word ( string -- stretched )
    ascend-string zip        ! zip string with ascending version of itself
    [
        first2 over          ! get each string index and its ascended version 
        [ = ] curry count    ! count how many times this letter has appeared
        swap <array> >string ! >string
    ] map concat ;           ! "" join

Translation of: @KennyLau's Pyth answer.

cat

Posted 2016-04-04T11:32:04.670

Reputation: 4 989

0

Ruby, 35 bytes

->s{s.gsub(/./){$&*-~$`.count($&)}}

It's an anonymous function using regex and some magical variables. Usage:

->s{s.gsub(/./){$&*-~$`.count($&)}}["bonobo"]
=> "bonoobbooo" 

daniero

Posted 2016-04-04T11:32:04.670

Reputation: 17 193

0

Java 10, 220 94 bytes

s->{var m=new int[123];for(var c:s.toCharArray())for(int i=++m[c];i-->0;System.out.print(c));}

Try it online.

Explanation:

s->{                   // Method with String parameter and no return-type
  var m=new int[123];  //  Integer-array containing 123 zeros
  for(var c:s.toCharArray())
                       //  Loop over the characters of the input-String
    for(int i=++m[c];  //   Increase the count of the current character in the array first,
                       //   and set `i` to this count
        i-->0;         //   Inner loop that many times
      System.out.print(c));}
                       //    And print that many times the current character `c`

Kevin Cruijssen

Posted 2016-04-04T11:32:04.670

Reputation: 67 575

0

Swift, 134 bytes

var c = NSCountedSet(),n = ""
i.characters.forEach({var s = String($0);c.addObject(s);for _ in 0..<c.countForObject(s){n.append($0)}})

Assumes Foundation has been implicitly imported. i is the input of type String, n is the output of type String.

I'm falling back on Foundation classes here as NSCountedSet gives the the character count lookup behavior we want. The problem with mixing Swift and Objective-C types is that Swift structs do not conform to NSObjectProtocol. We see this issue when trying to store a Swift Character (String.CharacterView) in an NSCountedSet, which is expecting objects of type AnyObject (or NSObject). I lose around 17 bytes having to create a String from each Character in the input string.

I also lose some bytes having to create a for loop to append the new characters based on their count in the set. I can't use forEach here since the return type of countForObject is an Int, not a collection type. There is room for improvement here.

Swift String types are immutable, so I can't explicitly mutate the input. There may be room for improvement by using an NSMutableString, but the characters lost by explicitly declaring the input of that type and calling the appendString method may add more characters to the program.

JAL

Posted 2016-04-04T11:32:04.670

Reputation: 304