11
\$\begingroup\$

A piggy bank is a container used to collect coins in. For this challenge use the four US coins: quarter, dime, nickel, and penny.

Challenge

Your challenge is to create an electronic piggy bank. Write a program (or function) that when run (or called), outputs (or returns) the count of each coin you have, as well as the total amount the coins amount to.

Input

A string, array, etc...(your choice) of the coins into your piggy bank(case insensitive).

 Q - Quarter(Value of 25)
 D - Dime(Value of 10)
 N - Nickel(Value of 5)
 P - Penny(Value of 1)

Output

The count of coins from the input and the total amount, separated by the non-integer delimiter of your choice. (The order in which you output the coin totals does not matter, but the total coin value(sum) must be the last element)

Examples

 Input          ->       Output

 P              ->       1,0,0,0,1 or 0,0,0,1,1 or 0,0,1,0,1 or 1,1
 N              ->       0,1,0,0,5
 D              ->       0,0,1,0,10 
 Q              ->       0,0,0,1,25
 QQQQ           ->       0,0,0,4,100
 QNDPQNDPQNDP   ->       3,3,3,3,123
 PPPPPPPPPP     ->       10,0,0,0,10
 PNNDNNQPDNPQND ->       3,6,3,2,113

Rules

Standard loopholes are not allowed.

This is , so the shortest code in bytes for each language wins!

\$\endgroup\$
  • 1
    \$\begingroup\$ @Shaggy Yes you can \$\endgroup\$ – DevelopingDeveloper Mar 29 '18 at 17:00
  • 1
    \$\begingroup\$ The order of the coins in the total. May we give it in the order of appearance in the input? \$\endgroup\$ – Adám Mar 29 '18 at 17:27
  • 1
    \$\begingroup\$ So if the order may be inferred from the input, may we omit 0s? It will still be clear which letters the each number refers to. \$\endgroup\$ – Adám Mar 29 '18 at 17:38
  • 1
    \$\begingroup\$ Is this output format too far off? 19 byte answer that I'm not sure is valid: Try it online! \$\endgroup\$ – Magic Octopus Urn Mar 29 '18 at 19:28
  • 1
    \$\begingroup\$ I feel like there should be a [money] tag. \$\endgroup\$ – 12Me21 Mar 30 '18 at 0:48

26 Answers 26

5
\$\begingroup\$

Python 2, 73 bytes

-3 bytes thanks to @Rod

C=map(input().count,'QDNP')
print C+[sum(map(int.__mul__,C,[25,10,5,1]))]

Try it online!

\$\endgroup\$
  • 4
    \$\begingroup\$ You can replace a*b for a,b in zip(C,[25,10,5,1]) with map(int.__mul__,C,[25,10,5,1]) to save few bytes \$\endgroup\$ – Rod Mar 29 '18 at 16:59
4
\$\begingroup\$

Python 2, 63 bytes

a,b,c,d=map(input().count,'PNDQ')
print a,b,c,d,a+b*5+c*10+d*25

Try it online!


Python 2, 63 bytes

l=map(input().count,'PNDQ')
a,b,c,d=l
print l+[a+b*5+c*10+d*25]

Try it online!

\$\endgroup\$
4
\$\begingroup\$

APL (Dyalog Unicode), 28 27 bytes

1 5 10 25(⊢,+.×)'PNDQ'+.=¨⊂

Try it online!

Tacit function. Takes input as a vector in the format ,'<input>'.

Thanks to ngn for one byte!

How?

1 5 10 25(⊢,+.×)'PNDQ'+.=¨⊂ ⍝ Main function, tacit.
                          ⊂ ⍝ Enclose
                         ¨  ⍝ Each character of the input
                      +.=   ⍝ Sum the number of matched characters
                'PNDQ'      ⍝ From this string
1 5 10 25(  +.×)            ⍝ Multiply the values with the left argument, then sum them.
          ⊢,                ⍝ And append to the original vector of coins.
