-7
\$\begingroup\$

You will take a set of input numbers, and output the minimum and maximum of the set. You can either write two programs, with 1 program doing each function, or one combined program.

Here's an example in Perl, 50 and 42 bytes (92 total):

Max:

sub mx {return ( reverse sort {$a <=> $b} @_ )[0]}

Min:

sub mn {return ( sort {$a <=> $b} @_ )[0]}

And a single program, 96:

sub mxmn {return ( reverse sort {$a <=> $b} @_ )[0] if shift; return ( sort {$a <=> $b} @_ )[0]}

Here's some more test cases.

Leaderboard

Here is a Stack Snippet to generate both a regular leaderboard and an overview of winners by language.

/* Configuration */

var QUESTION_ID = 4310; // Obtain this from the url
// It will be like https://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page
var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";
var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk";
var OVERRIDE_USER = 48934; // This should be the user ID of the challenge author.

/* App */

var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page;

function answersUrl(index) {
  return "https://api.stackexchange.com/2.2/questions/" +  QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}

function commentUrl(index, answers) {
  return "https://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER;
}

function getAnswers() {
  jQuery.ajax({
    url: answersUrl(answer_page++),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      answers.push.apply(answers, data.items);
      answers_hash = [];
      answer_ids = [];
      data.items.forEach(function(a) {
        a.comments = [];
        var id = +a.share_link.match(/\d+/);
        answer_ids.push(id);
        answers_hash[id] = a;
      });
      if (!data.has_more) more_answers = false;
      comment_page = 1;
      getComments();
    }
  });
}

function getComments() {
  jQuery.ajax({
    url: commentUrl(comment_page++, answer_ids),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      data.items.forEach(function(c) {
        if (c.owner.user_id === OVERRIDE_USER)
          answers_hash[c.post_id].comments.push(c);
      });
      if (data.has_more) getComments();
      else if (more_answers) getAnswers();
      else process();
    }
  });  
}

getAnswers();

var SCORE_REG = /<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/;

var OVERRIDE_REG = /^Override\s*header:\s*/i;

function getAuthorName(a) {
  return a.owner.display_name;
}

function process() {
  var valid = [];
  
  answers.forEach(function(a) {
    var body = a.body;
    a.comments.forEach(function(c) {
      if(OVERRIDE_REG.test(c.body))
        body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>';
    });
    
    var match = body.match(SCORE_REG);
    if (match)
      valid.push({
        user: getAuthorName(a),
        size: +match[2],
        language: match[1],
        link: a.share_link,
      });
    
  });
  
  valid.sort(function (a, b) {
    var aB = a.size,
        bB = b.size;
    return aB - bB
  });

  var languages = {};
  var place = 1;
  var lastSize = null;
  var lastPlace = 1;
  valid.forEach(function (a) {
    if (a.size != lastSize)
      lastPlace = place;
    lastSize = a.size;
    ++place;
    
    var answer = jQuery("#answer-template").html();
    answer = answer.replace("{{PLACE}}", lastPlace + ".")
                   .replace("{{NAME}}", a.user)
                   .replace("{{LANGUAGE}}", a.language)
                   .replace("{{SIZE}}", a.size)
                   .replace("{{LINK}}", a.link);
    answer = jQuery(answer);
    jQuery("#answers").append(answer);

    var lang = a.language;
    if (/<a/.test(lang)) lang = jQuery(lang).text();
    
    languages[lang] = languages[lang] || {lang: a.language, user: a.user, size: a.size, link: a.link};
  });

  var langs = [];
  for (var lang in languages)
    if (languages.hasOwnProperty(lang))
      langs.push(languages[lang]);

  langs.sort(function (a, b) {
    if (a.lang > b.lang) return 1;
    if (a.lang < b.lang) return -1;
    return 0;
  });

  for (var i = 0; i < langs.length; ++i)
  {
    var language = jQuery("#language-template").html();
    var lang = langs[i];
    language = language.replace("{{LANGUAGE}}", lang.lang)
                       .replace("{{NAME}}", lang.user)
                       .replace("{{SIZE}}", lang.size)
                       .replace("{{LINK}}", lang.link);
    language = jQuery(language);
    jQuery("#languages").append(language);
  }

}
body { text-align: left !important}

