7
\$\begingroup\$

Your task is to print out this exact text:

-
||
-|-
|---
|-|--
-|-|--
-|-----
|-|-----
|---|-|--
-|-----|--
---|-|-----
|---|-|-----
|---|-----|--
-----|---|-|--
-|-|---|-------
------|---|-----
|-|---------|-|--
---|-----|---|----
-|-----|-|---------
|-|---|-|-----------
|-----------|---|-|--
-|-----|-|---------|--
---|-----|-----|-|-----
|---|-|---------|-------
------|---|-|---|--------
-----|-----|---------|-|--
-|-----|-------|-----|-----
|---|-----|-------|---|-----
--|---------|-|---------|-|--
---|---|-----|-------|---|-|--
-|-----------|-------|---|-----
--|---|-----|-----------|-|-----
------------|-----|---------|----
-|-----|-|-----|---------|-----|--
---|-|-----|-----|---|-|-----------
|---------|-|---|-----|-----|-|-----
------|---|-----|-------|---------|--
-----|---------|-------|-----|-----|--
-|-------|-----|---|-------|---|-------
------|---------|-----------|-|---------

It at first look seems meaningless repititions of - and |, but it has a nice hidden pattern inside it. I won't reveal it now.

Binary matrix or 2D lists are not accepted as output. Exactly this text is required. But output can have trailing whitespace.

You can use any non-number character in place of - and |

Shortest code wins.