\$\endgroup\$
  • \$\begingroup\$ 1⊥∘.=∘'PNDQ' -> 'PNDQ'+.=¨⊂ \$\endgroup\$ – ngn Apr 5 '18 at 2:09
4
\$\begingroup\$

R, 70 69 bytes

function(n)c(x<-table(factor(n,c("P","N","Q","D"))),x%*%c(1,5,25,10))

Try it online!

Takes input as a vector of individual characters. Converts them to factors and tabulates them, then computes the values with a dot product.

For ease of testing purposes, I've added a way to convert from test cases above to the input that the function is expecting.

This barely beats out storing the coin names as vector names, which means that the approach below would be likely be golfier if we had more coin types:

R, 71 70 bytes

function(n)c(x<-table(factor(n,names(v<-c(P=1,N=5,Q=25,D=10)))),x%*%v)

Try it online!

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

Jelly, 19 bytes

ċЀ“PNDQ”µæ.“¢¦½ı‘ṭ

Try it online!

How it works

ċЀ“PNDQ”µæ.“¢¦½ı‘ṭ    Main link. Arguments: s (string)
 Ѐ“PNDQ”              For each char in "PNDQ":
ċ                        Count the occurrences of the char in s.
                       Collect the results in an array. Call this a.
         µ             Start a new monadic chain. Argument: a
          æ.           Take the dot product of a with
            “¢¦½ı‘       [1, 5, 10, 25].
                  ṭ    Tack this onto the end of a.
\$\endgroup\$
3
\$\begingroup\$

JavaScript (ES6), 63 61 bytes

Saved 2 bytes thanks to Shaggy

Takes input as an array of characters. Outputs P,N,D,Q,total.
Inspired by ovs' Python answer.

a=>eval(a.join`++,`+`++,[P,N,D,Q,P+N*5+D*10+Q*25]`,P=N=D=Q=0)

Try it online!


Original answer, 73 bytes

Takes input as an array of characters. Outputs Q,D,N,P,total.

a=>a.map(c=>o[o[4]+='521'[i='QDNP'.search(c)]*5||1,i]++,o=[0,0,0,0,0])&&o

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Very nicely done! You can knock 2 bytes off by shuffling some stuff around. \$\endgroup\$ – Shaggy Mar 29 '18 at 18:38
3
\$\begingroup\$

MATL, 22 20 bytes

!'PNDQ'=Xst[l5X25]*s

Try it online! Or verify all test cases.

Explanation with example

Consider input 'PNNDNNQPDNPQND' as an example. The stack contents are shown upside down, i.e. the top element appears below.

!        % Implicit input: string (row vector of chars). Transpose into a
         % column vector of chars
         % STACK: ['P';
                   'N';
                   'N';
                   'D';
                   'N';
                   'N';
                   'Q';
                   'P';
                   'D';
                   'N';
                   'P';
                   'Q';
                   'N';
                   'D']
'PNDQ'   % Push this string (row vector of chars)
         % STACK: ['P';
                   'N';
                   'N';
                   'D';
                   'N';
                   'N';
                   'Q';
                   'P';
                   'D';
                   'N';
                   'P';
                   'Q';
                   'N';
                   'D'],
                  'PNDQ'
=        % Implicit input. Test for equality, element-wise with broadcast
         % STACK: [1 0 0 0;
                   0 1 0 0;
                   0 1 0 0;
                   0 0 1 0;
                   0 1 0 0;
                   0 1 0 0;
                   0 0 0 1;
                   1 0 0 0;
                   0 0 1 0;
                   0 1 0 0;
                   1 0 0 0;
                   0 0 0 1;
                   0 1 0 0;
                   0 0 1 0]
Xs       % Sum of each column
         % STACK: [3 6 3 2]
t        % Duplicate
         % STACK: [3 6 3 2],
                  [3 6 3 2]
[l5X25]  % Push array [1 5 10 25]
         % STACK: [3 6 3 2],
                  [3 6 3 2],
                  [1 5 10 25]
*        % Multiply, element-wise
         % STACK: [3 6 3 2],
                  [3 30 30 50]
