10
\$\begingroup\$

(Hopefully it's still Thanksgiving for you)

You got a turkey for your thanksgiving dinner but you don't know how to evenly distribute it. The problem is, some people eat more than others, so you need to find a solution

Input

There will be two inputs. The first will be an ascii art of various people.

     o
 o  \|/
\|/  |
 |   |
/ \ / \

ascii-art specifications

Each person takes up a width of 3 columns. Each person is separated by a single column of spaces. The very top of each person is an o. Below the o, offset by 1 and -1 in the x, are \ and /, respectively. From the o to the second to last row in the input are |, the amount of these per person is their "height". The only data you will need to extract from each person is their "height".


There will always be at least one person. Each person always has at least 2-height. The max height your program should handle is at least a height of 64.

If you would like the input padded with spaces to form a rectangle, please specify this in your answer.


The second input is the turkey. The turkey is not really a turkey, more of NxM dimensions of a turkey. If the second input is 3x2, then the turkey has dimensions of 3*2, with a total area of 6.

Output

The output may be a list or your language's closest alternative (e.g. Array). You may also output a string, with the values separated by spaces.

The values for each person should be output in the order in which they were input.

Challenge

Your goal is to divide the area of the turkey among the people.

An example scenario:

Assume they are two people, with heights of 3 and 6, respectively. If there is a turkey of 5x3. The total area of the turkey that will need to be distributed is 15.

Now how would you distribute it among everyone? Here's how:

                    the_persons_height
TurkeyForAPerson = -------------------- * turkey_area
                    sum_of_all_heights

This means, for the first person with a height of 3, they will get 3/9*15 turkey, or 5, the second person with a height of 6 they will get 6/9*15 or 10 turkey.

Output

Output must solely consist of digits, and ., unless you choose to go for the bonus. In that case, it may only consist of digits, spaces (), and a slash (/).

Full example

Input:

6x5
     o 
     | 
 o  \|/
\|/  | 
 |   | 
 |   | 
/ \ / \

Output:

11.25 18.75

Bonuses

-20% Bonus: You output a fraction (must be simplified), it does not matter whether it is a mixed or improper fraction.

Scoring

This is so shortest code in bytes wins!

\$\endgroup\$
  • \$\begingroup\$ I may be missing something, but how should we separate the output for each person from the others? I.e. what exact format should the output be in? \$\endgroup\$ – ETHproductions Nov 26 '15 at 16:45
  • \$\begingroup\$ @ETHproductions You may output in a list, or separated by spaces, I can't believe I forgot to specify that. \$\endgroup\$ – Downgoat Nov 26 '15 at 17:04
  • \$\begingroup\$ Is there an upper limit on the turkey dimensions? i.e. is each dimension always one digit, or could it be like 11x10 or higher? \$\endgroup\$ – Tom Carpenter Nov 26 '15 at 18:39
  • \$\begingroup\$ @TomCarpenter it may be multiple digits, the upper limit is whatever your language supports \$\endgroup\$ – Downgoat Nov 26 '15 at 18:40
3
+150
\$\begingroup\$

Pyth, 23 bytes

mc*vXzG\*dsN=N-/R\|C.z0

This doesn't work in the online version, because it uses eval to determine the size of the turkey.

Explanation:

mc*vXzG\*dsN=N-/R\|C.z0   implicit: z = first input line
                    .z    read all other lines
                   C      transpose them
               /R\|       count the "|"s in each column
              -       0   remove 0s in this list (columns with no "|"s)
            =N            assign the resulting list to N
m                         map each value d in N to:
    XzG\*                    replace every letter in z with a "*"
   v                         evaluate the result (does the multiplication)
  *      d                   multiply with d
 c        sN                 divide by sum(N)
\$\endgroup\$
4
\$\begingroup\$

LabVIEW, 67 Bytes

Im counting after what i proposed in the meta post so its not fixed but yeah here goes.

enter image description here

input padded with spaces is expected.

Im counting heads and get the size of people from the line where the heads are at.

\$\endgroup\$
3
\$\begingroup\$

Japt, 49 46 bytes

Japt is a shortened version of JavaScript. Interpreter

W=UqR y f@Y%4¥1 £Xq'| l -1)£Vq'x r@X*Y,1 *X/Wx

Outputs as an array. (Note that you will need to wrap each of the two inputs in quotation marks.)

How it works

            // Implicit: U = stick-figures, V = turkey size
W=UqR y     // Assign variable W to: split U at newlines, transpose rows with columns,
f@Y%4==1    // take each stick-figure body,
m@Xq'| l -1 // and count the number of "|"s.
)m@Vq'x     // Now map each item X in W to: V split at "x",
r@X*Y,1     // reduced by multiplication, starting at 1,
*X/Wx       // multiplied by X and divided by the total of W.
            // Implicit: output last expression
\$\endgroup\$
3
\$\begingroup\$

MATLAB 109*80% = 87.2 bytes

