14
\$\begingroup\$

You just recently got a new phone, but you don't quite like the way it vibrates, you've decided you want to create your own vibration patterns. So, you've written a program where you used the keywords long, short and pause to make your phone vibrate according to these keywords.

Task

Create a small program that accepts a string of long, short, and pause and outputs another string representing the phonetic sound of a phone vibrating; Rrrr - Rr

long sounds are Rrrr
short sounds are Rr
(Casing matters)
pause is a dash -
all sounds are delimited by dash with surrounding spaces ' - '

Test Cases

input:   long long short long short
output: Rrrr - Rrrr - Rr - Rrrr - Rr

input:   long long long short short short
output: Rrrr - Rrrr - Rrrr - Rr - Rr - Rr

input:   short short short pause short short short
output: Rr - Rr - Rr - - - Rr - Rr - Rr

input:   long short short long long pause short short
output: Rrrr - Rr - Rr - Rrrr - Rrrr - - - Rr - Rr

This is a question so answers will be scored in bytes, with the fewest bytes winning.

\$\endgroup\$
15
  • 5
    \$\begingroup\$ Isn't that a subjective criterion? I would like to use empty string, it sounds like a vibrating phone to me. \$\endgroup\$
    – user72349
    Aug 25, 2017 at 7:15
  • 6
    \$\begingroup\$ Your "sounds like" rule is much too vague. I'd suggest just requiring exact strings. Code golf requires precise criteria so we can optimize code without having argument on whether an improvement is valid. \$\endgroup\$
    – xnor
    Aug 25, 2017 at 7:16
  • 4
    \$\begingroup\$ Do we have to delimit the sounds with a -? This is the case in your example, but is not specified anywhere. \$\endgroup\$
    – JAD
    Aug 25, 2017 at 7:51
  • 12
    \$\begingroup\$ The examples all use a capital lower followed by copies of a lowercased letter. Is this a rule? \$\endgroup\$
    – xnor
    Aug 25, 2017 at 8:46
  • 3
    \$\begingroup\$ What needs to be done before this can be reopened: 1) Specify the exact strings (or sets of strings) we must use, including case limitations, 2) Clarify whether input and/or output can be an array either of words or arrays of characters, 3) Specify the exact separator that must be used when outputting as a string. \$\endgroup\$
    – Shaggy
    Aug 25, 2017 at 12:24

28 Answers 28

14
\$\begingroup\$

JavaScript, 70 63 bytes

2 bytes saved thanks to Luke

a=>a.replace(/./g,a=>[['Rr','rr','-',' - ']['onp '.search(a)]])

Try it online!

\$\endgroup\$
1
  • 6
    \$\begingroup\$ Nice trick with the outer []s! \$\endgroup\$
    – Neil
    Aug 25, 2017 at 8:38
12
\$\begingroup\$

Pyke, 22 20 bytes

cFh.o6.&\R*\-|l4)J" - 

Try it here!

c                      -  split(input, " ")
 Fh.o6.&\R*\-|l4)      -  for i in ^:
  h                    -        ^[0]
   .o                  -       ord(^)
     6.&               -      ^ & 6
        \R*            -     ^
           \-|         -    ^ or "-"
              l4       -   ^.title()
                 J" -  - " - ".join(^)

The crux of this answer is the transformation of ["long", "short", "pause"] into [4, 2, 0]. It gets the code point of the first letter of each word and ANDs it with 6. By lucky coincidence it transforms to the values we're looking for. (I searched through quite a few other longer solutions before finding this one). Once that's done, we can further transform that list of ints into ["RRRR", "RR", ""] by multiplying our int by "R" which then turns into ["RRRR", "RR", "-"] and finally title casing it to get ["Rrrr", "Rr", "-"]. We then join the resulting list by " - "

