20
\$\begingroup\$

Winner: Chilemagic, a massive 21 bytes!

You may continue to submit your answer, however you can no longer win. Original post kept:


Your goal is to find all numbers in a string, and multiply each one individually by a value input by the user

  • You will not need to worry about decimals
  • The user will input a number and a string
  • The user must type the number and string at some point, however the method the program reads it does not matter. It can be with stdin, reading a text file, etc, however the user must press the 9 button on their keyboard (for example) at some point
  • Anything that can compile and run is acceptable

Example:

Sentence input: This 1 is22a 3352sentence 50

Number input: 3

Output: This 3 is66a 10056sentence 150


  • This contest ends on September 6th, 2014 (7 days from posting).
  • This is a , so the shortest code wins
\$\endgroup\$
13
  • \$\begingroup\$ Any number is to be multiplied. I updated my example. \$\endgroup\$
    – Jon
    Aug 31, 2014 at 4:59
  • \$\begingroup\$ I don't understand the significance or use of "press the 9 button" in your challenge. How or where does it apply in the example given? \$\endgroup\$ Aug 31, 2014 at 5:01
  • 3
    \$\begingroup\$ @Darren He's basically saying that you can't hardcode the number. \$\endgroup\$
    – Beta Decay
    Aug 31, 2014 at 8:59
  • 2
    \$\begingroup\$ Can we make assumptions about the size of the numbers involved, particularly the possibility of overflow? Depending on the results of the above, do we treat "-1234" as "-" followed by 1234 or as -1234? \$\endgroup\$
    – Alchymist
    Sep 1, 2014 at 11:30
  • 1
    \$\begingroup\$ To add to @IlmariKaronen's question: What to do with leading zeroes as in "Bond is agent 007" -> "Bond is agent 21" or "Bond is agent 0021" or "Bond is agent 021" or ...? \$\endgroup\$ Sep 2, 2014 at 11:35

31 Answers 31

24
\$\begingroup\$

Update - Perl - 17

s/\d+/$&*$^I/ge

15 characters + 2 for -i and -p flags.

We can use the -i flag to input a file extension, but since we aren't reading any files, we can use it to get the number and it the variable $^I will get assigned to it.

Run with:

perl -e'print"This 1 is22a 3352sentence 50"' | perl -i3 -pe's/\d+/$&*$^I/ge'

Perl - 21

Updated as per @Dennis's comment.

$n=<>;s/\d+/$&*$n/ge

Run with -p flag.

Example run:

perl -e'print"This 1 is22a 3352sentence 50\n3"' | perl -pe'$n=<>;s/\d+/$&*$n/ge'

Explanation:

$n=<>; read in the number

-p prints the output

s/\d+/$&*$n/ge Read the input with <> and search for one or more digits and replace them with the digits times the number. g is global, e is eval the replace potion of the s///. $& contains what was matched and it multiplied by the number, $n.

You can read more about s/// in perlop and more about Perl regexes in perlre.

Another solution:

@F.Hauri pointed out you can also use the s switch to assign the $n variable to 4. I'm not sure how many characters this counts as but I'll leave it here:

perl -spe 's/\d+/$&*$n/ge' -- -n=4 <<<'This 1 is22a 3352sentence 50'
\$\endgroup\$
12
  • \$\begingroup\$ I think you could save a few more characters by using <>=~ instead of _$=<>;. Also could you please explain what the s part of the regex means, for us novices? \$\endgroup\$
    – Tal
    Aug 31, 2014 at 5:26
  • \$\begingroup\$ @Tal String.​​​ \$\endgroup\$
    – Kaz Wolfe
    Aug 31, 2014 at 7:23
  • 3
    \$\begingroup\$ @Mew I'm pretty sure it's for "substitution" \$\endgroup\$ Aug 31, 2014 at 8:53
  • 1
    \$\begingroup\$ 1. If you use $& instead of $1, you can shorten (\d) to \d. 2. If you use the -p switch and change the input order, you can drop say<>=~ and r. \$\endgroup\$
    – Dennis
    Aug 31, 2014 at 14:59
  • 1
    \$\begingroup\$ You may use -s switch, to whipe $n=<> out: perl -spe 's/\d+/$&*$n/ge' -- -n=4 <<<'This 1 is22a 3352sentence 50' (do render: This 4 is88a 13408sentence 200) \$\endgroup\$ Sep 1, 2014 at 15:32
