Home » Character-Based Rhombus

Character-Based Rhombus

Solving Character-Based Rhombus challenge by Power Query, Power BI, Excel, Python and R

Create a formula to receive a number n as input and generate a rhombus with a diameter equal to n using “*” characters. Example for n=15

📌 Challenge Details and Links
Challenge Number: 77
Challenge Difficulty: ⭐⭐⭐
Designed by: Thang Van
📥Download Sample File
📥Link to the solutions on LinkedIn

Solving the challenge of Character-Based Rhombus with Power Query

Power Query solution 1 for Character-Based Rhombus, proposed by Zoran Milokanović:
let
  Source = 15, 
  D = {1 .. Source}, 
  H = Number.RoundUp(Source / 2), 
  P = each {Source - _ + 1, _}{Byte.From(_ < H)}, 
  S = Table.FromRows(
    List.TransformMany(
      D, 
      each {D}, 
      (i, _) => List.Transform(_, each {"*", null}{Byte.From(P(_) <= H - P(i))})
    )
  )
in
  S
Power Query solution 2 for Character-Based Rhombus, proposed by Ramiro Ayala Chávez:
let
N = 15,
R = List.Repeat,
a = List.Generate(()=>[i=1], each [i]<=N, each [i=[i]+2], each 
if [i]
Power Query solution 3 for Character-Based Rhombus, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
  Source = 15, 
  Null = List.Transform(
    List.Reverse({0 .. Number.RoundDown(Source / 2)}), 
    each List.Repeat({null}, _)
  ), 
  Null2 = Null & List.Skip(List.Reverse(Null)), 
  Rep = List.Transform({0 .. Number.RoundDown(Source / 2)}, each List.Repeat({"*"}, _)), 
  Rep2 = Rep & List.Skip(List.Reverse(Rep)), 
  Sol = Table.FromRows(
    List.Transform({0 .. Source - 1}, each Null2{_} & Rep2{_} & {"*"} & Rep2{_} & Null2{_})
  )
in
  Sol
Power Query solution 4 for Character-Based Rhombus, proposed by Alexis Olson:
let
  N = 15, 
  Mid = (N + 1) / 2, 
  L = List.Transform(
    {1 .. N}, 
    (i) =>
      [
        B      = Number.Abs(i - Mid), 
        S      = N - 2 * B, 
        Blanks = List.Repeat({" "}, B), 
        Stars  = List.Repeat({"*"}, S), 
        Line   = Blanks & Stars & Blanks
      ][Line]
  ), 
  Result = Table.FromRows(L)
in
  Result

Solving the challenge of Character-Based Rhombus with Excel

Excel solution 1 for Character-Based Rhombus, proposed by Bo Rydobon 🇹🇭:
=LET(
    n,
    15,
    MAKEARRAY(
        n,
        n,
        LAMBDA(
            r,
            c,
            REPT(
                "*",
                ABS(
                    2*r-n-1
                )+ABS(
                    2*c-n-1
                )<=n
            )
        )
    )
)
Excel solution 2 for Character-Based Rhombus, proposed by محمد حلمي:
=LET(n,15,e,SEQUENCE(n),s,n-ABS(n-e*2+1),
c,REPT("*",s),TRIM(MID(REPT(" ",(15-s)/2)&c,TOROW(e),1)))
Excel solution 3 for Character-Based Rhombus, proposed by محمد حلمي:
=LET(n,
    15,
    s,
    n-ABS(
        n-SEQUENCE(
            n,
            ,
            ,
            2
        )
    ),
    TRIM(
MID(REPT(" ",
    (15-s)/2)&REPT(
        "*",
        s
    ),
    SEQUENCE(
        ,
        n
    ),
    1)))
Excel solution 4 for Character-Based Rhombus, proposed by Oscar Mendez Roca Farell:
=LET(
    n,
     ROUND(
         A1/2,     ),
     s,
     SEQUENCE(
         n
     ),
     t,
     TOROW(
         s
     ),
     m,
     DROP(
         VSTACK(
             t+s>n,
              s-t<0
         ),
          -1
     ),
     IF(
         HSTACK(
             m,
              DROP(
                  CHOOSECOLS(
                      m,
                       n-s+1
                  ),
                   ,
                   1
              )
         ),
          "*",
          ""
     )
)
Excel solution 5 for Character-Based Rhombus, proposed by Owen Price:
=LET(    n,
    A1,    m,
    INT(
        n/2
    ),    MAKEARRAY(
        n,
        n,
        LAMBDA(
            r,
            c,
            IF(
                ABS(
                    m-r+1
                )+ABS(
                    m-c+1
                )<=m,
                "*",
                ""
            )
        )
    ))
Excel solution 6 for Character-Based Rhombus, proposed by Julian Poeltl:
=LAMBDA(n,
    LET(M,
    MAKEARRAY(
        ROUNDUP(
            n/2,
            0
        ),
        n,
        LAMBDA(
            R,
            C,
            IFS(
                AND(
                    R8
                ),
                "*",
                1,
                ""
            )
        )
    ),
    IF(ISEVEN(
        n
    ),
    VSTACK(
        M,
        CHOOSEROWS(
            M,
            SEQUENCE(
                n/2,
                ,
                n/2,
                -1
            )
        )
    ),
    VSTACK(M,
    CHOOSEROWS(M,
    SEQUENCE(n/2,
    ,
    (n-1)/2,
    -1))))))(15)
Excel solution 7 for Character-Based Rhombus, proposed by Sunny Baggu:
=LET(
 n, 15,
 a, ABS(n - SEQUENCE(n, , , 2)),
 IF(a + TOROW(a) <= n, "*", "")
)
Excel solution 8 for Character-Based Rhombus, proposed by Andy Heybruch:
=LET(_n,
    A1,
    _mid,
    ROUNDUP(
        _n/2,
        0
    ),
    MAKEARRAY(
        _n,
        _n,
        LAMBDA(
            r,
            c,
            IF(
                MIN(
                    r,
                    _n+1-r
                )+MIN(
                    c,
                    _n+1-c
                )>_mid,
                "*",
                ""
            )
        )
    )
Excel solution 9 for Character-Based Rhombus, proposed by Bilal Mahmoud kh.:
=TEXTSPLIT(
    TEXTJOIN(
        "|",
        ,
        MAP(
            MAP(
                VSTACK(
                    SEQUENCE(
                        ROUNDUP(
                            A1/2,
                            0
                        ),
                        ,
                        1,
                        2
                    ),
                    SEQUENCE(
                        ROUNDDOWN(
                            A1/2,
                            0
                        ),
                        ,
                        A1-IF(
                            ISODD(
                                A1
                            ),
                            2,
                            1
                        ),
                        -2
                    )
                ),
                LAMBDA(
                    x,
                    REPT(
                        " ",
                        ROUNDUP(
                            A1/2,
                            0
                        )-ROUNDUP(
                            x/2,
                            0
                        )
                    )&REPT(
                        "*",
                        x
                    )&REPT(
                        " ",
                        ROUNDUP(
                            A1/2,
                            0
                        )-ROUNDUP(
                            x/2,
                            0
                        )
                    )
                )
            ),
            LAMBDA(
                n,
                TEXTJOIN(
                    ",",
                    FALSE,
                    MID(
                        n,
                        SEQUENCE(
                                A1
                            ),
                        1
                    )
                )
            )
        )
    ),
    ",",
    "|"
)
Excel solution 10 for Character-Based Rhombus, proposed by Hussein SATOUR:
=LET(a,
    MAKEARRAY(
        A1,
        A1,
        LAMBDA(
            x,
            y,
            y
        )
    ),
    b,
    ROUNDUP(
        A1/2,
        0
    ),
    d,
    SEQUENCE(
        b
    ),
    c,
    VSTACK(
        SEQUENCE(
        b
    ),
        SEQUENCE(
            b-1,
            ,
            b-1,
            -1
        )
    ),
    IF(((a>=b-c+1)*(a
Excel solution 11 for Character-Based Rhombus, proposed by Nikola Z Grujicic – Nikola Ž Grujičić:
=LET(
    n,
     A1,
     MAKEARRAY(
         n,
          n,
          LAMBDA(
              a,
               b,
               LET(
                   x,
                    ROUND(
                        n/2,
                        0
                    ),
                    IF(
                        a+b<=x,
                         "",
                        IF(
                            a+b>n+x,
                             "",
                            IF(
                                b-a>=x,
                                 "",
                                 IF(
                                     a-b>=x,
                                     "",
                                     "*"
                                 )
                            )
                        )
                    )
               )
          )
     )
)
Excel solution 12 for Character-Based Rhombus, proposed by Sergei Baklan:
=LET(
 n,
     CEILING.MATH(
         num/2
     ), odd?,
     --(n*2<>num), a,
     SEQUENCE(
         n
     ), b,
     SEQUENCE(
         ,
         n
     ), ur,
     IF(
          a >= b,
          "*",
          "" 
     ), dr,
     DROP(
         SORTBY(
             ur,
              a,
             -1 
         ),
          odd?
     ), r,
     VSTACK(
         ur,
          dr
     ), HSTACK(
      DROP(
          SORTBY(
              r,
               b,
              -1
          ),
          ,
           -odd?
      ),
      r
 )
 )
Excel solution 13 for Character-Based Rhombus, proposed by Thang Van:
=LET(
    a,
    ROUNDUP(
        A1/2,
        0
    ),
    b,
    MAKEARRAY(
        a,
        a,
        LAMBDA(
            r,
            c,
            IFS(
                r=c,
                "*",
                c=1,
                "*",
                c<=r,
                "*",
                1000,
                ""
            )
        )
    ),    c,
    VSTACK(
        b,
        DROP(
            CHOOSEROWS(
                b,
                SEQUENCE(
                    ROWS(
                        b
                    ),
                    ,
                    ROWS(
                        b
                    ),
                    -1
                )
            ),
            1
        )    ),    d,
    CHOOSECOLS(
        c,
        SEQUENCE(
            COLUMNS(
                c
            ),
            ,
            COLUMNS(
                c
            ),
            -1
        )
    ),    HSTACK(
        DROP(
            d,
            ,
            -1
        ),
        c
    ))

Solving the challenge of Character-Based Rhombus with Python

Python solution 1 for Character-Based Rhombus, proposed by Konrad Gryczan, PhD:
import pandas as pd
import numpy as np

path = "CH-77 Character-Based Rhombus.xlsx"
test = pd.read_excel(path, header=None, usecols="C:Q", skiprows=1, nrows=16)
test = test.fillna("_")
test = test.apply(lambda x: "".join(x), axis=1)

def draw_rhombus(diag):
 if diag % 2 == 0:
 raise ValueError("diag must be an odd number")
 
 rhombus = np.full((diag, diag), "_")
 seq = np.arange(1, diag+1, 2)
 rev_seq = np.flip(seq)[1:]
 seq = np.concatenate((seq, rev_seq))
 
 for i in range(diag):
 rhombus[i, diag//2-seq[i]//2:diag//2+seq[i]//2+1] = "*"

 rhombus = pd.DataFrame(rhombus)
 rhombus = rhombus.apply(lambda x: "".join(x), axis=1)

 return rhombus

result = draw_rhombus(15)

print(result.equals(test)) # True
Python solution 2 for Character-Based Rhombus, proposed by Abdallah Ally:
import pandas as pd

# Create a function to generate the required results
def char_based_rhombus(n): 
 left = list(range(1 if n % 2 else 2, n if n % 2 else n + 1, 2))
 right = list(range(n, 0 if n % 2 else 1, -2))
 items = left + right
 values = [[''] * ((n - j) // 2) + ['*'] * j 
 + [''] * ((n - j) // 2) for j in items]
 return values

# Perform data wrangling
df = pd.DataFrame(char_based_rhombus(20))

# Display the final dataset
df

Solving the challenge of Character-Based Rhombus with R

R solution 1 for Character-Based Rhombus, proposed by Konrad Gryczan, PhD:
library(tidyverse)
library(readxl)

path = "files/CH-77 Character-Based Rhombus.xlsx"
test = read_xlsx(path, range = "C2:Q16", col_names = FALSE) %>%
 map_df(~replace_na(.x, "_")) %>%
 unite("rhombus", everything(), sep = "")

draw_rhombus = function(diag) {
 if (diag %% 2 == 0) {
 stop("diag must be an odd number")
 }
 
 rhombus = matrix(NA, nrow = diag, ncol = diag)
 seq = seq(1, diag, by = 2)
 rev_seq = rev(seq)[-1] 
 seq = c(seq, rev_seq)
 
 for (i in 1:diag) {
 rhombus[i, 1:seq[i]] = "*"
 }
 
 rhombus = as_tibble(rhombus) %>%
 mutate_all(as.character) %>%
 unite("rhombus", everything(), sep = "", na.rm = TRUE) %>%
 mutate(rhombus = str_pad(rhombus, diag, side = "both", pad = "_"))
 
 return(rhombus)
}

result = draw_rhombus(15)

identical(result, test)
#> [1] TRUE

Leave a Reply