Below is the solution for your problem If my understanding is right!
if ($tags) {
$tag_ids = array();
foreach($tags as $single_tag) $tag_ids[] = $single_tag->term_id;
$args=array(
'tag__in' => $tag_ids,
'post__not_in' => array($post->ID),
'showposts'=> 5,
);
if( count($args) < 5 ) {
$n = 5 - count($args); //to get posts based on the category
if ($categories) {
$category_ids = array();
foreach($categories as $cat) $category_ids[] = $cat->term_id;
$args2 = array( //this is the args array for category based posts
'category__in' => $category_ids,
'post__not_in' => array($post->ID),
'showposts'=> $n,
);
}
}
$args = array_merge( $args, $args2 );
} else {
$categories = get_the_category($post->ID);
if ($categories) {
$category_ids = array();
foreach($categories as $cat) $category_ids[] = $cat->term_id;
$args = array(
'category__in' => $category_ids,
'post__not_in' => array($post->ID),
'showposts'=> 5,
);
}
}
The logic I added to your code was not tested. So it might throw some errors!