9
\$\begingroup\$

JavaScript (ES6) - 48 44 chars

Thanks to @bebe for saving one character. Update: 8/Mar/16, removed another four characters

b=(p=prompt)();p(p().replace(/\d+/g,y=>y*b))

Ungolfed:

var sentence = prompt(),
    num = parseInt(prompt(), 10); // base 10

sentence = sentence.replace(/\d+/g, digit => digit * num);

alert(sentence);

43 chars:

(p=prompt)(p(b=p()).replace(/\d+/g,y=>y*b))

b=(p=prompt)();p(p().replace(/\d+/g,y=>y*b))

Requires number input first and then sentence. Cut one char more here thanks @bebe again!

\$\endgroup\$
4
  • \$\begingroup\$ you don't need to parse number input \$\endgroup\$
    – bebe
    Aug 31, 2014 at 15:44
  • \$\begingroup\$ @bebe Of course! I didn't notice! Thanks a lot! \$\endgroup\$ Sep 1, 2014 at 5:25
  • \$\begingroup\$ (p=prompt)(p(b=p()).replace(/\d+/g,y=>y*b)) another one (but this asks for multiplier first) \$\endgroup\$
    – bebe
    Sep 1, 2014 at 7:19
  • \$\begingroup\$ @bebe Thanks for this too! \$\endgroup\$ Sep 1, 2014 at 13:49
7
\$\begingroup\$

Python 2 (79)

import re
n=input()
s=input()
print re.sub('\d+',lambda x:`int(x.group())*n`,s)

Sample run

Input:
$ python mult.py
3
"This 1 is22a 3352sentence 50"
Output:
This 3 is66a 10056sentence 150

Online demo: http://ideone.com/V6jpyQ

\$\endgroup\$
3
  • \$\begingroup\$ Brilliant. I guess re.sub is the method Beta Decay and I (the other two Python submissions) were trying to reimplement. It would have been so easy... Something else that I've learned! ;) \$\endgroup\$
    – Falko
    Sep 1, 2014 at 10:19
  • \$\begingroup\$ @Falko re.sub aside, you've done an excellent job at golfing the string replace logic \$\endgroup\$ Sep 1, 2014 at 10:27
  • \$\begingroup\$ @Falko I agree, re.sub is exactly the thing I wanted! \$\endgroup\$
    – Beta Decay
    Sep 2, 2014 at 15:43
4
\$\begingroup\$

Python 2 - 126

import re
n=input()
s=input()
for i in list(re.finditer('\d+',s))[::-1]:s=s[:i.start()]+`int(i.group())*n`+s[i.end():]
print s

First input: integer n.

Second input: string s (with quotation marks, e.g. "abc42").

\$\endgroup\$
0
4
\$\begingroup\$

CJam, 47 33 30 bytes

q_A,sNerN%\[_A,s-Ner~](f*]zs1>

Reads the number and the string (in that order and separated by a single space) from STDIN.

Try it online.

Example run

$ cjam multiply.cjam <<< '7 N0 R3GUL4R 3XPR35510N5 1N CJ4M M4K3 M3 4 54D P4ND4'
N0 R21GUL28R 21XPR248570N35 7N CJ28M M28K21 M21 28 378D P28ND28

How it works

q                                 " Read from STDIN (“Q”) and push a second copy.         ";
  A,s                             " Push “0123456789” (thanks, @aditsu).                  ";
 _   NerN%                        " Replace digits with linefeeds and split at linefeeds. ";
          \ _A,s-Ner              " Replace non-digits with linefeeds.                    ";
                    ~             " Evaluate the resulting string.                        ";
           [         ]            " Collect the results in an array.                      ";
                      (f*         " Multiply all other integers by the first.             ";
                         ]z       " Interleave the elements of both arrays.               ";
                           s1>    " Flatten the result and discard the leading space.     ";