function o=f(t,p);p=char(strsplit(p,'\n'));a=sum(p(:,2:4:end)=='|');o=rats(prod(sscanf(t,'%dx%d'))*a/sum(a));

So this is a MATLAB function which takes two inputs, the first is a string for the turkey size (e.g. '8x4', and the second is the string containing the people. It returns a string containing improper fractions for each person.

This could have been a lot smaller, but the new lines got tricky. MATLAB could easily convert a string with ; as a separator for each line, but trying to use a newline proved difficult, costing 25 characters:

p=char(strsplit(p,'\n')); % Converts the input person string to a 2D array

Getting the size of the people is actually quite easy:

a=sum(p(:,2:4:end)=='|');

This takes every fourth column starting from the second (which will be all the columns where bodies of people will be), then converts that to an array containing 1's where there are body bits and 0's where there aren't. Finally it sums column-wise which results in the array a which is a 1D array containing the size of each person.

prod(sscanf(t,'%dx%d'))*a/sum(a)

Next we extract the size of the turkey from the input string which is in the form %dx%d, i.e. one number then 'x' then another number. The resulting array of two numbers are multiplied together to get turkey area.

This is multiplied by each of the peoples height, and also divided by the total height of all people to get the portion of turkey for each person as a decimal number.

rats(...)

The final step to qualify the bonus - this bit makes the code 6 characters longer, but the bonus knocks off ~22 so its worth it. rats() is a nice function which converts a decimal number to a simplified improper fraction (accurate to 13 d.p.). Feeding it an array of decimal numbers (i.e. the amount for each person) will return a single string containing fractions for each person in turn separated by spaces.

Granted the output of rats() adds more than one space, but the question doesn't say it can't - just says the string must contain only digits, ' ' and '/'.

This is the output from the example (quote marks added by me to prevent spaces being removed, not in actual output):

'     45/4          75/4     '

Example usage:

f('6x5',['     o ' 10 '     | ' 10 ' o  \|/' 10 '\|/  | ' 10 ' |   | ' 10 ' |   | ' 10 '/ \ / \'])

output:

'     45/4          75/4     '

It also works (albeit with warnings) on the online Octave interpreter. You can try it here. The link is to a workspace with the f function defined in a file already. So you should be able to just enter the example usage above at the prompt.

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

Pyth - 25 bytes

Can definitely golf a couple bytes off of it. Pretty straightforward approach.

KfT/R\|C.z*R*FsMcz\xcRsKK

Try it online here.

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

Haskell 119 bytes

import Data.List
g x=sum[1|y<-x,y>'{']
s#p|(h,_:t)<-span(<'x')s=[g x*read h*read t/g p|x<-transpose$lines p,any(>'{')x]

Usage example: "6x5" # " o \n | \n o \\|/\n\\|/ | \n | | \n | | \n/ \\ / \\\n" -> [11.25,18.75].

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

JavaScript (ES6), 131 bytes

(t,p)=>eval(`h=[];for(s=0;m=r.exec(p);s++)h[i=m.index%l/4|0]=~~h[i]+1;h.map(v=>v/s*${t.replace("x","*")})`,l=p.search`
`+1,r=/\|/g)

Returns an array of portions.

Explanation

(t,p)=>                      // t = turkey equation, p = ASCII art of people
  eval(`                     // use eval to enable for loop without {} or return
    h=[];                    // h = array of each person's height
    for(s=0;m=r.exec(p);s++) // for each match of "|", s = sum of all heights
      h[i=m.index%l/4|0]=    // i = person index of this match
        ~~h[i]+1;            // increment person's height (~~ casts undefined to 0)
    h.map(v=>v/s*            // divide each height by the sum and multiply by turkey area
      ${t.replace("x","*")}  // since this is inside an eval just convert t to an equation
    )`,                      // implicit: return array of each person's portion

    // These are executed BEFORE the eval (escaping characters would mean more bytes)
    l=p.search`
`+1,                         // l = line length
    r=/\|/g                  // r = regex to match height markers
  )

Test

var solution = (t,p)=>eval(`h=[];for(s=0;m=r.exec(p);s++)h[i=m.index%l/4|0]=~~h[i]+1;h.map(v=>v/s*${t.replace("x","*")})`,l=p.search`
`+1,r=/\|/g)
Turkey = <input type="text" id="turkey" value="6x5" /><br />
<textarea id="people" rows="8" cols="40">     o 
     | 
 o  \|/
\|/  | 
 |   | 
 |   | 
/ \ / \</textarea><br />
<button onclick="result.textContent=solution(turkey.value,people.value)">Go</button>
<pre id="result"></pre>

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

Python 99 bytes

lambda a,b: [`(''.join(i)).count('|')*1.0/a.count('|')*eval(b)` for i in zip(*a.split('\n'))[1::4]]

Input:' o \n | \n o \\|/\n\\|/ | \n | | \n | | \n/ \\ / \\','6*5'

Output: ['11.25', '18.75']

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