Visualise Bit Weaving

33

6

The esoteric programming language evil has an interesting operation on byte values which it calls "weaving". It is essentially a permutation of the eight bits of the byte (it doesn't matter which end we start counting from, as the pattern is symmetric):

  • Bit 0 is moved to bit 2
  • Bit 1 is moved to bit 0
  • Bit 2 is moved to bit 4
  • Bit 3 is moved to bit 1
  • Bit 4 is moved to bit 6
  • Bit 5 is moved to bit 3
  • Bit 6 is moved to bit 7
  • Bit 7 is moved to bit 5

For convenience, here are two other representations of the permutation. As a cycle:

(02467531)

And as a list of pairs of the mapping:

[[0,2], [1,0], [2,4], [3,1], [4,6], [5,3], [6,7], [7,5]]

Your task is to visualise this permutation, using the box-drawing characters , , , , , , (Unicode code points: U+2500, U+2502, U+250C, U+2510, U+2514, U+2518, U+253C). This visualisation should satisfy the following constraints:

The first and last line are exactly:

0 1 2 3 4 5 6 7

Between those, you can use as many lines as you want of up to 15 characters each to fit your box drawing characters (you will need at least 4 lines). The lines should start vertically beneath one of the digits on the first row and end vertically above the corresponding digit on the last row. The eight lines must be connected, and may only cross via (which is always a crossing, never two turning lines which are touching). The exact paths of the lines are up to you (and finding a particularly golfable layout is the core of this challenge). One valid output would be:

0 1 2 3 4 5 6 7
│ │ └─┼┐│ │ └┐│
└─┼─┐ ││└─┼─┐││
┌─┘ │ ││  │ │││
│ ┌─┼─┘│  │ │││
│ │ │ ┌┼──┘ │││
│ │ │ │└┐ ┌─┼┼┘
│ │ │ │ │ │ │└┐
0 1 2 3 4 5 6 7

However, any other layout that correctly connects the right digits is fine too. Please show your chosen output in your answer.

You may write a program or function and will not take any input. Output the diagram either to STDOUT (or closest alternative) or as a function return value in the form of a string or a list of strings (each representing one line).

Standard rules apply, so the shortest code (in bytes) wins.

Martin Ender

Posted 2016-06-27T16:57:14.197

Reputation: 184 808

This is strangely reminiscent of the utility graph... – Conor O'Brien – 2016-06-27T17:49:56.837

1Could we use other symbols for languages that do not support unicode? – flawr – 2016-06-27T19:22:28.500

3This challenge essentially boils down to copy-pasting the provided output... How about taking a permutation of 01234567 as an input and then connecting that to 01234567 ? So that you have to figure out the links yourself? It would be a significantly more challenging a task, especially for golfing. – shooqie – 2016-06-27T19:34:47.053

5@shooqie This was discussed in the sandbox. That would indeed be a very different challenge and I'm considering posting that as well at some point. However, I believe there's a lot more to this challenge than copy-pasting the example above. There are countless different admissible outputs and the one above is especially hard to compress whereas others (like the ones used by the existing answers) are much more compressible. The challenge is in finding a single compressible string. That's very different from automatically finding a layout in few bytes. – Martin Ender – 2016-06-27T19:50:58.377

2Someone has to solve this in evil. – RK. – 2016-06-28T05:50:45.250

It should be allowed to write a string or a string array expression. In Haskell there's no such thing as no-argument functions, though you can write a function that takes a void-typed argument (). – John Dvorak – 2016-06-28T08:02:46.557

1@JanDvorak Printing string/array literals seems rather unclean. A void-typed function returning the string(s) would be fine though. – Martin Ender – 2016-06-28T08:12:40.607

How about a function that ignores its argument, then? – John Dvorak – 2016-06-28T08:29:30.317

1@JanDvorak I think I'm fine with that too. Might be worth asking on meta for a general rule though. – Martin Ender – 2016-06-28T08:30:20.500

@JanDvorak Relevant meta post

– Mego – 2016-06-29T08:12:43.027

Great. The top voted answer so far has 131 bytes of program code to produce 95 bytes of constant output. Granted it has found a more compact output, but still proves @shooqie right as a program printing a constant string containing that output is shorter… or well, it depends on the chosen character encoding, of course. – Holger – 2016-06-29T12:27:46.730

1@Holger Just because it has the most votes doesn't mean it's the shortest. Also, unless your language can use a code page that has all the required characters in a single byte, the output is well over 200 bytes. I admit that this encoding discrepancy is a bit unfortunate, but if you ignore it, then even the PowerShell answer is shorter than its output. – Martin Ender – 2016-06-29T12:32:44.573

1Maybe counting characters would be better… – Holger – 2016-06-29T12:42:09.683

3

@Holger There's a good reason we don't do that: then people could just encode the string by packing it in large Unicode characters, which can store several bytes worth of information in a single character. Example.

– Martin Ender – 2016-06-29T12:44:31.153

I just noticed that I should have said code points rather than characters, but anyway, any kind of packing or compressing requires code for extracting which doesn’t differ to the situation we have with the bytes here. I don’t consider the character examples less readable than the examples here… – Holger – 2016-06-29T12:54:53.350

@Holger It's not about readability but about interesting approaches. In some of the golfing languages, Unicode packing is trivial and doesn't cost a lot of characters at all. (Also I don't see what the difference between characters and code points is for the purpose of the counting.) – Martin Ender – 2016-06-29T13:00:01.847

U+0041U+0302U+0333 are three code points, but only one character, Â̳ – Holger – 2016-06-29T13:27:46.487

@Holger Oh right, I believe we normally consider combining marks "characters" as far as counting is concerned. But yeah, that would make things even worse. – Martin Ender – 2016-06-29T13:28:49.207

1@flawr Sorry, I never saw your comment. In most languages you should be able to output a simple byte stream. There are single-byte code pages, like CP437 which contain all of the necessary characters. That means if you just output those bytes and interpret your output as CP437 (or some other suitable codepage), you'd still have a valid answer without having to worry about Unicode. – Martin Ender – 2016-06-30T07:16:47.400

@sergiol Interesting, but no. – Martin Ender – 2017-07-23T12:28:06.387

Answers

13

Actually, 69 bytes

"│ ┌┘│ │└┐ │└┐└┐""┌┘└┼┐└┼┐ └┼┐└┐""└┼┐│└┐┌┘└┐┌┘│""┌┼─┘"3*"│┌┘"+8r' j;)

Try it online! (the alignment is a little messed up in the online interpreter)

Actually has a HUGE advantage here - all of the box drawing characters are in CP437, so they're only a byte each. Though each character needed could theoretically be encoded in 4 bits (since there are only 9 unique characters), the 31 bytes saved by compressing the string would be lost due to Actually's very poor string processing capabilities. This also means that any 8x4 configuration would result in the same score. Since 8x4 appears to be the (vertically) shortest possible configuration, this is optimal.

Thanks to Martin for 3 bytes!

Thanks to TimmyD for 4 more bytes!

Explanation:

"│ ┌┘│ │└┐ │└┐└┐""┌┘└┼┐└┼┐ └┼┐└┐""└┼┐│└┐┌┘└┐┌┘│""┌┼─┘"3*"│┌┘"+8r' j;)
"│ ┌┘│ │└┐ │└┐└┐""┌┘└┼┐└┼┐ └┼┐└┐""└┼┐│└┐┌┘└┐┌┘│""┌┼─┘"3*"│┌┘"+         push the individual lines, using string multiplication to shorten repeated sections
                                                              8r' j   push the string "0 1 2 3 4 5 6 7" (range(8), join on spaces)
                                                                   ;)  make a copy and move it to the bottom of the stack

Mego

Posted 2016-06-27T16:57:14.197

Reputation: 32 998

1Technically a lot of the other answers could have made use of single-byte encodings as well by just using whatever single-byte encoding their language supports (if any), outputting the same bytes as yours and saying "the output is CP437-encoded", but it seems that no one picked up on that. ¯\(ツ) – Martin Ender – 2016-07-18T14:43:10.810

21

PowerShell v2+, 172 153 148 145 142 131 123 bytes (81 chars)

($a=""+0..7)
$b='┌┘'
"│$b$('┌┼─┘'*3)
└┼┐$('│└─┐'*3)
$b$('└┼─┐'*3)│
│ $($b*6)│"
$a

I golfed the weaving further, eliminating the need for several variables by using inline code blocks. This is probably within a few bytes of optimal.

We start by setting $a equal to the range 0..7 that's been joined together with spaces. This is because the default $ofs (Output Field Separator) for an array is a space, so when the array is stringified with ""+ (with an operator like this, PowerShell will try to implicitly cast the right-hand object as the left-hand object), the result is the range space-separated.

That's encapsulated in parens, which adds the result onto the pipeline. We then setup a one helper variable $b, followed by four lines of output with the appropriate variable in place (split with literal newlines), and using inline code-blocks for repeat sections, followed by $a again. The four lines and $a are also placed on the pipeline, and output is implicit at the end.

PS C:\Tools\Scripts\golfing> .\visualize-bit-weaving.ps1
0 1 2 3 4 5 6 7
│┌┘┌┼─┘┌┼─┘┌┼─┘
└┼┐│└─┐│└─┐│└─┐
┌┘└┼─┐└┼─┐└┼─┐│
│ ┌┘┌┘┌┘┌┘┌┘┌┘│
0 1 2 3 4 5 6 7

AdmBorkBork

Posted 2016-06-27T16:57:14.197

Reputation: 41 581

1Nice work with going back and forth at the bottom. :) – Martin Ender – 2016-06-28T15:27:05.247

