50
\$\begingroup\$

Given two positive integers, A and B, illustrate their least common multiple by outputting two lines of dashes (-) with length LCM(A, B) after replacing every Ath dash in the first line and every Bth dash in the second line with vertical bars (|).

In this way, the end of each line will be the only place two |'s line up.

For example, if A = 6 and B = 4, LCM(6, 4) = 12, so:

two lines of 12 dashes:
------------
------------

replace every 6th dash in the first line with a vertical bar:
-----|-----|
------------

replace every 4th dash in the second line with a vertical bar:
-----|-----|
---|---|---|

Thus the final output would be

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

The order of the input numbers should correspond to the order of the lines.

The shortest code in bytes wins.

Testcases

A B
line for A
line for B

1 1
|
|

1 2
||
-|

2 1
-|
||

2 2
-|
-|

6 4
-----|-----|
---|---|---|

4 6
---|---|---|
-----|-----|

2 3
-|-|-|
--|--|

3 2
--|--|
-|-|-|

3 6
--|--|
-----|

2 5
-|-|-|-|-|
----|----|

4 3
---|---|---|
--|--|--|--|

10 10
---------|
---------|

10 5
---------|
----|----|

10 6
---------|---------|---------|
-----|-----|-----|-----|-----|

24 8
-----------------------|
-------|-------|-------|

7 8
------|------|------|------|------|------|------|------|
-------|-------|-------|-------|-------|-------|-------|

6 8
-----|-----|-----|-----|
-------|-------|-------|

13 11
------------|------------|------------|------------|------------|------------|------------|------------|------------|------------|------------|
----------|----------|----------|----------|----------|----------|----------|----------|----------|----------|----------|----------|----------|
\$\endgroup\$
  • 3
    \$\begingroup\$ @LeakyNun Extending an answer from codegolf.stackexchange.com/q/94999 seems easier than from that one. Either way, people will have fun doing this one which is a decent reason imo. \$\endgroup\$ – Calvin's Hobbies Sep 25 '17 at 19:02
  • 1
    \$\begingroup\$ Can I output an array with two strings, one for each line? \$\endgroup\$ – BlackCap Sep 25 '17 at 19:05
  • \$\begingroup\$ @BlackCap No. Print the strings to stdout or a file or return the whole multiline string. \$\endgroup\$ – Calvin's Hobbies Sep 25 '17 at 19:06
  • 2
    \$\begingroup\$ Bonus for handling arbitrary number of inputs? \$\endgroup\$ – Adám Sep 25 '17 at 23:49
  • 1
    \$\begingroup\$ @HelkaHomba Ok thanks; saved 1 more byte. :) (As if there is any other reason to ask such questions on codegolf challenges. ;p) \$\endgroup\$ – Kevin Cruijssen Sep 28 '17 at 6:58

42 Answers 42

0
\$\begingroup\$

Pyth - 20 bytes

j.e*/@QtkiFQ+*\-tb\|

Test Suite.

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

Retina, 67 bytes

