# Fractional Unicode Bars

Your program should take as input a number n that is greater than 0 and output a bar composed of n // 8 ▉ characters (U+2588), as well as a final character which should be one of ▉ ▊ ▋ ▌ ▍ ▎▏(U+2589 to U+258F) representing n % 8. If n % 8 is 0, your program should not output any additional characters. This is difficult to explain well in text, so here are some examples:

Input: 8
Output: █
Input: 32
Output: ████
Input: 33
Output: ████▏
Input: 35
Output: ████▍
Input: 246
Output: ██████████████████████████████▊


This is , so shortest answer wins.

• what if n%8 == 1? Commented Nov 6, 2022 at 12:58
• @py3_and_c_programmer It looks like U+2589 has been left out of the list; it's probably meant to be there.
– m90
Commented Nov 6, 2022 at 13:07
• Note that the rendering of these characters is quite random (depending on the browser, OS, etc.). They look OK on my mobile and terrible on my laptop. Commented Nov 6, 2022 at 14:09
• Your examples seem to be wrong, with the repeating character being U+2589 instead of U+2588.
– m90
Commented Nov 6, 2022 at 14:25
• @m90 Fixed them, sorry about that Commented Nov 6, 2022 at 15:04

# Excel (ms365), 56 bytes

Formula in B1:

=REPT("█",A1/8)&IF(MOD(A1,8),UNICHAR(9616-MOD(A1,8)),)

• You can leave off the "" in the second part of the IF() if you want it to return blank. Saves 2 bytes. Also, you can get it down to 52 bytes with this alternative: =REPT("█",A1/8)&IFERROR(MID("▏▎▍▌▋▊▉",MOD(A1,8),1),) Commented Nov 7, 2022 at 13:30
• @EngineerToast, thanks for thinking along. I had exactly your 2nd suggestion under copy paste a few hours ago but decided against it. The actual bytecount appeared to be bigger. Chars vs. Bytes is usually the same for Excel, but not the case here with unicode chars.
– JvdV
Commented Nov 7, 2022 at 13:36
• Good point! I was using LEN() which just counts characters no matter how many bytes each is. Commented Nov 7, 2022 at 13:56
• @JvdV - surely this is 57 bytes for 55 characters? Commented Nov 8, 2022 at 22:47
• Woops yes it is @DominicvanEssen. Rollback it is. Sharp eye
– JvdV
Commented Nov 8, 2022 at 23:28

# Julia 0.7, 3532 27 bytes

!n='▐'.-diff((0:8:n)∪n)


Try it online!

Generates a range from 0 to n with step 8, and n itself force-included. Then taking the diff produces our codepoint offsets, e.g. 35 gives 8 8 8 8 3, etc. Returns character arrays.

Analogous solution in R:

# R, 4544 43 bytes

\(n)intToUtf8(9616-diff(c(0:(n/8-.1)*8,n)))


Attempt This Online!

Thanks to amelies and MarcMush for -3 and -5 on Julia and pajonk for -1 on R.

• -3 using union Unicode operator !n=Char.(9616-diff((0:8:n)∪n)) Commented Nov 6, 2022 at 22:16
• -5 by using the literal Char Try it online! Commented Nov 8, 2022 at 21:06

# Jelly, 8 bytes

s8Ẉ⁽"s_Ọ


A monadic Link that accepts a non-negative integer and yields a list of characters.

Try it online!

### How?

s8Ẉ⁽"s_Ọ - Link: integer, n   e.g. 17
8       - eight
s        - split (implicit [1..n]) into chucks of length (8)
[[1..8],[9..16],[17]]
Ẉ      - length of each          [8,8,1]
⁽"s   - 9616
_  - subtract (vectorises)   [9608,9608,9615]
Ọ - cast to characters      ['█','█','▏']


# Python 3, 43 41 36 bytes

lambda n:~-n//8*'▉'+chr(9608-n%-8)


Try it online! (Fails for n=0)

