23
\$\begingroup\$

Santa needs some help determining how many elves he will need to help him deliver gifts to each house.

Coal is considerably heavier than presents, so santa will need three elves for every naughty person in the house. Only two elves are needed to help santa carry presents.

On santa's map, a house is represented by a *, and each house is split by a +.

There will be a number on either side of the house - the one on the left representing the number of naughty people in the house, and the one on the right representing the number of nice people in the house. If there is no number on one side it is interpreted as a 0.

Santa doesn't visit those who are not in the christmas spirit (they don't even deserve coal), so sometimes, a house may not have a number on either side of it. In this case, santa doesn't need help from any elves

For example, one of santa's maps may look like this

1*3+2*2+1*+*2

In the first house there is 1 naughty and 3 nice, santa will need nine elves. In the second, there are 2 naughty and 2 nice, santa will need ten elves. In the third house there is 1 naughty and 0 nice, santa will need three elves, and in the last house there are 0 naughty and 2 nice, santa will need four elves.

This is an over-simplified version of one of santa's maps, though. Normally, santa's maps have multiple lines, and are in a square shape as to better fit on his list. A normal map might look something like this (a \n at the end of each line)

1*2+*+*4+1*
2*4+3*+1*6+*
*+*+4*2+1*1
*4+*3+1*+2*3
3*10+2*+*5+*

In this map, santa needs ((1 + 0 + 0 + 1 + 2 + 3 + 1 + 0 + 0 + 0 + 4 + 1 + 0 + 0 + 1 + 2 + 3 + 2 + 0 + 0) * 3) + ((2 + 0 + 4 + 0 + 4 + 0 + 6 + 0 + 0 + 0 + 2 + 1 + 4 + 3 + 0 + 3 + 10 + 0 + 5 + 0) * 2) = 151 elves

Challenge

Help santa determine how many elves he needs to deliver goods to each house!

Houses

  • A house is represented by a *
  • Houses are split by +
  • The number on the left of the house symbolizes the number of naughty people (no number means 0)
  • The number on the right symbolizes the number of nice people (no number means 0)
  • There may be newlines (\n) in the input, which should also be handled as a split

Elves

  • Santa needs help from three elves for naughty people (coal is much heavier than presents)
  • Santa needs help from two elves for nice people
  • If there is no number on either side, santa will not visit that house, and therefor does not need any elves

What to do

Print the number of elves santa needs to help him deliver presents to the houses to. Because all Santa needs to know is how many elves to bring, you only need to print the added number of elves he needs for the list of houses

Test Cases

1*1 => 5
1*2 => 7
2*1 => 8
1* => 3
*1 => 2
* => 0

1*1+1*1 => 10
1*2+2*1 => 15
1*+*1 => 5
1*1+*+1*1 => 10
*+*+*+* => 0

Rules

  • The input can be either taken as an argument in a function, or from STDIN or equivalent
  • The output can either be the return value of a function, or printed to STDOUT or equivalent
  • The input will only contain numbers, +, *, and newlines \n
  • The output should be only the total number of elves that Santa needs help from to deliver on Christmas
  • Standard loopholes apply

Scoring

Santa's sleigh is full of gifts giving him less space to run code, so he needs the shortest code he can get (don't worry if this doesn't make sense. If you question Santa's logic you'll end up on the naughty list). Due to Santa's CORRECT reasoning, the shortest submission in bytes wins!

Leaderboard

This is a Stack Snippet that generates both a leaderboard and an overview of winners by language.

To ensure your answer shows up, please start your answer with a headline using the following Markdown template

## Language Name, N bytes

Where N is the size, in bytes, of your submission

If you want to include multiple numbers in your header (for example, striking through old scores, or including flags in the byte count), just make sure that the actual score is the last number in your header

## Language Name, <s>K</s> X + 2 = N bytes

