23
\$\begingroup\$

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.
\$\endgroup\$
12
  • 5
    \$\begingroup\$ May you substitute the characters of the circles? E.g. replacing 🔵 with x and ⚪ with o or something like that? \$\endgroup\$ Commented Jan 19, 2023 at 22:13
  • 6
    \$\begingroup\$ It needs to be made clearer that values not in the range [0, 1] need to return a full bar of 🔵 \$\endgroup\$
    – lyxal
    Commented Jan 19, 2023 at 22:27
  • 4
    \$\begingroup\$ Yes, please add some test cases that include 0, −0.1, 0.95, 1.0, and 1.1 \$\endgroup\$
    – Adám
    Commented Jan 19, 2023 at 22:28
  • 12
    \$\begingroup\$ Nice try, the Dutch government. You can't outsource your coding needs to stack exchange. \$\endgroup\$ Commented Jan 19, 2023 at 22:35
  • 6
    \$\begingroup\$ The original code isn't actually bad though, it's actually very readable \$\endgroup\$
    – mousetail
    Commented Jan 20, 2023 at 7:08

33 Answers 33

13
\$\begingroup\$

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

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

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_

enter image description here

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.

\$\endgroup\$
12
  • \$\begingroup\$ I thought you had to "say" the output... \$\endgroup\$ Commented Jan 24, 2023 at 12:35
  • \$\begingroup\$ Also note that the set blocks are in the format set[var v]to() \$\endgroup\$ Commented Jan 24, 2023 at 12:40
  • \$\begingroup\$ @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 \$\endgroup\$ Commented Jan 24, 2023 at 21:47
  • \$\begingroup\$ See this: i.sstatic.net/ioudR.png \$\endgroup\$ Commented Jan 25, 2023 at 7:54
  • 1
    \$\begingroup\$ @Jacob feel free to make a post in the default IO methods post linked above to suggest that \$\endgroup\$
    – mousetail
    Commented Jan 25, 2023 at 14:43
9
\$\begingroup\$

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`)extends`0.${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 [0]=1, [1]=2, [9]=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.
  IsLoading extends number = 1,
  // 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
  CheckIsLoaded extends number = (Progress extends Length ? 0 : 1) & IsLoading,
  // 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] = [0]
  Symbol extends string = [CheckIsLoaded] extends [0] ? '⚪' : '🔵'
> =
  // 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
  // using EndLoading as the new IsLoading and concatinating Symbol to OutputString. Unfortunately,
  // 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!

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

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,"⚪")
\$\endgroup\$
6
  • 1
    \$\begingroup\$ 86 bytes: =REPT("🔵",10-INT(10*MAX(IF(A1<0,,1-A1),)))&REPT("⚪",INT(10*MAX(IF(A1<0,,1-A1),))) \$\endgroup\$ Commented Jan 24, 2023 at 16:16
  • 1
    \$\begingroup\$ 82 bytes: =REPT("🔵",10-INT(10*MAX(1-A1^(A1>=0),)))&REPT("⚪",INT(10*MAX(1-A1^(A1>=0),))) \$\endgroup\$ Commented Jan 24, 2023 at 17:21
  • 1
    \$\begingroup\$ 53 char, 58 bytes=LEFT(REPT("🔵",-INT(-10*A1^(A1>=0)))&REPT("⚪",10),10) \$\endgroup\$ Commented Feb 24, 2023 at 3:23
  • 1
    \$\begingroup\$ @TaylorAlexRaine Very impressive! You know some really cool Excel tricks :) \$\endgroup\$
    – Fhuvi
    Commented Feb 24, 2023 at 8:59
  • 1
    \$\begingroup\$ 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 \$\endgroup\$ Commented Feb 25, 2023 at 3:59
7
\$\begingroup\$

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+ (78 bytes) :

