KeyPad Code to Text!

Given a String and an Array as input, your task is to output the text the input String will print when typed on a typical Mobile Keypad. In a Mobile Keypad, a letter is typed by pressing a button n times, where n is the position of where the letter is at on the button's label. So, 22 should output b.

Rules

• The Helper Array will contain the Character Map ([" ",".,!","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"]). This will be given to save you some bytes.

• The # symbol will toggle case. Initial Case will be lower. So 2#3 should output aD.

• The 0 will add a space. So, 202 should output a a.

• There will be a space () in the input String to start a new letter that is on the same numeric button. For Example to type aa, the input String will be 2 2.

• It is guranteed that the input String will always be a valid KeyPad Code.

Input

You can take input in whatever way your language supports.

Output

You can output the result in any way you want. Function return is also allowed.

Test Cases

#4440555#666888330#999#66688111 -> "I Love You!"
#6#33777 7779990#222#4477744477778627777111 -> "Merry Christmas!"
#44#27 79990#66#3390#999#332777111 -> "Happy New Year!"


This is , so the shortest code in bytes wins!

• Closely related – Mego Dec 24 '16 at 3:38
• I think the capitalization on year in the last test case is wrong. – Maltysen Dec 24 '16 at 17:33
• Do we have to consider looping? Like, 2222->invalid or 2222->b? – Kuilin Li Dec 24 '16 at 18:26
• @Maltysen Yes, you are right. I've edited the question. Thanks for pointing it out. :) – Arjun Dec 24 '16 at 23:13
• Out of interest, do ## or double space need to be handled? – Neil Jan 8 '17 at 17:07

Pyth - 31 bytes

The new key thing cost me too much.

ss.emr!FZk@@QsedthdfndeTrb8cz\#


JavaScript, 105 99 bytes

f=
(s,a)=>s.replace(/#| ?((.)\2*)/g,(m,n,d)=>d?(l=a[d][n.length-1],x?l:l.toUpperCase()):(x=!x,''),x=1)

a=['  ','.,!','abc','def','ghi','jkl','mno','pqrs','tuv','wxyz']

F=s=>console.log( f(s,a) )
F('#4440555#666888330#999#66688111')
F('#6#33777 7779990#222#4477744477778627777111');
F('#44#27 79990#66#3390#999#332777111');

• 6 bytes off thanks @Neil.
• You can save some bytes by storing the letter in a temporary (e.g. l) and then using c?l:l.toUpperCase(). – Neil Jan 8 '17 at 17:06
• @Neil. Considering the array is already in lowercase... thanks :) – Washington Guedes Jan 10 '17 at 14:50

Perl 6,  119  97 bytes

map based solution 119 bytes

->$_,\a{my$u=0;[~] map {/'#'/??{$u+^=1;|()}()!!(&lc,&uc)[$u](a[.substr(0,1)].substr(.chars-1,1))},.comb(/(\d)$0*|'#'/)}  Try it substitution based solution 97 bytes ->$_,\a{my$u=0;S:g/(\d)$0*|./{$0??(&lc,&uc)[$u](a[$0].substr($/.chars-1,1))!!($u+^=$/eq'#')x 0}/}


Try it

Expanded:

->     # pointy block lambda

$_, # input string \a # helper array { my$u = 0;

S                        # substitute (implicit against ｢$_｣) :global / | (\d)$0*             # digit followed by same digit
| .                    # everything else

/{

$0 # is ｢$0｣ set (digit)

??                     # if so then
(&lc,&uc)[$u]( # call either ｢lc｣ or ｢uc｣ a[$0]            # get the value from the input array
.substr(         # select the correct character
$/.chars - 1, 1 ) ) !! ($u +^= $/ eq '#' # numeric xor$u if ｢#｣ was matched
) x 0              # string repeated zero times (empty string)

}/
}


JavaScript ES6 - 124 bytes

Golfed:

f=h=>a=>(o=c="")+a.match(/#|(.)\1*/g).forEach(e=>e==" "?0:e=="#"?c=!c:(n=h[e[0]][e.length-1])*(o+=c?n.toUpperCase():n))?o:0;


f=h=>a=>(o=c="")+a.match(/#|(.)\1*/g).forEach(e=>e==" "?0:e=="#"?c=!c:(n=h[e[0]][e.length-1])*(o+=c?n.toUpperCase():n))?o:0;

console.log(f(["  ",".,!","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"])("#4440555#666888330#999#66688111"));
console.log(f(["  ",".,!","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"])("#6#33777 7779990#222#4477744477778627777111"));
console.log(f(["  ",".,!","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"])("#44#27 79990#66#3390999332777111"));

Ungolfed:

f=(a,h)=>{
//out string
o="";
//uppercase or lowercase (initialized as "" and then inverted in golfed version)
c=0;
//split it into array of instructions, which are sets of repeated characters, or # solely alone
a.match(/#|(.)\1*/g).forEach((e)=>{
e==" "?0:
e=="#" ? (c=!c) : ( ()=>{ //lambda added because two statements ungolfed, multiplied in the golfed version
n=h[e[0]][e.length-1];
o+=c?n.toUpperCase():n;
})()
})
return o;
}


JavaScript, 301 bytes

(a,b)=>{u="l";p=[];r="";a.split.map((c,i)=>p.push(c!=a[i-1]?" "+c:c));p.join.trim().replace('   ', ' ').split .map(l=>{if(l=="#"){u=(u=="l"?b.forEach((y,j)=>b[j]=y.toUpperCase())||"u":b.forEach((y,j)=>b[j]=y.toLowerCase())||"l")}else{if(l!="  "){r+=b[+l[0]][l.length-1]}else{r+=" "}}});return r}


f=(a,b)=>{u="l";p=[];r="";a.split.map((c,i)=>p.push(c!=a[i-1]?" "+c:c));p.join.trim().replace('   ', ' ').split .map(l=>{if(l=="#"){u=(u=="l"?b.forEach((y,j)=>b[j]=y.toUpperCase())||"u":b.forEach((y,j)=>b[j]=y.toLowerCase())||"l")}else{if(l!="  "){r+=b[+l[0]][l.length-1]}else{r+=" "}}});return r}

console.log(f("#4440555#666888330#999#66688111 ",["  ",".,!","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"]));
console.log(f("#6#33777 7779990#222#4477744477778627777111",["  ",".,!","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"]));
console.log(f("#44#27 79990#66#3390#999#332777111",["  ",".,!","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"]));

I know this is very long, but this is the best I can.

V, 60 bytes

Í /|
Í¨ä©¨±*©/½a[submatch(1)][len(submatch(2))]
Í|
ò/#
g~$x  (There's an unprintable ½<Ctrl+r>a) Try it online! Explain  Í /| #Replace all " " with "|" Í¨ä©¨±*© #Replace all (\d)(\1*) /½ #With = ^Ra #(Inserts the passed array) [submatch(1)][len(submatch(2))] #Index into the array Í| #Replace all "|" with "" (second ò implied) ò ò #Recursively (until breaking) /# #Go to the next # g~$                                           #Toggle case until the of the line
x                                          #Delete current char (#)