\$\endgroup\$
4
  • \$\begingroup\$ Cool way of going about it with the transformation! \$\endgroup\$ Aug 25, 2017 at 8:03
  • \$\begingroup\$ The solution is absurdly similar in Pyth: j" - "m|*\M.&Chd6\-c :-) \$\endgroup\$
    – Mr. Xcoder
    Aug 25, 2017 at 12:04
  • \$\begingroup\$ Also The OP adds space to the examples but does not specify them, I've asked for clarification on that. \$\endgroup\$ Aug 25, 2017 at 17:14
  • \$\begingroup\$ @JonathanAllan The bytes \xef and \xa6 are .o and .& respectively. It's a backwards compatible change where if the high bit is set, it runs it like the old 2 byte commands. I'm writing it this way to make it easier for the reader and because Pyke technically doesn't use a code page anymore and I don't want to have to insert random bytes that don't work \$\endgroup\$
    – Blue
    Aug 25, 2017 at 17:42
11
\$\begingroup\$

Haskell, 71 66 59 bytes

g 'o'="Rr"
g 'n'="rr"
g 'p'="-"
g ' '=" - "
g _=""
f=(g=<<)

Try it online!

Oh right, =<< is concatMap.

Takes advantage of the fact that "long" and "short" both have the letter o.

\$\endgroup\$
2
  • \$\begingroup\$ You don't need to pay the 2 bytes for f= point-free functions are allowed without assignment \$\endgroup\$
    – Wheat Wizard
    Aug 26, 2017 at 18:13
  • \$\begingroup\$ You can save one whole byte with lambdacase by switching to lambdabot haskell: (>>=(\case 'o'->"Rr";'n'->"rr";'p'->"-";' '->" - ";_->"")) \$\endgroup\$
    – BlackCap
    Aug 26, 2017 at 21:11
7
\$\begingroup\$

JavaScript (ES6), 65 59 bytes

s=>s.split` `.map(x=>x<'m'?'Rrrr':x<'q'?'-':'Rr').join` - `

let f =

s=>s.split` `.map(x=>x<'m'?'Rrrr':x<'q'?'-':'Rr').join` - `

console.log(f("long long short long short")); // => Rrrr - Rrrr - Rr - Rrrr - Rr
console.log(f("long long long short short short")); // => Rrrr - Rrrr - Rrrr - Rr - Rr - Rr
console.log(f("short short short pause short short short")); // => Rr - Rr - Rr - - - Rr - Rr - Rr
console.log(f("long short short long long pause short short")); // => Rrrr - Rr - Rr - Rrrr - Rrrr - - - Rr - Rr

\$\endgroup\$
7
\$\begingroup\$

05AB1E, 33 27 25 21 bytes

#εÇн6&'m×™'-)éθ}… - ý

Try it online!

Explanation

#                       # split input on spaces
 ε             }        # apply to each
  Çн                    # get the character code of the head
    6&                  # AND with 6
      'm×               # repeat "m" this many times
         ™              # title case
          '-)           # wrap in a list with "-"
             éθ         # get the longest string       
                … - ý   # join to string using " - " as separator

Saved 3 bytes using the AND 6 trick from muddyfish's pyke answer

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

Python 2, 76 69 64 bytes

lambda s:' - '.join('Rrrr'[:ord(b[0])&6]or'-'for b in s.split())

Try it online!

Alternates:

Python 2, 76 69 bytes

lambda s:' - '.join(['Rrrr','-','Rr'][ord(b[1])%3]for b in s.split())

Try it online!

Python 2, 69 bytes

lambda s:' - '.join('-Rrrr'['o'in b:8-ord(b[1])%9]for b in s.split())

Try it online!

\$\endgroup\$
5
\$\begingroup\$

Mathematica, 81 bytes

