# Shortest digid-app GetPercentageRounds function

## Context

So the Dutch "Ministerie van Binnenlandse Zaken en Koninkrijksrelaties" (NL) - "Ministry of the Interior and Kingdom Relations" (EN) recently released the source code of their digid-app.

They have some goofy code in there, which led to mockery and memes on reddit

Source code of the offending method can be found here. Here's a copy:

private static string GetPercentageRounds(double percentage)
{
if (percentage == 0)
return "⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪";
if (percentage > 0.0 && percentage <= 0.1)
return "🔵⚪⚪⚪⚪⚪⚪⚪⚪⚪";
if (percentage > 0.1 && percentage <= 0.2)
return "🔵🔵⚪⚪⚪⚪⚪⚪⚪⚪";
if (percentage > 0.2 && percentage <= 0.3)
return "🔵🔵🔵⚪⚪⚪⚪⚪⚪⚪";
if (percentage > 0.3 && percentage <= 0.4)
return "🔵🔵🔵🔵⚪⚪⚪⚪⚪⚪";
if (percentage > 0.4 && percentage <= 0.5)
return "🔵🔵🔵🔵🔵⚪⚪⚪⚪⚪";
if (percentage > 0.5 && percentage <= 0.6)
return "🔵🔵🔵🔵🔵🔵⚪⚪⚪⚪";
if (percentage > 0.6 && percentage <= 0.7)
return "🔵🔵🔵🔵🔵🔵🔵⚪⚪⚪";
if (percentage > 0.7 && percentage <= 0.8)
return "🔵🔵🔵🔵🔵🔵🔵🔵⚪⚪";
if (percentage > 0.8 && percentage <= 0.9)
return "🔵🔵🔵🔵🔵🔵🔵🔵🔵⚪";

return "🔵🔵🔵🔵🔵🔵🔵🔵🔵🔵";
}


## Try it online:

https://dotnetfiddle.net/aMEUAM

## Challenge

Write code in any language as short as possible to replicate the above function

## Rule clarification

• You must exactly match the input and output of the original function. Substituting the ball characters with something else is not allowed.
• You must stick to the functions original boundaries. Meaning if the input is something unexpected like -1 or 42 you must still return the same result as the original function.
• May you substitute the characters of the circles? E.g. replacing 🔵 with x and ⚪ with o or something like that? Jan 19 at 22:13
• It needs to be made clearer that values not in the range [0, 1] need to return a full bar of 🔵 Jan 19 at 22:27
• Yes, please add some test cases that include 0, −0.1, 0.95, 1.0, and 1.1
Jan 19 at 22:28
• Nice try, the Dutch government. You can't outsource your coding needs to stack exchange. Jan 19 at 22:35
• The original code isn't actually bad though, it's actually very readable Jan 20 at 7:08

# JavaScript (Node.js), 53 bytes

f=(n,i=10)=>i?f(n,--i)+(n>=0&n<=i/10?"⚪":"🔵"):''


Try it online!

Need n>=0 to handle NaN

# Scratch, 172 166 142 bytes

