# Write a Chat Ping Counter

Your task is to write a program, that given a list of chat messages, count how many times each person gets pinged, so I can know how popular everyone is. But, since I have to do it surreptitiously, I need it to be as small as possible so I can hide the code.

# Specs

• The input comes in a list of 2-tuples, with each item being of the form ("username", "message").
• A ping to another user is defined as an @ followed by 3 or more letters that unambiguously refers to that user.
• However, you also have to consider replies, which have to start with :messageid followed by a space.
• Assume the first message has id 0 and proceed sequentially.
• Output each user and say how many times each one got pinged.
• The output can be in any order/reasonable format.
• This is , so shortest code in bytes wins!

# Test Cases

[["AlexA.", "I am wrong"], ["Quartatoes", "@Alex you are very wrong"], ["AlexA.", ":1 I am only slightly wrong"]]
AlexA.: 1
Quartatoes: 1

[["Doorknob", "I have never eaten an avocad."], ["AquaTart", ":0 I will ship you an avocad"], ["AlexA.", ":0 this is shocking"]]
Doorknob: 2
AquaTart: 0
AlexA.: 0

Geobits: 0
Flawr: 0

[["Downgoat", "goatigfs.com/goatgif"], ["Downotherthing", "@Downgoat cool gifs"], ["Dennis", "@Down cool gifs this is an ambiguous ping"]]
Downgoat: 1
Downotherthing: 0
Dennis: 0

• I like how :0 doubles as a surprised emoticon. – Doorknob Feb 29 '16 at 14:08
• "I like causing sadness through downvotes." You know there's only one proper way I can respond to that, right? ;) – Geobits Feb 29 '16 at 14:15
• At what point are we stopping with the "Alex is wrong" jokes? – Martin Ender Feb 29 '16 at 15:36
• Can a reply be out of range (e.g. first message starting with :3) or a ping not satisfying any user in the room (e.g. @zzz)? – Sp3000 Feb 29 '16 at 16:33
• Can a pinged user not yet have posted a message when he's pinged? e.g. is [["Doorknob","@Alex is wrong"],["Alex","I am only slightly wrong"]] valid input? – ETHproductions Mar 1 '16 at 1:19

# JavaScript (ES6), 245 210 bytes

a=>(p={},a.map(b=>p[b[0]]=0),(a.map(b=>b[1].match(/@[a-z]{3,}|^:\d+/gi)||[]).map(c=>c.map(d=>(z=(d[0]=='@'?(y=Object.keys(p).filter(e=>e.startsWith(d.slice(1)))).length<2?y:0:a[d.slice(1)[0]]))&&p[z[0]]++))),p)


Uses an object to create a unique list of names alongside pings. Then it looks through the messages for matches to either ping condition. If a name, it looks through the list of names to find if there is only one match, and then increments. If a reply, it simply references that index in the message array and pulls the name to be incremented. Finally, it returns the object.

• Surely using an object is shorter. If it isn't I don't think you need to return the Map as an array – Downgoat Feb 29 '16 at 22:56
• @Downgoat But Map is more fun right? Na, I originally overestimated how much extra it would take to reference an object, thinking I would have to a separate array for names, but you're right that it is much shorter this way. – Mwr247 Mar 1 '16 at 0:44

# PHP, 227 Bytes

foreach($_GET[a]as$c){$r[]=&$n[$c[0]]??$n[$c[0]]=0;preg_match("#^(:(\d+)|@(\w+))#",$c[1],$m);$m[2]==""?!$m[3]?:count($a=preg_grep("#^{$m[3]}#",array_keys($n)))>1?:$n[end($a)]++:$r[$m[2]]++;}foreach(($n)as$k=>$v)echo"$k: \$v\n";