s        % Sum
         % STACK: [3 6 3 2],
                  113
         % Implicitly display
\$\endgroup\$
  • \$\begingroup\$ !'PNDQ'=Xst[l5X25]!Y* is 21 bytes. although I admit I haven't tested it. \$\endgroup\$ – Giuseppe Mar 29 '18 at 16:52
  • \$\begingroup\$ @Giuseppe Thanks, but the challenge says "the non-integer delimiter of your choice", so I assume only one delimiter is allowed \$\endgroup\$ – Luis Mendo Mar 29 '18 at 16:54
  • \$\begingroup\$ I hadn't noticed that. Ah well. \$\endgroup\$ – Giuseppe Mar 29 '18 at 16:54
  • 1
    \$\begingroup\$ I think the 21 byte solution is OK... OP commented something to that effect \$\endgroup\$ – Giuseppe Mar 29 '18 at 19:57
  • \$\begingroup\$ @Giuseppe Great! Down to 20 bytes then. Thanks for the heads-up \$\endgroup\$ – Luis Mendo Mar 29 '18 at 20:49
3
\$\begingroup\$

Japt, 25 22 bytes

Saved 3 bytes thanks to @Shaggy

`p˜q`¬£èX
pUí*38#éìH)x

Test it online! Takes input in lowercase

Explanation

`p˜q`¬         Split the compressed string "pndq" into chars, giving ["p", "n", "d", "q"].
      £        Map each char X to
       èX      the number of occurrences of X in the input.
<newline>      Set variable U to the resulting array.
 Uí*           Multiply each item in U by the corresponding item in
    38#é         38233
        ìH       converted to base-32, giving [1, 5, 10, 25].
           x   Take the sum.
p              Append this to the end of U.
               Implicit: output result of last expression
\$\endgroup\$
  • \$\begingroup\$ Trying to figure out a way to golf away the comma, not having much luck so far. \$\endgroup\$ – Shaggy Mar 29 '18 at 16:52
  • \$\begingroup\$ Got it! \$\endgroup\$ – Shaggy Mar 29 '18 at 16:55
  • \$\begingroup\$ And save another byte by taking input in lowercase. \$\endgroup\$ – Shaggy Mar 29 '18 at 17:01
  • \$\begingroup\$ Knocked another byte off \$\endgroup\$ – Shaggy Mar 29 '18 at 17:41
  • \$\begingroup\$ @Shaggy Impressive, thanks! \$\endgroup\$ – ETHproductions Mar 30 '18 at 2:41
3
\$\begingroup\$

Excel (Polish language version), 150 bytes

The input is in A1. The formulas are in cells B1-F1:

cell  formula
------------------------------
B1    =DŁ(A1)-DŁ(PODSTAW(A1;"Q";""))
C1    =DŁ(A1)-DŁ(PODSTAW(A1;"D";""))
D1    =DŁ(A1)-DŁ(PODSTAW(A1;"N";""))
E1    =DŁ(A1)-DŁ(PODSTAW(A1;"P";""))
F1    =B1*25+C1*10+D1*10+E1

resulting in output of number of quarters, dimes, nickels, pennys and the sum in cells B1, C1, D1, E1 and F1 respectively.

English language version (162 bytes):

cell  formula
------------------------------
B1    =LEN(A1)-LEN(SUBSTITUTE(A1;"Q";""))
C1    =LEN(A1)-LEN(SUBSTITUTE(A1;"D";""))
D1    =LEN(A1)-LEN(SUBSTITUTE(A1;"N";""))
E1    =LEN(A1)-LEN(SUBSTITUTE(A1;"P";""))
F1    =B1*25+C1*10+D1*10+E1
\$\endgroup\$
3
\$\begingroup\$

APL+WIN, 33 27 bytes

5 bytes saved thanks to Adam

Prompts for screen input of coin string.