#answer-list {
  padding: 10px;
  width: 290px;
  float: left;
}

#language-list {
  padding: 10px;
  width: 290px;
  float: left;
}

table thead {
  font-weight: bold;
}

table td {
  padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b">
<div id="answer-list">
  <h2>Leaderboard</h2>
  <table class="answer-list">
    <thead>
      <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr>
    </thead>
    <tbody id="answers">

    </tbody>
  </table>
</div>
<div id="language-list">
  <h2>Winners by Language</h2>
  <table class="language-list">
    <thead>
      <tr><td>Language</td><td>User</td><td>Score</td></tr>
    </thead>
    <tbody id="languages">

    </tbody>
  </table>
</div>
<table style="display: none">
  <tbody id="answer-template">
    <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
  </tbody>
</table>
<table style="display: none">
  <tbody id="language-template">
    <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
  </tbody>
</table>

\$\endgroup\$
11
  • 1
    \$\begingroup\$ Welcome to code-golf. Please specify on what kind of input it should run (see faq on how to ask questions here). You also have to decide on what you wan't: "simplest way", "code-golf" or "fastest-code"? I suspect they contradict each other. \$\endgroup\$
    – Howard
    Commented Dec 11, 2011 at 17:55
  • 2
    \$\begingroup\$ Also, the definition of 'simplest' is highly subjective. \$\endgroup\$
    – Zaid
    Commented Dec 11, 2011 at 18:42
  • 7
    \$\begingroup\$ -1 because of: 1) language-specific, 2) overly broad (min or max? strings? sweet and simple despite the code-golf tag?); 3) a bit misinformed (Perl has min and max) \$\endgroup\$
    – J B
    Commented Dec 11, 2011 at 19:20
  • 1
    \$\begingroup\$ -1 boring. In Golfscript it's $0= and $-1=. \$\endgroup\$ Commented Dec 11, 2011 at 23:00
  • 2
    \$\begingroup\$ It's a one-liner in many languages - not challenging. Prepare your next question in the chat or on meta, where you get hints before going public. I vote to close. \$\endgroup\$ Commented Dec 13, 2011 at 8:00

8 Answers 8

1
\$\begingroup\$

Perl does have min and max subs.

use List::Util qw( min max );
my $min = min @values;
my $max = max @values;

A common module has a minmax function which finds both at once faster than they can be found individually (which is far more important than compactness of code).

use List::MoreUtils qw( minmax );
my ($min, $max) = minmax @values;
\$\endgroup\$
1
  • \$\begingroup\$ I only did this as a contest you don't need to use perl but anyway I decided to end it \$\endgroup\$ Commented Dec 12, 2011 at 23:30
1
\$\begingroup\$

If it doesn't have to be Perl and you just want the simplicity of Scheme instead of just shaving off characters (I don't care about long variable names (symbols in Scheme)), here's my Scheme for this (pun intended):

Of course we could cheat and use the fonctions (min a b c d ...) and (max a b c ...).

Don't mind the long variable names, they were chosen to be descriptive:

(define (min . args) (extremum < args))
(define (max . args) (extremum > args))

(define-syntax extremum
  (syntax-rules ()
    [(_ op . args)
     (if (null? args)
         (error "Read The Fucking Code!")
         (reduce (lambda (a b) (if (op a b) a b))
           (car rest) (cdr rest)))]
    [else (error "Read The Fucking Code!")]))

But if you want less code (fold is sort of like reduce):

(define (min . args) (e < args)) (define (max . args) (e > args))
(define-syntax e
  (syntax-rules ()
    [(_ o . r) (fold (lambda (a b) (if (o a b) a b)) (car r) (cdr r))]))
\$\endgroup\$
1
\$\begingroup\$

If all numbers are non-negative, this works:

