9
\$\begingroup\$

Your objective is to take multiline ASCII like

|  v  |
* * * *
 * * *

and have an array that includes everything that isn't a star changed to a star (except for [any-width] spaces) and the number of stars it included and the number of stars it now includes. So the output of my example would be:

['*  *  *
* * * *
 * * *',7,10]

or

["*  *  *\n* * * *\n * * *", 7, 10]

depending on what your code language does.

This is a challenge, so the shortest bytes wins!

\$\endgroup\$
3
  • 4
    \$\begingroup\$ Can you clarify the input and output formats, please? Which form the code should have (program, function)? \$\endgroup\$ May 6, 2014 at 3:15
  • 1
    \$\begingroup\$ @HeikoOberdiek Oh, yes. It can be both, whichever's shorter for you. \$\endgroup\$
    – Cilan
    May 6, 2014 at 12:42
  • 1
    \$\begingroup\$ @TheWobbuffet What about input/output formats? Can it just be a function that takes an argument and return an array, for example? Or does it have to print out the answer (and what would be the required format for that)? \$\endgroup\$
    – 14mRh4X0r
    May 6, 2014 at 14:38

16 Answers 16

3
\$\begingroup\$

GolfScript, 30 characters

.{.'
 '?)\42if}%.{@'*'/,(}2*]`

Takes the input from stdin. Example (test online):

> |  v  |
> * * * *
>  * * *

["*  *  *\n* * * *\n * * *\n" 7 10]
\$\endgroup\$
3
\$\begingroup\$

Python - 58 66 characters

Sooo... my first Code Golf attempt...

Code:

import re;p=re.sub(r'\S','*',i);print[p,i.count('*'),p.count('*')]

Output:

['*  *  *\n* * * *\n * * *', 7, 10]

Variables:

  • i - input string
  • p - pattern
  • o - output - removed

Dependencies:

Python re module

Full code:

import re
i = '|  v  |\n* * * *\n * * *'    
p = re.sub(r'\S','*', i)
print [p, i.count('*'), p.count('*')]

Edits:

  • Added import re to solution
  • Replaced o= with print
  • r'[/\S/g]' was changed to r'\S' (thanks @14mRh4X0r)
\$\endgroup\$
6
  • \$\begingroup\$ Hey, welcome to PPCG! This is mostly a good answer, so please don't take the rest of this post personally: There are a few things wrong with it. You've listed the re module as a dependency, but it's still necessary to include it in the answer and score. Your program also doesn't output the result like it's supposed to (however, since you don't actually use the o variable for anything, you can just s/o=/print/ and only lose three). Other than that, this looks good! \$\endgroup\$ May 6, 2014 at 14:29
  • 1
    \$\begingroup\$ Actually, there's one tiny other thing. Your i variable contains | v | * * * * * * * instead of the actual test input (which includes newlines). That being said, your program still works if you include the newlines, so your program doesn't have to be changed at all, just the post. :) \$\endgroup\$ May 6, 2014 at 14:31
  • 1
    \$\begingroup\$ Hi @undergroundmonorail - thanks for the feedback :) I'll update my post now \$\endgroup\$
    – martynas
    May 6, 2014 at 14:33
  • 1
    \$\begingroup\$ No problem. Also, I haven't tested this at all, but 14mRh4X0r from chat says that r'[/\S/g]' could be replaced with r'\S' to save a few characters. \$\endgroup\$ May 6, 2014 at 14:36
  • 1
    \$\begingroup\$ @undergroundmonorail and he's right :) thanks \$\endgroup\$
    – martynas
    May 6, 2014 at 14:39
2
\$\begingroup\$

Ruby 2.0, 53 characters

p [r=gets($n).gsub(/\S/,?*),$_.count(?*),r.count(?*)]

Not sure on the exact input/output formats required. This takes input on STDIN and formats the output like so:

Input:

|  v  |
* * * *
 * * *

Output:

["*  *  *\n* * * *\n * * *", 7, 10]
\$\endgroup\$
2
\$\begingroup\$

JavaScript (ECMASCript 6) - 51 Characters

i=j=0,[A.replace(/\S/g,x=>(j++,i+=x=='*','*')),i,j]

Assumes the variable A contains the multiline ASCII input. To take it from the user then replace the A with prompt() (+7 characters) or as a function (again +7 characters):

f=A=>(i=j=0,[A.replace(/\S/g,y=>(j++,i+=y=='*','*')),i,j])

Output is to the console.

Test:

A='|  v  |\n* * * *\n * * *'
i=j=0,[A.replace(/\S/g,x=>(j++,i+=x=='*','*')),i,j]

Outputs:

["*  *  *
* * * *
 * * *", 7, 10]
\$\endgroup\$
1
\$\begingroup\$

PHP ≥ 5.5, 84 69 63 bytes

$a=[preg_replace('/\S/','*',$s,-1,$n),substr_count($s,'*'),$n];

Not a lot to say about this. As there is no specification for how to handle input/output, I'm assuming variable storage. Expects the input in variable $s and stores the array in variable $a. Too bad those function names are s o long.

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

Rebol, 84

c: s: 0 parse t[any["*"(++ s)|" "|"^/"| m: skip(change m"*" ++ c)]]reduce[t s s + c]

Set t to the text like so....

t: {|  v  |
* * * *
 * * *}

and this would return...

["*  *  *^/* * * *^/ * * *" 7 10]

Ungolfed version with some notes:

c: s: 0    ;; "s" is star count before change, "c" is count of chars changed to stars

; so using single-char ANY rule to parse each character in "t"

parse t [
    any [                              ;; so "t" is made up of ANY...
        "*"     (++ s) |               ;; "*" (if so then increment s)
        " "            |               ;; or a space
        "^/"           |               ;; or a newline
        m: skip (change m "*"  ++ c)   ;; or anything else (skip) 
                                       ;;   (and so change to "*" & increment c)
    ]
]

reduce [t s s + c]      ;; return array with amended text (t) and counts
\$\endgroup\$
1
\$\begingroup\$

Groovy : 96 92 chars

s=System.in.text
t=s.replaceAll(/[^\*\s]/,/\*/)
println "['$t',${s.count"*"},${t.count"*"}]"

Uses Groovy 2.2.1

Reads from STDIN. IMHO, not especially clever, but fairly easy to read (given its brevity)

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

Stax, 12 bytes

ç≈°▼╔╔²AGΓM4

Run and debug it

Explanation

.\S'*YRQx2Dy#P
.\S              push regex \S
   '*            push '*'
     Y           store star in Y
      R          perform regex replacement on the input
       Q         peek and print with newline
        x        push input again
         2D      execute the following twice:
           y     push '*'
            #    number of stars
             P   pop and print with newline
            
\$\endgroup\$
1
\$\begingroup\$

05AB1E, 17 bytes

…
     м©S'*:I'*¢®g)

Assumes the mentioned "[any-width] spaces" only include spaces, tabs, and newlines (with codepoints 32, 9, and 10 respectively).

Try it online.

Explanation:

…\n\t м       # Remove all newlines, tabs, and spaces of the (implicit) input-string
       ©      # Store this string in variable `®` (without popping)
        S     # Convert it to a list of characters
         '*: '# Replace each non-whitespace character in the (implicit) input with a "*"
I             # Push the input again
 '*¢         '# Pop and count the amount of "*" in this string
®             # Push the non-whitespace string from variable `®`
 g            # Pop and push its length
            ) # Wrap everything on the stack into a list
              # (after which it is output implicitly as result)
\$\endgroup\$
0
\$\begingroup\$

In JavaScript/CoffeeScript - 66 Characters

Like the PHP Example, the length is due to the length of the function names

[x.replace(/\S/g,"*"),x.split("*").length-1,x.match(/\S/g).length]

Example Usage (CoffeeScript):