11

Javascript ES6, 168 167 bytes

Edit: Whoops, turned out I was using the pipe | char instead of U+2502 in part of the function, updated byte count.

_=>((n=`0 1 2 3 4 5 6 7 `)+[...`6452301`].map(i=>`${(d=n=>`│ `.repeat(n))(i)}└┐│ ${r=d(6)}┌┼┘ ${r}│└┐ ${d(6-i)}`).join``+n).match(/.{16}/g).join`
`

Returns a string.

Output:

0 1 2 3 4 5 6 7 
│ │ │ │ │ │ └┐│ 
│ │ │ │ │ │ ┌┼┘ 
│ │ │ │ │ │ │└┐ 
│ │ │ │ └┐│ │ │ 
│ │ │ │ ┌┼┘ │ │ 
│ │ │ │ │└┐ │ │ 
│ │ │ │ │ └┐│ │ 
│ │ │ │ │ ┌┼┘ │ 
│ │ │ │ │ │└┐ │ 
│ │ └┐│ │ │ │ │ 
│ │ ┌┼┘ │ │ │ │ 
│ │ │└┐ │ │ │ │ 
│ │ │ └┐│ │ │ │ 
│ │ │ ┌┼┘ │ │ │ 
│ │ │ │└┐ │ │ │ 
└┐│ │ │ │ │ │ │ 
┌┼┘ │ │ │ │ │ │ 
│└┐ │ │ │ │ │ │ 
│ └┐│ │ │ │ │ │ 
│ ┌┼┘ │ │ │ │ │ 
│ │└┐ │ │ │ │ │ 
0 1 2 3 4 5 6 7 