• -2 thanks to 97.100.97.109
• -5 thanks to loopy walt

(Note: 9608 is the decimal value of 0x2588)

• 41 bytes Commented Nov 6, 2022 at 16:22
• @97.100.97.109 - thanks. I think you meant n%8>0 rather than n%8>1. Commented Nov 6, 2022 at 17:04
• Whoops, you're right. Commented Nov 6, 2022 at 18:36
• 36 bytes. Fails for n=0 but that seems ok per OP. Commented Nov 6, 2022 at 19:25

# x86-64 machine code, 18 16 bytes

AB B8 88 25 00 00 83 EE 08 77 F5 29 F0 48 AB C3


Try it online!

Following the standard calling convention for Unix-like systems (from the System V AMD64 ABI), this takes in RDI an address at which to place the result, as a null-terminated UTF-32 string, and takes the number n in ESI. The starting point is after the first byte.

In assembly:

r:  stosd           # Write EAX to the string, advancing the pointer.
f:  mov eax, 0x2588 # (Start here) Set EAX to 0x2588.
sub esi, 8      # Subtract 8 from the input number in ESI.
ja r            # Jump back if the number was greater than 8.
sub eax, esi    # Subtract ESI from EAX, increasing it by 0 to 7.
stosq   # Write RAX (the 64-bit register containing EAX) to the string,
#  advancing the pointer. Because it's little-endian,
#  the first 32 bits are the value of EAX, and the next 32 bits are 0
#  (as the high bits are zeroed when operating on only EAX)
#  to add the null terminator.
ret             # Return.


# Factor, 66 65 64 46 bytes

[ [1,b] 8 group [ length ] map 9616 v-n vabs ]


Attempt This Online!

• -1 byte from Mama Fun Roll
• -1 more by taking an entirely different approach
• -18(!) by porting Jonathan Allan's amazing Jelly answer.
• Perhaps - neg instead of swap - to save a byte? Commented Nov 6, 2022 at 15:06
• @MamaFunRoll Nice thinking, thanks. Commented Nov 6, 2022 at 15:17

# Charcoal, 14 bytes

⭆⪪×ψＮ⁸℅⁻⁹⁶¹⁶Ｌι


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

   ψ            Predefined variable null byte
×             Repeated by
Ｎ           Input integer
⪪              Split into substrings of maximum length
⁸          Literal integer 8
⭆               Map over substrings and join
ι  Current substring
Ｌ   Length
⁻        Subtract from
⁹⁶¹⁶    Literal integer 0x2590
℅         Convert to Unicode


# JavaScript (Node.js), 50 bytes

-2 thanks to @Neil

f=n=>n?Buffer([226,150,144-(q=n>7?8:n)])+f(n-q):''


Try it online!

### How?

We use Buffer() to build the characters from their UTF-8 encodings.

For instance, the character with code point 9608 (0x2588) is generated with:

Buffer([226,150,136]) // 0xE2, 0x96, 0x88


That's a bit lengthy, but still shorter than the infamous String.fromCharCode(9608).

• You don't need that %8 do you?
– Neil
Commented Nov 6, 2022 at 14:26
• @Neil Which %8 are you talking about? :-p Commented Nov 6, 2022 at 14:29

# R, 5149 46 bytes

\(n)intToUtf8(9616-c(rep(8,n/8),if(b<-n%%8)b))


Attempt This Online!

Still not as golfy as Kirill L's approach, unfortunately...

• It looks like the approach that I took with Julia answer saves a few in R too Commented Nov 6, 2022 at 16:48
• @KirillL. I was just upvoting your beautiful Julia approach when I saw your message! Post your R one yourself (after changing union to c, of course)! Commented Nov 6, 2022 at 17:02
• OK, but c won't work as it will produce a duplicate when the range ends precisely on n, so yours is very close! Commented Nov 6, 2022 at 19:07
• @KirillL. Looks like a workaround to use c may be one byte shorter. Commented Nov 6, 2022 at 20:09

