58
\$\begingroup\$

Inspired by Alex's glorious Learn you an R for great good, we are going to humbly recreate Alex's "one true R program" -- but with a twist.

Alex-style Addition works like this -- it has a 90% chance of simply returning the sum of the two numbers given and a 10% chance of recursively Alex-adding the first number and the second number + 1. This means that, potentially, an addition could be off by 1 or more.

Challenge

Write a full program or function that takes two integers and Alex-adds them as defined. You may assume that your program will not stack overflow if your language doesn't have tail recursion. (Note that you do not have to implement it recursively, as long as the probabilities are the same.)

Reference Implementation (Groovy)

int alexAdd(int a, int b) {
  int i = new Random().nextInt(11);
  if(i == 1) {
    return alexAdd(a,b+1);
  } else {
    return a + b;
  }
}

Try this fiddle online.

Leaderboard

var QUESTION_ID=66522,OVERRIDE_USER=8478;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}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\$
  • 6
    \$\begingroup\$ So it gives the sum of two numbers plus a geometric random variable with failure probability 1/10? \$\endgroup\$ – xnor Dec 14 '15 at 2:00
  • \$\begingroup\$ @xnor Essentially, yes. I defined it recursively so that it is easier to understand, but you don't have to do it recursively (CJam solution does not, for instance) \$\endgroup\$ – a spaghetto Dec 14 '15 at 2:02
  • 10
    \$\begingroup\$ Why was this sandboxed for 20 minutes? That seems to be missing the point of the sandbox. \$\endgroup\$ – Peter Taylor Dec 14 '15 at 16:52
  • 3
    \$\begingroup\$ @PeterTaylor The one minor issue with it was fixed almost immediately, and the question was so simple I didn't think it needed to stay in the sandbox for that long (it had already been looked at by 10 people which I thought was sufficient peer review for such a simple challenge). The main reason I had it in the sandbox was to see if people thought it was too simple. \$\endgroup\$ – a spaghetto Dec 14 '15 at 17:30
  • 2
    \$\begingroup\$ I would say it still has a major issue, in that it's not clear whether you insist on implementations being written as recursive functions or just on giving the right distribution, but it's far too late to do anything about clarifying that now. \$\endgroup\$ – Peter Taylor Dec 14 '15 at 18:26

42 Answers 42

1
\$\begingroup\$

Ruby, 32 bytes

Can't believe there was no Ruby answer. Here's a pretty basic lambda function:

f=->a,b{rand(10)<1?f[a,b+1]:a+b}

But why not do it properly? Here's some ungolfed meta-Alexification:

module Alex
  def +(other)
    other += 1 if rand(10) == 7
    super
  end
end

[Fixnum, Bignum, Float].each { |klass| klass.prepend(Alex) }

# testing
p 1000.times.count { 1 + 1 == 3 } #=> 87
p 1000.times.count { 1 + 1 == 4 } #=> 19
p 1000.times.count { 1 + 1.3 == 5.3 } #=> 1
\$\endgroup\$
1
\$\begingroup\$

Tcl, 52 bytes

proc A n\ m {expr {rand()>.9?[A $n [incr m]]:$n+$m}}

Try it online!

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

SmileBASIC 3, 54 bytes

Recursive function that takes two numbers.

DEF A(B,C)IF RND(10)THEN RETURN B+C
RETURN A(B,C+1)END
\$\endgroup\$
1
\$\begingroup\$

05AB1E, 15 14 13 8 bytes

+[TLΩ≠#>

-5 bytes thanks to @Emigna by placing the > (increment by 1) after the # (break loop).

Try it online.

Explanation:

            # Implicit inputs `a` and `b`
+           # Sum of these two inputs
 [          # Start an infinite loop
    Ω       #  Random integer
  TL        #   in the range [1, 10]
     ≠      #  If this integer isn't exactly 1:
      #     #   Stop the loop
       >    #  Increase the result by 1
            # Implicitly output the result
\$\endgroup\$
  • 1
    \$\begingroup\$ +[TLΩ≠#> for 8 bytes \$\endgroup\$ – Emigna May 9 '18 at 11:04
  • \$\begingroup\$ @Emigna Ah, smart.. I guess I'm too used to languages like C and JS were 0 == false and anything else == true. In 05AB1E 1 == true, and anything else == false. Also, placing the increment > after the break is pretty obvious (now that I see it ;p). Thanks! \$\endgroup\$ – Kevin Cruijssen May 9 '18 at 11:59
1
\$\begingroup\$

F#, 66 bytes

let rec a x y=(if(System.Random()).Next(10)=9 then a x 1 else x)+y

Try it online!

The if statement is like a function itself. If the random number is 9 (in the range [0, 10)) then perform Alex-addition on x and 1 and return that value. Otherwise return just x.

Then add the result of the if statement to y, and return it.

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

APL (Dyalog Unicode), 10 bytes

+-{⌈10⍟?0}

Try it online!

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

Kotlin (1.3+), 60 bytes

fun a(b:Int,c:Int):Int=if((0..9).random()<1)a(b,c+1)else b+c

A solution that uses the new cross-platform random features added in Kotlin 1.3.

Try it online!


Kotlin (JVM), 59 bytes

fun a(b:Int,c:Int):Int=if(Math.random()<.1)a(b,c+1)else b+c

Try it online!

Works on the JVM version because java.lang.Math is automatically imported.


Kotlin (<1.3), 65 bytes

This version is "cross-platform" Kotlin since it doesn't depend on any Java features.

fun a(b:Int,c:Int):Int=if((0..9).shuffled()[0]<1)a(b,c+1)else b+c

Try it online!

The "randomness" is obtained by shuffling the inclusive range 0..9, which generates a List<Int>, and then checking the first element of that list. Assuming shuffled() is perfectly random (I have no idea how random it actually is) there is a 10% chance of the first element being 0.

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

Brachylog, 10 bytes

∧9ṙ9&↰+₁|+

Try it online!

Takes input as a list of numbers. The TIO header runs the predicate on the input infinitely and prints the results.

  ṙ           A random integer from zero to
 9            nine
∧             which is not necessarily the input
   9          is nine,
    &         and the input
     ↰        passed through this predicate again
      +₁      plus one
        |     is the output, or, the input
         +    summed
              is the output.
\$\endgroup\$
1
\$\begingroup\$

Java 8, 57 56 bytes

4 years and no Java answer? Shame.

int a(int a,int b){return.1>Math.random()?a(a,b+1):a+b;}

Try it online!
-1 byte thanks to ceilingcat

\$\endgroup\$
  • \$\begingroup\$ @ceilingcat thanks \$\endgroup\$ – Benjamin Urquhart Apr 16 at 2:03
0
\$\begingroup\$

R 33 bytes

f=function(a,b)a+b+rbinom(b,b,.1)

Edit: now simulates recursive application of +1 for each 1 in b.

\$\endgroup\$
  • 1
    \$\begingroup\$ I think it should be rgeom(1,.9). \$\endgroup\$ – alephalpha Dec 14 '15 at 6:37
0
\$\begingroup\$

Perl 5 -p, 23 bytes

$_+=<>;$_++while.1>rand

Try it online!

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

Python 2, 63 bytes

Returns the result as a string.

from random import*
f=lambda a,b:random()>.1and`a+b`or f(a,b+1)

Try it online!

Test program showing probability distribution: Try it online!

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