Extra: Using @TimmyD's method, I have another 167 byte solution:

(n=`0 1 2 3 4 5 6 7
`,a=`│┌┘ `,b=`└┼─┐`,d=`┌┼─┘`,f=` │└┐`)=>[n,a,a,a,a,`
`,b,b,b,`└┼┐
┌┘`,d,d,d,`│
│`,f,f,f,` │
`,n].join``

Dendrobium

Posted 2016-06-27T16:57:14.197

Reputation: 2 412

9

JavaScript (ES6), 137 134 bytes

f=
_=>`0
│2525252
1 1 1 1
24242423525252 3 1 1 1 3 242424│
0`.replace(/\d/g,d=>`0 1 2 3 4 5 6 7,└┼┐,┌┘,│
│,│ , │`.split`,`[d])  
;
o.textContent=f();
<pre id=o></pre>

As a bell-ringer I immediately recognised this as the first two rows of Plain Hunt Major (note that the linked image uses 1-8 instead of 0-7).

Neil

Posted 2016-06-27T16:57:14.197

Reputation: 95 035

4

Pyth - 119 104 100 81 bytes

Extremely simple. (Its actually bytes this time).

js[KjdU8cX."sz¨ú¨ãÆhÆ?\ÕüÓ¼xFNøa"_G"│┌┘└┼─┐ "15K

Try it online here.

I also stole @TimmyD's output:

0 1 2 3 4 5 6 7
│┌┘ │┌┘ │┌┘ │ │
└┼─┐└┼─┐└┼─┐└┐│
┌┘┌┼─┘ └┐│┌┼─┼┘
│ │└┐ ┌─┼┘│└┐└┐
0 1 2 3 4 5 6 7

Maltysen

Posted 2016-06-27T16:57:14.197

Reputation: 25 023

3

MS-DOS Batch, 136 bytes

@echo 0 1 2 3 4 5 6 7
@echo ³ÚÙ ³ÚÙ ³ÚÙ ³ÚÙ
@echo ÀÅÄ¿ÀÅÄ¿ÀÅÄ¿ÀÅ¿
@echo ÚÙÚÅÄÙÚÅÄÙÚÅÄÙ³
@echo ³ ³À¿ ³À¿ ³À¿ ³
@echo 0 1 2 3 4 5 6 7

Using @TimmyD's output. This might work in Windows Batch too, but my code page there is CP850, not CP437.

Neil

Posted 2016-06-27T16:57:14.197

Reputation: 95 035

Works in Windows too, regardless of whether you use CP437 or CP850. – Holger – 2016-06-29T12:41:14.570

@Holger Huh, I guess I should have tried it anyway, just to see! – Neil – 2016-06-29T15:16:32.643

3

///, 112 bytes (100 chars)

/8/0 1 2 3 4 5 6 7//9/│//A/└┐//B/┌┼┘/8/C/9 A9 A9 A9//D/9A 9A 9A 9/
AC
B B B B
DA
C 9
9 B B B 9
9 D
8

Thanks @MartinEnder for -3 bytes!
Thanks @MartinEnder for -9 bytes!
Thanks @MartinEnder (OP) for pointing 15-char rule out

Uses @TimmyD's @Marco's output

0 1 2 3 4 5 6 7
└┐│ └┐│ └┐│ └┐│
┌┼┘ ┌┼┘ ┌┼┘ ┌┼┘
│└┐ │└┐ │└┐ │└┐
│ └┐│ └┐│ └┐│ │
│ ┌┼┘ ┌┼┘ ┌┼┘ │
│ │└┐ │└┐ │└┐ │
0 1 2 3 4 5 6 7

Erik the Outgolfer

Posted 2016-06-27T16:57:14.197

Reputation: 38 134

3

MATLAB / Octave, 112 109 bytes

a='0 1 2 3 4 5 6 7';d=['└┐│ ';'┌┼┘ ';'│└┐ '];e=repmat('│ ',3,1);[a;d d d d;e d d d e;a]

Output:

0 1 2 3 4 5 6 7
└┐│ └┐│ └┐│ └┐│
┌┼┘ ┌┼┘ ┌┼┘ ┌┼┘
│└┐ │└┐ │└┐ │└┐
│ └┐│ └┐│ └┐│ │
│ ┌┼┘ ┌┼┘ ┌┼┘ │
│ │└┐ │└┐ │└┐ │
0 1 2 3 4 5 6 7

My code is based on the ouputs of @Dendrobium and @Neil.

Marco

Posted 2016-06-27T16:57:14.197

Reputation: 581

1

+1 for golfable output

– Erik the Outgolfer – 2016-06-29T13:08:40.240

Notice: The linked comment has been deleted. It was the OP saying your output is more golfable than that of @TimmyD. – Erik the Outgolfer – 2016-06-29T13:37:11.850

0

Tcl, 205 bytes

puts "[set B "0 1 2 3 4 5 6 7"]
│┌┘ │┌┘ │┌┘ └┐│
└┼┐ └┼─┐└┼──┐││
┌┘└─┐│ └┐│┌─┼┼┘
│ ┌─┼┘┌─┼┘│ │└┐
$B"

Try it online!

outputs

0 1 2 3 4 5 6 7
│┌┘ │┌┘ │┌┘ └┐│
└┼┐ └┼─┐└┼──┐││
┌┘└─┐│ └┐│┌─┼┼┘
│ ┌─┼┘┌─┼┘│ │└┐
0 1 2 3 4 5 6 7

sergiol

Posted 2016-06-27T16:57:14.197

Reputation: 3 055

0

SOGL V0.12, 64 bytes

└┼─┐³
┘┌┼─┘²
┐│└─┐¹
┌┘┌┘┌┘⁰
│┌²┌┼─²¶└┼¹│└─¹¶┌┘³³³│¶│ ⁰⁰│”8δ@∑Q;O

Try it Here!

Pattern stolen from the powershell

dzaima

Posted 2016-06-27T16:57:14.197

Reputation: 19 048

0

Python3, 209 bytes

lambda s="0 1 2 3 4 5 6 7\n":s+"│┌┘ │┌┘ │┌┘ │ │\n└┼─┐└┼─┐└┼─┐└┐│\n┌┘┌┼─┘ └┐│┌┼─┼┘\n│ │└┐ ┌─┼┘│└┐└┐\n"+s

Returns a string.

Thanks to @Mego for saving 2 bytes!

Credits of the character body go to @TimmyD !

Yytsi

Posted 2016-06-27T16:57:14.197

Reputation: 3 582

2You don't need the a, part, which will also remove the need for it to be called with a parameter. – Mego – 2016-06-28T02:54:30.097

0

Sprects, 99 bytes (87 chars)

$8
AC
BE
DA
C 9
9E 9
9 D
8$E B B B$D9A 9A 9A 9$C9 A9 A9 A9$B┌┼┘$A└┐$9│$80 1 2 3 4 5 6 7

Uses @Marco's output (replace every 16th character with a newline (regex: (.{15}). -> \1\n)).

0 1 2 3 4 5 6 7
└┐│ └┐│ └┐│ └┐│
┌┼┘ ┌┼┘ ┌┼┘ ┌┼┘
│└┐ │└┐ │└┐ │└┐
│ └┐│ └┐│ └┐│ │
│ ┌┼┘ ┌┼┘ ┌┼┘ │
│ │└┐ │└┐ │└┐ │
0 1 2 3 4 5 6 7

Erik the Outgolfer

Posted 2016-06-27T16:57:14.197

Reputation: 38 134

0

Bash + GNU sed, 140 bytes

sed 'h
s/$/nxxxacnb b b bnyyycanc xxxcnc b b b cnc yyyc/
:
s/x/ac /
s/y/ca /
s/a/└┐/
s/b/┌┼┘/
t
y/cn/│\n/
G'<<<'0 1 2 3 4 5 6 7'

Output:

0 1 2 3 4 5 6 7
└┐│ └┐│ └┐│ └┐│
┌┼┘ ┌┼┘ ┌┼┘ ┌┼┘
│└┐ │└┐ │└┐ │└┐
│ └┐│ └┐│ └┐│ │
│ ┌┼┘ ┌┼┘ ┌┼┘ │
│ │└┐ │└┐ │└┐ │
0 1 2 3 4 5 6 7

Using @TimmyD's output: 142 bytes

sed 'h
s/$/npbcccnsurdddnbeeepnp bbbbbbp/
:
s/b/qt/
s/c/quot/
s/d/psor/
s/e/suor/
t
y/nopqrstu/\n─│┌┐└┘┼/
G'<<<'0 1 2 3 4 5 6 7'

Output:

0 1 2 3 4 5 6 7
│┌┘┌┼─┘┌┼─┘┌┼─┘
└┼┐│└─┐│└─┐│└─┐
┌┘└┼─┐└┼─┐└┼─┐│
│ ┌┘┌┘┌┘┌┘┌┘┌┘│
0 1 2 3 4 5 6 7

Marco

Posted 2016-06-27T16:57:14.197

Reputation: 581