23
\$\begingroup\$

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.

\$\endgroup\$
8
  • \$\begingroup\$ what if n%8 == 1? \$\endgroup\$ Nov 6, 2022 at 12:58
  • 1
    \$\begingroup\$ @py3_and_c_programmer It looks like U+2589 has been left out of the list; it's probably meant to be there. \$\endgroup\$
    – m90
    Nov 6, 2022 at 13:07
  • 3
    \$\begingroup\$ 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. \$\endgroup\$
    – Arnauld
    Nov 6, 2022 at 14:09
  • 4
    \$\begingroup\$ Your examples seem to be wrong, with the repeating character being U+2589 instead of U+2588. \$\endgroup\$
    – m90
    Nov 6, 2022 at 14:25
  • 1
    \$\begingroup\$ @m90 Fixed them, sorry about that \$\endgroup\$
    – Ginger
    Nov 6, 2022 at 15:04

28 Answers 28

15
\$\begingroup\$

Excel (ms365), 56 bytes

enter image description here

Formula in B1:

=REPT("█",A1/8)&IF(MOD(A1,8),UNICHAR(9616-MOD(A1,8)),)
\$\endgroup\$
5
  • 2
    \$\begingroup\$ 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),) \$\endgroup\$ Nov 7, 2022 at 13:30
  • 2
    \$\begingroup\$ @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. \$\endgroup\$
    – JvdV
    Nov 7, 2022 at 13:36
  • 1
    \$\begingroup\$ Good point! I was using LEN() which just counts characters no matter how many bytes each is. \$\endgroup\$ Nov 7, 2022 at 13:56
  • 1
    \$\begingroup\$ @JvdV - surely this is 57 bytes for 55 characters? \$\endgroup\$ Nov 8, 2022 at 22:47
  • 1
    \$\begingroup\$ Woops yes it is @DominicvanEssen. Rollback it is. Sharp eye \$\endgroup\$
    – JvdV
    Nov 8, 2022 at 23:28
13
\$\begingroup\$

Julia 0.7, 35 32 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, 45 44 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.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ -3 using union Unicode operator !n=Char.(9616-diff((0:8:n)∪n)) \$\endgroup\$
    – amelies
    Nov 6, 2022 at 22:16
  • 1
    \$\begingroup\$ -5 by using the literal Char Try it online! \$\endgroup\$
    – MarcMush
    Nov 8, 2022 at 21:06
10
\$\begingroup\$

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      ['█','█','▏']
\$\endgroup\$
10
\$\begingroup\$

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)

\$\endgroup\$
4
  • \$\begingroup\$ 41 bytes \$\endgroup\$ Nov 6, 2022 at 16:22
  • \$\begingroup\$ @97.100.97.109 - thanks. I think you meant n%8>0 rather than n%8>1. \$\endgroup\$
    – The Thonnu
    Nov 6, 2022 at 17:04
  • \$\begingroup\$ Whoops, you're right. \$\endgroup\$ Nov 6, 2022 at 18:36
  • \$\begingroup\$ 36 bytes. Fails for n=0 but that seems ok per OP. \$\endgroup\$
    – loopy walt
    Nov 6, 2022 at 19:25
10
\$\begingroup\$

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

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.
\$\endgroup\$
2
  • \$\begingroup\$ Perhaps - neg instead of swap - to save a byte? \$\endgroup\$ Nov 6, 2022 at 15:06
  • \$\begingroup\$ @MamaFunRoll Nice thinking, thanks. \$\endgroup\$
    – chunes
    Nov 6, 2022 at 15:17
4
\$\begingroup\$

Charcoal, 14 bytes

⭆⪪×ψN⁸℅⁻⁹⁶¹⁶Lι

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

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

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).

