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\$
  • 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 '17 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 '17 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 '17 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 '17 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 '17 at 12:24

28 Answers 28

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\$
  • \$\begingroup\$ Cool way of going about it with the transformation! \$\endgroup\$ – tisaconundrum Aug 25 '17 at 8:03
  • \$\begingroup\$ The solution is absurdly similar in Pyth: j" - "m|*\M.&Chd6\-c :-) \$\endgroup\$ – Mr. Xcoder Aug 25 '17 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\$ – Jonathan Allan Aug 25 '17 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 '17 at 17:42
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\$
  • 6
    \$\begingroup\$ Nice trick with the outer []s! \$\endgroup\$ – Neil Aug 25 '17 at 8:38
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\$
  • \$\begingroup\$ You don't need to pay the 2 bytes for f= point-free functions are allowed without assignment \$\endgroup\$ – Wheat Wizard Aug 26 '17 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 '17 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\$
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\$
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\$
  • \$\begingroup\$ You can save 2 bytes by switching from match to %in%: scan(,'') %in% c('long','short','pause') \$\endgroup\$ – YCR Aug 25 '17 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 '17 at 9:51
  • \$\begingroup\$ Arf, true. I have test it with c('long','short','pause'). \$\endgroup\$ – YCR Aug 25 '17 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 '17 at 9:58
  • \$\begingroup\$ Instead of sep=' - ' you can use s=' - ' for 2 bytes less \$\endgroup\$ – Rift Aug 25 '17 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\$
  • \$\begingroup\$ Using Mmm and Mm is 1 byte shorter. \$\endgroup\$ – ATaco Aug 25 '17 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 '17 at 7:22
  • \$\begingroup\$ ATaco, please note that the criteriums have been further specified in the question. \$\endgroup\$ – tisaconundrum Aug 25 '17 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\$
  • 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 '17 at 9:42
  • \$\begingroup\$ Your second suggestion is genius! \$\endgroup\$ – scottinet Aug 25 '17 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 '17 at 21:29
  • \$\begingroup\$ This indeed saves a byte. Good catch! \$\endgroup\$ – scottinet Aug 27 '17 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\$
  • 2
    \$\begingroup\$ Suggested edit to remove all of the @s \$\endgroup\$ – Stephen Aug 25 '17 at 22:30
  • \$\begingroup\$ @Stephen Yes, I got the notification... \$\endgroup\$ – Neil Aug 25 '17 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\$ – Matheus Avellar Aug 26 '17 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 '17 at 4:58
  • \$\begingroup\$ @TOOGAM Yeah, when I say Batch I usually mean Windows NT's CMD.EXE's version. \$\endgroup\$ – Neil Aug 27 '17 at 9:09
2
\$\begingroup\$

Retina, 31 bytes

short|l
Bz
ong
zz
pause
-
 
 - 

-1 byte thanks to @fergusq!

Try it online!

\$\endgroup\$
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\$
  • \$\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 '17 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\$ – David Heyman Aug 26 '17 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\$

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\$
  • \$\begingroup\$ Welcome to the site! :) \$\endgroup\$ – DJMcMayhem Aug 25 '17 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\$

V, 32 bytes

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

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, privacy policy and cookie policy

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