41
\$\begingroup\$

You are a talented young chef who has just been offered the position of sous chef at the world's most prestigious Indian restaurant. You have little experience with preparing Indian cuisine, but you're determined, so you set out to prove yourself. You decide to become the leading dosa expert. To do this, you must not only master the creation of dosas, but you must be able to scale them to be arbitrarily large.

You find a promising recipe for dosa batter:

  • 1 cup rice
  • 1 cup ukda chawal
  • 1/2 cup urad dal
  • 1/4 cup poha
  • 1/4 tsp methi seeds
  • Salt to taste
  • Water as needed

This will make a dosa approximately 1/2 meter in length.

Challenge

Write a program or function that will tell the restaurant staff exactly what's needed to make a single dosa out of an integer multiple of the given recipe. Space is tight in the kitchen, so you want your code to be as short as possible. The shortest code wins, with ties going to the earlier post.

Measuring spoons and cups come in the following standard sizes: 1/4, 1/3, 1/2, 2/3, 3/4, and 1. To avoid angering the kitchen staff, measurements must be reported in the largest unit in which the number can be written as mixed numbers using standard sizes only.

Measurements propagate to larger sizes per the following convention:

  • 3 tsp == 1 tbsp
  • 4 tbsp == 1/4 cup

So for a multiple of 12, 1/4 tsp methi seeds becomes 1 tbsp. However, for a multiple of 13, it becomes 3 1/4 tsp. Otherwise it wouldn't be represented in standard sizes.

The wait staff must be able to carry the dosa to the tables. To ensure that the dosa does not break in transit, you instruct them to carry the dosa in teams. Each person can carry at most one meter of dosa. So for a single or double recipe, only one person is needed to carry it. The wait staff is less effective if they're cut into fractional pieces, so an integer number of waiters is always required.

Input

Take a positive integer via STDIN (or closest alternative), command line argument, or function argument. This number dictates the scaling factor for the recipe and can be as small as 1 but no larger than 232-1. It can be any integer in that range.

Output

Print to STDOUT (or closest alternative) the list of ingredients scaled according to the input as well as the number of waiters required to carry the dosa. The ingredients must be listed in the order given above and in the format given below.

Examples

Input:

2

Output:

2 cups rice
2 cups ukda chawal
1 cup urad dal
1/2 cup poha
1/2 tsp methi seeds
Salt to taste
Water as needed
1 waiter

Note that "cup" changes to "cups" when the value is greater than 1. "tsp" does not change. "waiter," like "cup," becomes plural.

Input:

5

Output:

5 cups rice
5 cups ukda chawal
2 1/2 cups urad dal
1 1/4 cups poha
1 1/4 tsp methi seeds
Salt to taste
Water as needed
3 waiters

Non-integer values greater than 1 are represented as mixed numbers, i.e. an integer followed by a reduced fraction.

Note: The title comes from a relevant video.

\$\endgroup\$
12
  • 15
    \$\begingroup\$ Now we need someone to do a Chef answer:) \$\endgroup\$
    – MickyT
    Commented Aug 3, 2015 at 22:37
  • 12
    \$\begingroup\$ "The wait staff is less effective if they're cut into fractional pieces, so an integer number of waiters is always required." ...How much less effective, exactly? \$\endgroup\$ Commented Aug 3, 2015 at 23:05
  • 5
    \$\begingroup\$ @LivingInformation Well, have you ever seen just a pair of legs carry food to your table? \$\endgroup\$
    – Alex A.
    Commented Aug 3, 2015 at 23:06
  • 7
    \$\begingroup\$ @AlexA. Have you not? \$\endgroup\$ Commented Aug 3, 2015 at 23:08
  • 8
    \$\begingroup\$ @MickyT: I tried, but I seem to have run into some bugs in the Chef interpreter from CPAN. (a) Output values are separated by spaces, except when they aren't. (b) Something about my Mixed Number Chutney sub-recipe (or is it the Comparison Minted Yoghurt?) is causing the interpreter to die with an obscure error message. \$\endgroup\$ Commented Aug 4, 2015 at 13:56