sub max{\@s[@_];$#s}
\$\endgroup\$
1
  • \$\begingroup\$ a.k.a. Thelen's Device. I prefer to write it as \@_[@_];$#_, but only because it's more obscure that way. \$\endgroup\$
    – primo
    Commented Sep 18, 2013 at 11:17
1
\$\begingroup\$

Japt -g, 1 byte Min

n

Try it online!


Japt -g, 2 bytes Max

n<

Try it online!


Total: 3 bytes

\$\endgroup\$
1
\$\begingroup\$

Both programs pretty much just evaluate the input & sort it. Min takes the first item of the sorted list, and Max takes the last item of the sorted list.

GolfScript, 4 bytes Min

~$0=

Try it online!

GolfScript, 5 bytes Max

~$-1=

Try it online!

Total: 9 bytes

\$\endgroup\$
0
\$\begingroup\$

Perl, 28 char

This sub provides an array that contains the min in the first member and the max in the second member:

sub a{@_=sort@_;(shift,pop)}

Perl, 34 char (27 inside the sub)

According to comments, in fact the above doesn't work for array length less than 2, here a new attempt that works even for zero length array and array that contains only numerics:

sub a{@_&&(sort{$a<=>$b}@_)[0,-1]}
\$\endgroup\$
7
  • \$\begingroup\$ whoa, its 28 char and does min and max and is easy to read? amazing! great job! \$\endgroup\$ Commented Dec 11, 2011 at 20:00
  • \$\begingroup\$ Are you sure that this works e.g. if you provide a single number (and not a list)? \$\endgroup\$
    – Howard
    Commented Dec 11, 2011 at 21:20
  • \$\begingroup\$ Make it shorter and handle the degenerate case: replace (shift,pop) with a slice: @_[0,-1] \$\endgroup\$
    – J B
    Commented Dec 11, 2011 at 21:58
  • 1
    \$\begingroup\$ And then get rid of temporaries: sub a{(sort@_)[0,-1]} is 21 characters long. \$\endgroup\$
    – J B
    Commented Dec 11, 2011 at 22:00
  • \$\begingroup\$ I like this one because you used a language not dedicated to code golf \$\endgroup\$ Commented Dec 11, 2011 at 23:42
0
\$\begingroup\$

I don't think Perl is very golfy for such a problem.

Here are two alternatives for numerical lists only:


20 chars (inside sub)

sub min{(sort{$a<=>$b}@_)[0]}
sub max{(sort{$b<=>$a}@_)[0]}

30 chars (inside sub)

sub min{$r=pop;$r=$_<$r?$_:$r for@_;$r}
sub max{$r=pop;$r=$_>$r?$_:$r for@_;$r}
\$\endgroup\$
4
  • \$\begingroup\$ Wow amazing only 20 characters! "the greatest thing since sliced bread!" as they would say \$\endgroup\$ Commented Dec 11, 2011 at 19:14
  • \$\begingroup\$ or the greatest thing since [soda] pop (pun intended) \$\endgroup\$ Commented Dec 11, 2011 at 19:15
  • \$\begingroup\$ you may rename the subs to n & x or mx & mn \$\endgroup\$ Commented Dec 11, 2011 at 19:42
  • \$\begingroup\$ or use a different language \$\endgroup\$ Commented Dec 11, 2011 at 19:43
0
\$\begingroup\$

Io, 28 + 28 = 56

I found the magical pure-arithmetic max/min functions! (You guys definitely have a better formula than be, so feel free to mention a better one!)

Io, 28 bytes

The max function;

method(x,y,(x+y+(x-y)abs)/2)

Try it online!

Io, 28 bytes

Min function

method(x,y,(x+y-(x-y)abs)/2)

Try it online!

Explanation for both programs

In order to find a purely-arithmetic max-min function, I started to think of averages. Let's take 3 and 4 as examples.

(3+4)/2 = 3.5

We can see that the distance towards both sides are equal:

3 - 3.5 = -0.5
4 - 3.5 = 0.5

We do the difference and take the absolute value, to get the distance that we need to add / subtract towards the average. 0.5 in this case.

Then, we find the average again. If we're finding the max, we add it by the distance, otherwise we subtract the value by the distance:

3.5 + 0.5 = 4
3.5 - 0.5 = 3

Our current expression is:

x + y   | x - y     |
----- ± | ----- - x |
  2     |   2       |

Actually, the rightmost x can also be y, but we chose x for the simplicity of simplification.

x + y   | x - y   2x  |
----- ± | ----- - --- |
  2     |   2      2  |

=

x + y   | x - y - 2x |
----- ± | ---------- |
  2     |     2      |

=

x + y   | x - y |
----- ± ---------
  2         2    

And then, the formula becomes the current formula:

x + y ± | x - y |
-----------------
       2
```
\$\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.