\d+
$*-
^((-+)(\2)*) ((\2)+)$
$1$#5$*1¶$4$#3$*11
-1
|
+`(-*.)1
$1$1

Try it online! Link includes test cases.

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

PHP, 142 bytes

list(,$a,$b)=$argv;for($n=$a;$n<=$a*$b;$n+=$a)if($n%$b==0)break;while($i<$n)echo++$i%$a==0?'|':'-';echo"
";while($j<$n)echo++$j%$b==0?'|':'-';

Try it online !

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

AWK, 80 bytes

{for(;++m%$1||m%$2;)for(i=0;i++<2;)r[i]=r[i](m%$i?"-":"|");$0=r[1]"|\n"r[2]"|"}1

Try it online!

For 2 or more values you can use the following 94 bytes:

{m=0;for(x=1;x&&++m;)for(x=i=0;i++<NF;){x+=r=m%$i;R[i]=R[i](r?"-":"|")}for(;++z<i;)print R[z]}

Try it online!

I'm probably missing something obvious to shorten this. :)

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

J, 20 bytes

*./($'-|'#~<:,1:)"0]

Try it online!

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

Javascript (ES6), 84 bytes

f=(a,b,c=1,o=x='-'.repeat(a-1)+'|')=>(o.length%b?f(a,b,0,o+x):o)+(c?`
`+f(b,a,0):'')

Test Cases:

f=(a,b,c=1,o=x='-'.repeat(a-1)+'|')=>(o.length%b?f(a,b,0,o+x):o)+(c?`
`+f(b,a,0):'')

console.log(f(1,1));
console.log(f(1,2));
console.log(f(2,1));
console.log(f(2,2));
console.log(f(6,4));
console.log(f(4,6));
console.log(f(2,3));
console.log(f(3,2));
console.log(f(10,10));
console.log(f(3, 6));
console.log(f(2, 5));
console.log(f(4, 3));
console.log(f(10, 10));
console.log(f(10, 5));
console.log(f(10, 6));
console.log(f(24, 8));
console.log(f(7, 8));
console.log(f(6, 8));
console.log(f(13, 11));

Old answer Javascript (ES6), 91 bytes

f=(a,b)=>{for(x=y='',i=0;!i++||q||r;)q=i%a,r=i%b,x+=q?'-':'|',y+=r?'-':'|';return x+'\n'+y}
\$\endgroup\$
0
\$\begingroup\$

Ruby, 45 bytes

->a,b{[a,b].map{|x|(?-*~-x+?|)*(a.lcm(b)/x)}}

Try it online!

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

PHP, 85 82 bytes

for([,$a,$b]=$argv;++$i%$a|$y=$i%$b;$t.="-|"[!$y])$s.=$i%$a?"-":"|";echo"$s|
$t|";

Try it online.

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

Perl 6, 39 bytes

{@^a>>.&{('-'x$_-1~'|')x([lcm] @a)/$_}}

Try it online!

Takes input as a pair of numbers and returns a list of lines. Note that you can pass in as many integers as you like and it will print the lcm graph of all of them.

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

Powershell, 79 bytes

param($a,$b)do{$x+='-|'[!($c=++$i%$a)];$y+='-|'[!($d=$i%$b)]}while($c+$d)
$x;$y

Ungolfed test script:

$f = {

param($a,$b)
do{
    $x+='-|'[!($c=++$i%$a)]
    $y+='-|'[!($d=$i%$b)]
}while($c+$d)
$x;$y

}

@(
    ,(1,1,"| |")
    ,(1,2,"|| -|")
    ,(2,1,"-| ||")
    ,(6,4,"-----|-----| ---|---|---|")
    ,(4,6,"---|---|---| -----|-----|")
    ,(2,3,"-|-|-| --|--|")
    ,(3,2,"--|--| -|-|-|")
    ,(3,6,"--|--| -----|")
    ,(2,5,"-|-|-|-|-| ----|----|")
    ,(4,3,"---|---|---| --|--|--|--|")
    ,(10,10,"---------| ---------|")
    ,(10,5,"---------| ----|----|")
    ,(10,6,"---------|---------|---------| -----|-----|-----|-----|-----|")
    ,(24,8,"-----------------------| -------|-------|-------|")
    ,(7,8,"------|------|------|------|------|------|------|------| -------|-------|-------|-------|-------|-------|-------|")
    ,(6,8,"-----|-----|-----|-----| -------|-------|-------|")
    ,(13,11,"------------|------------|------------|------------|------------|------------|------------|------------|------------|------------|------------| ----------|----------|----------|----------|----------|----------|----------|----------|----------|----------|----------|----------|----------|")
) | % {
    $a,$b,$expected = $_
    $result = &$f $a $b
    "$(""$result"-eq"$expected"): $a,$b"
    $result
}

Output:

True: 1,1
|
|
True: 1,2
||
-|
True: 2,1
-|
||
True: 6,4
-----|-----|
---|---|---|
True: 4,6
---|---|---|
-----|-----|
True: 2,3
-|-|-|
--|--|
True: 3,2
--|--|
-|-|-|
True: 3,6
--|--|
-----|
True: 2,5
-|-|-|-|-|
----|----|
True: 4,3
---|---|---|
--|--|--|--|
True: 10,10
---------|
---------|
True: 10,5
---------|
----|----|
True: 10,6
---------|---------|---------|
-----|-----|-----|-----|-----|
True: 24,8
-----------------------|
-------|-------|-------|
True: 7,8
------|------|------|------|------|------|------|------|
-------|-------|-------|-------|-------|-------|-------|
True: 6,8
-----|-----|-----|-----|
-------|-------|-------|
True: 13,11
------------|------------|------------|------------|------------|------------|------------|------------|------------|------------|------------|
----------|----------|----------|----------|----------|----------|----------|----------|----------|----------|----------|----------|----------|
\$\endgroup\$
0
\$\begingroup\$

Julia 1.0, 52 47 bytes

p->println.(@.("-"^(p-1)*"|").^(lcm(p...).÷p))

Anonymous function; takes a list or tuple of two integers and prints the ASCII-art. Try it online!

Explanation

p->                 Function of p (a list or tuple of two integers):
 println.(   )       Print with newline, vectorized:
  @.(   )             Vectorize throughout the following expression:
    "-"^(p-1)*"|"      String of x-1 hyphens and one pipe for each x in p
   (   ).^(   )        each repeated this many times:
      lcm(p...)         LCM of the two integers in p
               .÷p      divided by each number in p
\$\endgroup\$
0
\$\begingroup\$

Whispers v2, 131 bytes

> Input
> Input
>> 1⊔2
>> (3]
>> L∣1
>> L∣2
>> Each 5 4
>> Each 6 4
> '-|'
>> 9ⁿL
>> Each 10 7
>> Each 10 8
>> Output 11 12

Try it online!

How it works

If you're unfamiliar with Whispers' program structure, I'd recommend reading the first part of this post.

In this explanation, we'll refer to the two inputs as \$x\$ and \$y\$ respectively. Our first two lines simply take the inputs in, and store them on lines 1 (\$x\$) and 2 (\$y\$). We then move to line 3, which returns \$\alpha = \mathrm{lcm}(x, y)\$ and to line 4, which returns the range \$A = [1, 2, ..., \alpha]\$.

Next, we reach our first two Each statements, operating on each of the inputs:

>> L∣1
>> L∣2
>> Each 5 4
>> Each 6 4

These four lines both operate on \$A\$, but return two different arrays, which we will call \$A_x\$ and \$A_y\$. While being different arrays, they are both formed in similar ways, as can be noted from the similarities in the two pairs of lines. In fact, we can define \$A_x\$ and \$A_y\$ as

$$A_x := [(i \div x) \in \mathbb{Z} \: | \: i \in A]$$ $$A_y := [(i \div y) \in \mathbb{Z} \: | \: i \in A]$$

This leaves us with two lists consisting of a \$1\$ where we'd expect there to be a | character, and a \$0\$ where there should be a -. This takes us to the next section of our code:

> '-|'
>> 9ⁿL
>> Each 10 7
>> Each 10 8

First, we yield the string -|, then we create our next two arrays \$B_x\$ and \$B_y\$. Helpfully, we can use the same function to map \$A_x\$ to \$B_x\$ and \$A_y\$ to \$B_y\$, namely 9ⁿL. This function yields the \$n^{th}\$ element of the string on line 9 i.e. -|, where \$n\$ is either \$0\$ or \$1\$, depending on the element from the respective \$A\$ arrays. This yields the two arrays \$B_x\$ and \$B_y\$ as defined below:

$$(B_x)_i = \begin{cases} \text{"-"}, & (A_x)_i = 0 \\ \text{"|"}, & (A_x)_i = 1 \end{cases}$$

$$(B_y)_i = \begin{cases} \text{"-"}, & (A_y)_i = 0 \\ \text{"|"}, & (A_y)_i = 1 \end{cases}$$

The Each command is special-cased for when yielding an array of strings, where it returns a single string, rather than an array. Finally, we reach the statement

>> Output 11 12

which outputs \$B_x\$, then a newline, then \$B_y\$

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