| Bytes | Lang | Time | Link |
|---|---|---|---|
| 013 | Vyxal | 240910T234910Z | emanresu |
| 175 | Java 7 | 161019T093104Z | Kevin Cr |
| 135 | Python 3 | 150527T210724Z | Kade |
| 071 | rs | 150527T193310Z | kirbyfan |
| 087 | Julia | 150529T193917Z | Alex A. |
| 041 | Perl/Bash 54 40+1 = | 150527T192813Z | amon |
| 025 | CJam | 150528T003035Z | Dennis |
| nan | Pip | 150528T040221Z | DLosc |
| 027 | CJam | 150527T193729Z | Optimize |
| 083 | Javascript ES6 | 150527T194645Z | nderscor |
| 098 | Python 2.7 | 150528T013439Z | recursiv |
| 112 | JavaScript | 150527T215402Z | wolfhamm |
| 028 | Pyth | 150527T205518Z | Jakube |
| 073 | Ruby | 150527T193703Z | Cristian |
Vyxal, 13 bytes
`.+?\d`Ẏ⟑ṫ⌊*₴
Try it Online! -1 thanks to lyxal.
Ẏ # Find all matches of the regex
`.+?\d` # ".+?\d" - as few characters as possible, then a digit
⟑ # Over each match
ṫ⌊ # Remove the last character and convert it to an int
* # and repeat the rest of the string by that
₴ # Print the result
Java 7, 175 bytes
String c(String s){String r="",a[];for(String x:s.split("(?<=(\\d)(?!\\d))")){a=x.split("");for(int i=0,j,l=a.length-1;i<l;i++)for(j=0;j++<new Short(a[l]);r+=a[i]);}return r;}
The challenge is harder than it looks, imo..
Ungolfed & test code:
class M{
static String c(String s){
String r = "",
a[];
for(String x : s.split("(?<=(\\d)(?!\\d))")){
a = x.split("");
for(int i = 0, j, l = a.length-1; i < l; i++){
for(j = 0; j++ < new Short(a[l]); r += a[i]);
}
}
return r;
}
public static void main(String[] a){
System.out.println(c("ab3c5"));
System.out.println(c("a0b3"));
System.out.println(c("13b1"));
System.out.println(c("a13b1"));
System.out.println(c("a123b1"));
System.out.println(c("aa2a1b1"));
System.out.println(c("123"));
}
}
Output:
aaabbbccccc
bbb
111b
aaa111b
aaa111222b
aaaaab
111222
Python 3, 148 144 136 135 Bytes
w,o,r,d=''.join,'',[],[]
for c in input()+' ':
if'/'<c<':':d+=[c]
elif d:o+=w(x*int(w(d))for x in r);r=[c];d=[]
else:r+=[c]
print(o)
Thanks to Pietu1998 and mbomb007 for the suggestions.
Python 2, 161 151 147 139 138 Bytes
Maybe today's just been a long day at work, but I can't for the life of me figure out how to golf this..
w,o,r,d=''.join,'',[],[]
for c in raw_input()+' ':
if'/'<c<':':d+=[c]
elif d:o+=w(x*int(w(d))for x in r);r=[c];d=[]
else:r+=[c]
print o
rs, 43 71 chars
Well, this turned long quickly. Stupid numbers...
(\d)(\D)/\1 \2
+(\w)(\w+?)(\d)(?= |$)/\1\3 \2\3
(\w)(\d)/(\1)^^(\2)
/
Original version (did not work with input like 123):
+(\D)(\D+)(\d)/\1\3\2\3
(\D)(\d)/(\1)^^(\2)
Explanation
The first line places spaces between runs containing numbers, e.g. turning a313 into a3 13.
The second line continuously expands the compressed encodings like aa5 to a5a5.
The third line converts every instance of a5 into aaaaa using the repetition operator.
The last line removes the spaces.
Julia, 105 99 95 87 bytes
s->join([join([string(b)^(int(p[end])-48)for b=chop(p)])for p=matchall(r"\D*\d*\d",s)])
This creates an unnamed function that takes a string as input a returns a string. To call it, give it a name, e.g. f=s->....
Two array comprehensions are used here, one nested within the other. The outer comprehension acts on each match of the input string against the regular expression \D*\d*\d. The inner comprehension repeats each character of the match according to the trailing digit. The elements of the inner array are joined into a string, so the outer array is an array of strings. These are joined and returned.
In Julia, strings can be treated like character arrays. However, note that the Char and String types in Julia don't have the same methods defined; in particular, there is no method for repetition using ^ for characters. This uses a convoluted workaround:
- Loop over the string omitting the last character, which is removed using
chop(). - Convert the current character to a string using
string(). - Convert the trailing digit, which is also a character, into an integer. However, note that, for example,
int('4')does not return 4. Rather, it returns the codepoint, which in this case is 52. Thus we can subtract 48 to get back the actual integer. - Repeat
string(b)according toint(p[end]) - 48.
Examples:
julia> f("ab3c5")
"aaabbbccccc"
julia> f("a0b3")
"bbb"
julia> f("13b1")
"111b"
Perl/Bash 54 40+1 = 41 bytes
perl -pe's:(\D*\d*)(\d):"\$1=~s/./\$&x$2/egr":ege'
It's basically a regex within a regex. And a bit of magic.
Explanation
The outer regex /(\D*\d*)(\d)/g extracts each run-length encoded group. We capture the stuff to repeat in $1 and the number of repetitions in $2. Now we substitute each such group with the expansion of that group. For that, we evaluate the code "\$1=~s/./\$&x$2/egr" two times (as by the /ee flag on the outer substitution).
The first evaluation will only interpolate the number of repetitions into the string – the other variables are protected by a backslash. So assuming the input a14, we would now have the code $1=~s/./$&x4/egr, which will be evaluated again.
This will apply the substitution to the contents of $1 (the stuff to repeat a1). The substitution matches each character .. The $& variable holds the whole match, which we repeat x4 times. We do this /globally for each match and /return the substituted string rather than modifying the $1 variable (which is read-only). So the result of the inner substitution is aaaa1111.
The -p flag applies the substitution to each input line and prints out the result.
CJam, 27 25 bytes
r_'A+1>.{64&1$>{])~f*o}&}
Try it online in the CJam interpreter.
How it works
r_ e# Read a token from STDIN and push a copy.
'A+ e# Append the character A to the copy.
1> e# Discard the first character of the copy.
.{ } e# For each character C of the input string and the
e# corresponding character D of the copy:
64& e# Take the bitwise and of D and 64. This pushes @
e# if D is a letter and NUL if it is a digit.
1$> e# Compare the result to a copy of C. This pushes 1
e# if and only if D is a letter and C is a digit.
{ }& e# If the result was 1, do the following:
] e# Wrap the stack in an array.
)~ e# Pop and evaluate the last character.
f* e# Repeat each char in the array that many times.
o e# Print all characters.
Pip, 22 + 1 = 23 bytes
Uses -r flag. Note that this requires you to either 1) enter an EOF after the input (Ctrl-D on Linux, Ctrl-Z on Windows) or 2) pipe the input in from somewhere else.
(^_@<v)X_@vMa@`\D*\d+`
Explanation:
a is first line of stdin (from -r flag) and v is -1 (implicit)
`\D*\d+` Pattern (regex) object that matches zero or more non-digits
followed by at least one digit
a@ Find all non-overlapping matches in a, returning a list of strings
M To that list, map a lambda function:
_@<v Argument sans last character (equivalent to Python a[:-1])
(^ ) Split into a list of characters
_@v Last character of argument
X Repeat each character of the list that many times
(String multiplication X, like most operators, works item-wise
on lists)
Auto-print (implicit)
The result of the map operation is actually a list of lists, but by default lists are simply concatenated together when printed, so no manual conversion to string is necessary.
Example, with input a13b1:
Var a gets "a13b1"
After regex match ["a13" "b1"]
After map [["aaa" "111"] ["b"]]
Final output aaa111b
Pip has basic regex support as of... 2 days ago. Great timing!
CJam, 33 31 27 bytes
Ughh, lack of regular expressions makes this pretty long...
qN+{:XA,s&L\:L>{])~e*[}&X}%
How it works
We loop through all characters of the input string and in each iteration, keep track of the last encountered character (starting with an empty character for the first time). Then we check if the current character is non-numeric and the last character is numeric. If so, we repeat each previous character (which has not been repeated already), the number times.
(A bit outdated code expansion)
q{ }% e# Read the input (q) and loop through each character
L e# Put variable L (initially empty character) on stack
A, e# Put variable A (equals 10) and create an array 0..9
s e# Convert the array to string "0123456789"
& e# Do a set intersect b/w previous char and 0-9 string
e# If numeric, it gives 1 char string, otherwise 0
\:LA,s& e# Swap to bring current character on top. Store it in L
e# and do the same set intersect with it
> e# Means we are checking that current char is non-numeric
e# and previous numeric
{ }& e# Run this block if above is true
])~ e# Wrap everything not already repeated in an array and
e# take out the last character and convert it to integer.
e# This is the run length of the preceding string
e* e# Repeat each character in the string, run length times
[ e# Start a new array to help when next run length is found
L e# Restore the current character back on stack to be used
e# in next iteration
)~e* e# The last string-run-length pair is not decoded..
e# So we do that now
Javascript (ES6), 86 83 bytes
alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>b.replace(/./g,y=>y.repeat(c))))
Commented:
alert( // output final result
prompt(). // take input
replace(/(.+?)(\d)(?!\d)/g, // replace ungreedy capture group of any characters
// followed by a digit (captured)
// and not followed by a digit (negative lookahead)
(a, b, c)=> // replace with a function
b.replace(/./g, // replace all characters in b
y=>y.repeat(c) // with that character repeated c times
)
)
)
Python 2.7, 98 bytes
import re
print"".join(c*int(m[-1])for m in
re.findall(r".+?\d(?!\d)",raw_input())for c in m[:-1])
This just does a simple regex search for digits that aren't followed by a digit, and then does the string arithmetic on each group and joins them all back together.
JavaScript 112
alert(prompt().replace(/.*?\d+/g,function(m){for(i=n=m.length-1,o="";i--;){j=m[n];while(j--)o=m[i]+o}return o}))
Pyth, 33 32 28 bytes
ssmm*vedkPdPcz-hMJf<@zT\=UzJ
Try it online: Demonstration or Test harness
Explanation
I'll explain the code using the example input aa1a23b2. Hopefully this is a bit easier to follow than without.
implicit: z = input string = 'aa1a23b2'
Uz the indices of z: [0, 1, 2, 4, 5, 6, 7]
f filter for indices T, which satisfy:
<@zT\= z[T] < "="
this gives us the list of indices [2, 4, 5, 7],
which correspond to digits in z.
J assignment, J = [2, 4, 5, 7]
hMJ increment all element in J: [3, 5, 6, 8]
- J and remove the elements of J:
[3, 5, 6, 8] - [2, 4, 5, 7] = [3, 6, 8]
cz split z at these indices: ['aa1', 'a23', 'b2', '']
P remove last element: ['aa1', 'a23', 'b2']
m map each string d to:
m Pd map each string k of d-without-last-char to:
ved int(last element of d)
* k * k
this creates [['a', 'a'], ['aaa', '222'], ['bb']]
s sum the lists: ['a', 'a', 'aaa', '222', 'bb']
s sum the strings: 'aaaaa222bb'
Ruby 73
gets.split(/(\d)(?!\d)/).each_slice(2){|s,i|s.chars.map{|c|$><<c*i.to_i}}
Tests: http://ideone.com/L1fssb