6 Answers 6

9
+50
\$\begingroup\$

CJam, 214 bytes

ri[48_24C.25]{[48ZX]f{:DW$@*\md_D{_@\%}h;:M/iDM/}3/_{W=5<}#:I=[(\'/*]{S+_0e=!*}/["cup"2$2a>'s*+"tbsp"_'b-]I=S}%4/"rice
ukda chawal
urad dal
poha
methi seeds
Salt to taste
Water as needed"N/.+N*N@)2/" waiter"1$1>'s*

Try it online in the CJam interpreter.

\$\endgroup\$
2
  • \$\begingroup\$ Not really golfed yet, but it's late and I wanted to post the first answer. \$\endgroup\$
    – Dennis
    Commented Aug 5, 2015 at 5:17
  • \$\begingroup\$ Since no Chef answer has been posted and yours is the shortest valid answer at the end of the bounty period, you win the bounty. Thanks for participating in my first challenge. :) \$\endgroup\$
    – Alex A.
    Commented Aug 12, 2015 at 19:26
7
\$\begingroup\$

Javascript (ES6), 443 chars

This was very fun to golf, but the result is considerably longer than what I was expecting.

d=n=>(y=s=>n<s?' cup':' cups',z=s=>n/s|0,A=' 1/4',B=' 1/2',C=' 3/4',n+y(2)+` rice
${n+y(2)} ukda chawal
${(n%2<1?n/2:z(2)+B)+y(3)} urad dal
${((e=n%4)<1?n/4:z(4)+(e<2?A:e<3?B:C))+y(5)} poha
${(n%48<1?z(192)+((c=n/48%4)>2?C:c>1?B:c>0?A:'')+y(193):n%3<1?z(12)+((f=n/3%4)>2?C:f>1?B:f>0?A:'')+' tbsp':(z(4)+(e>2?C:e>1?B:e>0?A:''))+' tsp')} methi seeds
Salt to taste
Water as needed
${(b=Math.ceil(n/2))} waiter`+(b<2?'':'s')).replace(/\n0 /g,'\n')

Try it out:

d=n=>(y=s=>n<s?' cup':' cups',z=s=>n/s|0,A=' 1/4',B=' 1/2',C=' 3/4',n+y(2)+` rice
${n+y(2)} ukda chawal
${(n%2<1?n/2:z(2)+B)+y(3)} urad dal
${((e=n%4)<1?n/4:z(4)+(e<2?A:e<3?B:C))+y(5)} poha
${n%48<1?z(192)+((c=n/48%4)>2?C:c>1?B:c>0?A:'')+y(193):n%3<1?z(12)+((f=n/3%4)>2?C:f>1?B:f>0?A:'')+' tbsp':(z(4)+(e>2?C:e>1?B:e>0?A:'')+' tsp')} methi seeds
Salt to taste
Water as needed
${(b=Math.ceil(n/2))} waiter`+(b<2?'':'s')).replace(/\n0 /g,'\n')

W=function(){setTimeout(function(){
    (Q=document.getElementById("num").value)&&(document.getElementById("a").innerHTML =d(+Q).replace(/\n/g,'<br>'));
  }, 10);};
document.getElementById("num").addEventListener("keypress", function(){W();});
document.getElementById("num").addEventListener("click", function(){W();});
<form>How many recipes of dosa batter would you like?
  <input type="number" name="num" id="num" value="1" />
</form>
<p id="a">1 cup rice<br>
1 cup ukda chawal<br>
1/2 cup urad dal<br>
1/4 cup poha<br>
1/4 tsp methi seeds<br>
Salt to taste<br>
Water as needed<br>
1 waiter</p>

It accepts values up to and even including 2^32, or 4294967296. After that, the 'urad dal' overflows on odd numbers and becomes negative.

Basically, it calculates the correct amounts as it goes. Luckily, only the methi seeds need to have tsp/tbsp/cup measures; otherwise, this would have been a whole lot longer. (The methi seed line alone is 155 chars!)

This also would have been at least 500 chars long in ES5. I ❤ ES6.

