15
\$\begingroup\$

The way points are assigned on a dice follows a regular pattern, the center dot is present if and only if the number is odd. To represent the even numbers, pairs of dots on opposite sides of the center are added, which will stay present for all successive numbers.

1:
O

2:   3:    4:   5:    6:
O     O     O O   O O   O O
       O           O    O O
  O     O   O O   O O   O O

This "dice pattern" can be extended to numbers greater than 6.

  • The dots are arranged in a square of size k with k being the smalest odd integer that satisfies k*k>=n
  • the dots are added in layers for the center outwards
  • one each layer the corners are added first
  • then the midpoints of the sides, first on the vertical, then on the horizontal sides.
  • for the remaining pairs of dots on each level you can choose any convenient order

Due to there already being solutions a the time it was added, the next constraint is an optional additional requirement:

  • If the number of dots is divisible by 4 the pattern should be symmetric under reflections along the coordinate axes (through the center)
// one possible way to add the remaining dots
7:    8:
O O    OOO
OOO    O O
O O    OOO

10:     12:      14:      16:      18:     20:      22:      24:
O        O   O    O   O    O O O    O O O    O O O    OOO O    OOOOO
 OOO      OOO      OOO      OOO     OOOO     OOOOO    OOOOO    OOOOO
 O O      O O     OO OO    OO OO    OO OO    OO OO    OO OO    OO OO
 OOO      OOO      OOO      OOO      OOOO    OOOOO    OOOOO    OOOOO
    O    O   O    O   O    O O O    O O O    O O O    O OOO    OOOOO

26:        30:          32:          36:          40:         44:     
O           O     O      O  O  O      O  O  O      OO O OO      OO O OO
 OOOOO       OOOOO        OOOOO       OOOOOOO      OOOOOOO      OOOOOOO
 OOOOO       OOOOO        OOOOO        OOOOO        OOOOO       OOOOOOO
 OO OO      OOO OOO      OOO OOO      OOO OOO      OOO OOO      OOO OOO
 OOOOO       OOOOO        OOOOO        OOOOO        OOOOO       OOOOOOO    
 OOOOO       OOOOO        OOOOO       OOOOOOO      OOOOOOO      OOOOOOO
      O     O     O      O  O  O      O  O  O      OO O OO      OO O OO
46:         48:
OOOO OO      OOOOOOO
OOOOOOO      OOOOOOO
OOOOOOO      OOOOOOO
OOO OOO      OOO OOO
OOOOOOO      OOOOOOO
OOOOOOO      OOOOOOO
OO OOOO      OOOOOOO

Your task is to write a program of function, that given a positive integer as input outputs the dice pattern for that number.

Rules:

  • Trailing white-spaces are allowed
  • Additional white-spaces at the start of each line are allowed, as long as all lines are indented by the same amount
  • You can replace O by any non-whitespace character
  • You may return a matrix of Truthy/Falsey values instead of printing the outputs
  • Your program has to work for inputs at least up to 2601=51*51, but your algorithm should work for arbitrarily large numbers
  • This is the shortest solution in bytes wins

related

\$\endgroup\$
5
  • 2
    \$\begingroup\$ Are we supposed to use only odd values of k? \$\endgroup\$
    – Arnauld
    Sep 12 at 16:31
  • 1
    \$\begingroup\$ @Arnauld yes (otherwise, there would not be a unique center point) \$\endgroup\$
    – bsoelch
    Sep 12 at 21:06
  • 1
    \$\begingroup\$ "for the remaining pairs of dots on each level you can choose any convenient order" But surely the choice must be constrained by balance/symmetry, no? \$\endgroup\$
    – Jonah
    Sep 12 at 23:50
  • 1
    \$\begingroup\$ @Jonah I did not find a definition that captures what I would consider "balanced" patters, so for simplicity I only require that the mirror reflection of a point is added at that same time as the point. I added an optional additional symmetry requirement for even numbers of pairs. \$\endgroup\$
    – bsoelch
    Sep 13 at 7:46
  • \$\begingroup\$ What about rotational symmetry? \$\endgroup\$
    – Neil
    Sep 13 at 20:50

3 Answers 3

6
\$\begingroup\$

Python 3 (194 199 210 bytes) -16 (- 5 thanks to Kevin)

My First golf! Returns a int, array, where len(arr) == side ** 2

