| Bytes | Lang | Time | Link |
|---|---|---|---|
| 257 | Setanta | 250806T230033Z | bb94 |
| 039 | Zsh extendedglob | 220605T214346Z | GammaFun |
| 095 | Zsh | 211112T000551Z | Gilles & |
| 018 | 05AB1E | 211102T125527Z | Kevin Cr |
| 118 | Zsh builtins only | 211101T034856Z | roblogic |
| 093 | Lua | 160512T214040Z | Blab |
| 111 | Perl 6 | 161214T065842Z | bb94 |
| 060 | Groovy | 161013T181847Z | Magic Oc |
| 085 | Javascript ES6 | 161013T142151Z | Esteru |
| 014 | Jolf | 160513T200756Z | Conor O& |
| 163 | R | 161013T100348Z | Billywob |
| 039 | RProgN | 161013T032041Z | ATaco |
| 054 | Julia | 160512T204922Z | Dennis |
| 120 | PowerShell v4 | 160513T211140Z | Tessella |
| 144 | Bash + GNU coreutils | 160513T185908Z | rexkogit |
| 034 | Perl | 160512T213336Z | Dennis |
| 137 | PowerShell v2+ | 160512T204340Z | AdmBorkB |
| 413 | Kotlin | 160513T234328Z | Justinw |
| 087 | Python 2 | 160512T202233Z | ojdo |
| 029 | Pyth | 160513T135143Z | FryAmThe |
| 099 | Javascript ES6 | 160512T202724Z | Bál |
| 057 | JavaScript ES7 | 160512T200612Z | Neil |
| 043 | Ruby | 160512T200029Z | Value In |
Setanta, 257 bytes
gniomh(s,f){U:=go_uimh o:=f[0]f=U(cuid@f(1,fad@f))r:=""u:=""gniomh h(){ma fad@u {u=U(u)r+=go_teacs((o=="+"&u+f)|(o=="-"&u-f)|(o=="*"&u*f)|(o=="/"&u//f)|(o=="^"&cmhcht@mata(u,f))|0)u=""}}le i idir(0,fad@s){a:=U(s[i])ma a==a u+=s[i]no{h()r+=s[i]}}h()toradh r}
Zsh, 95 bytes
Whole program. Inputs: the meme and transformation as command line arguments. Output: standard output (with a trailing newline).
a=$1;repeat $#a c=${a/[^0-9]*}&&(($#c))&&b+=$[$c${2/^/**}] a=${a##<->}||b+=$a[1] a=${a#?};<<<$b
A 98-byte solution with a non-optimized number/letter test:
a=$1;repeat $#a [[ $a = <->* ]]&&b+=$[${a%%[^0-9]*}${2/^/**}] a=${a##<->}||b+=$a[1] a=${a#?};<<<$b
Explanation: first here's the code with additional whitespace.
a=$1;
repeat $#a \
c=${a/[^0-9]*} &&
(($#c)) &&
b+=$[$c${2/^/**}] a=${a##<->} ||
b+=$a[1] a=${a#?};
<<<$b
The general idea is to consume the input in $a from left to right, one multi-digit integer or one non-digit character at a time. Accumulate the result in $b, which is printed out after the loop.
repeat $#a … repeats the following code $#a (initial length of the input) times. The loop body consumes at least one character as long as $a is non-empty and does nothing when it runs out, so this works, and it's shorter than naive approaches such as while (($#a)) or while [ $a ]. In the loop body:
- Set
cto the initial digit sequence of$a(remove everything starting with the first non-digit).${a/[^0-9]*}is short for${a/[^0-9]*/}and shorter than the more intuitive${a%%[^0-9]*}. The assignment always succeeds, so the subsequent&&is just like;except that it doesn't terminate therepeatbody. ((#c))tests whethercis non-empty, i.e. if$astarts with a digit.- If the test above, i.e. if
$astarts with a digit, append the result of the arithmetic expression$[…](an alternative form of$((…))) tob. The expression uses the digits in$cand the operator-and-number from$2. Zsh has the operators+-*/as required but exponentiation is**instead of^. - If the test above was false, i.e. if
$astarts with a non-digit, append the first character of$atoband remove the first character froma.
05AB1E, 18 bytes
ε.γd]``s„^/„m÷‡.VJ
Input as a pair of strings.
Try it online or verify all test cases.
Explanation:
ε # Map both strings in the (implicit) input-pair to:
.γ # Group it into substrings by:
d # Is it a non-negative number
] # Close both the map and inner group-by
` # Pop and push both list or substrings separated to the stack
` # Pop and push the operator and number separated to the stack
s # Swap them, so the operator is at the top of the stack
„^/„m÷‡ # Transliterate "^" to "m" and "/" to "÷"
.V # Evaluate the operator string as 05AB1E command
# (the operations are no-ops on the non-number substrings)
J # Join the list of substrings back together to a single string
# (after which it is output implicitly as result)
If the final test case wasn't necessary, it could have been 17 bytes (which unfortunately has floating-point precision issues for the final test case):
ε.γd]``s'^'m:.VïJ
Try it online or verify all test cases.
Explanation:
Mostly the same as above, except for „^/„m÷‡ being '^'m: to only transform the exponent-operator and leave the division-operator as is, and the addition of ï to truncate the decimals after the eval.
Zsh (builtins only), 167 118 bytes
a=$1 S=(${(s: :)a//[0-9]/ })
for i (${(s: :)a//[a-z]/ })N+=($[i${2/^/**}])
((#a<58))&&<<<${(j::)N:^S}||<<<${(j::)S:^N}
Crack the input into a numerical array N and string array S, do operations on N, then zip the arrays together again (zip the arrays the other way if the leading character is a letter).
167 bytes! (longer than the bash solution! ☹️ )
Lua, 145 93 bytes
r=io.read;m=r()o=r()m=m:gsub("%d",function(n)return loadstring("return..."..o)(n)end)print(m)
Perl 6, 111 bytes
{/(\w+)\s(<[+\-*/^]>)(\d+)/&&my \b=+$2;my \o=(*+b,*-b,* *b,*div b,* **b)[index "+-*/^",$1];$0.subst(/\d+/,o):g}
Unfortunately EVAL is disabled by default. Also, you have to use div for integer division.
Groovy, 64 60 Bytes
{a,b->a.replaceAll(/\d+/,{Eval.me(it+b.replace("^","**"))})}
Replaces all instances of digits with a closure that evaluates the operation on the digit portions of the word passed. If passed an exponent function, it replaces it with the proper notation. Groovy implicitly handles BigInteger/BigDecimal conversion when using Eval.me() because parsed strings can potentially be out of the 2^32-1 range.
Explained
{a,b->...} - Closure with two arguments.
a.replaceAll(/\d+/,{...}) - Search for all digit sequences in string and replace with a closure.
{Eval.me(it+b.replace("^","**"))} - More specifically, a closure with each match having the operation appended to it, then evaluated as groovy code.
.replace("^","**") - Replace the first instance of ^ with the groovy exponent operator ** in the operation provided. If you want this to work with full equation strings that use exponents, use replaceAll() instead for a +3 byte penalty.
Fun side-note his is a valid test scenario:
(22348952345238905290858906209862398036spooky409552me, /200*4943^8-23939+((100/203)+600)
Javascript (ES6), 85 Bytes
x=(s)=>{var a=s.split(" ");return[...a[0]].map(x=>(!isNaN(x))?eval(x+a[1]):x).join``}
console.log(x("2spookie5me +1"));
Ungolfed:
x = (s) => {
var a = s.split(" ");
return [...a[0]].map(x => (!isNaN(x)) ? eval(x + a[1]) : x).join ``
}
console.log(x("2spookie5me +1"));
Jolf, 15 14 bytes
ρi«\d+»dC!6+HI
Explanation
ρi«\d+»dC!6+HI
ρ «\d+» replace all digits
i in the input
d (functional replace)
!6 eval (using jolf's custom infix eval)
+H the number as a string plus
I the second input
C floor the result (integer truncate)
Fun to note, I updated Jolf after this challenge, adding some RegExp builtins. This could be 12 11 bytes:
ρiLRdC!6+HI
R, 163 bytes
As someone who's learning regular expressions and string substitution in R, this proved to be a quite difficult challenge. Especially because matching the numbers is easy but I couldn't find a way to use multiple substitutions with gsub. Furthermore, I don't know if eval(parse(paste0(... is the most efficient way to switch between operations. Maybe the switch-function is better suited here.
function(s,o){p=strsplit;y=p(gsub("\\d+","?",s),"?")[[1]];x=na.omit(as.integer(p(s,"[a-zA-Z]+")[[1]]));y[y=="?"]=floor(eval(parse(,,paste0("x",o))));cat(y,sep="")}
Explanation
f=function(s,o){
p=strsplit # alias for stringsplit
y=p(gsub("\\d+","?",s),"?")[[1]] # substitute numbers with "?" and split into vector on "?"
x=na.omit(as.integer(p(s,"[a-zA-Z]+")[[1]])) # split at alphabetical char, return vector with numbers to be operated on
y[y=="?"]=floor(eval(parse(,,paste0("x",o)))) # replace inserted "?" with vector of numbers operated on
cat(y,sep="") # print concatenated vector
}
RProgN, 39 Bytes
►x='%d+'§x'%D+'''Rx'%d+'''Rg'y'=y_}R
Explained
►x='%d+'§x'%D+'''Rx'%d+'''Rg'y'=y_}R
► # Spaceless segment.
x= # Assign the top value of the stack '[+*/-]\d+'
'$d+'§ }R # Replace everything in the pattern %d+ (all numbers) based on an anonymous function
x'%D+'''R # Replace all Non-digits in the modifer with nothing, leaving just the second argument for the operator.
x'%d+'''R # Snip all digits, separating our operator from our digits such that digit operator exists in the stack.
g'y'= # Grab the function that is represented by the top of the stack (the operator in this case)
y # Run it
_ # Floor the result.
Technically invalid answer, because this language did not exist for it. However, it was not specifically designed for it, nor any particular addition. So I'm running it. Sue me.
Julia, 71 59 54 bytes
/ =÷
x%y=replace(x,r"\d+",t->"big($t)"y|>parse|>eval)
The requirement to use big if available makes this a lot longer than it could be...
PowerShell (v4), 124 120 bytes
# New 120 byte version:
$s,$a=$args;[regex]::Replace($s,'\d+',{($(if($a-ne($a=$a.Trim('^'))){
"$args*"*$a+1}else{"$args$a"})|iex)-replace'\..*'})
# Previous 124 byte version
$s,$a=$args;[regex]::Replace($s,'\d+',{if($a[0]-eq'^'){
[math]::pow("$args",$a.Trim('^'))}else{iex "$args$a-replace'\..*'"}})
(the newlines are only here to avoid horizontal scrolling, they work when saved as one line).
Comments, and ungolfed version was requested:
$meme, $instruction = $args
# Scriptblock which processes the numbers
# to be replaced. $args is the input number.
$replacement = {
# Generates a string of the calculation, by:
# Removing leading ^ character, if present.
# ^3 -> 3, +3 -> +3
# See if it was present, and switch code paths.
# (Can be one combined step in the golf)
# Switch code paths for "raise to the power of",
# or basic arithmetic.
$trimmedInstruction = $instruction.Trim('^')
$tmp = if ( $instruction -ne $trimmedInstruction ) {
# String multiplication, changes
# function input "45" and instruction "3" into
# "45*45*45*+1". The "3" implicitly casts to [int]
# the +1 is there to make the trailing * not crash.
"$args*" * $instruction + 1
} else {
# Cobble the basic math together as a string
# "45" and "+10" becomes
# "45+10"
"$args$instruction"
}
# eval() the generated string (e.g. "45+10" or "45*45*45*+1")
$tmp = Invoke-Expression $tmp # iex
# Use a regex golf to replace trailing .23423
# decimals in case of division with remainder.
# Acts as [math]::floor(), harmless on other numbers.
$tmp -replace'\..*'
}
# A regular expression replacement which picks out all
# the numbers (\d+) and runs them through the
# replacement function. Returns a string which
# ends up on stdout
[regex]::Replace($meme, '\d+', $replacement)
- .Net regex library can do a replace with a scriptblock that executes on the content of the match, and PowerShell casts types strings to numbers, and
iexis likeeval()in other languages. It just does"2spooky" "+3"->eval("2+3") - Except... it can't handle
^operator or any other convenient exponentiation like**, it can only use the[math]::Pow()library call so there's a big block to handle that branch.- The updated version steals an idea from @TimmyD and does string multiplication instead -
"2*" * nwhich becomes"2*2*2*2*"and then adds+1on the end to multiply by one instead of complaining about the trailing*.
- The updated version steals an idea from @TimmyD and does string multiplication instead -
- Except... .Net does Banker's Rounding which rounds to the nearest even number by default, and 3/2 = 2 rather than 3/2 = 1. This challenge calls for truncation, and that means
[math]::Truncate(). Instead, I save characters by using-replaceto trim a decimal point and anything after it.
Test cases:
PS D:\> .\meme.ps1 2spooky4me +1
3spooky5me
PS D:\> .\meme.ps1 2spooky4me -1
1spooky3me
PS D:\> .\meme.ps1 2spooky4me *15
30spooky60me
PS D:\> .\meme.ps1 10spooky900me /5
2spooky180me
PS D:\> .\meme.ps1 idontunderstandememes3 /2
idontunderstandememes1
PS D:\> .\meme.ps1 "idontunderstandememes3" "/2"
idontunderstandememes1
PS D:\> .\meme.ps1 "notreallyafunnymeme" "*100"
notreallyafunnymeme
PS D:\> .\meme.ps1 "2spooky4me" "^3"
8spooky64me
PS D:\> .\meme.ps1 "some1meme2sequences3can4be5really6long7" "/2"
some0meme1sequences1can2be2really3long3
PS D:\> .\meme.ps1 2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000spooky4me /2
1E+780spooky2me
NB. In the last test the numbers overflow into type [BigInteger] automatically, but they get rendered in scientific notation. Luckily, every known race able to communicate between the stars has enough scientific development to be able to process scientific notation without problem.
Bash + GNU coreutils, 144 Bytes
d=
u=$1,
for((i=0;i<${#u};i++)){ l=${u:i:1}
[[ "$l" =~ [0-9] ]]&&d=$d$l||{ [ -z $d ]||echo -n `bc<<<$d$2`&&{ [ $l != , ]&&echo -n $l; };d=; }
}
This looks at the alteration between digits and non-digits, that's why a random invalid input character (comma) is appended to the input string. This comma is then ignored in the output. The convention of the OP follows exactly the syntax of bc which is used here to do the maths.
Perl, 36 34 bytes
s/\d+/"0|$&$^I"=~s#\^#**#r/gee
The source code is 30 bytes long and it requires the switches -pi (+4 bytes). It takes the first input from STDIN, the second input as an argument to -i.
Thanks to @DenisIbaev for golfing off 2 bytes!
Test it on Ideone.
PowerShell v2+, 139 137 bytes
param($a,$b)-join($a-split"(\d+)"|%{if($_-match"\d+"){if($b[0]-ne'^'){[math]::Floor((iex $_$b))}else{"$_*"*$b.Trim('^')+1|iex}}else{$_}})
Ooof ... 47 bytes just to account for ^ since that's not a native operator in PowerShell. Saved 2 bytes thanks to @TessellatingHeckler.
Takes input as $a=<word>, $b=<operation>, like .\universal-spooky-meme.ps1 2spooky4me ^3. We -split $a on digits, enclosing that in parens so we keep the delimiters, and pipe the resultant array through a loop |%{...}. If the current piece is a number, we're in the first if. We need to check whether the first character of $b is ^. If it's not, we simply concatenate our current piece and $b and send it to iex (similar to eval), then leave that on the pipeline. Otherwise, we need to create an exponentiation string with "$_*"*$b.Trim('^')+1 and pipe that to iex, and leave that on the pipeline. For the given 2spooky4me ^3 example, this will be 2*2*2*1 and 4*4*4*1, respectively.
Otherwise, we just leave the string as-is on the pipeline.
All of those results are gathered from the pipeline with the encapsulating parens before being -joined back together into one string. That is the re-left on the pipeline, and output is implicit at program termination.
Examples
PS C:\Tools\Scripts\golfing> .\universal-spooky-meme.ps1 2spooky4me ^5
32spooky1024me
PS C:\Tools\Scripts\golfing> .\universal-spooky-meme.ps1 2spooky4me /3
0spooky1me
Kotlin, 416 413 Bytes
The lack of an eval() in Kotlin really upped that byte count...
fun main(a:Array<String>){var r=Regex("\\d+");var i=a[0];var n=a[1].takeLast(a[1].length-1).toInt();when(a[1][0]){'+'->print(r.replace(i,{m->""+(m.value.toInt()+n)}));'*'->print(r.replace(i,{m->""+(m.value.toInt()*n)}));'/'->print(r.replace(i,{m->""+(m.value.toInt()/n)}));'-'->print(r.replace(i,{m->""+(m.value.toInt()-n)}));'^'->print(r.replace(i,{m->""+(Math.pow(m.value.toDouble(),n.toDouble())).toInt()}));}}
Ungolfed
fun main(a: Array<String>) {
var r = Regex("""\d+""")
var i = a[0]
var n = a[1].takeLast(a[1].length - 1).toInt()
when (a[1][0]) {
'+' -> print(r.replace(i, { m -> "" + (m.value.toInt() + n) }))
'*' -> print(r.replace(i, { m -> "" + (m.value.toInt() * n) }))
'/' -> print(r.replace(i, { m -> "" + (m.value.toInt() / n) }))
'-' -> print(r.replace(i, { m -> "" + (m.value.toInt() - n) }))
'^' -> print(r.replace(i, { m -> "" + (Math.pow(m.value.toDouble(), n.toDouble())).toInt() }))
}
}
Python 2, 156 89 88 87 bytes
Inspired by the other answers that use their languages' substitution function with a function handler to process the numeric parts of the long input string with the operator. Unlucky for Python, the ^ must be replaced by **, which costs a whopping 18 bytes. The .group(0) call just to access the match object's string representation does not make things better...
Thanks to QPaysTaxes for spotting a spurious space and RootTwo for the unnecessary argument to .group!
import re
lambda i,o:re.sub(r'\d+',lambda p:str(eval(p.group()+o.replace('^','**'))),i)
Pyth, 29
Jws.i:zK"\d+"3m.vs.iJ]+d;:zK1
This works by extracting each number from the meme, and then interleaving (.i) it followed by a space and wrapped in a list with the other argument. So if our number is 7 and we had ^20 we would get the list: ["^", "7 ", "20"]. Flattening and using Pyth's eval (.v) on this always gives the operation we want. Finally these values are interleaved with the original string split on occurrences of numbers.
This could be a byte shorter if both inputs were surrounded by quote characters, or two bytes shorter if only one of them could be quoted.
Try it here or run a Test Suite
Javascript (ES6) 99 bytes
Another example, why we hate to wait for ES7 to get compatibility
(a,b)=>a.match(/\d+|\D+/g).map(_=>(d=- -_)?eval(b[0]=="\^"?Math.pow(_,b.slice(1)):d+b)|0:_).join``
Runnable example:
f=(a,b)=>a.match(/\d+|\D+/g).map(_=>(d=- -_)?Math.ceil(eval(b[0]=="\^"?Math.pow(_,b.slice(1)):d+b)):_).join``
alert(f(prompt("Enter string!"), prompt("Enter operation!")));
JavaScript (ES7), 58 57 bytes
(s,t)=>s.replace(/\d+/g,n=>0|eval(n+t.replace('^','**')))
Edit: Saved 1 byte when I remembered that replace also works on literal strings.
Ruby, 50 44 43 bytes
FGITW answer. Gotta go fast!
Thanks to @Neil for saving 6 bytes.
Oh right, crossed out 44 is still 44
->m,t{m.gsub(/\d+/){eval$&+t.sub(?^,'**')}}