n,+/1 5 10 25×n←+⌿⎕∘.='PNDQ'
\$\endgroup\$
  • \$\begingroup\$ Save 5 bytes: n,+/1 5 10 25×n←+⌿⎕∘.='PNDQ' \$\endgroup\$ – Adám Mar 29 '18 at 17:35
  • \$\begingroup\$ @ngn Thanks. Old age is getting the better of me :( \$\endgroup\$ – Graham Apr 5 '18 at 16:14
2
\$\begingroup\$

05AB1E, 30 26 22 21 19 bytes

X5T25)s.•50†•S¢=*O=

Try it online!


X                   # Push 1.
 5                  # Push 5.
  T                 # Push 10.
   25               # Push 25.
     )s             # Wrap stack to array, swap with input.
       .•50†•       # Push 'pndq'.
             S      # Push ['p','n','d','q'] (split).
              ¢     # Count (vectorized).
               =    # Print counts, without popping.
                *   # Multiply counts by [1,2,10,25]
                 O  # Sum.
                  = # Print.

Dump:

Full program: X5T25)s.•50†•S¢=*O=
current >> X  ||  stack: []
current >> 5  ||  stack: [1]
current >> T  ||  stack: [1, '5']
current >> 2  ||  stack: [1, '5', 10]
current >> )  ||  stack: [1, '5', 10, '25']
current >> s  ||  stack: [[1, '5', 10, '25']]
current >> .  ||  stack: [[1, '5', 10, '25'], 'pnndnnqpdnpq']
current >> S  ||  stack: [[1, '5', 10, '25'], 'pnndnnqpdnpq', 'pndq']
current >> ¢  ||  stack: [[1, '5', 10, '25'], 'pnndnnqpdnpq', ['p', 'n', 'd', 'q']]
current >> =  ||  stack: [[1, '5', 10, '25'], [3, 5, 2, 2]]
[3, 5, 2, 2]
current >> *  ||  stack: [[1, '5', 10, '25'], [3, 5, 2, 2]]
current >> O  ||  stack: [[3, 25, 20, 50]]
current >> =  ||  stack: [98]
98
stack > [98]

Printed Output:

[3, 25, 20, 50]\n98 or [P, N, D, Q]\n<Sum>

Because something was printed, the ending stack is ignored.

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

J, 29 bytes

1 5 10 25(],1#.*)1#.'PNDQ'=/]

Try it online!

Explanation:

'PNDQ'=/] creates an equality table

   'PNDQ' =/ 'PNNDNNQPDNPQND'
1 0 0 0 0 0 0 1 0 0 1 0 0 0
0 1 1 0 1 1 0 0 0 1 0 0 1 0
0 0 0 1 0 0 0 0 1 0 0 0 0 1
0 0 0 0 0 0 1 0 0 0 0 1 0 0

1#. finds the sum of each row of the table, thus the number of occurences of each value

   1#. 'PNDQ' =/ 'PNNDNNQPDNPQND'
3 6 3 2

1#.* finds the dot product of its left and right argument

    1 5 10 25(1#.*)3 6 3 2
113

], appends the dot product to the list of values

   1 5 10 25(],1#.*)1#.'PNDQ'=/] 'PNNDNNQPDNPQND'
3 6 3 2 113
\$\endgroup\$
2
\$\begingroup\$

C# (.NET Core), 163 136 bytes

Thanks to @raznagul for saving alot of bytes there!

n=>{var m="";int c=0,i=0,k=0;for(var v=new[]{1,5,10,25};i<4;m+=k+",",c+=k*v[i++],k=0)foreach(var x in n)k+=x=="PNDQ"[i]?1:0;return m+c;}

Try it online!


Old version:

n=>{var v=new[]{1,5,10,25};string l="PNDQ",m="";int c=0,i,j,k;for(i=0;i<4;i++){for(j=0,k=0;j<n.Length;j++)k+=n[j]==l[i]?1:0;m+=k+",";c+=k*v[i];k=0;}m+=c;return m;}

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ I've managed to golf your soultion down to 136 bytes. To many changes to list. \$\endgroup\$ – raznagul Mar 30 '18 at 12:11
  • \$\begingroup\$ @raznagul Great solution! May I ask why you switched the input to a generic list instead of an array? AFAIK you can iterate over the characters of a string without using a list. \$\endgroup\$ – Ian H. Mar 30 '18 at 13:57
  • \$\begingroup\$ That is a remnant from an earlier version, so I could use n.Count instead of n.Length. As that was dropped entirely you can use string now. \$\endgroup\$ – raznagul Mar 30 '18 at 14:02
