22
\$\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\$
13
  • 3
    \$\begingroup\$ I like how :0 doubles as a surprised emoticon. \$\endgroup\$
    – Doorknob
    Feb 29, 2016 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, 2016 at 14:15
  • 9
    \$\begingroup\$ At what point are we stopping with the "Alex is wrong" jokes? \$\endgroup\$ Feb 29, 2016 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, 2016 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\$ Mar 1, 2016 at 1:19

2 Answers 2

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\$
2
  • \$\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, 2016 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, 2016 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 and acknowledge you have read our privacy policy.

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