StringReplace[#,{"long"->"Bzzz -","short"->"Bz -","pause"->"- -"}]~StringDrop~-2&

Try it online!

\$\endgroup\$
5
\$\begingroup\$

Retina, 31 29 bytes

1 byte saved thanks to Dom Hastings
1 byte saved thanks to Neil

[^lhp ]

l
hrr
h
Rr
p
-
 
 - 

Try it online!

This is different approach than @DomHastings's answer.

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

Perl 5, 39 bytes

37 bytes code + 2 for -pa.

$_=join" - ",map/p/?"-":Bz.zz x/l/,@F

Try it online!

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

R, 77 bytes

cat(c('Rrrr','Rr','-')[match(scan(,''),c('long','short','pause'))],sep=' - ')

Takes input through STDIN, checks whether the input matches long, short or pause and swaps the matches for Rrrr, Rr or - respectively.

This is then printed with - padded with spaces as separator, matching the desired output.

\$\endgroup\$
6
  • \$\begingroup\$ You can save 2 bytes by switching from match to %in%: scan(,'') %in% c('long','short','pause') \$\endgroup\$
    – YCR
    Aug 25, 2017 at 9:45
  • \$\begingroup\$ @YCR I don't think that'll work. a %in% b checks whether entries in the a are present in b, while match(a, b) returns the actual indices of the matches. Since we can assume that the input is valid, using %in% would just return a vector of TRUEs. \$\endgroup\$
    – JAD
    Aug 25, 2017 at 9:51
  • \$\begingroup\$ Arf, true. I have test it with c('long','short','pause'). \$\endgroup\$
    – YCR
    Aug 25, 2017 at 9:55
  • \$\begingroup\$ That's because when you feed a boolean vector into [, it is interpreted as [which(bool) == TRUE], which in your example would be [c(1,2,3)], which in turn happens to give the correct output. \$\endgroup\$
    – JAD
    Aug 25, 2017 at 9:58
  • \$\begingroup\$ Instead of sep=' - ' you can use s=' - ' for 2 bytes less \$\endgroup\$
    – Rift
    Aug 25, 2017 at 9:59
4
\$\begingroup\$

Röda, 73 57 47 46 40 44 bytes

f&a{a~=*`s\w+|l;Rr;ong;rr;p\w+;-; ; - `/";"}

Try it online!

+4 bytes due to rule change (must use Rrrr instead of any 4 letter variant).

Previous code:

{[[split()|["Bzzz"]if[_="long"]else["Bz"]if[_1="short"]else["-"]]&" - "]}
\$\endgroup\$
3
  • \$\begingroup\$ Using Mmm and Mm is 1 byte shorter. \$\endgroup\$
    – ATaco
    Aug 25, 2017 at 7:20
  • \$\begingroup\$ @ATaco It's said in the question that "Long sounds should be 4 characters long, and short sounds should be 2 characters long". \$\endgroup\$
    – fergusq
    Aug 25, 2017 at 7:22
  • \$\begingroup\$ ATaco, please note that the criteriums have been further specified in the question. \$\endgroup\$ Aug 25, 2017 at 7:22
4
\$\begingroup\$

C (gcc), 93 77 76 bytes

-2 bytes thanks to Scepheo!
-1 byte thanks to Cyoce!

Takes a NULL terminated **char or equivalent as an input.

f(char**a){for(;*a;*++a&&printf(" - "))printf(**a&6?**a&1?"Rr":"Rrrr":"-");}

Try it online!

Explanations:

f(char**a){
  // While the string at the current position is not NULL
  for(;*a;
    // Advances the pointer to the next string
    // Then if the current string is not NULL, prints a delimiter
    *++a&&printf(" - ")
  )
    /* 
      If the 1st char of the string is not a 'p'
        If the 1st char is not a 'l'
          Prints "Rr"
        Else
          Prints "Rrrr"
      Else:
        Prints "-"
     */
    printf(**a&6?**a&1?"Rr":"Rrrr":"-");
}
\$\endgroup\$
4
  • 2
    \$\begingroup\$ I think you can combine a++,*a into *++a to save two bytes, and take advantage of the vague "sound" definition to use *a instead of "Rrrr" to save another four bytes. \$\endgroup\$
    – Scepheo
    Aug 25, 2017 at 9:42
  • \$\begingroup\$ Your second suggestion is genius! \$\endgroup\$
    – scottinet
    Aug 25, 2017 at 9:47
  • 1
    \$\begingroup\$ Can you move part of the increment stage of the for-loop to the body instead of being comma-separated? \$\endgroup\$
    – Cyoce
    Aug 27, 2017 at 21:29
  • \$\begingroup\$ This indeed saves a byte. Good catch! \$\endgroup\$
    – scottinet
    Aug 27, 2017 at 21:52
3
\$\begingroup\$

R, 72 bytes

Takes input from stdin, prints to stdout.

cat(sapply(scan(,''),switch,long="vvvv",short="vv",pause="-"),sep=" - ")

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Batch, 88 bytes

@set/ps=
@set s=%s: = - %
@set s=%s:long=Rrrr%
@set s=%s:short=Rr%
@echo %s:pause=-%

Takes input on STDIN. Unfortunately loop overhead costs 26 bytes so this is just boring replacements.

\$\endgroup\$
5
  • 2
    \$\begingroup\$ Suggested edit to remove all of the @s \$\endgroup\$
    – Stephen
    Aug 25, 2017 at 22:30
  • \$\begingroup\$ @Stephen Yes, I got the notification... \$\endgroup\$
    – Neil
    Aug 25, 2017 at 23:47
  • \$\begingroup\$ Nice! Just two things, though: I counted that answer to be 84 bytes long, not 88. Also, OP has replaced Mmmm and Mm with Rrrr and Rr, it would be nice to update your answer c: \$\endgroup\$ Aug 26, 2017 at 1:59
  • \$\begingroup\$ Batch as of what platform? I doubt MS-DOS 6.22 would do what XP does when in enhanced command mode. \$\endgroup\$
    – TOOGAM
    Aug 27, 2017 at 4:58
  • \$\begingroup\$ @TOOGAM Yeah, when I say Batch I usually mean Windows NT's CMD.EXE's version. \$\endgroup\$
    – Neil
    Aug 27, 2017 at 9:09
2
\$\begingroup\$

Retina, 31 bytes

short|l
Bz
ong
zz
pause
-
 
 - 

-1 byte thanks to @fergusq!

Try it online!

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

PHP, 113 bytes

<?$s=[];for($i=1;$i<$argc;$i++){$c=$argv[$i][0];$s[]=($c<'m')?'Rrrr':(($c<'q')?'-':'Rr');}echo implode(' - ',$s);

Try it online!

First attempt at code golf, so probably a lot of optimisations available!

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

Vim (52 bytes)

:s/long/Rrrr/ge|s/short/Rr/ge|s/pause/-/ge|s/ / - /genter

Can probably be made shorter...

\$\endgroup\$
2
  • \$\begingroup\$ Stringing the commands together like this stops the train if one of them errors IE if there's no pause or something in the given string, the replacements after the one that failed won't work. You can either split them on separate lines or put an e flag at the end \$\endgroup\$
    – nmjcman101
    Aug 25, 2017 at 18:24
  • \$\begingroup\$ Corrected the error. I still feel there ought to be some way to speed it up, but the only other way I thought of (after turning "pause" into a dash, s/[^ -]/r/, capitalize the first R after every space, trim four-r to two-r) came out longer. \$\endgroup\$
    – Vivian
    Aug 26, 2017 at 18:22
1
\$\begingroup\$

Excel, 100 bytes

=REPLACE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(A1,"long","- Bzzz"),"short","- Bz"),"pause","- -"),1,2,"")