\$\endgroup\$
2
  • \$\begingroup\$ You don't need that %8 do you? \$\endgroup\$
    – Neil
    Nov 6, 2022 at 14:26
  • \$\begingroup\$ @Neil Which %8 are you talking about? :-p \$\endgroup\$
    – Arnauld
    Nov 6, 2022 at 14:29
4
\$\begingroup\$

R, 51 49 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...

\$\endgroup\$
4
  • \$\begingroup\$ It looks like the approach that I took with Julia answer saves a few in R too \$\endgroup\$
    – Kirill L.
    Nov 6, 2022 at 16:48
  • \$\begingroup\$ @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)! \$\endgroup\$ Nov 6, 2022 at 17:02
  • 1
    \$\begingroup\$ OK, but c won't work as it will produce a duplicate when the range ends precisely on n, so yours is very close! \$\endgroup\$
    – Kirill L.
    Nov 6, 2022 at 19:07
  • 1
    \$\begingroup\$ @KirillL. Looks like a workaround to use c may be one byte shorter. \$\endgroup\$
    – pajonk
    Nov 6, 2022 at 20:09
4
\$\begingroup\$

Vyxal, 12 bytes

ɾ8ẇvL9616εCṅ

Try it Online!

Yet another port of Jonathan Allan's Jelly answer.

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

Ruby, 46 36 bytes

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

Attempt This Online!

A whopping 10 bytes saved by G B.

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

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

Mathematica, 59 bytes

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

View it on Wolfram Cloud!

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

///, 73 bytes

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

Try it online!

Input is a unary.

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

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!

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

Retina 0.8.2, 30 bytes

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

Try it online! Link includes test cases. Explanation:

.+
$*

Convert to unary.

1{1,8}
$.&

Convert groups of up to 8 to decimal.

T`8-1`▉-▏

Map digits to the appropriate Unicode character.

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

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.

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

Haskell, 44 40 bytes

f n|n<9=[toEnum$9616-n]
f n='█':f(n-8)

Attempt This Online!

-4 bytes by ignoring n=0

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

Go, 91 81 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
\$\endgroup\$
1
2
\$\begingroup\$

Java 11, 58 48 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)
\$\endgroup\$
1
  • 1
    \$\begingroup\$ 39 bytes by not supporting 0: Try it online! Rough port of latest Python answer. \$\endgroup\$
    – Neil
    Nov 8, 2022 at 0:52
2
\$\begingroup\$

05AB1E, 14 11 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
\$\endgroup\$
5
  • 2
    \$\begingroup\$ (+( could be s-, but α will work in this case \$\endgroup\$
    – naffetS
    Nov 6, 2022 at 20:54
  • 2
    \$\begingroup\$ 9616 can be compressed to Žb¶ \$\endgroup\$
    – naffetS
    Nov 6, 2022 at 20:56
  • \$\begingroup\$ Also, you can move the J to the footer, since outputting a string as a list of characters is allowed by default. \$\endgroup\$ Nov 7, 2022 at 13:58
  • \$\begingroup\$ @Sʨɠɠan - thanks. I somehow missed α in the commands page (even though it's right at the top). \$\endgroup\$
    – The Thonnu
    Nov 7, 2022 at 16:27
  • \$\begingroup\$ @KevinCruijssen - thanks for the info. I've added that in. \$\endgroup\$
    – The Thonnu
    Nov 7, 2022 at 16:27
2
\$\begingroup\$

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!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 50 bytes by not supporting 0: Try it online! \$\endgroup\$
    – Neil
    Nov 8, 2022 at 0:57
2
\$\begingroup\$

><>, 43 bytes

:8,:1%-v
v1-"█"$>:?!
>~{8%:"█"+$?!~}>o<

Try it online!

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

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

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

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

jq, 43 bytes

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

Try it online!

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

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.

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

Thunno J, \$ 12 \log_{256}(96) \approx \$ 9.88 bytes

R8Ap.L9616_C

Attempt This Online!

Yet another port of Jonathan Allan's Jelly answer.

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