p->{int n=(int)(p<0|p>1?0:10-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 ⚪ (109 bytes) :

p->Integer.toString(2048-(1<<(int)(p<0|p>1?0:10-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 ⚪ (110 bytes) :

p->(""+(long)(Math.pow(10,10)-Math.pow(10,(int)(p<0|p>1?0:10-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[0],10d):p[1]>0?f(p[0],--p[1])+(p[0]<0|p[0]>p[1]*.1?"🔵":"⚪"):"";}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ 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 \$\endgroup\$ Commented Jan 23, 2023 at 17:23
  • 2
    \$\begingroup\$ Thank you @RydwolfPrograms ! I added my other solutions, for the science and/or the funniness of it :) \$\endgroup\$
    – Fhuvi
    Commented Jan 24, 2023 at 10:53
6
\$\begingroup\$

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

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

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
        )
    );
}
\$\endgroup\$
2
  • \$\begingroup\$ Welcome to Code Golf, and nice answer! \$\endgroup\$ Commented Jan 20, 2023 at 14:19
  • \$\begingroup\$ 64 bytes \$\endgroup\$
    – ceilingcat
    Commented Jan 20, 2023 at 16:34
6
\$\begingroup\$

R, 48 bytes

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

Try it online!

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

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!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Seems to fail on -0.1 \$\endgroup\$
    – Adám
    Commented Jan 19, 2023 at 22:30
5
\$\begingroup\$

Vyxal U, 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.

\$\endgroup\$
1
  • \$\begingroup\$ 24 for #1 \$\endgroup\$
    – emanresu A
    Commented Jan 19, 2023 at 22:48
5
\$\begingroup\$

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
\$\endgroup\$
0
5
\$\begingroup\$

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!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Why neec //1? \$\endgroup\$
    – l4m2
    Commented Jan 21, 2023 at 0:21
5
\$\begingroup\$

JavaScript 62 60 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.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Welcome to Code Golf, and nice answer! You can save two bytes by replacing .join('') with .join`` \$\endgroup\$ Commented Jan 25, 2023 at 15:55
  • \$\begingroup\$ @RydwolfPrograms what is this witchery \$\endgroup\$
    – Seggan
    Commented Jan 25, 2023 at 16:09
  • \$\begingroup\$ @RydwolfPrograms: I love that! \$\endgroup\$
    – rougepied
    Commented Jan 25, 2023 at 16:09
  • \$\begingroup\$ @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. \$\endgroup\$ Commented Jan 25, 2023 at 17:40
  • \$\begingroup\$ @RydwolfPrograms i knew js is worse than python \$\endgroup\$
    – Seggan
    Commented Jan 25, 2023 at 18:23
4
\$\begingroup\$

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

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

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
\$\endgroup\$
1
  • \$\begingroup\$ 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. \$\endgroup\$ Commented Jan 20, 2023 at 8:35
4
\$\begingroup\$

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
\$\endgroup\$
4
\$\begingroup\$

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.

Try it online or verify all test cases.

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.

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

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

\$\endgroup\$
1
  • \$\begingroup\$ +1 for golfing their C# code in C# \$\endgroup\$ Commented Jan 21, 2023 at 15:15
4
\$\begingroup\$

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!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Flip the >= and <= to get rid of the = and save two bytes! ( Will also have to change to an || and flip the balls around.) \$\endgroup\$
    – hatcyl
    Commented Jan 21, 2023 at 19:08
  • \$\begingroup\$ @hatcyl i edited it with your suggestion, thanks! \$\endgroup\$ Commented Jan 22, 2023 at 21:26
4
\$\begingroup\$

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]<0|@_[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]<0|@_[0]>$_/10?"🔵":"⚪"} , #@_[0] 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]<0?10:@_[0]*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{(@_[1]//=10)?a(@_[0],@_[1]-1).(@_[0]<0|@_[0]>(@_[1]-1)/10?"🔵":"⚪"):''}
sub t($n,$i=10){$i?t($n,--$i).($n<0|$n>$i/10?"🔵":"⚪"):''}

I expected this to work :

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

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

\$\endgroup\$
1
  • \$\begingroup\$ This site is one place where using "cheaty" tricks and language abuse is OK :) \$\endgroup\$
    – roblogic
    Commented Jul 25, 2023 at 6:17