This program outputs to a global variable o which is automatically displayed and assumes that the i variable is initialized at 0 and that the procedure will only be run once1. define(n
set[o v]to(
set[a v]to[🔵
repeat(10
change[i v]by(1
if<<(i)>((n)*(10))>and<(-.01)<(n)>>then
set[a v]to[⚪
end
set[o v]to(join(o)(a


Try it on Scratch!

## Scratch, 116 bytes

This solution is technically invalid because it replaces the emojis with the characters "x" and "_". Unfortunately, this method cannot use emojis due to the way strings seem to work in Scratch, as getting the character at a certain index of a string doesn't work for unicode chars. I just wanted to add this since I think it's really cool.

define(n
set[o v]to(
repeat(10
change[i v]by(1
set[o v]to(join(o)(letter((1)+<<(i)>((n)*(10))>and<(-.01)<(n)>>)of[x_ Try it on Scratch!

1For testing purposes, the procedure is run many times in the scratch link, so o is pushed to an array of test results at the end of each call.

• I thought you had to "say" the output... Jan 24 at 12:35
• Also note that the set blocks are in the format set[var v]to() Jan 24 at 12:40
• @UndoneStudios set[var v]to() doesn't produce the correct result in Scratchblocks, while set(v)to() does. Not sure about the "say" thing, I can change it if that's necessary Jan 24 at 21:47
• See this: i.stack.imgur.com/ioudR.png Jan 25 at 7:54
• @Jacob feel free to make a post in the default IO methods post linked above to suggest that Jan 25 at 14:43

# Type System (TypeScript 4.9.4) - 243 188 Bytes

Now they can validate their function with type safety!

• 56 Bytes thanks to @ASCII-only

• 8 Bytes thanks to @ASCII-only

• 114 Bytes only by @ASCII-only (without rounding)

type H<N,C=[],E={length:N},I='🔵',L=C['length'],D=(${N}extends${}e-${}?'0.0':${N}.0)extends0.${L}.0|0.${E['length']}${string}?'⚪':I>=${D}${L extends 9?'':H<N,[...C,0],C,D>}  Example usage: type ProgressBarZero = H<0> type ProgressBarHalf = H<0.5> type ProgressBarFull = H<1>  (Original) Un-golfed Version: type LoadingBar< // N is a given number N extends number, // AddOne is used to add 1 to a number since we can't use addition =1, =2, =10 etc. AddOne extends number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], // Progress is calculated by checking if N is 0 if so return 0, otherwise cast to string and extract first digit after 0.(M)(R...) // and cast to a number along with anything else after R. If R is an empty string '' then we can just return M since this means // it must be .(1)(0), .(2)(0), .(3)(0), etc. otherwise we use M to index V to add one. Progress = N extends 0 ? 0 : ${N} extends 0.${infer M extends number}${infer R} ? R extends '' ? M : AddOne[M] : 10,
// ArrayCounter is an empty tuple which is used to count the iterations by tracking the length and appending
// elements recursively.
ArrayCounter extends any[] = [],
// IsLoading is a cached flag to help denote when to display ⚪ or 🔵 since we can only check for equality and not less than
// or greater than we need to be able to keep track of when we are finished showing the percent loaded.
// OutputString is our output string which we return at the end.
OutputString extends string = '',
// Length tracks the length of A each pass.
Length extends number = ArrayCounter['length'],
// Check if we have loaded all the 🔵 elements by checking if our Length is equal to our Progress
// Symbol is which string to display and in order to check for "never" we need to compare [never] inside a tuple
// otherwise it becomes distributive, also [never] = 
Symbol extends string = [CheckIsLoaded] extends  ? '⚪' : '🔵'
> =
// Here is the logic portion: if our Length is 10 we are finished and return the OutputString
Length extends 10 ?  OutputString :
// Otherwise call recursively adding a new element to ArrayCounter each time to keep of the iterations
// we can only keep track of the tuple ArrayCounter'ss length and not strings.
LoadingBar<N, AddOne, Progress, [...ArrayCounter, Symbol], CheckIsLoaded, ${OutputString}${Symbol}>


Try it on the TypeScript playground!

• I'm a big fan of TS types in codegolf lol. Nice answer Jan 21 at 15:12
• @Jacob it's quite fun to use, not having basic arithmetic forces some different ways of problem solving! Jan 21 at 20:05
• 243 by inlining V Jan 22 at 8:10
• 178? Jan 22 at 8:21
• half the golfs were me just removing stuff and seeing nothing break... chances are it's now broken somewhere Jan 22 at 8:23

# Java (JDK), 70 bytes

p->{var s="";for(int i=0;i<=9;)s+=p<0|p>i++*.1?"🔵":"⚪";return s;}


Try it online!

Don't hesitate to correct me, or ask me if this needs explanations!

I've really tried to do this challenge using alternative approaches, but it could never beat the good ol' for :(

Here are my other attempts so far :

Using the repeat available in Java 11+ (80 bytes) :

p->{int n=(int)(10-(p<0|p>1?1:p)*10);return"🔵".repeat(10-n)+"⚪".repeat(n);}


Using a single inline Stream (85 bytes) :

p->"0123456789".chars().mapToObj(e->p<0|p*10>e-48?"🔵":"⚪").reduce("",(a,b)->a+b)


Creating a 11-bits binary (the "1" to the left end is to protect the "ten zeroes" case) and mapping 1's as 🔵, and 0's as ⚪ (111 bytes) :

p->Integer.toString(2048-(1<<(int)(10-(p<0|p>1?1:p)*10)),2).substring(1).replace("0","⚪").replace("1","🔵")


Creating a number of exactly 10 digits composed exclusively of 9's mapped as 🔵, and 8's mapped as ⚪ (112 bytes) :

p->(""+(long)(Math.pow(10,10)-Math.pow(10,(int)(10-(p<0|p>1?1:p)*10))/9)).replace("8","⚪").replace("9","🔵")


Dirty recursion with optional parameter to match original function call signature (113 bytes) (fails if called without parameter) :

String f(Double... p){return p.length<2?f(p,10d):p>0?f(p,--p)+(p<0|p>p*.1?"🔵":"⚪"):"";}

• Welcome to Code Golf, and nice answer! If the Streams answer was interesting, you should totally include it; even if it's less golfy now, someone might find a way to make it competitive, and we like creative solutions here anyway :p Jan 23 at 17:23
• Thank you @RydwolfPrograms ! I added my other solutions, for the science and/or the funniness of it :) Jan 24 at 10:53

# Japt, 34 bytes

*A c mA         : multiply input by 10, round up to nearest whole n, max of this and 10. Store this result in U
<0?A:U          : If U is negative, 10, else U. Store in V
"🔵"pV +"⚪"pVnA : Blue dot repeated V times, white dot repeated 10-V times
: Implicit output


Try it

## Japt-E"🔵🔵🔵🔵🔵🔵🔵🔵🔵🔵", 24 bytes + 13 = 37

-E"s" implicitly outputs "s" if an error is thrown, but is considered a cheating flag.

*A c            : Multiply input by 10, round up to whole number. Store in U
"🔵"pU +"⚪"pUnA : Blue dot repeated U times, white dot repeated 10-V times
: Implicit: Output that, or 10 dots if (0 < input < 1) is false


Try it

# C(gcc/clang) 86 characters (126 bytes)

returns a constant string of 30 bytes, same as the original and not a null terminated string as is common in C.

const char*p(double f){return"●●●●●●●●●●○○○○○○○○○○"+3*(int)(10.5-10*(f>1?1:f<0?1:f));}

const char*p(double f){
return "●●●●●●●●●●○○○○○○○○○○" //the constant string we index into
+3*                           //each character is three bytes
(int)(                        //pointers must be integers
10.5                      //constant offset handling centering and rounding
-10*(                     //multiply up from the range 0->1 to
f>1?1:f<0?1:f         //correctly enforce the bounds
)
);
}

• Welcome to Code Golf, and nice answer! Jan 20 at 14:19
• 64 bytes Jan 20 at 16:34

# R, 48 bytes

function(i)intToUtf8(9898+118411*(0:9<10*i|i<0))


Try it online!

## Excel formula, 58 82 104 bytes

-22 bytes thanks to @DominicvanEssen massive optimizations !

-24 bytes thanks to @TaylorAlexRaine even more massive optimization !

=LEFT(REPT("🔵",-INT(-10*A1^(A1>=0)))&REPT("⚪",10),10)


Put the formula in any cell, and the parameter in the "A1" cell

Alternative solution : Creating a number of exactly 10 digits composed exclusively of 9's mapped as 🔵, and 8's mapped as ⚪ (82 bytes) :

=SUBSTITUTE(SUBSTITUTE(10^10-1-INT(10^INT(10*(1-A1^(A1>=0)))/9),9,"🔵"),8,"⚪")

• 86 bytes: =REPT("🔵",10-INT(10*MAX(IF(A1<0,,1-A1),)))&REPT("⚪",INT(10*MAX(IF(A1<0,,1-A1),))) Jan 24 at 16:16
• 82 bytes: =REPT("🔵",10-INT(10*MAX(1-A1^(A1>=0),)))&REPT("⚪",INT(10*MAX(1-A1^(A1>=0),))) Jan 24 at 17:21
• 53 char, 58 bytes=LEFT(REPT("🔵",-INT(-10*A1^(A1>=0)))&REPT("⚪",10),10) Feb 24 at 3:23
• @TaylorAlexRaine Very impressive! You know some really cool Excel tricks :) Feb 24 at 8:59
• I do :D And I have written up a good bit about golfing both in Excel and VBA on their respective tips page. You might want to check them out Feb 25 at 3:59

# PowerShell Core, 59 bytes

param($a)-join(0..9|%{("⚪","🔵")[$a-lt0-or$_-lt$a*10]})


Try it online!

Fixed the behaviour for negative values, thanks Adám!

• Seems to fail on -0.1
Jan 19 at 22:30

# VyxalU, 24 bytes

01?ŀ¬∨:⌐"₀*⌈ǐẏḭ≈≠ṙ₅½*∑


Try it Online!

Utf-8 emojis amiright

## Vyxal, 16 bytes

01?ŀ[₀*⌊×*₀↲|×₀*


Try it Online!

Uses * for 🔵 and   for ⚪, otherwise I'd have to score this in utf 8.

• 24 for #1 Jan 19 at 22:48

# C# (.NET 7), 72 bytes

string a(double b,double c=0)=>c<.9?(b<0|b>c?"🔵":"⚪")+a(b,c+.1):"";


Try it here!

string a(double b,double c=0) =>  //return
c<.9                           //if counter is less than .9
?                             //then
(                         //this "X"
b<0|b>c               //if the percentage is less less than 0 or greater than the counter
?                     //then
"🔵"              //blue ball
:                     //otherwise
"⚪"              //white ball
)                         //end "X"
+                         //plus
a(b,c+.1)                 //the result of calling the same function again with the counter increased by .1
:                             //otherwise (counter is greater than or equal to 1)
"";                       //return an empty string


# Python, 55 bytes

-4 bytes thanks to l4m2 and -15 bytes thanks to Dominic van Essen.

lambda n:(10-(b:=int(10-10*n)*(0<=n<1)))*'🔵'+b*'⚪'


Attempt This Online!

• Why neec //1?
– l4m2
Jan 21 at 0:21

# APL(Dyalog Unicode), 37 bytes SBCS

Tacit function.

⎕UCS 128309 9898/⍨10(⊢,-)∘⌈10×1⌊|+0∘>


Try it on APLgolf!

0∘> is argument negative? (0 or 1)

|+ add that to the absolute value of the argument

10× multiply 10 by that

10()∘⌈ round up and then, with 10 as left argument, apply the following function:

- difference between the arguments

⊢, prepend the left argument

128309 9898/⍨ use those counts to replicate the code points

⎕UCS  convert to characters

# Pip, 33 30 bytes

Y!@a?-:-a///tt'🔵Xy.'⚪Xt-y


Attempt This Online!

### Explanation

I've replaced 🔵 and ⚪ with @ and o below so the columns will line up.

Y!@a?-:-a///tt'@Xy.'oXt-y
a                      ; Command-line argument
@                       ; Get the first character
!                        ; Negate (truthy for 0, falsey for anything else)
?                     ; If that is truthy (which means 0.0 <= a < 1.0):
-a                 ;  Negate a
//               ;  Int-divide (rounding down) by
/t             ;  1/10
;  (i.e. multiply by 10 and round down)
-:                   ;  Negate the result
; Else:
t            ;  10
Y                         ; Yank that value into y
'@Xy        ; String of y copies of @ character
'oXt-y ; String of 10-y copies of o character
.       ; Concatenate the two strings

• Funny how ! is truthy for 0 and 0.0, but falsey for -0 or -0.0. Not really valid inputs, but just something I noticed. Jan 20 at 8:35

# 05AB1E, 19 bytes

•
#*Γ•6ôç9ÝT/I@Id*è


Output as a list of characters, since strings are basically sequences of characters. But since the challenge does ask to mimic the output exactly, a trailing Join could be added for +1 byte.

Explanation:

•\n#*Γ•    # Push compressed integer 1283099898
6ô  # Split it into parts of size 6: [128309,9898]
ç # Convert both to a character with this codepoint: ["🔵","⚪"]
9Ý         # Push list [0,1,2,3,4,5,6,7,8,9]
T/       # Divide each by 10: [0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9]
I@         # Check for each value in the list whether it's >= the input
I        # Push the input-decimal again
d       # Check that it's non-negative (1 if >=0; 0 if <0)
*      # Multiply that to each check, so negative inputs will become a list of 0s
è     # 0-based index each 0 or 1 into the pair of unicode characters
# (after which the list of characters is output implicitly as result)


See this 05AB1E tip of mine (section How to compress large integers?) to understand why •\n#*Γ• is 1283099898.

# C# (Visual C# Interactive Compiler), 69 bytes

void a(double b){for(int c=0;c<10;)Write(b<0|b*10>c++?"🔵":"⚪");}


Try it online!

Iterative Solution

# C# (Visual C# Interactive Compiler), 71 bytes

string a(double b,int c=0)=>c<10?(b<0|b*10>c?"🔵":"⚪")+a(b,++c):"";


Try it online!

Recursive Solution

• +1 for golfing their C# code in C# Jan 21 at 15:15

# Swift, 70 84 bytes

-2 bytes thanks to @hatcyl suggestion

var f={i in(0...9).map{i<0||i>Float($0)/10 ?"🔵":"⚪️"}.joined()}  Try it online! • Flip the >= and <= to get rid of the = and save two bytes! ( Will also have to change to an || and flip the balls around.) Jan 21 at 19:08 • @hatcyl i edited it with your suggestion, thanks! Jan 22 at 21:26 # JavaScript 6260 57 bytes ## Update. 57 bytes Slitly shorter version using [...1e9+''] to generate an array of 10 elements instead of [...Array(10)] i=>[...1e9+''].map((_,b)=>i<0|b<i*10?'🔵':'⚪').join  f=i=>[...1e9+''].map((_,b)=>i<0|b<i*10?'🔵':'⚪').join const testCases = [-2, 0, 0.01, 0.20, .666, 0.9, 0.99, 1, 10, NaN]; testCases.forEach(i => console.log(f(i), i)) .as-console { background-color: grey !important; } ## Older version Thank to @RydwolfPrograms for the join tip. Non recursive solution.  i=>[...Array(10)].map((_,b)=>i<0|b<i*10?'🔵':'⚪').join  This solution does not handle a NaN parameter. • Welcome to Code Golf, and nice answer! You can save two bytes by replacing .join('') with .join Jan 25 at 15:55 • @RydwolfPrograms what is this witchery Jan 25 at 16:09 • @RydwolfPrograms: I love that! Jan 25 at 16:09 • @Seggan You can prepend a function to a template string which acts as a preprocessor for it. E.g., String.raw. But if there's no ${...} parts, the function just gets passed ["..."] where ... is the string's contents (IIRC without escapes processed? doesn't matter here; edit: nvm). Most built-in methods will implicitly stringify that, joining it by ,, which since it's a single element array, just gives the original string. It's so cursed. Jan 25 at 17:40
• @RydwolfPrograms i knew js is worse than python Jan 25 at 18:23

# Perl, 52 54 bytes

Edit : Change condition with >=&<= to handle NaN + add note

sub k($c){join'',map$c>=0&$c<=$_/10?"⚪":"🔵",0..9}


Try it online!

#### Note

It is possible to remove the join part, because Perl default behavior when you print an array is to join it, but it feel cheaty. What you guys think ?

##### Perl Cheaty version - 47 Bytes
sub k($c){map$c>=0&$c<=$_/10?"⚪":"🔵",0..9}


Try it online!

It uses "signatures 15 years beta" feature (activable via commande line -Mfeature=signature) or via import. The old school perl take 2 bytes more :

sub j{join'',map@_<0|@_>$_/10?"🔵":"⚪",0..9}  #### Explaination : sub j{ join ('', # Join each element of a list with the string ''. map( # Return a list of what the block return for each element of the list passed in second argument {@_<0|@_>$_/10?"🔵":"⚪"} , #@_ is the function first parameter, $_ the current iterated element (0..9)) # Simple list }  ### Other interesting solution : ### The substr 61|59(signatures) Bytes, probably fastest and lightest solution, (OK NaN) sub b{substr'🔵'x(10).'⚪'x(10-(@_<0?10:@_*10)),-10} sub p($c){substr'🔵'x(10).'⚪'x(10-($c<0?10:$c*10)),-10}


### The for loop 55|57 Bytes

Work only once, dunno if it can be improve without too many bytes (KO NaN):

sub l($c){$a.=($c<0|$c>$_/10?"🔵":"⚪")for 0..9;$a}


### Recursive 81|62 Bytes

Not very interesting at first, juste a copy cat of JS. But i run into a small bug on the "old perl" version (KO NaN):

sub a{(@_//=10)?a(@_,@_-1).(@_<0|@_>(@_-1)/10?"🔵":"⚪"):''}
sub t($n,$i=10){$i?t($n,--$i).($n<0|$n>$i/10?"🔵":"⚪"):''}


I expected this to work :

sub z{(@_//=10)?z(@_,--@_).(@_<0|@_>(@_)/10?"🔵":"⚪"):''}


But it does not. --@_1 do not work and i dont understand why.

# Julia 0.6, 49 bytes

~x=rpad("🔵"^ceil(Int,10(0<=x<1?x:1)),20,"⚪")


Try it online!

If the input x falls outside the range [0,1), it's replaced with 1. The value ⌈10x⌉ determines the number of "🔵", and the output is padded to length with "⚪".

Using the ternary operator without spaces is deprecated in Julia 0.7 and disabled in Julia 1.0. The padding length passed to rpad has to be adjusted for Julia 0.6, probably because textwidth was added in Julia 0.7.

# Jelly, 19 bytes

>⁵Ḷ÷¤»⁻A$ị“¢€:“&Ɠ’Ọ  A monadic Link that accepts a double precision floating point number and yields a list of characters. Try it online! Or see the test-suite. ### How? >⁵Ḷ÷¤»⁻A$ị“¢€:“&Ɠ’Ọ - Link: double D
⁵                  -   ten
Ḷ                 -   lowered range -> [0, 1, 2, ..., 9]
÷                -   divided by (ten) -> [0, 0,1, 0.2, ..., 0.9]
>                   - (D) greater than (that) (vectorised) -> G
$- last two links as a monad - f(D): A - absolute value (D) ⁻ - (D) not equal to (that)? -> K (K = (x<0 or x is nan)?) » - (G) maximum (K) (vectorised) -> L = list with 1 at blue and 0 at white “¢€:“&Ɠ’ - list of base 250 compressed numbers = [128309, 9898] ị - (L) index into (that) (vectorised) Ọ - cast to characters  # Retina 0.8.2, 67 bytes ^[^0]|^0.9. 10$*@
T_dd....
\d(..)?
$1$*@10$*⚪ 1M!.{10} @ 🔵  Try it online! Link includes test cases. Explanation: ^[^0]|^0.9. 10$*@


Unless the input is from 0 to 0.9 inclusive, put 10 @s at the start. (I use @ as it's a single UTF-16 character and 🔵 isn't.)

T_dd....


Increment the digits if there are at least three (not including the decimal point) i.e. leave 0, 0.1 ... 0.9.

\d(..)?.*
$1$*@10$*⚪  Convert the number of tenths (if any) into @s and also add 10 ⚪s. 1M!.{10}  Keep just the first 10 characters. This removes any surplus ⚪s and also spurious @s or ⚪ arising from later digits. @ 🔵  Turn @s into 🔵s. • Can you save any bytes by assuming that 0 will always be entered in the form 0.0? Jan 20 at 16:57 • @DLosc Well I already assume it won't be entered in the form 0.00 but technically yes, I could save a byte. – Neil Jan 20 at 17:36 # Factor, 56 bytes [| x | 10 iota [ x 10 * < x 0 < or 128309 9898 ? ] map ]  Try it online! [| x | ! a quotation taking an argument x 10 iota ! the range [0..9] [ ! start map quotation x 10 * < ! is the range number less than x times ten? x 0 < or ! or is x less than zero? 128309 9898 ? ! 128309 if so; 9898 if not ] map ! map each number in the range to something ] ! end quotation  # Arturo, 54 bytes $[x][join map 0..9'n[(or? n<x*10x<0)?->"🔵"->"⚪"]]


Try it

\$[x][                 ; a function taking an argument x
join                ; join a block of strings into a string
map 0..9'n[         ; map over 0..9 and assign current element to n
(or? n<x*10x<0)?  ; is n<x*10 or x<0?
->"🔵"            ; blue orb if so
->"⚪"            ; white orb if not
]                   ; end map
]                     ; end function


# C (gcc) with -lm, 86 85 Unicode characters (91 90 bytes)

• -1 thanks to ceilingcat

Converts the value to an integer to avoid floating-point rounding issues. Although float would be sufficient for this task, the original specified a double, so I used that type instead.

b,c;f(double a){for(b=c=fmin(a<0?:a,1)*10;b--;)printf("🔵");for(;c++<10;)printf("⚪");}


Try it online!

# JavaScript, 68 bytes

Without recursion:

(p,i=0)=>'⚪'.repeat(10).replace(/⚪/g,e=>p>=0&i++>=p*10?e:'🔵')


Try it:

f=(p,i=0)=>'⚪'.repeat(10).replace(/⚪/g,e=>p>=0&i++>=p*10?e:'🔵')

console.log(f(-2));
console.log(f(0));
console.log(f(1));
console.log(f(2));
console.log(f(0.1));
console.log(f(0.4));
console.log(f(0.68));
console.log(f(0.9));
console.log(f(0.99));
console.log(f(NaN));
.as-console {
background-color: grey !important;
}

## UPD 96 -> 86

Thanks to mousetail for the tip to reduce bytes count

## UPD 86 -> 70

Thanks to Dominic van Essen for the tip to reduce bytes count

## UPD 70 -> 68

Thanks to Rydwolf Programs for the tip to reduce bytes count

• You could save some bytes by switching the blue and white circles, since the blue ones are 4 bytes in UTF-8 while the white ones are just 3 Jan 25 at 12:37
• @mousetail Thank you! Next time I will check things like this :) Jan 25 at 13:24
• You could even use '⚪'.repeat(10) instead of '⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪' to save some more (16?) bytes... Jan 25 at 13:28
• @DominicvanEssen Yes you are right but in this case I must use 63 chars instead of 61. Because of "Write code in any language as short as possible" I didn't use this Jan 25 at 13:35
• That's a valid point! Although, in general, we tend to measure the 'shortness' of 'code golf' answers in bytes, rather than in characters, unless explicitly specified otherwise. Jan 25 at 13:43

# Japt-P, 22 bytes

AÇ¨A*U©ÎÌ?9898d:# 309d


Try it

AÇ¨A*U©ÎÌ?9898d:# 309d     :Implicit input of float U
A                          :10
Ç                         :Map the range [0,A)
¨A*U                     :  Is greater than or equal to A*U
Î                   :    Sign of U
Ì                  :    Sign of difference with -1
?                 :  If true
9898d            :    Character at codepoint 9898
:           :  Else
# 309d     :    Character at codepoint 128309
:Implicitly join and output

• Note that the useful input is in the range 0-1, not 0-10... Jan 20 at 15:53
• You have the right score up but you are missing a character in the code and description that is there in the interpreter link Mar 24 at 10:36
• That's Stack Exchange stripping that unprintable out, @Jacob; I'll replace it with a space. Mar 24 at 11:23

# Scala, 81 78 bytes

saved 3 bytes thanks to comment.

Try it online!

def f(p:Double):String=(0 to 9).map(i=>if(p<0|p>i*.1)"🔵"else"⚪").mkString


Ungolfed version

object Main {

def f(p: Double): String =
(0 to 9).map(i => if (p < 0 || p > i * 0.1) "🔵" else "⚪").mkString

def main(args: Array[String]): Unit = {
println(f(-10.0))   // expected : 🔵🔵🔵🔵🔵🔵🔵🔵🔵🔵
println(f(-0.01))   // expected : 🔵🔵🔵🔵🔵🔵🔵🔵🔵🔵
println(f(0.0))     // expected : ⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪
println(f(0.001))   // expected : 🔵⚪⚪⚪⚪⚪⚪⚪⚪⚪
println(f(0.1))     // expected : 🔵⚪⚪⚪⚪⚪⚪⚪⚪⚪
println(f(0.11))    // expected : 🔵🔵⚪⚪⚪⚪⚪⚪⚪⚪
println(f(0.5))     // expected : 🔵🔵🔵🔵🔵⚪⚪⚪⚪⚪
println(f(0.9))     // expected : 🔵🔵🔵🔵🔵🔵🔵🔵🔵⚪
println(f(0.91))    // expected : 🔵🔵🔵🔵🔵🔵🔵🔵🔵🔵
println(f(1.0))     // expected : 🔵🔵🔵🔵🔵🔵🔵🔵🔵🔵
println(f(10.0))    // expected : 🔵🔵🔵🔵🔵🔵🔵🔵🔵🔵
}
}

• Nice answer! And nice test cases ;) I think you can replace || with | and 0.1 with .1, and it seems you can remove the space before the else for a total of -3 bytes. I don't know the language so i don't know if there are other optimizations possible Apr 8 at 9:02

# jq, 32 bytes

.*10|["🔵"*.,"⚪"*(10-.)]|add


Try it online!

• Unfortunately, this doesn't work for inputs like 0.71 (output should be 🔵🔵🔵🔵🔵🔵🔵🔵⚪⚪) or 2.0 (output should be 🔵🔵🔵🔵🔵🔵🔵🔵🔵🔵). Jan 20 at 0:06
• @DLosc Thanks; you're right of course. I completely overlooked that bit. Jan 20 at 0:21
• This doesn't seem to work for negative values or values above 1 (both need to result in 10 blue balls). Jan 20 at 8:27

# Charcoal, 21 bytes

Ｎθ⭆χ§⚪🔵‹ι×χ∨‹θ⁰θ


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

Ｎθ                  First input as a number
χ                Predefined variable 10
⭆                 Map over implicit range and join
⚪🔵             Literal string ⚪🔵
§               Indexed by
ι           Current value
‹            Is less than
χ         Predefined variable 10
×          Multiplied by
θ      Input number
‹       Is less than
⁰     Literal integer 0
∨        Logical Or
θ    Input number
Implicitly print


Although ⚪ and 🔵 are not in Charcoal's code page it can still represent them using special byte sequences which take 3 and 4 bytes respectively as you can see in its xxd-style dump: Try it online!