1
\$\begingroup\$

Perl 5 -pF, 59 bytes

for$i(P,N,D,Q){say s:$i:$\+={P,1,Q,25,D,10,N,5}->{$&}:eg}}{

Try it online!

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

Ruby, 66 bytes

->s{t=0;{P:1,N:5,D:10,Q:25}.map{|c,v|t+=v*m=s.count(c.to_s);m}<<t}

Try it online!

Not great.

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

05AB1E, 19 bytes

"PNDQ"S¢D•Ωт•₂в*O)˜

Try it online!

Explanation

"PNDQ"                # push this string
      S               # split to list of chars
       ¢              # count the occurrences of each in input
        D             # duplicate
         •Ωт•         # push 21241
             ₂в       # convert to a list of base 26 digits
               *      # element-wise multiplication
                O     # sum
                 )˜   # wrap in a flattened list
\$\endgroup\$
1
\$\begingroup\$

Java (OpenJDK 8), 148 bytes

c->{int q=0,d=0,n=0,p=0;for(char w:c){if(w=='Q')q++;if(w=='D')d++;if(w=='N')n++;if(w=='P')p++;}return ""+q+","+d+","+n+","+p+","+(q*25+d*10+n*5+p);}

Try it online!

Well it's only one byte shorter than the other Java submission, but hey- shorter is shorter :D

Explanation:

int q=0,d=0,n=0,p=0;    //Initialize too many integers
for(char w:c){    //Loop through each coin
  if(w=='Q')q++;if(w=='D')d++;if(w=='N')n++;if(w=='P')p++;    //Increment the correct coin
}return ""+q+","+d+","+n+","+p+","+(q*25+d*10+n*5+p);    //Return each coin count and the total monetary value 
\$\endgroup\$
1
\$\begingroup\$

Gol><>, 47 bytes

5R0TiE!vD;
5+@P@@t>b%m$.
a+$P$t
PrPrt
9s+r$P$rt

Try it online!

The output format is [P Q N D Value].

How it works

5R0TiE!vD;
       >b%m$.

5R0            Repeat command '0' (push 0) 5 times
   T           Set teleport location for later
    i          Input a char
     E         Pop if the last input was EOF; skip next otherwise

               If the last is EOF, the following is run:
      ! D;     Skip 'v', print the contents of the stack from bottom to top, then exit

               Otherwise the following is run:
       v
       >b%m$.  Take the top (input) modulo 11, and jump to (-1, input % 11)
               P%11 = 3, N%11 = 1, D%11 = 2, Q%11 = 4

5+@P@@t        Runs if the input is N
5+             Add 5 to top
  @            Rotate top 3 (the 3rd comes to the top)
   P           Increment the top
  @P@@         Increment the 3rd from top
      t        Teleport to the last 'T'

a+$P$t         Runs if the input is D
a+             Add 10 to top
  $            Swap top two
  $P$          Increment the 2nd from top
     t         Teleport to the last 'T'

PrPrt          Runs if the input is P
P              Increment the top
 r             Reverse the stack
 rPr           Increment the bottom
    t          Teleport to the last 'T'

9s+r$P$rt      Runs if the input is Q
9s+            Add 25 to the top ('s': add 16 to the top)
   r$P$r       Increment the 2nd from bottom
        t      Teleport to the last 'T'
\$\endgroup\$
1
\$\begingroup\$

Perl 5 -p, 47 bytes

#!/usr/bin/perl -p
P1N5D10Q25=~s:\D:$\-=-$'*($n=s/$&//g);say$n:egr

Try it online!

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

Pyth, 23 27 26 bytes