# Vyxal, 12 bytes

ɾ8ẇvL9616εCṅ


Try it Online!

Yet another port of Jonathan Allan's Jelly answer.

# Ruby, 46 36 bytes

->n{?█*(n/8)<<(n%8>0?9616-n%8:"")}


Attempt This Online!

A whopping 10 bytes saved by G B.

# sclin, 25 bytes

O>a8/"len"map9616- _ c>S


Try it here! Port of @Jonathan Allan's clever Jelly answer!

For testing purposes:

[8 32 33 35 246] ( ; n>o ) map
O>a8/"len"map9616- _ c>S


## Explanation

Prettified code:

O>a 8/ \len map 9616- _ c>S


Assuming input n.

• O>a range [0, n)
• 8/ chunk into lengths of max 8
• \len map get lengths of each chunk
• 9616- _ subtract from 9616
• c>S convert to fractional block char

# sclin, 38 bytes

8/%"█"rot ** >o""Q"9616- _ c>S >o"&#


Try it here! Outputs the bars.

For testing purposes:

[8 32 33 35 246] ( ; ""n>o ) map
8/%"█"rot ** >o""Q"9616- _ c>S >o"&#


## Explanation

Prettified code:

8/% "█" rot ** >o dup ( 9616- _ c>S >o ) &#

• 8/% divmod by 8
• "█" rot ** repeat █ <div part> times
• >o output
• dup (...) &# execute if <mod part> is truthy (i.e. greater than 0)...
• 9616- _ c>S convert to fractional block char
• >o output

# Mathematica, 59 bytes