((x="|  v  |\n* * * *\n * * *")->[x.replace(/\S/g,'*'),x.split('*').length-1,x.match(/\S/g).length])()
\$\endgroup\$
1
  • 1
    \$\begingroup\$ 3-char shorter : [x.replace(r=/\S/g,s='*'),x.split(s).length-1,x.match(r).length] \$\endgroup\$
    – Michael M.
    May 6, 2014 at 5:55
0
\$\begingroup\$

C# - 116

Shortest way i can think of that returns an array..

object[]R(string a){var o=Regex.Replace(a,"\\S", "*");return new object[]{o,a.Count(x=>x=='*'),o.Count(x=>x=='*')};}
\$\endgroup\$
0
\$\begingroup\$

Perl, 52 bytes

$_=join'',<>;printf'["%s",%s,%s]',$_,tr/*//,s/\S/*/g

Takes input from standard input, prints to standard output.

Assuming the output format like you described in your question, could be made quite a bit shorter if a different output format would be allowed.

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

Javascript - 50 characters

i.replace(/\S/g,'*').replace(/\n/g,':').split(':')

Test

Input

var i = 'Lately I been, I been losing sleep\nDreaming about the things that we could be\nBut baby, I been, I been prayin\' hard';
i.replace(/\S/g,'*').replace(/\n/g,':').split(':')

Output

["****** * ***** * **** ****** *****", "******** ***** *** ****** **** ** ***** **", "*** ***** * ***** * **** ******* ****"]
\$\endgroup\$
1
  • \$\begingroup\$ This doesn't really meet the specification. Look here for an example. \$\endgroup\$
    – tomsmeding
    May 8, 2014 at 18:42
0
\$\begingroup\$

AWK, (too long)

awk '{y+=gsub(/[^* ]/, "*"); x+=NF}NR>1{z=z "\n" $0} NR==1{z=z $0} END{print "[\x27"z (x-y) "," x "\x27]"}'

I'm no awk master so I'm sure it can be improved. The takeaway is I had fun writing it! The struggle came with how to preserve the newlines from the input but not put the , 7,10] on a new line. That bit of logic (NR>1{z=z "\n" $0} NR==1{z=z $0}) cost me a lot of characters. I'd be interested to see any other awk approaches on that front.

I didn't provide the file at the end of the script, but obviously the usage would be awk '{<code>}' ascii.txt, where ascii.txt contains the mult-line "input".

Output

 ['* * *
 * * * *
 * * *',7,10]
\$\endgroup\$
0
\$\begingroup\$

Java, 199 bytes

Golfed:

class C{public static void main(String[]a){String i=a[0],o=i.replaceAll("\\S","*");System.out.println("["+o+","+g(i)+","+g(o)+"]");}static int g(String x){return x.replaceAll("[^\\*]","").length();}}

Un-golfed:

public class CountingStars {

    public static void main(String[] args) {
        String input = args[0];
        //replace all non-white-space char with *
        String output = input.replaceAll("\\S", "*");
        System.out.println("[" + output + "," + getStars(input) + "," + getStars(output) +"]");
    }

    static int getStars(String x) {
        //replace all non-* characters with empty-string and return length
        return x.replaceAll("[^\\*]", "").length();
    }
}

Run online.

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

Zsh -F, 44 bytes

T(){tr -dc *|wc -c}
T<f
tr<f -c '
 ' *>g
T<g

Try it online!

Input from a file f, output to stdout and a file g

Ungolfed and commented:

T () {        # define a function T
  tr -dc *  \ # keep only the asterisks in the input
    | wc -c   # count characters
}
T < f         # apply T to the file f
tr        \   # replace
  -c      \   # everything except
  '\n '   \   # spaces or newlines
  *       \   # with asterisks
  < f     \   # input from the file f
  > g         # output to the file g
T < g         # apply T to the file g

-F prevents the * from being interpreted specially

\$\endgroup\$

Your Answer

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

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