As always, suggestions are greatly appreciated!

Edit 1: Just realized that according to the rules, 1 tsp should be replaced with 1/3 tbsp, same with 2 tsp and 2/3 tbsp, as well as 16 tsp and 1/3 cup....

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Math.ceil can be shortened to -~ so, b=-~t/2 is much shorter, You can also exclude the parenthesis \$\endgroup\$
    – Downgoat
    Commented Aug 11, 2015 at 4:02
  • 1
    \$\begingroup\$ @vihan Thanks for the tip, but this only works on non-integers. -~1 results in 2, which is not the intended result. The best alternative I could find, b=-~((n-1e-9)/2), is just as long, so I'll keep it the way it is for now. \$\endgroup\$ Commented Aug 14, 2015 at 21:00
3
\$\begingroup\$

Common Lisp, 435

(lambda(n)(labels((k(y)(some(lambda(x)(integerp(* y x)))'(1 4/3 3/2 2 3 4)))(h(s m)(multiple-value-bind(q r)(floor m)(format()"~[~:;~:*~A ~]~[~:;~:*~A ~]~@? " q r s m)))(g(o &aux(h(/ o 3))(c(/ h 4)))(cond((k c)(h"cup~P"c))((k h)(h"tbsp"h))(t(h"tsp"o)))))(format t"~&~A rice
~Aukda chawal
~Aurad dal
~Apoha
~Amethi seeds
Salt to taste
Water as needed
~A waiter~:P
"(g(* n 12))(g(* n 12))(g(* n 6))(g(* n 3))(g(/ n 4))(ceiling(/ n 2)))))

Slightly ungolfed

(lambda (n)
  (labels ((k (y)
             (some (lambda (x) (integerp (* y x))) '(1 4/3 3/2 2 3 4)))
           (h (s m)
             (multiple-value-bind (q r)
                 (floor m)
               (format nil "~[~:;~:*~A ~]~[~:;~:*~A ~]~@?" q r s m)))
           (g (o &aux (h (/ o 3)) (c (/ h 4)))
             (cond ((k c) (h "cup~P" c)) ((k h) (h "tbsp" h)) (t (h "tsp" o)))))
    (format t "~&~A rice
~A ukda chawal
~A urad dal
~A poha
~A methi seeds
Salt to taste
Water as needed
~A waiter~:P
"
            (g (* n 12)) (g (* n 12)) (g (* n 6)) (g (* n 3)) (g (/ n 4))
            (ceiling (/ n 2)))))

All measures are expressed in tsp. Based on the k function, g decides which units to use for printing and call the formatting function h with the appropriate arguments.

  • k returns true when the argument can be expressed as a multiple of 1, 1/4, 1/3, 2/3, 4/3 units
  • g converts the input as a number of tbsp and the number of tbsp as a number of cups (as given in the question). We try to print by units of cups first, or units of tbsp, or else in tps.
  • h use a conditional formatting directives to print either x, x y/z or y/z followed by the formatting of s with argument m: for cups, s is "cup~P" which plurializes the word according to m.

Exemple (n = 17)

17 cups rice
17 cups ukda chawal
8 1/2 cups urad dal
4 1/4 cups poha
4 1/4 tsp methi seeds
Salt to taste
Water as needed
9 waiters
\$\endgroup\$
1
  • \$\begingroup\$ This is neat. Nice work. \$\endgroup\$
    – Alex A.
    Commented Aug 12, 2015 at 20:10
3
\$\begingroup\$

R, 602 603 526 bytes

Still lots of room to golf this I suspect, but I have run out of time and I really wanted to do an answer for this one.

function(i){S=gsub
M=i/c(1,5,60)
A=list(c(2,1),c(4,3),c(64,48))[[I<-max(which(M>=1))]]
B=c(4,12,192)[I]
V=c(' tsp',' tbsp',' cup')[I]
C=i%/%B
C=C+max((i%%B)%/%A*c(.3,.25))
cat(S('([ ]*)0 ','\\1',S('\\.3',' 1/3',S('\\.6',' 2/3',S('\\.5',' 1/2',S('\\.25',' 1/4',S('\\.75',' 3/4',paste0(i,' cup',if(i>1)'s',' rice
',i,' cup',if(i>1)'s',' ukda chawal
',i*.5,' cup',if(i>2)'s',' urad dal
',i*.25,' cup',if(i>4)'s',' poha
',C,V,if(C>1&I>2)'s',' methi seeds
Salt to taste
Water as needed
',ceiling(i*.5),' waiter',if(i>2)'s'))))))))}
\$\endgroup\$
3
  • \$\begingroup\$ For an input of 5 this has 1/3 tbsp 1/4 tsp methi seeds but it should should be represented in a single common unit. So it should be 1 1/4 tsp methi seeds (if my mental math is correct). \$\endgroup\$
    – Alex A.
    Commented Aug 11, 2015 at 4:04
  • \$\begingroup\$ @AlexA. That's good too know. I'll fix it up soonish. I assume that it's the same with cups and tbsp. \$\endgroup\$
    – MickyT
    Commented Aug 11, 2015 at 5:53
  • \$\begingroup\$ Yep, same rule for all the units. +1 in the meantime though, on good faith that it'll be correct soon. Thanks for participating in my first challenge. :) \$\endgroup\$
    – Alex A.
    Commented Aug 11, 2015 at 12:59
1
\$\begingroup\$

JavaScript (Node.js), 419 bytes

a=>(y=g=>a<g?" cup":" cups",z=g=>a/g|0,a+y(2)+` rice
${a+y(2)} ukda chawal
${(1>a%2?a/2:z(2)+(B=" 1/2"))+y(3)} urad dal
${(1>(e=a%4)?a/4:z(4)+(2>e?A=" 1/4":3>e?B:C=" 3/4"))+y(5)} poha
${1>a%48?z(192)+(2<(c=a/48%4)?C:1<c?B:0<c?A:"")+y(193):1>a%3?z(12)+(2<(f=a/3)?C:1<f?B:0<f?A:"")+" tbsp":z(4)+(2<e?C:1<e?B:0<e?A:"")+" tsp"} methi seeds
Salt to taste
Water as needed
${b=-~a/2|0} waiter`+(2>b?"":"s")).replace(`
0 `,`
`)

Try it online!

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

Stax, 122 120 117 bytes

Öàu≈9o∞3┴&•ªâ6üòf±Σ§LXâ¢vò╣*/T≥C└ôZüæR-^╦ìóσ∩A←··■☼⌂▌2åH╨bgrp╬3L♫-◙•►]╘═º♀ú♣ɱ╧○+╧┴Qî¼▼◄I"a≤ΩzH♦╩k╖FΦúZa═q|▬◄┼W╥ßöo29

Run and debug it

It was a bit infuriating to start over after closing this program's tab, but now it works, and it's shorter!

-5 bytes from recursive.

Explanation (Unpacked)

3:B244E{um+{x*uuB\"cup"sch1>{s's+}{s}?]+{fJm"rice,ukda chawal,urad dal,poha,methi seeds"',/\{JmN"cup""tsp"R]+{PF"Salt to taste"P"Water as needed"P2:_ecp" waiter"p1>{'sp}*

3:B244E{um+ array [1,1,1/2,1/4,1/4]

{...m map to:

 x*uu product with input,  converted to fraction

 B\                        push fractional part and whole part, and pair them

 "cup"sch1>{s's+}{s}?]+    if whole part <1, append "cup", else cups

 {fJ                       remove zeroes, and join with spaces

"rice,ukda chawal,urad dal,poha,methi seeds"',/ array of ingredients

\{Jm zip with the amounts, and jin with spaces

N remove last element and push separately(methi seeds)

"cup""tsp"R]+ replace "cup" with "tsp", add it back in

{PF print each ingredient

"Salt to taste"P"Water as needed"P print the constant instructions

2:_ecp divide input by 2, ceil, duplicate, and print

" waiter"p print "waiter"

1>{'sp} if number of waiters > 1, print an s

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