Per examples, Input is SPACE separated string, as is output.

Question itself does not mention a SPACE requirement, allowing for a slightly shorter 97 byte solution:

=REPLACE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(A1,"long","-Bzzz"),"short","-Bz"),"pause","--"),1,1,"")
\$\endgroup\$
1
\$\begingroup\$

V, 32 bytes

Í /ò
çl/CRrrr
ço/CRr
çp/-
HòJa- 

Try it online!

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

AutoIt, 145 bytes

EXECUTE(STRINGREPLACE('MSGBOX(0,0,STRINGSTRIPWS(====INPUTBOX(0,0),"PAUSE",""),"LONG","Rrrr"),"SHORT","Rr")," "," - "),4))',"=","STRINGREPLACE("))

(AutoIt is really bad choice for code golf, tried my best to make it small as possible)

\$\endgroup\$
1
  • \$\begingroup\$ Welcome to the site! :) \$\endgroup\$
    – DJMcMayhem
    Aug 25, 2017 at 23:00
1
\$\begingroup\$

Alice, 37 bytes

/ lRnrhR
\""orgrp-""!yi'."?-e"ySNo?@/

Try it online!

Explanation

This program makes the following substitutions:

  • l, hR
  • o, n, gr
  • p-
  • Space → Space
  • Everything else → Nothing