\$\endgroup\$
8
  • \$\begingroup\$ This is the weirdest piece of code ever!!! \$\endgroup\$
    – azerafati
    Aug 31, 2014 at 16:05
  • 1
    \$\begingroup\$ @Bludream: This isn't even the weirdest code I've written. :P \$\endgroup\$
    – Dennis
    Aug 31, 2014 at 16:43
  • \$\begingroup\$ Hmm, 3 * 7 = 27? \$\endgroup\$ Aug 31, 2014 at 20:41
  • \$\begingroup\$ lol, yeah voted for both. Though These are not going to make world a better place. How on earth programming languages who are supposed to be readable turned into this?? \$\endgroup\$
    – azerafati
    Sep 1, 2014 at 7:26
  • \$\begingroup\$ @aditsu: Splitting vs iterating, the battle continues. :P \$\endgroup\$
    – Dennis
    Sep 1, 2014 at 14:34
4
\$\begingroup\$

Bash+coreutils, 38 bytes

eval echo `sed "s/[0-9]\+/$\[$1*&]/g"`

Reads input string from STDIN and multiplier as a command-line parameter.

Output:

$ ./multstr.sh 3 <<< "This 1 is22a 3352sentence 50"
This 3 is66a 10056sentence 150
$ 
\$\endgroup\$
2
  • 6
    \$\begingroup\$ Interesting idea, but this will work only if the string doesn't any contain characters that are special to Bash... This is an example of a string I wouldn't try: 1 D4R3 Y0U: ; rm -rf / \$\endgroup\$
    – Dennis
    Sep 1, 2014 at 6:22
  • \$\begingroup\$ @Dennis yes that is a rather unfortunate caveat \$\endgroup\$ Sep 1, 2014 at 15:04
3
\$\begingroup\$

C# in LINQPad, 124

Straightforward. Please use CTRL+2 in LINQPad (Language: C# Statements).

var s=Console.ReadLine();var k=int.Parse(Console.ReadLine());new Regex("\\d+").Replace(s,t=>""+int.Parse(t.Value)*k).Dump();

If the multiplier is given as first input parameter, it can be done in 116 characters:

var k=int.Parse(Console.ReadLine());new Regex("\\d+").Replace(Console.ReadLine(),t=>""+int.Parse(t.Value)*k).Dump();

EDIT:

Thanks to Abbas's comment below, this can even be golfed more by using Regex static method, rather than instantiate it:

var k=int.Parse(Console.ReadLine());Regex.Replace(Console.ReadLine(),"\\d+",t=>""+int‌​.Parse(t.Value)*k).Dump();
\$\endgroup\$
4
  • \$\begingroup\$ Nice one, code-golf in C# isn't easy! I don't want to get rep on your effort so I'll provide you a tip instead of posting my own answer: use the static Regex.Replace(string, string, string) instead of new Regex("...").Replace(...); Here's the short multiplier-first version: var k=int.Parse(Console.ReadLine());Regex.Replace(Console.ReadLine(),"\\d+",t=>""+int.Parse(t.Value)*k).Dump();. In both versions this saves another 5 characters, getting you on 119 for the long version and 111 for the multiplier-first version \$\endgroup\$
    – Abbas
    Sep 1, 2014 at 14:23
  • 1
    \$\begingroup\$ Thanks for the tip, however, I decided not to change my original answer, such that others will be able to learn what-not-to-do from me, and what-to-do from you - regarding C# Regex Golfing. \$\endgroup\$
    – Jacob
    Sep 1, 2014 at 14:29
  • \$\begingroup\$ I understand you but you could also add my tip in your answer as an edit. Users tend to read this more than they will a list of comments with tips. \$\endgroup\$
    – Abbas
    Sep 1, 2014 at 14:32
  • \$\begingroup\$ Sure. The answer was edited. \$\endgroup\$
    – Jacob
    Sep 1, 2014 at 14:36
2
\$\begingroup\$

Cobra - 171

use System.Text.RegularExpressions
class P
    def main
        a=int.parse(Console.readLine?'')
        print Regex.replace(Console.readLine,'\d+',do(m as Match)="[int.parse('[m]')*a]")
\$\endgroup\$
2
\$\begingroup\$

Python 3 - 141

I don't think I can golf this any more...

import re
n=input()
f=input()
o=''
p=0
for i in re.finditer('\d+',f):o+=f[p:i.start()]+str(int(i.group())*int(n));p=i.end()
o+=f[p:]
print(o)

Example:

3     # This is input
h3110 # This is input
h9330 # This is output

10
hello100 hello100
hello1000 hello1000
\$\endgroup\$
3
  • 2
    \$\begingroup\$ Unfortunately this approach does not work. For n=2 and s="1 2" it yields 4 4, since replace modifies the first number twice. That's the same problem I'm facing right now with Python 2... ;) \$\endgroup\$
    – Falko
    Aug 31, 2014 at 7:45
  • \$\begingroup\$ @Falko I've managed to fix the problem, although making my code longer in the process \$\endgroup\$
    – Beta Decay
    Aug 31, 2014 at 8:57
  • \$\begingroup\$ Oh, well done! Just some minor remarks: m=input() saves you nothing. And x=int is actually 2 bytes longer than calling int(...) twice. \$\endgroup\$
    – Falko
    Aug 31, 2014 at 12:16