\$\endgroup\$
4
  • 8
    \$\begingroup\$ Welcome to Code Golf! This looks like a reasonably well-specified challenge, but for future reference, we strongly recommend using the Sandbox to get feedback on challenge ideas before posting them to the main site. For example, posting challenges with "hidden" patterns is strongly discouraged. \$\endgroup\$ – pxeger Jul 11 at 6:17
  • 10
    \$\begingroup\$ (for those who haven't figured it out, the |s are at the prime positions, 1-indexed) \$\endgroup\$ – pxeger Jul 11 at 6:19
  • 1
    \$\begingroup\$ Is a leading newline ok? \$\endgroup\$ – pxeger Jul 11 at 6:44
  • \$\begingroup\$ can we take the number of lines as input? \$\endgroup\$ – MarcMush Jul 11 at 10:45

23 Answers 23

12
\$\begingroup\$

Python 2, 70 bytes

p=n=i=1
while i<41:s='';exec"s+='-|'[p%n];p*=n*n;n+=1;"*i;i+=1;print s

Try it online!

The |s mark the position of primes.

The idea here, as with many prime-related tasks in Python, is to use Wilson's theorem. Essentially, \$ (n - 1)!^2 \bmod n \$ will equal 1 if \$ n \$ is prime, and 0 if it is not. @xnor gives a more in-depth explanation here if you're interested.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Alwin left a message in chat with a bit of a spoiler as to how this works, as well as a request for a more in-depth explanation of the specific mathematical trick used here (I'm being deliberately vague, their chat message should make it clearer) \$\endgroup\$ – caird coinheringaahing Jul 12 at 1:51
  • 1
    \$\begingroup\$ @cairdcoinheringaahing I've given a short explanation as to how this works, as requested. \$\endgroup\$ – dingledooper Jul 12 at 3:36
10
\$\begingroup\$

J, 29 26 25 bytes

({&'-|'/.1 p:#\)@(#~i.41)

Try it online!

-3 thanks to an idea from Lynn!

-1 thanks to xash!

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Maybe something like (]/.'-|'{~1 p:#\)#~i.41 works (I don't understand the rules for posting J here well enough to know if that counts as a full answer or not, but the main idea is to use #\ ). \$\endgroup\$ – Lynn Jul 11 at 15:33
  • 1
    \$\begingroup\$ Thanks Lynn! The rules are just that the submission must be assignable to a function like f=:<your submission>. In this case it meant we just had to surround in parenthesis and use the @ since the verb@noun creates another legal verb. \$\endgroup\$ – Jonah Jul 11 at 15:56
  • 1
    \$\begingroup\$ -1 with inlining to ({&'-|'/.…. Nice way to create the triangle. \$\endgroup\$ – xash Jul 11 at 16:44
7
\$\begingroup\$

Jelly, 11 bytes

40RRȷR¤ṁẒỌY

Try It Online!

The |s are at prime indexes

I figured out the pattern by smash-printing the rows into one flat string and realizing that the distribution looked familiar :P I had another idea to use base conversion but I decided to flatten the string first and then noticed.

Leaky Nun has two tricks in their answer - firstly, that you can take the range up to 1000 (which is shorter) since mold will discard extras, and secondly, I didn't notice other characters were allowed, so the digraph nilad ØA is shorter. Jonathan Allan also noticed that we can just use chr and output the unprintables 0x00 and 0x01, so thanks to both of them for the byte saves. Please go upvote Leaky Nun's answer as well.

40RRȷR¤ṁẒỌY  Main Link (Niladic)
40           Start at 40
  R          Range; [1, 2, ..., 40]
   R         Range; [[1], [1, 2], [1, 2, 3], ...]
       ṁ     Mold; to the shape of [[1], [1, 2], [1, 2, 3], ...], reshape
    ȷR¤      Range of 1000 ([1, 2, 3, ..., 1000]) - extra elements are discarded
        Ẓ    x => isprime(x)
         Ọ   chr
          Y  Join on newlines

There are a couple of ways to go about this idea - you can swap which list you generate first, you can index into a multitude of other strings, you can prime-check before or after molding since it vectorizes and thus doesn't really care what shape it is, etc.

\$\endgroup\$
2
  • \$\begingroup\$ No need to index into anything, will do fine by the given rules. \$\endgroup\$ – Jonathan Allan Jul 11 at 14:02
  • \$\begingroup\$ @JonathanAllan ah, good find \$\endgroup\$ – hyper-neutrino Jul 11 at 14:28
6
\$\begingroup\$

Jelly, 13 bytes

ȷRẒṁ40RR¤ịØAY

Try it online!

Uses Z and A instead of - and |.

This is basically the same answer as @hyper-neutrino's answer, which was published 3 minutes before mine, but our answers arose independently.

\$\endgroup\$
1
  • \$\begingroup\$ There doesn't seem to be anything wrong with ȷRẒṁ40RR¤ỌY which saves two. \$\endgroup\$ – Jonathan Allan Jul 11 at 13:58
4
\$\begingroup\$

Pyth, 19 bytes

jmsm@GP_hkrZ=+ZdS40

Try it online!

Uses a and b instead of - and |.

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

brainfuck, 1249 bytes

++++++++++[>+>++++>++++++<<<-]>>.<.>>..<<.>.>.<.<.>>.<...<.>>.<.>.<..<.>.>.<.>.<..<.>.>.<.....<.>>.<.>.<.....<.>>.<...>.<.>.<..<.>.>.<.....>.<..<.>...>.<.>.<.....<.>>.<...>.<.>.<.....<.>>.<...>.<.....>.<..<.>.....>.<...>.<.>.<..<.>.>.<.>.<...>.<.......<.>......>.<...>.<.....<.>>.<.>.<.........>.<.>.<..<.>...>.<.....>.<...>.<....<.>.>.<.....>.<.>.<.........<.>>.<.>.<...>.<.>.<...........<.>>.<...........>.<...>.<.>.<..<.>.>.<.....>.<.>.<.........>.<..<.>...>.<.....>.<.....>.<.>.<.....<.>>.<...>.<.>.<.........>.<.......<.>......>.<...>.<.>.<...>.<........<.>.....>.<.....>.<.........>.<.>.<..<.>.>.<.....>.<.......>.<.....>.<.....<.>>.<...>.<.....>.<.......>.<...>.<.....<.>..>.<.........>.<.>.<.........>.<.>.<..<.>...>.<...>.<.....>.<.......>.<...>.<.>.<..<.>.>.<...........>.<.......>.<...>.<.....<.>..>.<...>.<.....>.<...........>.<.>.<.....<.>............>.<.....>.<.........>.<....<.>.>.<.....>.<.>.<.....>.<.........>.<.....>.<..<.>...>.<.>.<.....>.<.....>.<...>.<.>.<...........<.>>.<.........>.<.>.<...>.<.....>.<.....>.<.>.<.....<.>......>.<...>.<.....>.<.......>.<.........>.<..<.>.....>.<.........>.<.......>.<.....>.<.....>.<..<.>.>.<.......>.<.....>.<...>.<.......>.<...>.<.......<.>......>.<.........>.<...........>.<.>.<.........

Try it online!

Kind of boring; just a hardcoded solution. I'm trying to create a solution that computes it with the prime relation, but I'm not that experienced in brainfuck and also I'll need to find an interpreter that goes up to 820 if I don't want excessive pain and suffering.

\$\endgroup\$
1
  • \$\begingroup\$ -11 bytes with a slightly shorter initializer. \$\endgroup\$ – ovs Jul 11 at 9:00
4
\$\begingroup\$

Vyxal j, 16 bytes

40ɾƛʁƛkA¥›:£æi;ṅ

Try it Online!

-1 byte thanks to @hyper-neutrino

Replace all those characters with numbers from 1, 2 and so on. The |'s are at prime indices. So then it's easy.

(pxeger spoiled it, though I came to it independently)

\$\endgroup\$
2
  • \$\begingroup\$ Actually, following a tip from Jonathan Allan, you can use \x00 and \x01 so you can just use chr instead of indexing: Try it Online! \$\endgroup\$ – hyper-neutrino Jul 11 at 18:20
  • \$\begingroup\$ 13 bytes \$\endgroup\$ – lyxal Jul 12 at 1:18
4
\$\begingroup\$

Jelly, 8 bytes

ØYxJĠẒỌY

Try it online!

ØY         The string "BCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz"
  xJ       Repeat "B" once, "C" twice, "D" thrice... "z" 40 times.
    Ġ      Group indices by values: [[1], [2,3], [4,5,6], …, […820]]
                                     ↑B   ↑C     ↑D          ↑z
     Ẓ     Is prime?
      Ọ    Translate 0,1 into "\x00","\x01"
       Y   Join lines
\$\endgroup\$
0
4
\$\begingroup\$

05AB1E, 14 bytes

A820ÅTüŸ€¦pèJ»

Try it online!

-1 byte thanks to ovs

A820ÅT>üŸ€¦pèJ»  Full Program
A                Push "abc...xyz"
 820             Push 820
    ÅT           Pop 40; Push [0, 1, 3, 6, 10, ...] (triangular numbers)
      üŸ         Pairwise range; get [[0, 1], [1, 2, 3], [3, 4, 5, 6], ...]
        €¦       For each sublist, remove the first element
          p      Primality; get the 2D list of 1s and 0s
           è     Index into "abc...xyz"
            J    Join each row into a string
              »  Join the result into a multiline string
\$\endgroup\$
5
  • \$\begingroup\$ >üŸ€¨ -> üŸ€¦ for -1 \$\endgroup\$ – ovs Jul 11 at 13:10
  • \$\begingroup\$ And there a few other ways to get the list of triangular numbers, such as 41L2c and 820ÅT, but I couldn't find anything shorter. \$\endgroup\$ – ovs Jul 11 at 13:15
  • \$\begingroup\$ @ovs Oh, oops, I was on the wrong branch's info.txt so I didn't see the triangular numbers built-in. Thanks! Although, isn't 820ÅT the same length as 40ÝÝO, or am I missing something? \$\endgroup\$ – hyper-neutrino Jul 11 at 15:33
  • 1
    \$\begingroup\$ Yeah it is the same length, I should've been a bit clearer in my previous comment ;). Just wanted to point out that builtin exists. \$\endgroup\$ – ovs Jul 11 at 15:38
  • \$\begingroup\$ @ovs Ah, I see, I believe I misread your comment :) thanks though. \$\endgroup\$ – hyper-neutrino Jul 11 at 15:40
4
\$\begingroup\$

Excel, 110 bytes

=LET(a,SEQUENCE(820),CONCAT(IF(MMULT((MOD(a,TRANSPOSE(a))=0)*1,a^0)=2,"|","-")&IF(MOD(SQRT(8*a+1),1),"","
")))

Link to Spreadsheet

=LET(a,SEQUENCE(820),                               a = (1..820)
CONCAT(                                             concatenate the following
IF(MMULT((MOD(a,TRANSPOSE(a))=0)*1,a^0)=2,"|","-")& if a is prime (has 2 factors) then "|" else "-"
IF(MOD(SQRT(8*a+1),1),"","                          if a is triangular (8a+1 is a perfect square) then add a line feed
")))
\$\endgroup\$
4
\$\begingroup\$

APL (Dyalog Extended), 23 19 bytes

‒1 thanks to Razetime.

Full program.

↑⎕UCS{1⍭⍳≢⍵}⍢∊,\⍳40

Try it online!

⍳40indices 1 through 40

,\ prefixes of that; [1,[1,2],[1,2,3],,39,40]]

{}⍢∊ apply the following anonymous lambda to the enlisted (flattened) data:

 the argument; [1,1,2,1,2,3,,39,40]

 the length of that; 820

1⍭ indicate which elements are prime; [0,1,1,0,1,0,,0,0]

⎕UCS convert to characters in the Universal Character Set; [\x00,\x01,\x01,\x00,\x01,\x00,,\x00,\x00]

 mix the list of strings into a matrix, padding with spaces as necessary to make it rectangular; ["\x00 ","\x01\x01 ",\x00\x00\x00\x00\x00\x00\x00\x00"]

\$\endgroup\$
3
  • \$\begingroup\$ may want to use ⎕A instead of '-|' \$\endgroup\$ – Razetime Jul 11 at 8:29
  • \$\begingroup\$ @Razetime Ah, right. \$\endgroup\$ – Adám Jul 11 at 8:30
  • \$\begingroup\$ @Shaggy Oh, right. I read that as not being able to return numbers. My bad; should be fixed now. \$\endgroup\$ – Adám Jul 12 at 8:59
3
\$\begingroup\$

Python 3, 105 bytes

r=range
for i in r(1,41):
	for j in r(i):n=i*~-i//2-~j;print(end="-|"[all(n%y for y in r(2,n))])
	print()

Try it online!

One byte longer than wasif's, but no exec trick used here.

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

Python 3.8 (pre-release), 98 bytes

r=range
for _ in r(n:=1,41):s="";exec("s+='-|'[all(n%y for y in r(2,n))and n>1];n+=1;"*_);print(s)

Try it online!

-6 bytes thanks to @hyper-neutrino and @pxeger

\$\endgroup\$
5
  • \$\begingroup\$ why 46? (padding) \$\endgroup\$ – hyper-neutrino Jul 11 at 6:39
  • \$\begingroup\$ 101 bytes, and the 46 should be a 41 (consistent tip - if you want to output a single string without a trailing newline, end=x is shorter than x,end="") \$\endgroup\$ – hyper-neutrino Jul 11 at 6:46
  • \$\begingroup\$ 98 bytes \$\endgroup\$ – pxeger Jul 11 at 6:49
  • \$\begingroup\$ @hyper-neutrino sorry was a mistake \$\endgroup\$ – wasif Jul 11 at 7:07
  • \$\begingroup\$ @pxeger thanks! \$\endgroup\$ – wasif Jul 11 at 7:07
2
\$\begingroup\$

JavaScript (ES7), 78 bytes

A recursive function going from \$k=820\$ to \$k=1\$ and testing whether \$\sqrt{8k+1}\$ is an integer to detect triangular numbers and figure out where line-feeds have to be inserted.

f=(k=820)=>k?f(k-1)+'-|'[(g=n=>n%--d?g(n):+!~-d)(d=k)]+[`
`[(1+8*k)**.5%1]]:''

Try it online!

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

Japt -R, 13 11 bytes

Uses f for composites and t for primes.

#(õ_ç Ëî°Tj

Test it

#(õ_ç Ëî°Tj
#(              :40
  õ             :Range [1,40]
   _            :Map each Z
    ç           :  Z spaces (could be any character)
      Ë         :  Map each character
       î        :    Slice the following to length (always 1)
        °T      :      Prefix increment T (initially 0)
          j     :      Is prime? (Returns a Boolean which gets coerced to a string by î)
                :Implicit output joined with newlines

Japt -R, 13 bytes

Preserving this version as I quite liked the ú trick. Uses q for qomposites(!) and p for primes.

40õ_ç¬Ëú²g°Tj

Test it

40õ_ç¬Ëú²g°Tj
40õ_              :Map each Z in the range [1,40]
    ç             :  Repeat to that length
     ¬            :    "q"
      Ë           :  Map each character
       ú          :    Left pad
        ²         :    With "p" to length 2
         g        :    Get the character at index
          °Tj     :      As above, with the Boolean this time coerced to 0 or 1
                  :Implicit output joined with newlines
\$\endgroup\$
2
\$\begingroup\$

Vyxal j, 11 14 bytes

40ƛɽ÷Ṡnɾ+æ₁+Cṅ

Try it Online!

I'm posting this because it's significantly shorter than the other one. I didn't realise the non-number rule, but still fairly short.

40ƛ            # Map 1...40 to...
   ɽ÷Ṡ         # Sum of 1...n-1 
      nɾ+      # Added to each of 1...n, this produces the correct indices
         æ     # Is prime (vectorised)
          ₁+C  # Add 100 and get the corresponding character (d or e)
             ṅ # Joined
               # (j flag) join by newlines
\$\endgroup\$
1
  • \$\begingroup\$ @Razetime Oops. \$\endgroup\$ – A username Jul 12 at 8:53
1
\$\begingroup\$

Factor, 75 bytes

820 [1,b] [ prime? 43 45 ? ] ""map-as 40 [1,b] [ cut swap print ] each drop

Try it online!

  • 820 [1,b] Create a range from 1 to 820 inclusive. 820 is the number of elements in the triangle sans newlines.
  • [ prime? 43 45 ? ] ""map-as Create a flat version of the triangle as a string, where 43 is the code point for + and 45 is the code point for -. |'s code point has 3 digits so I changed this (as it is allowed by the rules).
  • 40 [1,b] [ cut swap print ] each drop Cut the sequence in two at ever-increasing indices, printing each line after it is cut off from the main sequence.
\$\endgroup\$
1
\$\begingroup\$

Charcoal, 25 bytes

G↓→⁴⁰ψ¤⭆⁸²⁰§-|﹪ΠE⊕ι∨λ±¹⊕ι

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

G↓→⁴⁰ψ

Draw an empty triangle of side 40. (Unfortunately Charcoal doesn't have a 1-byte shortcut for a triangle in this orientation.) The y variable is the null byte, which has a special meaning for the Fill function, in that it counts as a fillable area.

¤⭆⁸²⁰§-|﹪ΠE⊕ι∨λ±¹⊕ι

Calculate the first 820 factorials, negate them, reduce them modulo the incremented index, and index the results into the string -|. Use this to fill the triangle drawn above. (Charcoal's Fill works by painting the string across the region to be filled, rather than repeating it horizontally and vertically. See @ASCII-only's answer to Bake a slice of Pi for another example of how it works.)

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

Julia 1.0, 76 bytes

f(y=1)=1:40 .|>i->print.(y:(y+=i).|>j->"
-|"[j==y||2+(2==sum(j.%(1:j).<1))])

Try it online!

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

Perl 5, 73 bytes

say join($/,map$"x$_,1..40)=~s/./!$n++|(grep$n%$_==0,2..$n-1)?"-":"|"/ger

Try it online!

say                         # print triangle string, say adds a \n at the end
join($/,map$"x$_,1..40) =~  # make multi-line triangle
                            # of $" (spaces) and $/ (newlines)
s/ /                        # replace spaces
  !$p++                     # count position, ! prevent first from becoming "|"
  |                         # bit-or instead of || or 'or'
  (grep $p%$_==0, 2..$p-1)  # check if $p position is a prime
  ? "-"                     # replace non-prime $p with -
  : "|"                     # replace prime $p with |
/ger                        # g=replace all, e=eval, r=return triangle to say
\$\endgroup\$
1
\$\begingroup\$

brainfuck, 223 bytes

-[>-<-----]>[>++++[<[[->>>+<<<]>]<+>>>-]<-]>>-[--->+<]>[<<<<<[>+[[>]>]>>[->+>]>[[-<+>]<<[-<<<[[<]<]>>[-]-[[>]>]>]+>>>>]<<<<<<<[[<]<]<]>+[->>>]<[-<+>]<-]<<<+<+<--[>[[[-<<<+>>>]>]<<-[---<+>]<.[-]<+<-]++++++++++.[-]>[-<+>]+<<]

Try it online!

Uses trial division up to 86 to determine every prime up to 820. Outputs T for - and V for |.

Populate list of 820 numbers not yet considered composite
-[>-<-----]>[>++++[<[[->>>+<<<]>]<+>>>-]<-]

tape is 1 0 0 1 0 0 1 etc 1 0 0 1 0 (0)

Create 85 to test visibility by up to N=86 (which is high enough and short to create)
>>-[--->+<]>

working tape will be 1 0 0 1 0 0 1 etc 1 1 0 1 1 0 (0 or 1) x y 0 0
with x plus y = 85 in first iteration

For all numbers from 85 down to 1: (N is this number plus one)
[

  For all numbers to sieve:
  <<<<<[

    Mark number seen
    >+

    Decrement x and increment y if x is nonzero
    [[>]>]>>[->+>]

    Otherwise, the last number was divisible by N
    >[

      Move y back to x
      [-<+>]

      If this isn't the first time we've seen a multiple of N:
      <<[

        Mark number composite
        -<<<[[<]<]>>[-]-[[>]>]>

      Mark that we've seen a multiple of N
      ]+>>>>

    ]

    Go to next number (for loop termination condition)
    <<<<<<<[[<]<]<

  Repeat until all 820 numbers checked
  ]

  Remove all "seen" markings and "seen multiple of N"
  >+[->>>]

  Copy whatever was left of y back to x and decrement
  <[-<+>]<-
]

Now all numbers have been checked and marked composite if applicable
We are 5 cells right of first number (1) now

Set up counters for triangle shape (x=1 for first row; and y=1 so y is always nonzero)
<<<+<+

Mark 1 as nonprime
<--

For each number
[

  While x is nonzero
  >[

    Move x and y left three cells
    [[-<<<+>>>]>]

    Add 85 to primality indicator to output ASCII
    <<-[---<+>]

    Output and remove number
    <.[-]

    Increment y and decrement x
    <+<-

  ]

  Output newline
  ++++++++++.[-]

  Copy y to x (now one more than it was; restore y=1)
  >[-<+>]+

<<]

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

C (gcc), 101 \$\cdots\$ 99 98 bytes

p;r;d;f(n){for(n=r=0;++r<41;puts(""))for(;r*-~r>2*n;printf(L"|-"+!p))for(p=d=n++;d>1;p=n%d--&&p);}

Try it online!

Saved a byte (and got below \$100\$!) thanks to ceilingcat!!!
Saved another byte thanks to Shaggy!!!

\$\endgroup\$
2
  • \$\begingroup\$ 98 bytes \$\endgroup\$ – Shaggy Jul 13 at 14:40
  • \$\begingroup\$ @Shaggy Nioce one - thanks! :D \$\endgroup\$ – Noodle9 Jul 13 at 21:13
0
\$\begingroup\$

Retina 0.8.2, 60 bytes


820$*|
.(?<=^\1+(..+))
-
^.
-¶
+`(.)+¶(?=.+$)(?<-1>.)+.
$&¶

Try it online! Explanation:


820$*|

Insert 820 |s. (820 = 40 × 41 ÷ 2)

.(?<=^\1+(..+))
-

Change most of them to -s appropriately.

^.
-¶

Change the first one too, and start building the triangle.

+`(.)+¶(?=.+$)(?<-1>.)+.
$&¶

Build up each row of the triangle to be one character longer than the previous.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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