# StackExchange Mustafa can't stand to be asked the same question three times

Austin: "Who sent you?"

Mustafa: "You have to kill me!"

Austin: "Who sent you?"

Mustafa: "Kiss my ass, Powers!"

Austin: "Who sent you?"

Mustafa: "Dr. Evil."

(...)

Mustafa: "I can't stand to be asked the same question three times. It just irritates me."

You are to simulate a short dialogue in the spirit of Austin Powers and Mustafa. But the data source for the entire conversation will be a StackOverflow question (provided as input from a URL).

# Rules

The question asker's username will be used in place of "Austin". The question they will ask three times comes from the last sentence in the question title, (which has been forced to end in a question mark if it did not already).

StackExchange will be playing the part of "Mustafa". The answer ultimately given comes from the first sentence in the answer that does not end in a question mark, and will be attributed to the name of the user who answered.

For a question to qualify for the game, it must (a) have an answer, and (b) there must be a sequence of comments on the original question that goes:

• comment from someone other than questioner
• (any number of skipped comments)
• comment from questioner
• comment from someone other than questioner
• (any number of skippable comments)
• comment from questioner

If this sequence is not satisfied prior to the date of the top ranked answer, the program should simply output "Oh, behave!"

StackExchange Mustafa's angry retorts come from the first sentence of the comments from someone other than the questioner that don't end with a question mark--and ensuring it ends with an exclamation mark. If no sentence exists in the comment that doesn't end in a question mark, it is skipped as a candidate for the retort. Comment retorts are attributed to the user name of the author.

# Clarifications

• Strip any leading "@XXX" response data from a comment.

• Because StackOverflow summarizes the comments if there are many of them, you will probably have to use a second request to get the full list. That request is of the form https://stackoverflow.com/posts/NNN/comments?_=MMM with the post ID in N and question ID in M. See for instance: https://stackoverflow.com/posts/11227809/comments?_=211160

• URLs should be stripped to anchor text only.

• We'll define a "sentence" as anything outside of a code block that ends in a period, question mark, or exclamation point. If a run of text has no ending punctuation of this form, then the end of the text is the end of the sentence; as if it were written with a period.

• If you're looking for funny test cases that are likely to qualify, you might try using StackExchange Data Explorer, such as Posts with the Most Comments.

• ... more to come, I'll wager...

# Samples

### Sample One

Input:

https://stackoverflow.com/questions/2283937/how-should-i-ethically-approach-user-password-storage-for-later-plaintext-retrie/

Output:

shanee: "How should I ethically approach user password storage for later plaintext retrieval?"

stefanw: "I think he knows that it is not good!"

shanee: "How should I ethically approach user password storage for later plaintext retrieval?"

Rook: "Perhaps you should ask how you can implement a Buffer Overflow Vulnerability in a Secure way!"

shanee: "How should I ethically approach user password storage for later plaintext retrieval?"

Michael Burr: "Ask why the password is required to be in plaintext: if it's so that the user can retrieve the password, then strictly speaking you don't really need to retrieve the password they set (they don't remember what it is anyway), you need to be able to give them a password they can use."

### Sample Two

Input:

http://scifi.stackexchange.com/questions/2611/why-dont-muggle-born-wizards-use-muggle-technology-to-fight-death-eaters

Output:

DVK: "Why don't muggle-born wizards use Muggle technology to fight Death Eaters?"

DampeS8N: "This dances on the edge again!"

DVK: "Why don't muggle-born wizards use Muggle technology to fight Death Eaters?"

DampeS8N: "Right, but this site isn't about pointing out plot holes!"

DVK: "Why don't muggle-born wizards use Muggle technology to fight Death Eaters?"

Jeff: "I believe, though I've been unable to find a reference, that JK Rowling actually mentioned this at one point."

### Sample Three

Input:

https://stackoverflow.com/questions/11227809/why-is-processing-a-sorted-array-faster-than-an-unsorted-array

Output:

"Oh, behave!"

