# German pharmacy payment

Your task is to calculate the amount you have to pay for prescribed medication at a pharmacy in Germany. The amount is simply based on the full price of the item, which will be your input. It is a decimal number with exactly two fractional digits (ex. 5.43). You can assume it's strictly positive. Your task is to calculate the amount a customer has to pay, according to this function:

$$A(x)=\begin{cases} x&\text{if } x\le 5\\ 5&\text{if } 5\le x \le 50\\ 0.1x&\text{if }50\le x \le 100\\ 10&\text{if }100 \le x \end{cases}$$ or equivalently $$A(x)=\min(x,\min(\max(0.1x,5),10))$$

The result must be rounded to two decimal places (half up). If these are 0, they may be skipped from the output. There must not be more than 2 decimal places. You can take numbers or strings as input and output, but be aware of inexact floating point representations.

Use a comma or a point as the decimal separator.

## Test cases

5.00, 5.0 and 5 are all ok.

  4.99  ->  4.99
5.00  ->  5.00
5.05  ->  5.00
10.00 ->  5.00
49.00 ->  5.00
50.00 ->  5.00
50.04 ->  5.00
50.05 ->  5.01
50.14 ->  5.01
50.15 ->  5.02
99.84 ->  9.98
99.85 ->  9.99
99.94 ->  9.99
99.95 -> 10.00
100.00 -> 10.00
1000.00 -> 10.00

• You should have a test case between 5 and 50; otherwise the second row of your formula isn’t tested Nov 19, 2023 at 15:09
• A price of zero doesn't make sense in this context, so I removed the test case. Nov 19, 2023 at 17:38
• No, it will always be printed with two decimal places on your reciept, and that's what I'm trying to go for. Nov 19, 2023 at 20:22
• @corvus_192 It seems that most answers are not outputting in the correct format. Nov 20, 2023 at 2:03
• @corvus_192 a float of exactly 5.00 might be represented as 5.0 or 5 etc. Is a function that returns floats not valid? Nov 20, 2023 at 12:46

# Jelly, 14 bytes

÷⁵«⁵»5«+ȷ-4ær2


A monadic Link that accepts the full price as a float and outputs the charge as a float.

Try it online!

### How?

