30
\$\begingroup\$

You work at a bakery and every day you make exactly 100 bagels. However your customers are not as reliable and every day a random number of bagels will be ordered. So sometimes you will run out of bagels and sometimes you will have leftovers.

Now leftover bagels will still be good for 1 more day. After a day on the shelves they have to be tossed. But until then you can still sell them. So you keep them for the next day. Customers will prefer fresh bagels so if you haven't run out of fresh bagels they will get a fresh bagel. Only when you are out of fresh bagels will they ask for a day-old bagel.

So for example if you have have 25 bagels left over one day and the next day 100 bagels are ordered, you don't sell any of the old bagels so you throw them out and have 0 leftover bagels the next day.

Your task is to write a program or function which takes a non-empty list of non-negative integers representing how many orders were placed in a given time:

e.g.

[106,25,134,99,85,12]

means that on the first day 106 bagels were ordered, on the second day 25 bagels were ordered and then 134 etc.

Your task is to calculate how many bagels were sold in the described period. You should assume that at the start of the period there will be no leftover bagels available.

This is so answers will be scored in bytes with fewer bytes being the goal.

Test cases

[100,100,100] -> 300
[372,1920,102] -> 300
[25,25,25] -> 75
[25,100,120] -> 225
[0,200] -> 200
[0,175,75] -> 250
[75,150,150] -> 300
[0,101,199]-> 201
[200,0] -> 100
\$\endgroup\$
2
  • 8
    \$\begingroup\$ Interesting variation would be to take the max tolerated days oldness as an input \$\endgroup\$
    – Jonah
    Jan 19 at 14:55
  • 11
    \$\begingroup\$ Now I want a bagel. \$\endgroup\$
    – Giuseppe
    Jan 19 at 15:18

23 Answers 23

7
\$\begingroup\$

Perl 5 + -p -MList::Util+min, 28 bytes