FromCharacterCode[9616-Tr[1^#]&/@Range@#~Partition~UpTo@8]&


View it on Wolfram Cloud!

# ///, 73 bytes

/d/iii//ddii/█//ddi/▉//dd/▊//dii/▋//di/▌//d/▍//ii/▎//i/▏/


Try it online!

Input is a unary.

# Rust, 61 bytes

|n,r|{*r=[9608].repeat((!-n/8)as _);r.push((9615-!-n%8)as _)}


A fn(i32,&mut Vec<u32>), where the first argument is n, and r is a mutable reference to a vector where the output will be stored.

Attempt This Online!

# Retina 0.8.2, 30 bytes

.+
$* 1{1,8}$.&
T8-1▉-▏


Try it online! Link includes test cases. Explanation:

.+
$*  Convert to unary. 1{1,8}$.&


Convert groups of up to 8 to decimal.

T8-1▉-▏


Map digits to the appropriate Unicode character.

# Sequences, 30 bytes

iH8/nx$\▉$""Jfh8%H?9616h-VF:


Sequences was definitely not made for this!

Explained:

iH8/nx$\▉$""Jfh8%H?9616h-VF:
iH                            // Get an integer input and store in h
8/                          // Divide by 8
n                         // Convert to integer (floor)
x                    // This many times:
\▉                     //   Push the string "▉"
// Implicitly put into a list
""J                 // Join by empty strings
f                // Output with no newline
h               // Push h
8%H            // Mod by 8 and store in h
?           // If this is truthy (h != 0)
h      //   Push h
9616 -     //   Subtract from 9616
V    //   Get chr of the result
F   //   Output with a newline
:  // Else: (do nothing)


In Sequences there is no way of multiplying an integer with a string, so we have to settle for making a list of that string, repeated, and then join it by an empty string.

Also, Sequences uses the 96 printable ASCII characters as its codepage, but because we have ▉ in our code, we have to use UTF-8.

f n|n<9=[toEnum$9616-n] f n='█':f(n-8)  Attempt This Online! -4 bytes by ignoring n=0 # Go, 9181 73 bytes func f(n int)(s string){ for;n>8;n-=8{s+="▉"} s+=string(9616-n) return}  Attempt This Online! • -10 bytes by @jdt • -8 bytes by @Neil • 73 bytes by not supporting 0: Attempt This Online! – Neil Commented Nov 8, 2022 at 0:54 # Java 11, 5848 39 bytes n->"█".repeat(--n/8)+(char)(9615-n%8)  -9 bytes thanks to @Neil. Doesn't support n=0. Try it online. Explanation: n-> // Method with integer parameter and String return-type "█".repeat( // Repeat this character --n/8) // n-1 integer-divided by 8 times // (by first decreasing n by 1 with --n) +(char) // Append an integer casted to a character: (9615-n%8) // 9615 minus (n-1 modulo 8)  • 39 bytes by not supporting 0: Try it online! Rough port of latest Python answer. – Neil Commented Nov 8, 2022 at 0:52 # 05AB1E, 1411 10 bytes L8ô€gŽb¶αç  Try it online! (I've put J for join in the footer, but apparently outputting a list of characters is ok) • -3 thanks to Sʨɠɠan • -1 thanks to Kevin Cruijssen ### Explained L8ô€gŽb¶αç # Implicit integer input 17 L # Inclusive range [1, 2, ..., 17] 8ô # Split into groups of 8 [1, ..., 8], [9, ..., 16], [17] €g # Length of each [8, 8, 1] Žb¶ # 9616 α # Absolute difference from 9616 [9608, 9608, 9615] ç # chr of each ["█", "█", "▏"] # Implicit output  • (+( could be s-, but α will work in this case Commented Nov 6, 2022 at 20:54 • 9616 can be compressed to Žb¶ Commented Nov 6, 2022 at 20:56 • Also, you can move the J to the footer, since outputting a string as a list of characters is allowed by default. Commented Nov 7, 2022 at 13:58 • @Sʨɠɠan - thanks. I somehow missed α in the commands page (even though it's right at the top). Commented Nov 7, 2022 at 16:27 • @KevinCruijssen - thanks for the info. I've added that in. Commented Nov 7, 2022 at 16:27 # C (clang), 54 50 bytes -4 bytes thanks to @Neil! f(*o,n){for(;n>8;n-=8)*o++=9608;*o++=9616-n;*o=0;}  Try it online! • 50 bytes by not supporting 0: Try it online! – Neil Commented Nov 8, 2022 at 0:57 # ><>, 43 bytes :8,:1%-v v1-"█"$>:?!
>~{8%:"█"+\$?!~}>o<


Try it online!

# JavaScript (Node.js), 45 bytes

f=n=>n>8?'█'+f(n-8):Buffer([226,150,144-n])


Try it online!

52 bytes without Buffer:

f=n=>n>7?'█'+f(n-8):['▏▎▍▌▋▊▉'[n-1]]


# C (clang), 46 44 bytes

f(*o,n){for(;*o=n>0;*o++=9608-(n<0)*n)n-=8;}


Try it online!

From jdt's solution, support 0

# jq, 43 bytes

[9616-((range(1;./8)|8),(.-1)%8+1)]|implode


Try it online!

# BQN, 23 bytes

@+9608+{𝕩>7?0∾𝕊𝕩-8;7-𝕩}


Try it at BQN REPL

@+9608+{𝕩>7?0∾𝕊𝕩-8;7-𝕩}
{              }  # recursive function 𝕊 with argument 𝕩
𝕩>7?             # if x is greater than 7
0∾           #   prepend zero onto
𝕊𝕩-8       #   result of recursive call with agument 𝕩-8
;      # otherwise
7-𝕩   #   7-𝕩
+                  # now, add the result of this to
@                        #   the null character
+9608                   #   +9608


We could use the literal character '▉' instead of @+9608, but this would prevent the code from being encoded with the BQN single byte character system, so the UTF8-encoded code would end-up longer.

# ThunnoJ, $$\ 12 \log_{256}(96) \approx \$$ 9.88 bytes

R8Ap.L9616_C


Attempt This Online!

Yet another port of Jonathan Allan's Jelly answer.