+Jm/Qd"PNDQ"s.b*NYJ[h05T25

Saved a byte thanks to @RK. Outputs as [P, N, D, Q, value].
Try it here

Explanation

+Jm/Qd"PNDQ"s.b*NYJ[h05T25
 Jm/Qd"PNDQ"                Save the count of each coin (in PNDQ order) as J.
                   [h05T25  [1, 5, 10, 25].
             .b   J       For each pair of count and value...
               *NY          ... take the product...
            s               ... and get the sum.
+                          Stick that onto the list of counts.
\$\endgroup\$
  • \$\begingroup\$ You can condense the definition of J and the first usage of J to get +Jm/Qd"PNDQ"s.b*NYJ[h05T25 \$\endgroup\$ – RK. Mar 31 '18 at 14:01
1
\$\begingroup\$

C (clang), 112 bytes

f(char *i){int c,d,v[5]={0};for(;c=*i++;v[d=(c|c/2)&3]++,v[4]+="AYJE"[d]-64);for(c=0;c<5;printf("%d,",v[c++]));}

Try it online!

Output seq is now of P,Q,D,N,total-value
Works with both lower-case and upper-case inputs.

Explanation:

"AYJE" or {64+1,64+25,64+10,64+5} is. 64+value-of-coin.
d=(c|c/2)&3 (used as index) has value 1,2,3,0 for q,d,n,p inputs respectively, in both upper and lower case.

\$\endgroup\$
  • \$\begingroup\$ 106 bytes \$\endgroup\$ – ceilingcat Dec 30 '18 at 21:48
  • \$\begingroup\$ Eliminating c=0 was good catch. Thanks. \$\endgroup\$ – GPS Jan 2 at 12:20
0
\$\begingroup\$

C# (.NET Core), 156 bytes

s=>{Func<char,int>f=i=>{return s.Split(i).Length-1;};var a=new[]{f('P'),f('N'),f('D'),f('Q')};return$"{string.Join(",",a)},{a[0]+a[1]*5+a[2]*10+a[3]*25}";};
\$\endgroup\$
0
\$\begingroup\$

Java (OpenJDK 8), 149 bytes

a->{int[]c={0,0,0,0,0};for(String g:a){if(g=="P")c[0]+=1;if(g=="N")c[1]+=5;if(g=="D")c[2]+=10;if(g=="Q")c[3]+=25;}c[4]=c[0]+c[1]+c[2]+c[3];return c;}

Try it online!

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

Retina, 50 bytes

P
P_
N
N5*
D
D10*
Q
Q25*
^
PNDQ_
O`.
(.)(\1*)
$.2¶

Try it online! Outputs in the order D, N, P, Q, total. Explanation:

P
P_
N
N5*
D
D10*
Q
Q25*

Calculate the total by inserting _s corresponding to the value of each coin.

^
PNDQ_

Insert an extra copy of each character so there is at least one of each to match.

O`.

Sort the characters into order.

(.)(\1*)
$.2¶

Count the number of each character after the first.

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

SmileBASIC, 70 bytes

INPUT C$P=N+D+Q
WHILE""<C$INC VAR(POP(C$))WEND?P,N,D,Q,P+N*5+D*10+Q*25

Example:

? PNDNDNDQP
2   3   3   1   72

Explanation:

INPUT COINS$
P=N+D+Q 'create variables
WHILE COINS$>"" 'loop until the coin list is empty
 'pop a character from the coin list
 'and increment the variable with that name
 INC VAR(POP(COINS$))
WEND
PRINT P,N,D,Q,P+N*5+D*10+Q*25
\$\endgroup\$
0
\$\begingroup\$

C, 149 bytes

f(char*s){int a[81]={},b[]={1,5,10,25},c=0;char*t,*v="PNDQ";for(t=s;*t;a[*t++]++);for(t=v;*t;printf("%d,",a[*t++]))c+=a[*t]*b[t-v];printf("%d\n",c);}

Try it online!

C doesn't have associative arrays, so I fake it (very inefficiently, memory-wise!) and then loop through again with a lookup array to add up the coins. It won't calculate foreign currency, though :-)

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