$\+=min$_,100+$-;$-=100-$_}{

Try it online!

Explanation

Adds the minimum of $_ (implicit input via -p) or 100+$- (where $- starts as 0) to $\ (which is automatically output at the end of all lines of input).

$- is set to 100-$_, which is safe because $- can never be negative.

\$\endgroup\$
7
\$\begingroup\$

BQN, 17 bytesSBCS

+´⊢⌊100+·»0⌈100⊸-

Run online!

-1 from ovs.

Explanation

{+´𝕩⌊100+»0⌈100-𝕩}
            100-𝕩 subtract input from 100
          0⌈      maximum with 0
         »        shift right, prepending a 0
     100+         add 100. This is the number of bagels available on a day.
   𝕩⌊             minimum with input
 +´               sum the minimums
\$\endgroup\$
1
  • 1
    \$\begingroup\$ A tacit function is a byte shorter: +´⊢⌊100+·»0⌈100⊸- \$\endgroup\$
    – ovs
    Jan 19 at 13:37
5
\$\begingroup\$

JavaScript (Node.js), 57 55 54 bytes

x=>x.map(i=>[s+=i>a?a:i,a=i>99?100:200-i],s=0,a=100)|s

Try it online!

Badly golfed maybe...

\$\endgroup\$
5
\$\begingroup\$

Haskell, 42 bytes

sum.(zipWith(min.max 100.(-)200)=<<(100:))

Try it online!

Since there's now a Haskell answer I thought I'd toss mine in the ring.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Thanks, you saved me an headache tomorrow! \$\endgroup\$
    – AZTECCO
    Jan 19 at 22:05
  • 1
    \$\begingroup\$ @AZTECCO I don't know it might be worth trying the BQN strategy anyway. I can't read BQN, but I could imagine this going better than 42. \$\endgroup\$
    – Wheat Wizard
    Jan 19 at 22:06
  • 1
    \$\begingroup\$ I was only able to get 43 bytes with a direct recursive function \$\endgroup\$
    – xnor
    Jan 20 at 8:39
5
\$\begingroup\$

Excel, 66 bytes

=LET(o,A:A,a,100+INDEX((100-o)*(o<100),ROW(o)-1),SUM(IF(o<a,o,a)))

Input is in the range A:A with each day's order in a cell by itself. Output is wherever the formula is.

The LET() function allows you to define variables and later reference them by that variable name. The terms come in pairs (variable, value) except the last term which is just the output value.

  • o,A:A defines o (orders) to be the entirety of column A. This technically limits you to about 2,870 years of bagel orders. I consider this to be acceptable.
  • a,100+INDEX((100-o)*(o<100),ROW(o)-1) defines a (available) and does most of the heavy lifting so let's break it down into pieces.
    • 100 is how many bagels are made fresh each day.
    • (100-o) is how many leftover fresh bagels there are each day.
    • *(o<100) filters out negatives (more orders than fresh so no leftovers).
    • ROW(o)-1 tells us that we're going to be looking at the data for the previous day.
    • In plain(er) text: 100+INDEX([leftover fresh]*[not negative],[from yesterday]).
    • All together, you could read it as [fresh] + [yesterday's fresh leftovers].
  • IF(o<a,o,a) returns either the number of orders (if it was less than what was available) or just what was available.
  • SUM(IF(~)) adds it all up.

Result

\$\endgroup\$
2
  • \$\begingroup\$ How long did this challenge take you? \$\endgroup\$
    – kaiser
    Jan 23 at 22:35
  • 1
    \$\begingroup\$ @kaiser The Created and Last Modified timestamps on the file are about an hour apart but I was working on it off and one during that time. It was probably somewhere in the 30-45 minutes range. \$\endgroup\$ Jan 24 at 13:13
4
\$\begingroup\$

05AB1E, 14 bytes

тs-Dd*т+тšø€ßO

Port of @Razetime's BQN answer.

Try it online or verify all test cases.

Explanation:

                #  e.g. input = [0,101,199]
тs-             # Subtract the values in the (implicit) input-list from 100
                #  STACK: [100,-1,-99]
   D            # Duplicate this list
                #  STACK: [100,-1,-99],[100,-1,-99]
    d           # Check for each that they're non-negative (>=0)
                #  STACK: [100,-1,-99],[1,0,0]
     *          # Multiply the values at the same positions
                #  STACK: [100,0,0]
      т+        # Add 100 to each
                #  STACK: [200,100,100]
        тš      # Prepend 100
                #  STACK: [100,200,100,100]
          ø     # Create pairs with the (implicit) input-list,
                # ignoring the additional trailing item
                #  STACK: [[0,100],[101,200],[199,100]]
           ۧ   # Get the minimum of each pair
                #  STACK: [0,101,100]
             O  # Sum those minima
                #  STACK: 201
                # (after which the result is output implicitly)
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Rotate fails for an input of [200,0]; you need to shift or equivalent. \$\endgroup\$
    – Neil
    Jan 19 at 14:09
  • \$\begingroup\$ @Neil Should be fixed, thanks for noticing \$\endgroup\$ Jan 19 at 14:18
4
\$\begingroup\$

Wolfram Language (Mathematica), 37 36 bytes

Tr[i=c=100;Min[2c-c~Min~i,i=#]&/@#]&

Try it online!

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

C(gcc -O0), 115 109 84 82 78 bytes.

m,l,g;f(a,n)int*a;{m=l=0;for(g=100;n--;++a)m+=fmin(g+l,*a),l=*a<g?g-*a:0;m=m;}

Try it online!

The function takes two arguments, a pointer to the array and the size of the array.

-25 bytes thanks to AZTECCO

-4 bytes thanks to ceilingcat

Can I golf it further?

\$\endgroup\$
2
  • 3
    \$\begingroup\$ Welcome to the site! If you haven't already you can find tips for golfing in C here. \$\endgroup\$
    – Wheat Wizard
    Jan 19 at 13:40
  • \$\begingroup\$ @WheatWizard Should they find tips for tio, too? :) \$\endgroup\$
    – l4m2
    Jan 19 at 14:31
4
\$\begingroup\$

Brainfuck, 148 bytes

,[->[-]>[-<+>]>++++++++++[-<++++++++++>],[>>>+<<<-<[->>+>>-<<<<[->>>+<<<]]>>>[-<<<+>>>]>[-<<<<<[->>>+<<<[->>>>+<<<<]]>>>>[-<<<<+>>>>]>]<<<]<<<]>>>>.

First is inputed length of array, then the values. Sadly I can't find any site which supports input&output as decimal numbers. Best I got is this site where you can input escape squences like \3\100\100\100, but the output is ASCII, so you will need to convert it to decimal. (Please let me know about any sites supporting decimal in comments)

Explanation

Memory map: arrayLength old fresh order output temp flag

,[-                          loop through all elements of array
  >[-]                       reset old count
  >[-<+>]                    set old count to the remaining amount from fresh
  >++++++++++[-<++++++++++>] set fresh to 100
  ,[                         while there is order
    >>>+                     set flag
    <<<-                     reduce order size
    <[                       check if there are any fresh
      -                      reduce amount of fresh
      >>+                    increase output
      >>-                    unset flag
      <<<<[->>>+<<<]         copy fresh to temp variable so condition can exit
    ]
    >>>[-<<<+>>>]            copy from temp back to fresh
    >[                       check if flag is set (if previous condition wasnt executed it acts as else)
      -                      unset flag
      <<<<<[                 check if there are any old
        -                    reduce amount of old
        >>>+                 increase output
        <<<[->>>>+<<<<]      copy old to temp variable so condition can exit
      ]
      >>>>[-<<<<+>>>>]       copy from temp back to old
      >
    ]<<<
  ]<<<
]
\$\endgroup\$
3
\$\begingroup\$

Python, 56 bytes

lambda a:sum(map(min,[200-min(r,100)for r in[100]+a],a))

Attempt This Online!

If it weren't for Python 2 padding arguments to map with Nones, we could abuse its global ordering like so:

lambda a:sum(map(min,[200-min(r,100)for r in[a]+a],a))

because a will always be "larger" than 100.

As it is, we have to work around it with a+[0])) for 58.


Python, 58 bytes

lambda a,S=100:sum(min(r,100-S+(S:=min(r,100)))for r in a)

Attempt This Online!

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

R, 51 48 bytes

function(n,`~`=pmin)sum(c(n,0)~100-c(0,n-100~0))

Try it online!

Ports Razetime's BQN answer.

-3 bytes thanks to pajonk.

\$\endgroup\$
2
  • \$\begingroup\$ -3 bytes \$\endgroup\$
    – pajonk
    Jan 19 at 21:00
  • \$\begingroup\$ @pajonk thanks! \$\endgroup\$
    – Giuseppe
    Jan 19 at 21:15
2
\$\begingroup\$

Python 3.8 (pre-release), 63 62 bytes

f=lambda o,*v,l=1:min(o,99+l)+(len(v)and f(*v,l=max(1,101-o)))

Try it online!

Takes the input as a vararg list

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

Charcoal, 22 bytes

IΣEθ⌊⟦ι⌈⟦¹⁰⁰∧κ⁻²⁰⁰§θ⊖κ

Try it online! Link is to verbose version of code. Explanation:

   θ                    Input array
  E                     Map over orders
    ⌊⟦                  Minimum of
      ι                 Today's order and
       ⌈⟦               Maximum of
         ¹⁰⁰            Literal integer `100` and
             κ          Current index
            ∧           Logical And
               ²⁰⁰      Literal integer `100`
              ⁻         Subtract
                  §θ⊖κ  Previous day's order
 Σ                      Take the sum
I                       Cast to string
                        Implicitly print
\$\endgroup\$
1
\$\begingroup\$

APL+WIN, 24 bytes

Prompts for input

+/b⌊100+¯1↓0,0⌈n←100-b←⎕

Try it online! Thanks to Dyalog Classic

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

Haskell, 57 55 bytes

(0!)
r!(x:t)|x>100=0!t+min(100+r)x|j<-100-x=x+j!t
_!x=0

Try it online!

saved 2 Bytes thanks to @Wheat Wizard

\$\endgroup\$
1
  • \$\begingroup\$ Thanks @Wheat Wizard , I also trying razetime Bqn method which is 54 for now , I'll work on it tomorrow \$\endgroup\$
    – AZTECCO
    Jan 19 at 21:57
1
\$\begingroup\$

x86-64 machine code, 24 bytes

31 c0 99 97 91 ad 01 c7 83 e8 64 01 c2 78 02 29 d7 99 21 c2 e2 ef 97 c3

Fixed.
Try it online!

Following the standard calling convention for Unix-like systems (from the System V AMD64 ABI), this takes the length in RDI and the address of an array of 32-bit integers in RSI.

Assembly:

.global bagels
bagels:
    xor eax, eax    # EAX = 0.
    cdq             # EDX = 0.
    xchg edi, eax   # Exchange EDI (length) with EAX (0).
    xchg ecx, eax   # Exchange ECX with EAX (length).
                    #   Here, EDI will hold the number of bagels sold, and EDX
sl:                 #    will hold -l, with l being the number of leftover bagels.
    lodsd           # Load the current number n into EAX, advancing the pointer in ESI.
    add edi, eax    # Add the number ordered to EDI.
    sub eax, 100    # Subtract 100 from EAX, producing n-100.
    add edx, eax    # Add n-100 to EDX, producing n-100-l.
    js skip         # Jump if that's negative (more bagels available than ordered).
    sub edi, edx    # (Otherwise) Subtract the shortfall n-100-l from EDI.
skip:
    cdq             # Fill EDX with the sign bit of EAX.
    and edx, eax    # Bitwise AND; makes EDX equal n-100 if it's negative, 0 otherwise.
    loop sl         # Count down from the length in ECX, looping that many times.
    xchg edi, eax   # Switch the result (in EDI) into EAX.
    ret             # Return.
\$\endgroup\$
1
\$\begingroup\$

Java (JDK), 73 bytes

a->{int s=0,l=0,h=100;for(var o:a){s+=h+l<o?h+l:o;l=o<h?h-o:0;}return s;}

Try it online!

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

Pari/GP, 56 bytes

f(b)=sum(i=1,#b,min(b[i],100+if(i>1,max(0,100-b[i-1]))))

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ vecsum(vector(#b,i,...)) => sum(i=1,#b,...) \$\endgroup\$
    – alephalpha
    Jan 26 at 7:18
  • \$\begingroup\$ Thanks alephalpha for that suggestion. I’m so used to working on vectors … \$\endgroup\$
    – Joe Slater
    Jan 26 at 7:56
1
\$\begingroup\$

Kotlin, 115 101 bytes

shaved off 14 bytes thanks to a helpful user

{var s=0;var l=0;for(d in it){var t=Math.min(d,100);t+=Math.min(d-t,l);s+=t;l=100-Math.min(d,100)};s}

Try it online!

Ungolfed:

fun bagelCalculator1(arg: Array<Int>) : Int
{
    var sold = 0
    var left = 0
    for(demand in arg)
    {
        var soldToday = min(demand,100)
                          // V the deficit V
        soldToday += min(demand-soldToday, left)
        sold += soldToday
        left = 100-min(demand,100)
    }
    return sold
}
\$\endgroup\$
1
\$\begingroup\$

Pip, 25 23 bytes

MN{H[ah+yYMX[h-a0]]}MSg

Takes the list of orders-per-day as separate command-line arguments. Attempt This Online! Or, verify all test cases.

Explanation

                         ; We store the number of leftovers in y (initially = 0)
                      g  ; List of cmdline args
                    MS   ; Map this function and sum the results:
MN                       ; Apply min to the result of
  {                }     ; This function:
   H                     ;   All but the last element of
    [             ]      ;   This list:
     a                   ;     Function arg (today's number of orders),
      h+y                ;     100 plus yesterday's leftovers,
         Y               ;     and yank the new number of leftovers:
          MX[    ]       ;       Take the max of
             h-a         ;       100 minus function arg
                0        ;       and 0
\$\endgroup\$
1
\$\begingroup\$

Jelly, 11 bytes

ȷ2ð_«Ż+ḷṖ«S

Try it online!

Another handful of ports of Razetime's BQN.

ȷ2 could hypothetically be golfed to ³ if this is used as a function in a program with no command-line arguments, but the existing Jelly corpus seems to discourage this. Modifying the programs to use STDIN has yielded no savings (but thanks to emanresu A for reminding me).

ȷ2ð            With 100 as the left argument to a dyadic chain:
    «          Take the minimum of each element of the input and 100,
   _           and subtract each minimum from 100.
     Ż         Prepend a 0,
      +ḷ       add 100 to each,
        Ṗ      remove the last element,
         «     take the pairwise minima with the input,
          S    and sum.

Jelly, 11 bytes

ȷ2ɓ«ṖạŻ+ɓ«S

Try it online!

Jelly, 11 bytes

ȷ2ðḤ_«Ṗ⁸;«S

Try it online!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Would it be cheaper to use a full program and the nilad for 100? \$\endgroup\$
    – emanresu A
    Feb 1 at 5:40
  • \$\begingroup\$ @emanresuA The way it's structured it would cost a byte overall to use STDIN, but ³ might be usable if it's treated purely as a function submission... might spend a few minutes looking for precedent \$\endgroup\$ Feb 1 at 5:47
  • \$\begingroup\$ Precedent seems to forbid it, but I'll note it anyways. \$\endgroup\$ Feb 1 at 5:56
0
\$\begingroup\$

PHP, 79 bytes

function b($a){foreach($a as$o){$t+=min(100+$d,$o);$d=max(0,100-$o);}return$t;}

And now I want a bagel :)

Try it online!

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

///, 63 bytes

/b|/|bbbbb// /bbbb||//b1///b\||1/||//1///b*/*s//*/\/// *//sb// 

Try it online!

Takes input appended to the program, as space-separated unary numbers using 1s; produces output in unary using ss.

Or, run a modified version with added pre-processing and post-processing to use decimal numbers in input and output.

Explanation

/b|/|bbbbb/
/ /bbbb||/

The first substitution modifies the second substitution's replacement string: each | multiplies the number of bs by 5 as it passes through them, resulting in ||bbb…(100)…bbb.

Then, the second substitution replaces each space with that string. In addition to the spaces between the input numbers, there is one more space from the end of the program (just before the input), so the string appears at the start of every day, providing the 100 bagels (as bs) made for the day and a separator ||.

/b1//

Use bagels to fulfil orders made on the same day, removing both.

/b\||1/||/

Use bagels to fulfil orders made on the next day, removing both. The backslash prevents this code from being modified by the first substitution.

/1//

Remove unfulfilled orders.

/b*/*s/
/*/\//
/ */

The last of these three pieces will have already been modified by the second substitution in the program, to /||bbb…(100)…bbb*/. It is further modified here, becoming /||*sss…(100)…sss/ and then /||/sss…(100)…sss/, and then executed, replacing each day separator || with a hundred ss, again producing the number of bagels made that day.

/sb//

Cancel out bagels made with bagels unsold, leaving the number of bagels sold in ss.

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