2
\$\begingroup\$

Mathematica 71 61

With 10 chars saved thanks to Martin Buttner.

Spaces in code are for readability.

f is a function in which s is the input string and n is the number to multiply discovered string numbers by.

 StringReplace[#, a : DigitCharacter .. :> ToString[#2 FromDigits@a]] &

Examples

 s="This 1 is22a 3352sentence 50"

Integer

StringReplace[#, a : DigitCharacter .. :> ToString[#2 FromDigits@a]] &@@{s, 3}

"This 3 is66a 10056sentence 150"


Rational number

StringReplace[#, a : DigitCharacter .. :> ToString[#2 FromDigits@a]] &@@{s, -7.13}

"This -7.13 is-156.86a -23899.8sentence -356.5"


Complex Number

StringReplace[#, a : DigitCharacter .. :> ToString[#2 FromDigits@a]] &@@{s, -5 + 3 I}

"This -5 + 3 I is-110 + 66 Ia -16760 + 10056 Isentence -250 + 150 I"

\$\endgroup\$
3
  • 1
    \$\begingroup\$ I don't know Mathematica. But in your examples all numbers and words are separated by spaces. Does it work for numbers directly attached to letters as well, like "abc42"? \$\endgroup\$
    – Falko
    Aug 31, 2014 at 9:45
  • \$\begingroup\$ For StringReplace it makes no difference whether there are spaces. I used the examples originally given by Chiperyman. \$\endgroup\$
    – DavidC
    Aug 31, 2014 at 15:55
  • \$\begingroup\$ I switched to the updated example. (I had used the example given earlier by Chiperyman.) For StringReplace it makes no difference whether there are spaces. \$\endgroup\$
    – DavidC
    Aug 31, 2014 at 16:04
2
\$\begingroup\$

Ruby 40

a,b=$*
p a.gsub(/\d+/){|s|s.to_i*b.to_i}

Input from stdin.

Example run:

$ ruby mult.rb "This 1 is22a 3352sentence 50" 3 
"This 3 is66a 10056sentence 150"

Online demo: http://ideone.com/4BiHC8

\$\endgroup\$
2
\$\begingroup\$

Lua: 73 69 characters

r=io.read
s=r()n=r()s=s:gsub("%d+",function(m)return m*n end)print(s)

Sample run:

bash-4.3$ lua -e 'r=io.read;s=r()n=r()s=s:gsub("%d+",function(m)return m*n end)print(s)' <<< $'This 1 is22a 3352sentence 50\n3'
This 3 is66a 10056sentence 150
\$\endgroup\$
2
  • 1
    \$\begingroup\$ You can golf it a bit more by putting everything on one line, and smooshing instructions next to ")". Like "s=r()n=()" is perfectly fine. \$\endgroup\$
    – AndoDaan
    Sep 1, 2014 at 15:33
  • 1
    \$\begingroup\$ Doh, and I read Tips for golfing in Lua just a couple of weeks ago. :( Thank you, @AndoDaan. \$\endgroup\$
    – manatwork
    Sep 1, 2014 at 16:22
2
\$\begingroup\$

JavaScript, ES6, 43 characters

This is my first attempt at golfing!

(p=prompt)(p(n=p()).replace(/\d+/g,y=>y*n))

Run this in latest Firefox's Console. The first input is the number and the second input is the string from which the numbers are to be multiplied with the first input number.

The final prompt lists the output.

\$\endgroup\$
4
  • \$\begingroup\$ Pretty nice JS Golf for a first timer! \$\endgroup\$
    – Optimizer
    Sep 29, 2014 at 13:55
  • \$\begingroup\$ Many other answers could be shorter if number was read first. That was is much easier. \$\endgroup\$
    – manatwork
    Sep 29, 2014 at 13:57
  • \$\begingroup\$ @manatwork - Yeah, but the question does not give any preference on the order, so I think it should be fine. \$\endgroup\$
    – user31482
    Sep 29, 2014 at 13:57
  • \$\begingroup\$ Correct. This is a lack of the question itself. Personally I preferred to handle input in string+number order in my answers to keep them comparable with the others. \$\endgroup\$
    – manatwork
    Sep 29, 2014 at 14:13
2
\$\begingroup\$

Vyxal s, 8 bytes

⁽±Ḋƛ⌊⁰*∨

Try it Online!

\$\endgroup\$
1
\$\begingroup\$

Perl - 48 chars

$n=<>;print/\d/?$_*$n:$_ for(<>=~/(\d+)|(\D+)/g)

Read a number on the first line, then read a sentence and break it into chunks of either digits or non digits. Print the non digits as they are, and the numbers get multiplied.

\$\endgroup\$
1
\$\begingroup\$

J - 63 char

Program reads in the number, and then the sentence.

;(*&.".&(1!:1]1)^:(0{i)(<@);.1~1,2~:/\i=.e.&'0123456789')1!:1]1

Explained by explosion:

;(*&.".&(1!:1]1)^:(0{i)(<@);.1~1,2~:/\i=.e.&'0123456789')1!:1]1
                                                         1!:1]1  NB. read sentence
                                         e.&'0123456789'         NB. is digit? bool vector
                                      i=.                        NB. save to i
                                 2  /\                           NB. between adjacent chars:
                                  ~:                             NB.  true if not equal
                               1,                                NB. pad to sentence length
 (                         ;.1~                         )        NB. cut the sentence
                ^:(0{i)                                          NB. if cut is digits:
  *&.".                                                          NB.  multiply as number
       &(1!:1]1)                                                 NB.  with user input
;                                                                NB. rejoin sentence

If we get to use J's PCRE library and make the sentence come first, we can knock this down to 54 characters:

;_2(,*&.".&(1!:1]1)&.>)/\'\d+'(rxmatches rxcut])1!:1]1

Explained by explosion:

                                                1!:1]1  NB. read in sentence
                         '\d+'(rxmatches       )        NB. all /\d+/ matches
                              (          rxcut])        NB. cut by those matches
 _2                     \                               NB. on each nonmatch-match pair:
   (               &.>)/                                NB.  take the match
     *&.".                                              NB.  multiply as number
          &(1!:1]1)                                     NB.  by user input
   (,                 )                                 NB.  prepend nonmatch
;                                                       NB. rejoin sentence

J is bad at this, what can I say. It's a inconvenient because J's so nonimperative.

Some examples:

   ;(*&.".&(1!:1]1)^:(0{i)(<@);.1~1,2~:/\i=.e.&'0123456789')1!:1]1
3
This 1 is22a 3352sentence 50
This 3 is66a 10056sentence 150
   ;(*&.".&(1!:1]1)^:(0{i)(<@);.1~1,2~:/\i=.e.&'0123456789')1!:1]1
100
N0 R3GUL4R 3XPR35510N5 1N J M4K35 M3 54D ALS0
N0 R300GUL400R 300XPR3551000N500 100N J M400K3500 M300 5400D ALS0
   0!:0 <'system\main\regex.ijs'  NB. this is usually preloaded by J on startup anyway
   ;_2(,*&.".&(1!:1]1)&.>)/\'\d+'(rxmatches rxcut])1!:1]1
TH4T'5 M4RG1N411Y B3TT3R
0
TH0T'0 M0RG0N0Y B0TT0R
\$\endgroup\$
1
\$\begingroup\$

CJam - 35

li:X;lN+{_sA,s-,{])\_!!{iX*}*oo}*}/

Try it at http://cjam.aditsu.net/

Sample input:

7
CJ4M W1LL H4V3 R3GUL4R 3XPR35510N5 L4T3R

Sample output:

CJ28M W7LL H28V21 R21GUL28R 21XPR248570N35 L28T21R

Explanation:

The program goes through each character, collecting the digits on the stack, and for each non-digit it first prints the collected number (if any) multiplied by the numeric input, then prints the character.

li:X; reads the numeric input and stores it in X
lN+ reads the string and appends a newline (it helps with trailing numbers)
{…}/ for each character in the string
- _s copies the character and converts to string
- A,s-, removes all the digits and counts the remaining characters; the result will be 0 if the character was a digit or 1 if not
- {…}* executes the block if the count was 1 (i.e. non-digit); for digits it does nothing, so they remain on the stack
-- ] collects the characters from the stack into an array (i.e. a string); the characters are any digits from the previous iterations, plus the current character
-- )\ separates the last item (the current character) and moves it before the (remaining) string
-- _!! copies the string and converts it to a boolean value - 0 if empty, 1 if not
-- {…}* executes the block if the string was not empty, i.e. we had some digits before the current non-digit character
--- iX* converts the string to integer and multiplies by X
-- o prints the top of the stack - either the multiplied number or the empty string if we didn't have a number
-- o (the 2nd one) prints the new top of the stack - the current non-digit character

\$\endgroup\$
1
  • \$\begingroup\$ That's a much saner approach. \$\endgroup\$
    – Dennis
    Sep 1, 2014 at 13:17
1
\$\begingroup\$

Haskell (161)

Golfed

main=do{n<-getLine;l<-getContents;let{g c(t,s)|c>'/'&&c<':'=(c:t,s)|t/=""=([],c:(show.(*(read n)).read$t)++s)|True=(t,c:s)};putStr.tail.snd.foldr g("","")$' ':l}

Ungolfed

modify :: (Show a, Read a) => (a -> a) -> String -> String
modify f = show . f . read

main=do
  number <- fmap read $ getLine    -- get number  
  l <- getContents                 -- get input

  -- if the current character is a digit, add it to the digits
  -- if the current character isn't a digit, and we have collected
  --    some digits, modify them and add them to the string
  -- otherwise add the current characters to the string

  let go current (digits , string) 
        | current `elem` ['0'..'9'] = (current : digits, string)
        | not (null digits)         = ([], current:(modify (*number) digits) ++ string)
        | otherwise                 = (digits, current:string)

  -- since the result of `go` is a pair, take the second value,
  -- remove the head (it's a space, in order to convert digits at the start)
  -- and print it
  putStr . tail . snd . foldr go ("","")$' ':l

Unfortunately, Haskell doesn't have a Regex library in its Prelude.

\$\endgroup\$
1
1
\$\begingroup\$

flex(-lexer) (94 89 characters)

 int m;main(c,v)char**v;{m=atoi(*++v);yylex();}
%%
[0-9]+ {printf("%d",m*atoi(yytext));}

Ungolfed version which doesn't segfault if you forget the command-line argument (not much longer):

%{
#define YY_DECL int y(int m)
%}
%option noyywrap noinput nounput
%%
[0-9]+ {printf("%d",m*atoi(yytext));}
%%
int main(int argc, char** argv) {
  return (argc > 1) ? y(atoi(argv[1])) : 1;
}

Compile with:

flex -o m.c m.l
cc -o m m.c -lfl

or:

flex --noyywrap -o m.c m.l
cc -o m m.c

Eg:

$ ./m 163
This 1 is22a 3352sentence 50
This 163 is3586a 546376sentence 8150
\$\endgroup\$
1
\$\begingroup\$

Groovy - 124

Scanner s=new Scanner(System.in)
def x=s.nextLine()
def n=s.nextInt()
x=x.replaceAll(/\d+/,{it->it.toInteger()*n})
println x

Click on the title to see the runnable example

Examples Tried:

This 1 is22a 3352sentence 50
3
This 3 is66a 10056sentence 150


This 1 is22a 3352sentence 50
42
This 42 is924a 140784sentence 2100

\$\endgroup\$
1
\$\begingroup\$

Japt, 9 bytes

r"%d+"_*V

Try it

\$\endgroup\$
0
\$\begingroup\$

GNU Awk: 86 characters

s{n=split(s RS,a,/[^0-9]+/,d);while(++i<n)printf"%s%s",a[i]==""?"":a[i]*$1,d[i]}{s=$0}

Sample run:

bash-4.3$ awk 's{n=split(s RS,a,/[^0-9]+/,d);while(++i<n)printf"%s%s",a[i]==""?"":a[i]*$1,d[i]}{s=$0}' <<< $'This 1 is22a 3352sentence 50\n3'
This 3 is66a 10056sentence 150
\$\endgroup\$
0
\$\begingroup\$

PHP - 75/115 68/109

Two versions, newer php versions can do this:

echo preg_replace_callback("/\d+/",function($m){return$m[0]*$f;},$s);

Older php versions: I did not count the newline, added those for readability.

function a($s){echo preg_replace_callback("/\d+/",b,$s);}
function b($i){global$f;return$i[0]*$f;}
a($s,$f);

Example input+output

$s = "ab11cd22"; // string
$f =  3; // -> output: ab36cd69
$f = -2; // -> output: ab-24cd-46

Kinda difficult, the words 'function' and 'preg_replace_callback' take up a lot of chars.
The space after global and return arent needed if followed by a $var (-2 chars)

\$\endgroup\$
3
  • \$\begingroup\$ No need to put \d in character class (-2 chars); no need to enclose the function in double quotes (-2 chars); you have to properly terminate the statement inside the function with semicolon (+1 char). By the way, \d in double quoted string should be written as \\d, so better change the quotes to single quotes. \$\endgroup\$
    – manatwork
    Sep 1, 2014 at 13:19
  • \$\begingroup\$ Thanks. Started with [0-9], changed 0-9 to \d. Wasnt sure about the quotes around the function, I cant test that one, my local php's version doesnt allow it. \$\endgroup\$
    – Martijn
    Sep 1, 2014 at 13:23
  • \$\begingroup\$ The double quotes work fine (at least for me) :) \$\endgroup\$
    – Martijn
    Sep 1, 2014 at 13:26
0
\$\begingroup\$

C (142 134 characters)

main(a,b)char**b;{char*c=b++[2],*d="0123456789";for(;*c;c+=strspn(c
,d))write(1,c,a=strcspn(c,d)),dprintf(1,"%d",atoi(*b)*atoi(c+=a));}

Newline inserted for enhanced legibility. Pass the factor as the first, the string as the second command line option. This implementation requires the dprintf function which is part of POSIX.1 2008 and might not be available on Windows. Here is the unminified source:

/*
 * Multiply all numbers in a string by a number.
 * http://codegolf.stackexchange.com/q/37110/134
 * Solution by user FUZxxl
 */

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

extern int
main(int count, char **argv)
{
    char *str = argv++[2], *digits = "0123456789";

    while (*str) {          /* as long as we have not reached the end */
        count = strcspn(str, digits);
        write(1, str, count);

        dprintf(1, "%d", atoi(*argv) * atoi(str += count));
        str += strspn(str, digits);
    }
}

Improvements

  • 142 → 134: Use strspn and strcspn instead of looping over the string.
\$\endgroup\$
0
\$\begingroup\$

Python 89

import re,sys
j,n,s=sys.argv
print re.sub('(\d+)',lambda m:str(int(m.group())*int(n)),s)

eg:

# python numberstring.py 3 '1shoop da2 w007p!'
3shoop da6 w21p!
\$\endgroup\$
0
\$\begingroup\$

Rebol - 117

n: do input d: charset"0123456789"parse s: input[any[b: some d e:(e: insert b n * do take/part b e):e | skip]]print s


Ungolfed:

n: do input 
d: charset "0123456789"

parse s: input [
    any [
        b: some d e: (e: insert b n * do take/part b e) :e
        | skip
    ]
]

print s
\$\endgroup\$
0
\$\begingroup\$

Clojure - 141 140 128 chars

I'm a Clojure newbie, but FWIW:

(let[[a b]*command-line-args*](println ((fn[s n](clojure.string/replace s #"\d+"#(str(*(read-string %)(read-string n)))))a b)))

Sample run:

bash$ java -jar clojure-1.6.0.jar multstr.clj "This 1 is22a 3352sentence 50" 3  
This 3 is66a 10056sentence 150

Ungolfed (ugly but hopefully somewhat easier to read):

(let [[a b] *command-line-args*]
    (println ( (fn [s n] 
                    (clojure.string/replace 
                        s 
                        #"\d+" 
                        #(str (* (read-string %) (read-string n)))))
                    a b)))
\$\endgroup\$
0
\$\begingroup\$

Python - 142

import re
s=raw_input()
i=int(raw_input())
print ''.join([x[0]+str(int(x[1])*i) for x in filter(None,re.findall('(\D*)(\d*)',s)) if x[0]!=''])
\$\endgroup\$
0
\$\begingroup\$

Java 218

Someone had to do java. The input string are 2 token on the command line.

java M 'This 1 is22a 3352sentence 50' 3

public class M{
    public static void main(String[]a) {
        int m=new Integer(a[1]),n=0,b=0;
        String s="";
        for(char c:a[0].toCharArray()){
            if(c<48|c>57)s=b>(b=0)?s+m*n+c:s+c;
            else n=b*n+c-38-(b=10);
        }
        System.out.println(b>0?s+m*n:s);
    }
}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ According to my test, the if condition works with bitwise | too, which is 1 character shorter. \$\endgroup\$
    – manatwork
    Sep 6, 2014 at 12:19
  • \$\begingroup\$ Thanks. Code updated. (It is actually still a boolean or, just without evaluation shortcut). \$\endgroup\$
    – Florian F
    Sep 6, 2014 at 13:13
0
\$\begingroup\$

Two answer: +

Pure bash (~262)

First, there is an not so short pure bash version (no fork, no external binaries)!

mn () { 
    if [[ $1 =~ ^(.*[^0-9]|)([0-9]+)([^0-9].*|)$ ]]; then
        local num=${BASH_REMATCH[2]} rhs="${BASH_REMATCH[3]}";
        mn "${BASH_REMATCH[1]}" ${2:-3} l;
        echo -n "$[num*${2:-3}]$rhs";
    else
        echo -n "$1";
    fi;
    [ "$3" ] || echo
}

Let's show:

mn "This 1 is22a 3352sentence 50" 42
This 42 is924a 140784sentence 2100

(Which is a totally improbable sentence)

Perl little obfuscated (for fun only)

This version (based on @Chilemagic's answer) is not shorter, but designed as a totem script:

cat <<eof >mn.pl

#!/usr/bin/perl          -sp
                      eval eval'"'
                      .('['^'(')
           .'/\\'.'\\'.('`'|'$').'+'.'/\\$\&'
                        .'*\\$'
                      .('`'|'.').'/'
                      .('`'|"'")
                      .('`'|'%').'"'

eof chmod +x mn.pl

Sample run:

./mn.pl -n=2 <<<$'This 1 is22a 3352sentence 50\n21.'
This 2 is44a 6704sentence 100
42.
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.