÷⁵«⁵»5«+ȷ-4ær2 - Link: Full Price           P
÷⁵             - divide Full Price by 10    P/10
«⁵           - minimum with 10            min(10,P/10)
»5         - maximum with 5             max(5,min(10,P/10))
«        - minimum with Full Price    min(P,max(5,min(10,P/10)))
+ȷ-4    - add 0.0001 (catering for banker's rounding effects below)
ær2 - round to two decimal places

• This doesn't satisfy the output requirement of always having 2 decimal places Nov 20, 2023 at 12:39
• This is a monadic Link (function) and the result is a float. It is always rounded to two decimal places, but the representation of a float like 5.00 is 5.0. I have added a comment under the question as output formatting isn't part of the requirements unless clearly specified as such, and I don't feel that this challenge is about output formatting. Nov 20, 2023 at 12:49
• @SamDean the restrictions have been relaxed. Nov 20, 2023 at 17:06

# APL+WIN, 21 bytes

Prompts for input

2⍕(n⌊((.1×n←⎕)⌈5))⌊10


Try it online! Thanks to Dyalog Classic

• You can get rid of the parentheses and write as a dfn {2⍕⍵⌊10⌊5⌈.1×⍵}
– Tbw
Nov 22, 2023 at 10:13
• Thanks for the comment but unfortunately my version of APL+WIN is 20 years old and does not have any of that functionality. Fortunately I can still use the basic functionality of Dyalog Classic to post my answers on TIO. Nov 22, 2023 at 10:18
• @Tbw see my comment above. Please feel free to port any of my answers into a modern APL to demonstrate how far the language has developed. Nov 22, 2023 at 10:20
• ah I see. You can actually make my solution shorter by making it tacit as 2⍕⊢⌊10⌊5⌈.1×⊢, but I'm not sure that would help in running in your case. I think I will post a solution.
– Tbw
Nov 22, 2023 at 10:25

# R, 39 bytes

\(x)round(.001+min(x,max(.1*x,5),10),2)


Basically using the formula given by the OP.

-5 bytes thanks to @doubleunary

-3 bytes and fix a rounding error thanks to @NickKennedy

-6 bytes since the OP removed the requirement for exactly 2 decimal places.

Try it online!

• hmm... round(min(x,max(.1*x,5),10),2) Nov 19, 2023 at 20:52
• @doubleunary obviously... thx! Nov 19, 2023 at 20:56

# APL (Dyalog Unicode), 13 bytes

2⍕⊢⌊10⌊5⌈.1×⊢


Try it online!

Tacit prefix function. Takes input as number. Thanks to Graham for original APL solution.

### How it works:

2⍕⊢⌊10⌊5⌈.1×⊢ ⍝ Anonymous, tacit function.
.1×⊢ ⍝ 0.1x
5⌈      ⍝ max with 5
10⌊        ⍝ min with 10
⊢⌊          ⍝ min with x (as a fork)
2⍕            ⍝ format with 2 decimal places

• Welcome to Code Golf! Nov 22, 2023 at 18:58

# JavaScript (Node.js), 40 bytes

x=>Math.min(x,x<50?5:(x*10+.5|0)/100,10)


Try it online!

# Python 3, 45 bytes

lambda x:round(sorted([x,5,10,x/9.999])[1],2)


Try it online!

-2 from PattuX

• The reason to add a small positive number here is to cater for the fact that Python's round does banker's rounding by default, which rounds half-way points to the nearest even multiple. (It also negates any floating point effects that this rounding can introduce as per the first note in the round documentation) Nov 19, 2023 at 14:12
• @JonathanAllan As it happens, there are no floating point effects between 0.00 and 100.00, at least not using the naïve formula floor(x*10+0.5)/100 rather than round(x/10,2).
– Neil
Nov 19, 2023 at 14:32
• The rounding only affects the cases from 50 too 100€, i.e., the x/10 part. You can also fix it by not dividing by 10 but a slightly smaller number, saving 2 bytes: lambda x:round(sorted([x,5,10,x/9.999])[1],2) Nov 20, 2023 at 12:08

# Retina 0.8.2, 95 92 bytes

\.

.+
$* ^(.{1000}(?=.{8995})|.(.{499,998})(?=\2{9}....)|.{0,500}).* 00$.1
0*(.+)(..)
$1.$2


Try it online! Link includes test cases. Explanation:

\.



Multiply by 100.

.+
$*  Convert to unary. ^(.{1000}(?=.{8995})|.(.{499,998})(?=\2{9}....)|.{0,500}).* 00$.1


Calculate the amount to pay, with two 0s prefixed in case the amount is less than 100.

0*(.+)(..)
$1.$2


Divide by 100.

The disjunctions are as follows:

• .{1000}(?=.{8995}) Any amount over 9994 becomes 1000.
• .(.{499,998})(?=\2{9}....) Any amount over 4999 becomes a tenth of its value. .(.{499,998}) is the amount to pay, between 500 and 999, but the input has to match that value plus 9 times 1 less than that value plus 4, which equals 10 times that minus 5, thus rounding half up.
• .{0,500} Any amount below 500 is unchanged, but amounts between 500 and 4999 become 500.

# Google Sheets / Microsoft Excel, 31 bytes

=fixed(min(10,A1,max(5,A1/10)))

Put the input in cell A1 and the formula in B1. The fixed() function also takes care of rounding.

Equivalent JavaScript (rounding issue, non-competing, 45 bytes):

x=>Math.min(10,x,Math.max(5,x/10)).toFixed(2)

# Ruby, 42 36 bytes

->a{[a,[a/10,5].max,10].min.round 2}


Try it online!

# Ruby, 38 bytes

Formatted as per initial requirement:

->a{"%.2f"%[a,[a/9.999,5].max,10].min}


Try it online!

• This sometimes prints 5 or 5.0 instead of 5.00 Nov 19, 2023 at 20:41
• @Evargalo That's ok, it was unclear, so I removed the restriction. Nov 20, 2023 at 13:37

# JavaScript (ES6), 45 bytes

x=>~~(Math.min(x*10,x<50?50:x,100)*10+.5)/100


Try it online!

## 40 bytes

This one works in theory, but fails on some test cases because of rounding errors.

x=>Math.min(x,x<50?5:x/10,10).toFixed(2)


Try it online!

• x=>Math.min(x,x<50?5:(x*10+.5|0)/100,10) works for all cases and conveniently is also the same length!
– Neil
Nov 19, 2023 at 20:01
• @Neil Seems like l4m2 already came to the same version. Nov 19, 2023 at 20:14
• Huh, I hadn't even noticed...
– Neil
Nov 19, 2023 at 23:11
• Think you need to include the toFixed(2) in the first answer to comply with the output requirement of always having 2 decimal places Nov 20, 2023 at 12:43
• @SamDean The OP has since clarified that 5, 5.0 and 5.00 are all acceptable. Nov 20, 2023 at 16:21

# Python, 41 bytes

lambda x:min(max(5,(x*20+1)//2/100),x,10)


Attempt This Online!

Straight-forward implementation of OP's formula. For the rounding it uses floor division resulting in integer-valued floats which - unlike tenths - are guaranteed to be represented exactly.

# sclin, 26 bytes

dup.1*5|10, &/100* |~100/


Try it on scline!

sclin's default real/rational number representation comes in handy here.

## Explanation

Prettified code:

dup .1* 5| 10, &/ 100* |~ 100/


Assuming input n:

• dup .1* n * .1
• 5| min with 5
• 10, &/ min with 10 and n
• 100* |~ 100/ round 2 decimal places

# Wolfram Language (Mathematica), 36 bytes

#~Min~Max[.1#,5]~Min~10~Round~.01&@x


Alas, we cannot save an extra byte by using infix notation with Max because multiplication has a lower precedence than passing an argument, so .1#~Max~5 is equivalent to .1(#~Max~t), rather than (.1#)~Max~t.

Try it online!

# PARI/GP, 44 bytes

x->printf("%.2f",min(x,min(max(x/10,5),10)))


Attempt This Online!

A port of @Evargalo's R answer.

Prints the result to stdout.

# 05AB1E, 16 (or 25) bytes

T/5‚à‚Tªß4°z+2.ò


This outputs 5.0 or 10.0 instead of 5.00 or 10.00, like most other answers. To fix this, the following 9 bytes can be added:

т+0«6∍¦0Û


Explanation:

T/        # Divide the (implicit) input by 10
5‚        # Pair it with 5
à       # Pop and push the maximum of the pair
‚         # Pair it with the (implicit) input
Tª       # Append 10 to this pair
ß      # Pop and push the minimum of this triplet
4°        # Push 10**4: 10000
z       # Pop and push 1/10000: 0.0001
+      # Add it to the value
2.ò   # Then (banker's) round it to 2 decimals

0«      # Append a trailing 0
6∍    # Shorten it to length 6
¦   # Remove the leading 1
0Û # Trim any leading 0s
# (after which the result is output implicitly)


# AWK, 48 bytes

{y=$0/10;a=y>5?y>10?10:y:5>$0?$0:5;print a+1e-4}  Try it online! Ungolfed : BEGIN{ OFMT = "%.2f" } func min(n,m){ return m>n?n:m } func max(p,q){ return p>q?p:q } { x=min($0,min(max(0.1*$0,5),10))+0.0001 print$1, "->", x
}


# Scala 3, 106 100 bytes

Saved 6 bytes thanks to @corvus_192

Golfed version. Attempt This Online!

x=>BigDecimal(Seq(x,5,10,x/10).sorted.apply(1)+1e-6).setScale(2,BigDecimal.RoundingMode(4)).toDouble


Ungolfed version. Attempt This Online!

object Main {
def f(x: Double): Double = {
val sortedList = List(x, 5, 10, x/10).sorted
BigDecimal(sortedList(1) + 1e-6).setScale(2, BigDecimal.RoundingMode.HALF_UP).toDouble
}

def main(args: Array[String]): Unit = {
println(f(90))
println(f(210))
println(f(16))
println(f(4.21))
println(f(5.05))
println(f(25.15))
println(f(25.654321))
println(f(75))
println(f(75.987654))
println(f(1000))
}
}

• 100 bytes: x=>BigDecimal(Seq(x,5,10,x/10).sorted.apply(1)+1e-6).setScale(2,BigDecimal.RoundingMode(4)).toDouble Nov 20, 2023 at 13:30

# Rust, 50 bytes

|x|(500f64.max(1e1*x).min(1e3).round()/1e2).min(x)


Try it online!

# Charcoal, 21 bytes

ＮθＩ⌊⟦θχ⌈⟦⁵∕⌊⁺·⁵×θχ¹⁰⁰


Try it online! Link is to verbose version of code. Explanation: Port of the formula given in the question, but with rounding as required. I checked all inputs from 50.00 to 99.99 and none of them had any rounding errors; even though for example 64.35*100 does not result in 6435, 64.35*10 does result in 643.5, which is then rounded to 644, with a final result of 6.44.

Ｎθ                      First input as a number
θ       First input
×        Multiplied by
χ      Literal integer 10
⁺           Plus
·⁵         Literal number 0.5
⌊            Floor
∕             Divided by
¹⁰⁰   Literal integer 100
⁵              Literal integer 5
⟦               Make into list
⌈                Take the maximum
χ                 Predefined variable 10
θ                  Input number
⟦                   Make into list
⌊                    Take the minimum
Ｉ                     Cast to string
Implicitly print


Formatted to two decimal places also turns out to be 21 bytes:

Ｎθ﹪%.2f⌊⟦θχ⌈⟦⁵∕θ⁹·⁹⁹⁹


Try it online! Link is to verbose version of code. Explanation: Uses @PattuX's observation that dividing by 9.999 before rounding suffices to compensate for floating-point errors.

# *><>, 90 89 bytes

-1 byte by removing a semicolon that shouldn't have been there

I'm still trying to condense it using the dive u and rise O instructions, but in case I forget, here's a working version without them.

Requires running with the -i flag to receive input.

:5)?!\:5a*)?!\:9b*(?!\aa*:}*:a%:4)?v-   >$a*,n; ;n/ ;n5/ ;na/ \a$-+/


