19
\$\begingroup\$

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", "I like causing sadness through downvotes."], ["Flawr", "I want to put random message ids in my chat messages :0 askjdaskdj"]]
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
\$\endgroup\$
  • 2
    \$\begingroup\$ I like how :0 doubles as a surprised emoticon. \$\endgroup\$ – Doorknob Feb 29 '16 at 14:08
  • 4
    \$\begingroup\$ "I like causing sadness through downvotes." You know there's only one proper way I can respond to that, right? ;) \$\endgroup\$ – Geobits Feb 29 '16 at 14:15
  • 9
    \$\begingroup\$ At what point are we stopping with the "Alex is wrong" jokes? \$\endgroup\$ – Martin Ender Feb 29 '16 at 15:36
  • 1
    \$\begingroup\$ 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)? \$\endgroup\$ – Sp3000 Feb 29 '16 at 16:33
  • 2
    \$\begingroup\$ 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? \$\endgroup\$ – ETHproductions Mar 1 '16 at 1:19
2
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ Surely using an object is shorter. If it isn't I don't think you need to return the Map as an array \$\endgroup\$ – Downgoat Feb 29 '16 at 22:56
  • \$\begingroup\$ @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. \$\endgroup\$ – Mwr247 Mar 1 '16 at 0:44
0
\$\begingroup\$

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";
\$\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.