"longhp "!i.?eyN?"RrrrR- "y' " - "So@

"longhp "    Push this string
!            Immediately move to tape
i            Take input string
.            Duplicate
?ey          Remove all instances of the characters "longhp " from copy
N            Remove the remaining characters from the original, leaving only "longhp "
?"RrrrR- "y  Replace the characters in "longhp " with the corresponding characters in "RrrrR- "
' " - "S     Replace all spaces with " - "
o            Output
@            Terminate
\$\endgroup\$
1
\$\begingroup\$

Sed, 50 bytes

Takes input from stdin, prints to stdout

s/l\w*/Rrrr -/g
s/s\w*/Rr -/g
s/p\w*/- -/g
s/ -$//

Edit - saved 2 bytes

Sed, 40 bytes

Copying idea from Nitrodon's answer

s/[srtaue]//g
y/lhongp/RRrrr-/
s/ / - /g

Edit: saved another 2 bytes

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

Python 2, 69 bytes

lambda s:" - ".join((ord(i[0])&6)*"R"or"-"for i in s.split()).title()

Try it online!

Port of my Pyke answer

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

Paradoc (v0.2.10), 21 bytes (CP-1252)

Wμ‹6&'r\°"-":Ãu}« rTc

Try it online!

Takes a string on the stack and results in a string on the stack. Prepend i to turn into a full program that reads from STDIN.

Uses &6 like the Pyke answer and everybody else, but joins the tokens together slightly differently, by adding a "-" token after each noise, deleting the last one, and then joining these tokens by spaces. Seems to save a byte over joining by " - ".

Explanation:

W                     .. Break into words
 μ             }      .. Map over this block:
  ‹                   .. Take the first character
   6&                 .. Binary AND with 6, to get 4, 2, or 0
     'r               .. Character "r"
       \              .. Swap top two of stack
        °             .. Replicate, to get "rrrr", "rr", or ""
         "-"          .. Push string "-"
            :         .. Duplicate on stack
             Ã        .. Compute the max...
              u       .. ... underneath the top of the stack (so, of the
                      .. second and third elements on the stack, i.e. the
                      .. string of "r"s and "-")
                      .. The mappped block ends here; we now have
                      .. something like ["rrrr", "-", "-", "-", "rr", "-"]
                «     .. Take all but the last
                  r   .. Join with spaces (this built-in's name is two
                      .. characters, the first of which is a space)
                   Tc .. Title-case

v0.2.11 will support shaving two more bytes by replacing with x and "-" with '-.

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

SOGL V0.12, 28 bytes

θ{K;⁄5κ« r*; p=?X┌}}¹" - ”∑ū

Try it Here!

fun fact: if it was allowed to delimit with - or - it'd be a byte shorter

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

Ruby, 67 bytes

p ARGV[0].split(' ').map{|w|w<'m'?'Rrrr':w<'q'?'-':'Rr'}.join ' - '

This is Johan Karlsson's JavaScript solution ported to Ruby. If you like this answer, you should upvote Johan's answer.

The key idea is to compare the word strings 'short', etc. to a single character in order to distinguish between words.

| Word  | < 'm' | < 'q' | Output |
|-------|-------|-------|--------|
| short | false | false | 'Rr'   |
| long  | true  | N/A   | 'Rrrr' |
| pause | false | true  | '-'    |

Or, in alphabetical order:

  • long
  • m
  • pause
  • q
  • short

Try it online!

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

Ruby, 78 bytes

p ARGV[0].chars.map{|c|{p:'-',o:'Rr',g:'rr',' '.to_sym=>' - '}[c.to_sym]}.join

The only important parts of the input are p, o, g, and space... ignore the rest.

  • short becomes o
  • long becomes og
  • pause becomes p

Try it online!

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

Python 3, 66 bytes

' - '.join(['Rrrr','-','Rr'][ord(s[1])%3]for s in input().split())

Try it online!

\$\endgroup\$

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.