var QUESTION_ID=67600;var OVERRIDE_USER=20634;function answersUrl(e){return"http://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"http://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\$
4
  • 1
    \$\begingroup\$ I wonder, as Santa will stop by at any house, wouldn't he just need a maximum of max(naughty) + max(nice) elves for the whole route? I thought he has a bunch of elves flying with him, but maybe you have insider information on that and I need to look closer this year. :) \$\endgroup\$ Commented Dec 24, 2015 at 8:32
  • 9
    \$\begingroup\$ @insertusernamehere I currently work at Santa Inc. and I can tell you our infrastructure operates in a heavily async fashion. He doesn't want his resources to starve, so we allocate as many workers as needed. In case we need an extra ELF, we can compile one in few seconds from hello-world.c. Worker elves are eagerly allocated to targets as Jojodmo said (I am sure I know Jojodmo, he must be our sysadm) and then use a callback for notifying when it's time to be reinserted in the sleigh pool or when a child saw them. \$\endgroup\$ Commented Dec 24, 2015 at 16:47
  • 2
    \$\begingroup\$ @StefanoSanfilippo Ah, I see. Thanks for all the detailed insights of this classified information. And Merry Christmas. :) \$\endgroup\$ Commented Dec 24, 2015 at 17:29
  • \$\begingroup\$ This totally makes sense. Santa needs the shortest code because he prints out every character of the code with a printer and then puts them on his sleigh before he executes them. \$\endgroup\$
    – user85052
    Commented Oct 3, 2019 at 7:40

13 Answers 13

13
\$\begingroup\$

JavaScript (ES6), 52 bytes

s=>eval(s.replace(/\D|$/g,m=>`.0*${m=="*"?3:2}+`)+0)

Explanation

Converts the input into a valid JavaScript statement. Replaces all * with .0*3+ and all other (non-digit) symbols with .0*2+. For example 8*9+*10 becomes 8.0*3+9.0*2+.0*3+10. Finally it appends .0*2 to the end for the last nice count. This works because n.0 = n and .0 = 0.

s=>
  eval(                      // execute the formed equation
    s.replace(/\D|$/g,       // replace each symbol (and also add to the end) with:
      m=>`.0*${m=="*"?3:2}+` // case * = ".0*3+", else replace with ".0*2+"
    )
    +0                       // add "0" to the end for the trailing "+"
  )

Test

var solution = s=>eval(s.replace(/\D|$/g,m=>`.0*${m=="*"?3:2}+`)+0)
<textarea id="input" rows="6" cols="30">1*2+*+*4+1*
2*4+3*+1*6+*
*+*+4*2+1*1
*4+*3+1*+2*3
3*10+2*+*5+*</textarea><br />
<button onclick="result.textContent=solution(input.value)">Go</button>
<pre id="result"></pre>

\$\endgroup\$
1
  • 9
    \$\begingroup\$ +1 for the .0 idea. \$\endgroup\$
    – nimi
    Commented Dec 24, 2015 at 7:15
3
\$\begingroup\$

Flex+C, 112 90 bytes

 m=3,t;
%%
[0-9]+ t+=m*atoi(yytext);
\* m=2;
[+\n] m=3;
%%
main(){yylex();printf("%d",t);}

The first character is a space. Compile with:

flex -o santa.c santa.l
cc santa.c -o santa -ll

Reads from STDIN, writes to STDOUT. Input is terminated by EOF (Ctrl+D in console).

\$\endgroup\$
2
\$\begingroup\$

Pyth, 21 bytes

ssMs*VCcR\*scR\+.z_S3

Multi-line example

Single-line test suite

ssMs*VCcR\*scR\+.z_S3
                .z        Take a input, as a list of lines.
            cR\+          Chop each line on '+'.
           s              Flatten into list of strings.
       cR\*               Chop each line on '*'.
      C                   Transpose, into a list of naughty and nice.
    *V            _S3     Vectorized multiplication with [3, 2, 1]. This replicates
                          the naughty list 3 times and the nice list 2 times.
   s                      Flatten.
 sM                       Convert each string to an int.
s                         Sum.
\$\endgroup\$
2
  • \$\begingroup\$ Seriously... Is there anything Pyth can't do in under 30 bytes? \$\endgroup\$
    – Jojodmo
    Commented Dec 26, 2015 at 20:23
  • 2
    \$\begingroup\$ @Jojodmo Not if I can help it ... \$\endgroup\$
    – isaacg
    Commented Dec 26, 2015 at 21:12
2
\$\begingroup\$

Mathematica, 70 bytes