(The top rated answer time is Jun 27 '12 at 13:56, while the second follow-up comment on the question by the questioner is at time Jun 27 '12 at 14:52. Hence, there isn't a causal link between the second follow-up and the answer. :-P)

## Winning Criteria

Code Golf - shortest code wins.

• Just spent the last half hour reading that Harry Potter thread. +1 for that! Jul 21, 2014 at 22:03
• There have been no new answers to this question in a while. Maybe it is time to end it now, or at least add a deadline? Jul 9, 2015 at 7:30
• @LarsEbert Done... (though I actually was going to take a crack at it in Rebmu, the odds of it making it on my schedule are slim ATM.) Jul 9, 2015 at 7:32
• You can still add it in the future. I would love to see an alternative (and possibly shorter) solution. Jul 9, 2015 at 7:36

# PHP, 1282 chars

While 1282 quite huge for a code golf challenge, the challenge is quite complex. (And I am not very good at golf.)

<?php function a($a,$b='q'){$a=strip_tags(htmlspecialchars_decode($a,ENT_QUOTES));$a=preg_replace('/^@[^ ]+\s+/','',$a);$a=mb_split('(?<=(?:\.|!|\?))\s+',$a);if($b=='q'){return preg_replace('/(?:\.|!|\?)$/','',$a[0]).'?';}else{foreach($a as$s){if(!preg_match('/\?$/',$s)){if($b=='c'){return preg_replace('/(?:\.|!)$/','',$s).'!';}else{return preg_replace('/(?<!(?:\.|!))$/','.',$s);}}}}return 0;}function b($a){return json_decode(gzdecode(file_get_contents('http://api.stackexchange.com/2.2/questions/'.$a)));}function c($a){return$a->owner->display_name;}$n="\n";$x="Oh, behave!\n";$r=parse_url($argv[1]);$b=explode('/',$r['path']);$b=$b[2];$u=b($b.'?site='.$r['host']);$u=$u->items[0];$c=b($b.'/comments?filter=withbody&order=asc&sort=creation&site='.$r['host']);$a=b($b.'/answers?filter=withbody&order=desc&sort=votes&site='.$r['host']);if(!count($a->items)||!count($c->items))die($x);$a=$a->items[0];$s=array();$d=1;foreach($c->items as$e){if($e->creation_date>$a->creation_date)break;if($e->owner->user_id==$u->owner->user_id){$d=1;}elseif($d){$e->body=a($e->body,'c');if($e->body){$s[]=$e;}$d=0;}}if(count($s)<2)die($x);$q=c($u).': "'.a($u->title,'q').'"'.$n;echo$q.c($s[0]).': "'.$s[0]->body.'"'.$n.$q.c($s[1]).': "'.$s[1]->body.'"'.$n.$q.c($a).': "'.a($a->body,'a').'"'.$n;


## Ungolfed version

<?php

function firstSentence($string,$type = 'q') {
$string = strip_tags(htmlspecialchars_decode($string, ENT_QUOTES));
$string = preg_replace('/^@[^ ]+\s+/', '',$string);
$string = mb_split('(?<=(?:\.|!|\?))\s+',$string);
if($type === 'q') { return preg_replace('/(?:\.|!|\?)$/', '', $string[0]) . '?'; } else { foreach($string as $s) { if(!preg_match('/\?$/', $s)) { if($type === 'c') {
return preg_replace('/(?:\.|!)$/', '',$s) . '!';
} else {
return preg_replace('/(?<!(?:\.|!))$/', '.',$s);
}
}
}
}
return false;
}

$x = "Oh, behave!\n";$url = parse_url($argv[1]);$api = 'http://api.stackexchange.com/2.2/';

$id = explode('/',$url['path']);
$id =$id[2];

$question = json_decode(gzdecode(file_get_contents($api . 'questions/' . $id . '?site=' .$url['host'])));
$question =$question->items[0];
$comments = json_decode(gzdecode(file_get_contents($api . 'questions/' . $id . '/comments?filter=withbody&order=asc&sort=creation&site=' .$url['host'])));
$answer = json_decode(gzdecode(file_get_contents($api . 'questions/' . $id . '/answers?filter=withbody&order=desc&sort=votes&site=' .$url['host'])));
if(!count($answer->items) || !count($comments->items))
die($x);$answer = $answer->items[0];$selected = array();
$usable = true; foreach($comments->items as $comment) { if($comment->creation_date > $answer->creation_date) break; if($comment->owner->user_id === $question->owner->user_id) {$usable = true;
} elseif($usable) {$comment->body = firstSentence($comment->body, 'c'); if($comment->body !== false) {
$selected[] =$comment;
}
$usable = false; } } if(count($selected) < 2)
die($x);$q = $question->owner->display_name . ': "' . firstSentence($question->title, 'q') . '"' . "\n";
echo $q; echo$selected[0]->owner->display_name . ': "' . $selected[0]->body . '"' . "\n"; echo$q;
echo $selected[1]->owner->display_name . ': "' .$selected[1]->body . '"' . "\n";
echo $q; echo$answer->owner->display_name . ': "' . firstSentence($answer->body, 'a') . '"' . "\n"; ?>  • You can chain all of those $a=function(1,2,\$a) things together. Dec 15, 2017 at 15:14