## Explanation

### x ≤ 5

:5)?!\
;n/

:         Duplicate the input
5        Push 5 onto the stack
)       Evaluate 5 > input
?!\   If true, redirect down
/   Redirect left
;n     Print the input, and halt execution


### 5 ≤ x ≤ 50

:5a*)?!\
;n5/

:         Duplicate the input again
5        Push 5 onto the stack
a       Push 10 onto the stack
*      Multiply the top to values, thus putting 50 onto the stack
)     Evaluate 50 > input
?!\   If true, redirect down
/   Redirect left
;n5    Push 5 onto the stack, print it, and halt execution


### 100 ≤ x

:aa*(?!\
;na/

:          Duplicate the input
aa*       Multiply 10by 10, putting 100 onto the stack
(      Evaluate 100 < input
?!\   If true, redirect down
/   Redirect left
;na    Push 10 onto the stack, print it, and halt execution


### 50 ≤ x ≤ 100

In order to get half-up rounding, we multiply the input by 100 to make it an integer. From there we then round up/down to the nearest 10, and then divide by 1000 to get our final amount.

aa*:}*:a%:4)?v-   >$a*,n; \a$-+/

aa*                         Push 100 onto the stack
:                        Duplicate the 100 on the stack
}                       Shift the stack to the right, moving the duplicated 100 to the 0th index
*                      Multiply the input by 100, replacing future instances of "input" with "input * 100"
:                     Duplicate the input
a                    Push 10 onto the stack
%                   Push input modulo 10 onto the stack
:                  Duplicate that value
4                 Push 4 onto the stack
)                Evaluate (input modulo 10) > 4
?v              If (input modulo 10) > 4 == true, redirect down
// If (input modulo 10) > 4 == true
\              Redirect right
a             Push 10 onto the stack
$Swap the top two values on the stack - Subtract (input module 10) from 10 + Add that to the input / Redirect up // If (input modulo 10) > 4 == false - Else, subtract (input module 10) from input // After conditional > Force instruction pointer to the right$        Swap the two values on the stack, making it [input, 100]
a*      Multiply the top value by 10, pushing 1000 onto the stack
,     Divide the input by 1000
n;   Print the value and halt execution


Try it online!

# Uiua 0.3.1, 16 bytes

↧↧↥5⍜×⁅100⊃÷∘10.


See it in action

# Desmos, 30 actually 35 bytes

A one-liner Desmos equation for once (thanks to Aiden Chow for the fix and optimization):

f(x)=round([x,5,10,x/10].sort[2],2)


Try it on Desmos!

• You say Desmos takes care of rounding but if I input 50.55 it shows 5.055 not 5.06. Nov 20, 2023 at 15:59
• @Jonathan Allan Fixed it! Nov 20, 2023 at 16:38
• I see the fix, however it is not rounding half-up (same now gives 5.05 not 5.06). Nov 20, 2023 at 17:03
• If I'm not mistaken, wrapping your original answer with round(..., 2) seems to fix the issue (Desmos seems to always round half up from what I've noticed). Nov 20, 2023 at 20:55
• I just realized that x/10 can be .1x`, saving another byte (I just copy-pasted the list from the aforementioned Python answer without much attention, so I didn't catch this before). Nov 20, 2023 at 23:10