4
\$\begingroup\$

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.

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

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
    ¤               - nilad followed by link(s) as a nilad:
 ⁵                  -   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
\$\endgroup\$
3
\$\begingroup\$

Retina 0.8.2, 67 bytes

^[^0]|^0.9.
10$*@
T`_d`d`....
\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`_d`d`....

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.

\$\endgroup\$
2
  • \$\begingroup\$ Can you save any bytes by assuming that 0 will always be entered in the form 0.0? \$\endgroup\$
    – DLosc
    Commented Jan 20, 2023 at 16:57
  • \$\begingroup\$ @DLosc Well I already assume it won't be entered in the form 0.00 but technically yes, I could save a byte. \$\endgroup\$
    – Neil
    Commented Jan 20, 2023 at 17:36
3
\$\begingroup\$

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
\$\endgroup\$
3
\$\begingroup\$

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!

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

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

\$\endgroup\$
10
  • 2
    \$\begingroup\$ 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 \$\endgroup\$
    – mousetail
    Commented Jan 25, 2023 at 12:37
  • \$\begingroup\$ @mousetail Thank you! Next time I will check things like this :) \$\endgroup\$
    – EzioMercer
    Commented Jan 25, 2023 at 13:24
  • 1
    \$\begingroup\$ You could even use '⚪'.repeat(10) instead of '⚪⚪⚪⚪⚪⚪⚪⚪⚪⚪' to save some more (16?) bytes... \$\endgroup\$ Commented Jan 25, 2023 at 13:28
  • \$\begingroup\$ @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 \$\endgroup\$
    – EzioMercer
    Commented Jan 25, 2023 at 13:35
  • \$\begingroup\$ 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. \$\endgroup\$ Commented Jan 25, 2023 at 13:43
3
\$\begingroup\$

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
      ©                    :  Logical AND with
       Î                   :    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
\$\endgroup\$
3
  • \$\begingroup\$ Note that the useful input is in the range 0-1, not 0-10... \$\endgroup\$ Commented Jan 20, 2023 at 15:53
  • \$\begingroup\$ You have the right score up but you are missing a character in the code and description that is there in the interpreter link \$\endgroup\$ Commented Mar 24, 2023 at 10:36
  • 1
    \$\begingroup\$ That's Stack Exchange stripping that unprintable out, @Jacob; I'll replace it with a space. \$\endgroup\$
    – Shaggy
    Commented Mar 24, 2023 at 11:23
3
\$\begingroup\$

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 : 🔵🔵🔵🔵🔵🔵🔵🔵🔵🔵
  }
}
\$\endgroup\$
1
  • 1
    \$\begingroup\$ 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 \$\endgroup\$
    – Fhuvi
    Commented Apr 8, 2023 at 9:02
2
\$\begingroup\$

Charcoal, 21 bytes

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

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

Nθ                  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!

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

Nibbles, 22.5 bytes (45 nibbles)

+.*10`,10=`$?@]~-$@@%`D-256~f09f94b500e29aaa

Nibbles uses only integers, so input to the 'getpercentagerounds' function is a percentage value 0-100 (and values outside this range mimic the behaviour of the digid-app reference implementation).

Nibbles also doesn't natively handle multibyte characters, but here we work around this by outputting multi-character strings that re-create the encoding of the multibyte "🔵" and "⚪" characters.

enter image description here

Note that if we take input as integers in the range 0-10 (and handling values outside this appropriately), the Nibbles code can be reduced to 19.5 bytes (39 nibbles: .,10=`$?@/$@@%`D-256~f09f94b500e29aaa) but this doesn't seem a very faithful match to the input/output of the digid-app reference function.

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