def f(n):
 s=2*round(.5*n**.5-1)+3;q=s*s;d,e=[1]*q,~-s>>1;r=*({*range(s-2,0,-1)}-{0,e}),e,0;d[s*s//2]=n&1;q&=-2;b=(q-n+3)//2
 for k in*r[:b//2],*(s*~i for i in r[:~-b//2]):d[k]=d[~k]=0
 return d

Inputs: n
Output: returns 1d array containing pips

Attempt it online!

Formatting code:

print(n, sum(d), *(list((map(int, d[i:(i+s)]))) for i in l(0, s*s, s)), sep="\n")

Explanation:

Calculates the correct odd-square size to have a proper center

s=2*round(.5*n**.5-1)+3

Sets a variable keeping track of how many pips there are currently

q=s*s

Creates a 1D pip array, all filled with 1s, and sets e to center index

d,e=[1]*q,~-s>>1

Creates a tuple of which order to delete pips. Goes from right right-left, center, corner. (-4 bytes)

r=*({*range(s-2,0,-1)}-{0,e}),e,0

Sets the center pip based on if it's odd

d[s*s//2]=n&1

Clears the last bit of q (sets it to even)

q&=-2

Stores number of pip-pairs to remove

b=(q-n+3)//2

Clears pips over the limit in the pip-array

 for k in*r[:b//2],*(s*~i for i in r[:~-b//2]):d[k]=d[~k]=0

Returns d

 return d
\$\endgroup\$
5
  • 3
    \$\begingroup\$ Welcome to Code Golf! As a general policy, submitted answers need some way to receive input, whether it's from STDIN, ARGV, or as a function argument. Snippets of code that assume n has been defined before the program runs are not allowed. It's a good start, though! \$\endgroup\$
    – Value Ink
    Sep 13 at 21:07
  • \$\begingroup\$ @ValueInk All fixed. \$\endgroup\$ Sep 14 at 1:58
  • \$\begingroup\$ Welcome to CGCC, and nice first answer. +1 from me. :) If you want, feel free to edit in this ATO link with test code. As for three minor golfs: (s-1)>>1 and (b-1)//2 can be ~-s>>1 and ~-b//2 respectively (see this general tip), and (s*~i)for can be s*~i for, for -5 bytes total. (PS: Your current function seems to be 200 bytes instead of the 199 you currently mention in your header?) EDIT: I only now noticed you mentioned your own formatting code, so feel free to replace it in the ATO link. :) \$\endgroup\$ Sep 14 at 9:40
  • \$\begingroup\$ Can't really edit ATO/TIO, as on a whitelisted network. You can add the link as an edit. \$\endgroup\$ Sep 14 at 15:19
  • 1
    \$\begingroup\$ I've added the ATO-link. Since your "Formatting code" uses an unknown l-function and seems to use d from within your function, I've just used the verbose pretty-printer I already had in my ATO-link. Feel free to change it as you see fit once you're on a regular network. \$\endgroup\$ Sep 15 at 9:54
5
\$\begingroup\$

JavaScript (ES7), 180 bytes

Returns a binary matrix.

n=>[...Array(w=n**.5-n/~n&~1),W=w/2].map((_,y,a)=>a.map((_,x)=>x-W|y-W?(g=k=>k--?g(k)|y==W+(A=[d=k<4?W:(k&4?k:-k)/8|0,-d,W,-W])[k&=3]&x==W+A[6>>k&3]:x%w&&y%w>0)(n-w*w+2*w&~1):n&1))

Try it online! (with post-processing for readability)

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

Charcoal, 50 bytes

NθF﹪θ²POW⁻θLKA«↙≔ⅉηF⁸«P✳&⁶κ×O⌊⟦η÷⁺ιI§4062κ⁸⟧Mη✳&⁶κ

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

Nθ

Input n.

F﹪θ²PO

If n is odd then print an O at the origin.

W⁻θLKA«

Repeat while more Os are required.

Move to the bottom left corner of the next size of square.

≔ⅉη

Get the new offset (which is an eighth of the perimeter of this square).

F⁸«

Repeat to complete the perimeter of this square.

P✳&⁶κ×O⌊⟦η÷⁺ιI§4062κ⁸⟧

Output a number of Os depending on how many more are needed and which part of the perimeter is being drawn, but no more than the current offset.

Mη✳&⁶κ

Move to the next compass point without printing anything, which would throw off the count of Os written.

Example: When n is between 2 and 9, the number of Os is added to the given digit according to the following pattern:

604
2 2
406

This means that Os will only be drawn on the horizontal midpoints if n is 8 or 9, but will be drawn for lower values of n in the other positions.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.