a=Tr[FromDigits/@StringExtract[#,"
"|"+"->;;,"*"->#2]]&;3#~a~1+2#~a~2&

Uses StringExtract to extract the individual numbers.

\$\endgroup\$
2
\$\begingroup\$

CJam, 23 bytes

q'+NerN/{'*/3*5<:~~}%1b

Test it here.

Explanation

q      e# Read all input.
'+Ner  e# Replaces all "+" with linefeeds.
N/     e# Split the string around linefeeds (i.e. into houses).
{      e# Map this block over the list of house...
  '*/  e#   Split the string around the "*".
  3*   e#   Repeat the times.
  5<   e#   Truncate to 5 elements, keeping 3 copies of the naughty number and 2 copies of
       e#   the nice number.
  :~   e#   Evaluate each number (which may be an empty string which pushes nothing).
  ~    e#   Dump the list of numbers on the stack.
}%
1b     e# Sum all the numbers.
\$\endgroup\$
0
2
\$\begingroup\$

Seriously, 38 30 bytes

'*Ws`'0+'*@s'≈£M4rR*`MΣ+'+,WXX

Hex Dump:

272a57736027302b272a407327f79c4d3472522a604de42b272b2c575858

This new version breaks the online interpreter, but works fine locally. Here's an example run:

$ python2 seriously.py -f elves.srs
1*2+*+*4+1*
2*4+3*+1*6+*
*+*+4*2+1*1
*4+*3+1*+2*3
3*10+2*+*5+*

151

Explanation:

'*                              Push a "*" to make the stack truthy
  W                        W    Repeat while the top of stack is truthy
                                  (A whole bunch of instructions just turn the "*" into a
                                  zero on the first pass, so I'll list them here in the
                                  order they actually accomplish useful things:)
                          ,     Read in a line of input
   s                    '+      Split it on occurrence of "+"
    `               `M          Map this function over the list of strings.
     '0+                        Prepend a "0" to ensure a naughty number exists
        '*@s                    Split the string on "*"
            '≈£M                Map over the string with int() to convert it to int
                4rR             Push [3,2,1,0]
                   *            Dot product
                      Σ+        Sum all the houses, and add it to the results
                                  from the previous line of input
                            XX  Pop the "" and '+ from the stack, leaving only the
                                result to be implicitly output.

Old Version:

'+ε'*`+'++,`╬Xs`≈`╗`'0+'*@s╜M[3,2]*`MΣ

Hex Dump:

272bee272a602b272b2b2c60ce587360f760bb6027302b272a4073bd4d5b332c325d2a604de4

Try It Online

Explanation:

  ε'*                                   Initialize with two strings so the first + works
     `+'++,`╬                           Read in strings and compile them until "" is read
             X                          Throw away the ""
'+            s                         Split on +
               `≈`╗                     Chuck int function into reg0 to use within function
                   `               `M   Map this function over the list of houses
                    '0+                 Prepend a "0" to ensure a naughty number exists
                       '*@s             Split on *
                           ╜M           Convert the resulting list to ints with stored func
                             [3,2]*     Dot product with [3,2]
                                     Σ  Sum all houses

This maybe could be shorter if I just converted each line separately and summed them all at the end. I'll look into it later.

\$\endgroup\$
2
\$\begingroup\$

PowerShell, 52 bytes

Using variation of user81655's .0 trick

$OFS='+';"$("$args"-replace'\*','.0*3+2*0'|iex)"|iex

Ungolfed version

$OFS='+' # Set Output Field Separator to '+'
         # So if $arr = 1,2,3 then "$arr" will output 1+2+3

" # Cast result of subexpression to string using $OFS

    $( # Subexpression

        "$args" # Input is an array of arguments. Casting it to string using "$args"
                # is shorter then acessing the first element using $args[0]
                # $OFS wouldn't affect this, because input has only 1 element.

        -replace '\*' , '.0*3+2*0' # Replace every * with .0*3+2*0
                                   # Example: 1*+*1 becomes 1.0*3+2*0+.0*3+2*01

    ) | Invoke-Expression # Execute a result of subexpression as PS code.
                          # This will execute resulting multiline string line-by line
                          # and return an array of values, e.g.: 18,38,21,29,45

" Cast the aray above to string using '+' as Output Field Separator, e.g: 18+38+21+29+45

| Invoke-Expression # Execute the string above as PS code to get final result.
                    # E.g.: 18+38+21+29+45 = 151

Usage example

$Map = @'
1*2+*+*4+1*
2*4+3*+1*6+*
*+*+4*2+1*1
*4+*3+1*+2*3
3*10+2*+*5+*
'@

PS > .\SantaMap.ps1 $Map
151
\$\endgroup\$
2
\$\begingroup\$

Vyxal Dad, 12 bytes

ƛ‛\Wṡ⌊:ż∷2+*

Try it Online!

ƛ            # Map (multiline input) to...
 ‛\Wṡ        # Split on non-word chars
     ⌊       # parse an integer from each
      :ż     # 1...x.length
        ∷2+  # Modulo 2, + 1 results in array of 2s and 3s
           * # Multiply these
             # (d flag) deep sum of result

D makes sure the backslash in ‛\W doesn't get removed, a is necessary for multiline input and d takes the deep sum of the result.

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

Swift 2, 283 211 Bytes

func f(s:String)->Int{var r=0;for p in(s.characters.split{$0=="\n"}.map(String.init)){for v in p.utf8.split(43){let k="0\(v)".utf8.split(42);r+=(Int("\(k[0])")!)*3;r+=(k.count<2 ?0:Int("\(k[1])")!)*2}};return r}

This can be tested on SwiftStub, here

Ungolfed

func f(s: String) -> Int{
    var r = 0

    //for every value in the input, split every "\n" and mapped
    //to a String array
    for p in (s.characters.split{$0=="\n"}.map(String.init)){

        //for every value in the split input, split again at every + (Decimal 43)
        for v in p.utf8.split(43){
            //change the value to "0" + v, which doesn't change the
            //input, but in the event that there is no input on the
            //left side, a "0" will be used
            //
            //then split on every * (Decimal 42)
            let k = "0\(v)".utf8.split(42)

           //add to the total count of elves the number on the left * 3
            r+=(Int("\(k[0])")!) * 3

            //add to the total count of elves the number on the left * 2
            r+=(k.count < 2 ? 0 : Int("\(k[1])")!) * 2
        }

        //return the number of elves
        return r
    }
}
\$\endgroup\$
1
\$\begingroup\$

Python 3, 141 114 112 bytes

Takes multi-line inputs like this c("1*2+*+*4+1*\n2*4+3*+1*6+*\n*+*+4*2+1*1\n*4+*3+1*+2*3\n3*10+2*+*5+*")

lambda s:sum(a and(3-z)*int(a)or 0for j in s.split("\n")for i in j.split("+")for z,a in enumerate(i.split("*")))

Ungolfed:

def c(s):
    t = 0
    for j in s.split("\n"):
        for i in j.split("+"):
            for z,a in enumerate(i.split("*"))
                if a == "":
                    a = 0
                else:
                    a = int(a)
                t += (3-z) * a  # alternate a*3 and a*2
    return t
\$\endgroup\$
1
\$\begingroup\$

I'm super late, but I wanted to give it a shot anyways.

Ruby, 84 55 bytes

I found this question again after so many years and was thinking up a fresh answer before I realized I'd already answered this before. Whoops! Anyways, here's a drastically improved answer.

->m{m.scan(/(\d*)\*(\d*)/).sum{|a,b|3*a.to_i+2*b.to_i}}

Try it online!

Old 84-byte answer from when I first answered this 2 years ago:

->m{m.split(/[+\n]/).map{|h|b,g=h.split(?*).map &:to_i
3*(b||0)+2*(g||0)}.inject :+}

Try it online!

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

Python 3, 96 bytes

lambda s:sum(int('0'+n)*(3-i%2)for i,n in enumerate(re.sub('[*\s]','+',s).split('+')));import re

Try it online!

101 bytes without regex

lambda s:sum(int('0'+n)*(3-i%2)for i,n in enumerate(s.replace('*','+').replace('\n','+').split('+')))

Try it online!

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

JavaScript (ES6), 47 bytes

x=>x.split(/\W/).reduce((y,x,i)=>y+x*(3-i%2),0)

Try it online!

Beats the winning JS answer!

How does it work?

x =>            // Defining a function taking an argument x
  x.split(      // Split x on...
    /\W/        // The regex \W, matching non-word characters
  )
  .reduce((     // Reduce by a function taking...
      y,        // y - current total value
      x,        // x - value of this one
      i         // i - index in input
    ) =>        // and returning
    y + x *     // y, plus x times...
    (3 - i % 2) // 3 if index is even (naughty) otherwise 2
  , 0)          // With initial value 0.
\$\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.