Write language name in 3D ASCII
The task is to write the language's name in 3D ASCII. (We can leave the definition of "3D ASCII" fuzzy, so long as the result is interesting or amusing, not a cheap hack to satisfy the task.)
You are encouraged to solve this task according to the task description, using any language you may know.
Ada
Quotes are not escaped by \ in ada (nor does \ have any meaning in strings), so this turns out highlighting funny. <lang Ada>with Ada.Text_IO; use Ada.Text_IO; with Ada.Strings.Fixed; use Ada.Strings.Fixed; procedure AsciiArt is
art : constant array(1..27) of String(1..14) := (1=>" /\\\\\\ ", 2=>" /\\\", 3|6|9=>" ", 4|12=>" /\\\\\\\\\\ ", 5|8|11=>" \/\\\", 7|17|21=>" /\\\//////\\\", 10|19|20|22=>"\/\\\ \/\\\", 13|23|24=>"\/\\\\\\\\\\\\", 14|18=>" /\\\\\\\\\\\", 15=>" \/////////\\\", 16=>"\/\\\//////\\\", 25=>"\/// \/// ", 26|27=>"\//////////// ");
begin
for i in art'Range loop Put(art(i)&' '); if i mod 3 = 0 then New_Line; Put(i/3*' '); end if; end loop;
end AsciiArt;</lang>
- Output:
/\\\\\\ /\\\ /\\\\\\\\\\ \/\\\ /\\\//////\\\ \/\\\ \/\\\ \/\\\ \/\\\ /\\\\\\\\\\ \/\\\\\\\\\\\\ /\\\\\\\\\\\ \/////////\\\ \/\\\//////\\\ /\\\//////\\\ /\\\\\\\\\\\ \/\\\ \/\\\ \/\\\ \/\\\ /\\\//////\\\ \/\\\ \/\\\ \/\\\\\\\\\\\\ \/\\\\\\\\\\\\ \/// \/// \//////////// \////////////
BBC BASIC
Uses the built-in BBC Micro-compatible character generator, so any text can be specified. <lang bbcbasic> PROC3dname("BBC BASIC")
END DEF PROC3dname(name$) LOCAL A%, X%, Y%, char%, row%, patt%, bit% DIM X% 8 : A% = 10 : Y% = X% DIV 256 FOR row% = 1 TO 8 FOR char% = 1 TO LEN(name$) ?X% = ASCMID$(name$,char%) CALL &FFF1 patt% = X%?row% FOR bit% = 7 TO 0 STEP -1 CASE TRUE OF WHEN (patt% AND 2^bit%) <> 0 : PRINT "#"; WHEN GET$(POS-1,VPOS-1) = "#": PRINT "\"; OTHERWISE: PRINT " "; ENDCASE NEXT NEXT char% PRINT NEXT row% ENDPROC</lang>
Output:
##### ##### #### ##### #### #### ###### #### ##\\## ##\\## ##\\## ##\\## ##\\## ##\\## \##\\\ ##\\## ##\ ##\ ##\ ##\ ##\ \\ ##\ ##\ ##\ ##\ ##\ \\ ##\ ##\ \\ #####\\ #####\\ ##\ #####\\ ######\ #### ##\ ##\ ##\\## ##\\## ##\ ##\\## ##\\##\ \\## ##\ ##\ ##\ ##\ ##\ ##\ ##\ ## ##\ ##\ ##\ ##\ ## ##\ ##\ ##\ ## #####\\ #####\\ ####\\ #####\\ ##\ ##\ ####\\ ###### ####\\ \\\\\ \\\\\ \\\\ \\\\\ \\ \\ \\\\ \\\\\\ \\\\
C
3D enough?<lang c>#include <stdio.h> char*s = " _____\n /____/\\\n/ ___\\/\n\\ \\/__/\n \\____/"; int main(){ puts(s); return 0; }</lang>
D
This generates a single image ASCII stereogram. <lang d>// Derived from AA3D - ASCII art stereogram generator // by Jan Hubicka and Thomas Marsh // (GNU General Public License) // http://aa-project.sourceforge.net/aa3d/ // http://en.wikipedia.org/wiki/ASCII_stereogram
import std.stdio, std.string, std.random;
immutable image = "
111111111111111 1111111111111111 11111 1111 11111 1111 11111 1111 11111 1111 11111 1111 11111 1111 1111111111111111 111111111111111
";
void main() {
enum int width = 50; immutable text = "DLanguage"; enum int skip = 12;
char[65536 / 2] data;
foreach (y, row; image.splitLines()) { immutable int shift = uniform(0, int.max); bool l = false;
foreach (x; 0 .. width) { int s; if (!l && x > skip) { s = (x < row.length) ? row[x] : '\n'; if (s == ' ') { s = 0; } else if (s == '\n') { s = 0; l = true; } else if (s >= '0' && s <= '9') { s = '0' - s; } else s = -2; } else s = 0;
s += skip; s = x - s; s = (s < 0) ? text[(x + shift) % text.length] : data[s]; data[x] = cast(char)s; write(data[x]); }
writeln(); }
}</lang>
- Output:
nguageDLangunguageDLangunguageDLangunguageDLangung DLanguageDLaDLangugeDLaDLangugeDLLaDLangugeDLLaDLa nguageDLangunguageLangunguageLanguunguageLanguungu LanguageDLanLanguagDLanLLanguagLanLLLanguagLanLLLa eDLanguageDLeDLangugeDLeeDLangugDLeeeDLangugDLeeeD guageDLanguaguageDLnguagguageDLnuaggguageDLnuagggu LanguageDLanLanguagDLanLLanguagDanLLLanguagDanLLLa nguageDLangunguageDangunnguageDagunnnguageDagunnng LanguageDLanLanguagDLanLLanguagLanLLLanguagLanLLLa nguageDLangunguageLangunguageLanguunguageLanguungu geDLanguageDgeDLanuageDgeDLanuageeDgeDLanuageeDgeD guageDLanguaguageDLanguaguageDLanguaguageDLanguagu
Go
Go does have a "Go" logo, although it is rarely used. A graphic is at http://golang.org/doc/gopher/bumper.png and the logo is the word Go with the two little lines to suggest movement. It's not 3D, so for inspiration I googled 3D ASCII fonts or something similar and found Patrick Gillespie's site at patorjk.com/software/taag/ with lots of ASCII fonts. The first one I liked was "Block" for its simple 3D illusion of drawing only the shadow, then I found "Lean." It's the same 3D effect as Block only slanted, reminiscent of the slanted Go logo.
For the interest component of the task, I thought about rendering the result from an input string and realized that it wasn't completely trivial as the glyphs of the Lean font overlap with the standard letter spacing. Rendering different fonts would add interest because now there would be a point in developing a common font representation and rendering function. Block and Lean would have sufficed, but I looked further and found the Keyboard and Small Keyboard fonts. These I found somewhat amusing, for the final component of the task. <lang go>package main
import (
"fmt" "strings"
)
var lean = font{
height: 5, slant: 1, spacing: 2, m: map[rune][]string{ 'G': []string{ ` _/_/_/`, `_/ `, `_/ _/_/`, `_/ _/`, ` _/_/_/`, }, 'o': []string{ ` `, ` _/_/ `, `_/ _/`, `_/ _/`, ` _/_/ `, }, }}
var smallKeyboard = font{
height: 4, slant: 0, spacing: -1, m: map[rune][]string{ 'G': []string{ ` ____ `, `||G ||`, `||__||`, `|/__\|`, }, 'o': []string{ ` ____ `, `||o ||`, `||__||`, `|/__\|`, }, }}
type font struct {
height int slant int spacing int m map[rune][]string
}
func render(s string, f font) string {
rows := make([]string, f.height) if f.slant != 0 { start := 0 if f.slant > 0 { start = f.height } for i := range rows { rows[i] = strings.Repeat(" ", (start-i)*f.slant) } } if f.spacing >= 0 { spacing := strings.Repeat(" ", f.spacing) for j, c := range s { for i, r := range f.m[c] { if j > 0 { r = spacing + r } rows[i] += r } } } else { overlap := -f.spacing for j, c := range s { for i, r := range f.m[c] { if j > 0 { r = r[overlap:] } rows[i] += r } } } return strings.Join(rows, "\n")
}
func main() {
fmt.Println(render("Go", lean)) fmt.Println(render("Go", smallKeyboard))
}</lang>
- Output:
_/_/_/ _/ _/_/ _/ _/_/ _/ _/ _/ _/ _/ _/ _/_/_/ _/_/ ____ ____ ||G |||o || ||__|||__|| |/__\|/__\|
Haskell
A simple printing of the ASCII art <lang Haskell>module Main where {-
__ __ __ ___ ___
/\ \/\ \ /\ \ /\_ \ /\_ \ \ \ \_\ \ __ ____\ \ \/'\ __\//\ \ \//\ \
\ \ _ \ /'__`\ /',__\\ \ , < /'__`\\ \ \ \ \ \ \ \ \ \ \/\ \L\.\_/\__, `\\ \ \\`\ /\ __/ \_\ \_ \_\ \_ \ \_\ \_\ \__/.\_\/\____/ \ \_\ \_\ \____\/\____\/\____\ \/_/\/_/\/__/\/_/\/___/ \/_/\/_/\/____/\/____/\/____/
-}
ascii3d :: String ascii3d = " __ __ __ ___ ___ \n" ++
"/\\ \\/\\ \\ /\\ \\ /\\_ \\ /\\_ \\ \n" ++ "\\ \\ \\_\\ \\ __ ____\\ \\ \\/'\\ __\\//\\ \\ \\//\\ \\ \n" ++ " \\ \\ _ \\ /'__`\\ /',__\\\\ \\ , < /'__`\\\\ \\ \\ \\ \\ \\ \n" ++ " \\ \\ \\ \\ \\/\\ \\L\\.\\_/\\__, `\\\\ \\ \\\\`\\ /\\ __/ \\_\\ \\_ \\_\\ \\_ \n" ++ " \\ \\_\\ \\_\\ \\__/.\\_\\/\\____/ \\ \\_\\ \\_\\ \\____\\/\\____\\/\\____\\\n" ++ " \\/_/\\/_/\\/__/\\/_/\\/___/ \\/_/\\/_/\\/____/\\/____/\\/____/"
main = do
putStrLn ascii3d
</lang>
This outputs
__ __ __ ___ ___ /\ \/\ \ /\ \ /\_ \ /\_ \ \ \ \_\ \ __ ____\ \ \/'\ __\//\ \ \//\ \ \ \ _ \ /'__`\ /',__\\ \ , < /'__`\\ \ \ \ \ \ \ \ \ \ \/\ \L\.\_/\__, `\\ \ \\`\ /\ __/ \_\ \_ \_\ \_ \ \_\ \_\ \__/.\_\/\____/ \ \_\ \_\ \____\/\____\/\____\ \/_/\/_/\/__/\/_/\/___/ \/_/\/_/\/____/\/____/\/____/
Icon and Unicon
The following fits under the fuzzy definition of 3D ASCII and pays homage to one of the Icon Newsletter logos. <lang Icon>procedure main(arglist) write(ExpandText(
if !arglist == "icon" then "14/\\\n14\\/\n12/\\\n11/1/\n10/1/1/\\\n10\\/1/2\\\n12/1/\\1\\\n_ 12\\1\\1\\/\n10/\\1\\1\\2/\\\n9/2\\1\\/1/2\\\n_ 8/1/\\1\\2/1/\\1\\2/\\\n8\\1\\/1/2\\1\\/1/2\\1\\\n_ 6/\\1\\2/4\\2/1/\\1\\1\\\n5/1/2\\/6\\/1/2\\1\\/\n_ /\\2/1/1/\\10/1/\\1\\2/\\\n\\/2\\1\\/1/10\\/1/1/2\\/\n_ 2/\\1\\2/1/\\6/\\2/1/\n2\\1\\1\\/1/2\\4/2\\1\\/\n_ 3\\1\\2/1/\\1\\2/1/\\1\\\n4\\/2\\1\\/1/2\\1\\/1/\n_ 9\\2/1/\\1\\2/\n10\\/2\\1\\1\\/\n12/\\1\\1\\\n12\\1\\/1/\n_ 13\\2/1/\\\n14\\/1/1/\n16/1/\n16\\/\n14/\\\n14\\/\n" else "13/\\\n12/1/\n11/1/1/\\\n11\\1\\/1/\n12\\2/1/\\\n13\\/1/2\\\n_ 15/1/\\1\\2/\\\n15\\/1/1/2\\/\n17/1/1/\\18/\\\n17\\/1/1/17/2\\\n_ 19/1/1/\\14/1/\\1\\\n19\\/1/2\\13\\1\\1\\/\n21/1/\\1\\10/\\1\\1\\\n_ 21\\1\\1\\/10\\1\\1\\/\n19/\\1\\1\\2/\\6/\\1\\1\\\n_ 18/2\\1\\/1/2\\5\\1\\/1/\n17/1/\\1\\2/1/\\1\\2/\\1\\2/\n_ 17\\1\\/1/2\\1\\/1/2\\1\\1\\/\n15/\\1\\2/4\\2/1/\\1\\1\\\n_ 14/1/2\\/6\\/1/2\\1\\/\n9/\\2/1/1/\\10/1/\\1\\2/\\\n_ 9\\/2\\1\\/1/10\\/1/1/2\\/\n11/\\1\\2/1/\\6/\\2/1/\n_ 11\\1\\1\\/1/2\\4/2\\1\\/\n9/\\1\\1\\2/1/\\1\\2/1/\\1\\\n_ 8/2\\1\\/2\\1\\/1/2\\1\\/1/\n7/1/\\1\\5\\2/1/\\1\\2/\n_ 7\\1\\1\\/6\\/2\\1\\1\\/\n5/\\1\\1\\10/\\1\\1\\\n_ 5\\1\\1\\/10\\1\\/1/\n3/\\1\\1\\13\\2/1/\\\n3\\1\\/1/14\\/1/1/\n_ 4\\2/17/1/1/\\\n5\\/18\\/1/1/\n23/\\2/1/1/\\\n23\\/2\\1\\/1/\n_ 28\\2/1/\\\n29\\/1/2\\\n31/1/\\1\\\n31\\/1/1/\n33/1/\n33\\/\n" ))
end
procedure ExpandText(s) s ? until pos(0) do
writes(repl(" ",tab(many(&digits)))|tab(upto(&digits)|0))
end</lang>
Sample output with "icon" as the argument:
/\ \/ /\ / / / / /\ \/ / \ / /\ \ \ \ \/ /\ \ \ /\ / \ \/ / \ / /\ \ / /\ \ /\ \ \/ / \ \/ / \ \ /\ \ / \ / /\ \ \ / / \/ \/ / \ \/ /\ / / /\ / /\ \ /\ \/ \ \/ / \/ / / \/ /\ \ / /\ /\ / / \ \ \/ / \ / \ \/ \ \ / /\ \ / /\ \ \/ \ \/ / \ \/ / \ / /\ \ / \/ \ \ \/ /\ \ \ \ \/ / \ / /\ \/ / / / / \/ /\ \/
J
<lang j> require 'vrml.ijs' NB. Due to Andrew Nikitin
view 5#.^:_1]21-~a.i.'j*ez`C3\toy.G)' NB. Due to Oleg Kobchenko ________________________ |\ \ \ \ \ | \_____\_____\_____\_____\ | | | | |\ \ |\| | | | \_____\ | \_____|_____|_____| | | | | | | | |\| | \| | |\| | \_____| \_____| | \_____| | | | |\| | | \_____| ______ | | |
|\ \ |\| | | \_____\_________|_\_____| | |\ \ \ \ |
\| \_____\_____\_____\ | | | | | |___| \| | | | \_____|_____|_____|
</lang>
For the VRML script, see Andrew Nikitin's J page (search for VRML) and for the origin of the 3D J banner, see Oleg Kobchenko's post to the J Forums.
NetRexx
Based on an idea found in the Scala version. <lang NetRexx>/* NetRexx */ options replace format comments java crossref symbols nobinary
txt = ; x = 0 x = x + 1; txt[0] = x; txt[x] = ' * * *****' x = x + 1; txt[0] = x; txt[x] = ' ** * * * *' x = x + 1; txt[0] = x; txt[x] = ' * * * *** *** * * *** * * * *' x = x + 1; txt[0] = x; txt[x] = ' * * * * * * ***** * * * * * *' x = x + 1; txt[0] = x; txt[x] = ' * ** ***** * * * ***** * *' x = x + 1; txt[0] = x; txt[x] = ' * * * * * * * * * * *' x = x + 1; txt[0] = x; txt[x] = ' * * *** ** * * *** * * * *' x = x + 1; txt[0] = x; txt[x] =
_top = '_TOP' _bot = '_BOT' txt = Banner3D(txt, isTrue()) loop ll = 1 to txt[0]
say txt[ll, _top] say txt[ll, _bot] end ll
return
method Banner3D(txt, slope = ) public static
select when slope = isTrue() then nop when slope = isFalse() then nop otherwise do if slope = then slope = isFalse() else slope = isTrue() end end
_top = '_TOP' _bot = '_BOT' loop ll = 1 to txt[0] txt[ll, _top] = txt[ll] txt[ll, _bot] = txt[ll] txt[ll, _top] = txt[ll, _top].changestr(' ', ' ') txt[ll, _bot] = txt[ll, _bot].changestr(' ', ' ') txt[ll, _top] = txt[ll, _top].changestr('*', '///') txt[ll, _bot] = txt[ll, _bot].changestr('*', '\\\\\\') txt[ll, _top] = txt[ll, _top] || ' ' txt[ll, _bot] = txt[ll, _bot] || ' ' txt[ll, _top] = txt[ll, _top].changestr('/ ', '/\\') txt[ll, _bot] = txt[ll, _bot].changestr('\\ ', '\\/') end ll
if slope then do loop li = txt[0] to 1 by -1 ll = txt[0] - li + 1 txt[ll, _top] = txt[ll, _top].insert(, 1, li - 1, ' ') txt[ll, _bot] = txt[ll, _bot].insert(, 1, li - 1, ' ') end li end
return txt
method isTrue public constant binary returns boolean
return 1 == 1
method isFalse public constant binary returns boolean
return \isTrue()
</lang> Output:
///\ ///\ ///////////////\ \\\/ \\\/ \\\\\\\\\\\\\\\/ //////\ ///\ ///\ ///\ ///\ \\\\\\/ \\\/ \\\/ \\\/ \\\/ ///\ ///\ ///\ /////////\ /////////\ ///\ ///\ /////////\ ///\ ///\ ///\ ///\ \\\/ \\\/ \\\/ \\\\\\\\\/ \\\\\\\\\/ \\\/ \\\/ \\\\\\\\\/ \\\/ \\\/ \\\/ \\\/ ///\ ///\ ///\ ///\ ///\ ///\ ///////////////\ ///\ ///\ ///\ ///\ ///\ ///\ \\\/ \\\/ \\\/ \\\/ \\\/ \\\/ \\\\\\\\\\\\\\\/ \\\/ \\\/ \\\/ \\\/ \\\/ \\\/ ///\ //////\ ///////////////\ ///\ ///\ ///\ ///////////////\ ///\ ///\ \\\/ \\\\\\/ \\\\\\\\\\\\\\\/ \\\/ \\\/ \\\/ \\\\\\\\\\\\\\\/ \\\/ \\\/ ///\ ///\ ///\ ///\ ///\ ///\ ///\ ///\ ///\ ///\ ///\ \\\/ \\\/ \\\/ \\\/ \\\/ \\\/ \\\/ \\\/ \\\/ \\\/ \\\/ ///\ ///\ /////////\ //////\ ///\ ///\ /////////\ ///\ ///\ ///\ ///\ \\\/ \\\/ \\\\\\\\\/ \\\\\\/ \\\/ \\\/ \\\\\\\\\/ \\\/ \\\/ \\\/ \\\/
Perl 6
<lang perl6>print <T,cc^,cc^,cc^,^,,1ccTA,^/A,c_A,^/A-,,@1c:@6;666;`,6;6666,A-c^U-,c`-,c_ -,,`--,661,N66;`66;`,6,/66;_--_-U-_,--cc_-_O_-cc_CccD6@@,6@,,@@B,@@,.@@,D8`,, 8cc`8`E`8cc@Lc`X>>>.ords>>.comb.map({(" |/\\\n_".comb)[$_-4]});</lang>
- Output:
_____ _____ _____ _ _____ /| _ \/| ___|/| _ \/| | / ___| / | |_| | | |__/ | |_| | | | /| |___ | | ___/ | ___| | _/ | | | | _ \ | | |__/| | |__/ | \| | |__| | |_| | | |_| | |_____| |_|\__| |_____|/\____/ | / / | / / / // / / // / / |/_/ |/_____/|/_//__/|/____/ \/___/
Python
Again based on the Scala type idea of 'fleshing out' a 2D banner version. <lang python>py = \
##### # # ##### # # #### # # # # # # # # # # # ## # # # # # ###### # # # # # ##### # # # # # # # # # # # # # # # # # ## # # # # # #### # #
lines = py.replace('#', '<<<').replace(' ','X').replace('X', ' ').replace('\n', ' Y').replace('< ', '<>').split('Y') for i, l in enumerate(lines):
print( ' ' * (len(lines) - i) + l)</lang>
- Output:
<<<<<<<<<<<<<<<> <<<> <<<> <<<<<<<<<<<<<<<> <<<> <<<> <<<<<<<<<<<<> <<<> <<<> <<<> <<<> <<<> <<<> <<<> <<<> <<<> <<<> <<<> <<<<<<> <<<> <<<> <<<> <<<> <<<> <<<<<<<<<<<<<<<<<<> <<<> <<<> <<<> <<<> <<<> <<<<<<<<<<<<<<<> <<<> <<<> <<<> <<<> <<<> <<<> <<<> <<<> <<<> <<<> <<<> <<<> <<<> <<<> <<<> <<<> <<<> <<<<<<> <<<> <<<> <<<> <<<> <<<> <<<<<<<<<<<<> <<<> <<<>
REXX
block chars
The REXX program works in ASCII or EBCDIC.
It's astonishing how much time I wasted spent on this program.
Most of the time was spent on writing comments, but the code was so easy to read, so the comments were elided.
Some older REXXes don't have the changestr bif, so one is included here.
<lang rexx>/*REXX program that displays a "REXX" 3D "ASCII art" as a logo. */
signal . /* Uses left-hand shadows, slightly raised view.
0=5~2?A?2?A?
@)E)3@)B)1)2)8()2)1)2)8()2)
@]~")2@]0`)0@)%)6{)%)0@)%)6{)%)
- E)1#A@0}2)4;2(1}2)4;2(
- 3??3@0#2??@1}2)2;2(3}2)2;2(
- 2@5@)@2@0#2@A}2)0;2(5}2)0;2(
- 2@?"@)@2@0#2@?7}2){2(7}2){2(
- 2@6)@2@0#2@3)7}2)(2(9}2)(2(
- 2@??@2@0#2@?_)7}5(B}5(
- F@0#8@8}3(D}3(
- 3%3?(1#3?_@7;3)C;3)
- 2@0}2)5#2@C;5)A;5)
- 2@1}2)4#2@B;2()2)8;2()2)
- 2@2}2)3#2@?"4;2(}2)6;2(}2)
- 2@3}2)2#2@5)2;2(1}2)4;2(1}2)
- 2@4}2)1#2@?%)0;2(3}2)2;2(3}2)
0]@2@5}2)1]@A@0)[2(5}2)1)[2(5}2) 1)@%@6}%)1)@`@1V%(7}%)1V%(7}%)
- /;.:a=sigL+1;signal ..;..:u='_';do j=a to sigl-1
_=sourceline(j);_=_('(',"/");_=_('[',"//");_=_('{',"///") _=_(';',"////");_=_(')',"\");_=_(']',"\\");_=_('}',"\\\");_=_('"',"__") _=_('%',"___");_=_('?',left(,4,u));_=_('`',left(,11,u));_=_('~',left(, ,13,u));_=_('=',left(,16,u));_=_('#','|\\|');_=translate(_,"|"u,'@"') do k=0 for 16;x=d2x(k,1);_=_(x,left(,k+1));end;say ' '_;end;exit;_:return, changestr(arg(1),_,arg(2)) /*───────────────────────────CHANGESTR subroutine───────────────────────*/ changestr: procedure; parse arg o,h,n,,r; w=length(o); if w==0 then return n||h do forever; parse var h y (o) _ +(w) h; if _== then return r||y;r=r||y||n;end</lang> output
________________ _____________ ____ ____ ____ ____ |\ \ |\ \ \ \ /\ \ \ \ /\ \ |\\_______________\ |\\ ___________\ |\___\ ///\___\ |\___\ ///\___\ |\\| \ |\\| | \\\ \ //// / \\\ \ //// / |\\| ________ | |\\| ________| \\\ \ //// / \\\ \ //// / |\\| | |\| | |\\| | \\\ \ //// / \\\ \ //// / |\\| |______|\| | |\\| |____ \\\ \/// / \\\ \/// / |\\| | \| | |\\| | \ \\\ \/ / \\\ \/ / |\\| |________| | |\\| |_____\ \\\ / \\\ / |\\| | |\\| | \\\ / \\\ / |\\| ___ ____/ |\\| _____| //// \ //// \ |\\| | \\\ \ |\\| | //// \ //// \ |\\| | \\\ \ |\\| | //// /\ \ //// /\ \ |\\| | \\\ \ |\\| |______ //// /\\\ \ //// /\\\ \ |\\| | \\\ \ |\\| | \ //// / \\\ \ //// / \\\ \ |\\| | \\\ \ |\\| |_______\ //// / \\\ \ //// / \\\ \ \\| | \\\ \ \\| | \// / \\\ \ \// / \\\ \ \|___| \\\___\ \|___________| V___/ \\\___\ V___/ \\\___\
Unobfuscated
<lang REXX>/* Rexx */
drop !top !bot x = 0 x = x + 1; txt.0 = x; txt.x = ' *****' x = x + 1; txt.0 = x; txt.x = ' * *' x = x + 1; txt.0 = x; txt.x = ' * * ***** * * * *' x = x + 1; txt.0 = x; txt.x = ' ***** * * * * *' x = x + 1; txt.0 = x; txt.x = ' * * *** * *' x = x + 1; txt.0 = x; txt.x = ' * * * * * * *' x = x + 1; txt.0 = x; txt.x = ' * * ***** * * * *' x = x + 1; txt.0 = x; txt.x =
call Banner3D isTrue() do ll = 1 to txt.0
say txt.ll.!top say txt.ll.!bot end ll
return exit
Banner3D: procedure expose txt.
drop !top !bot parse arg slope .
select when slope = isTrue() then nop when slope = isFalse() then nop otherwise do if slope = then slope = isFalse() else slope = isTrue() end end
do ll = 1 to txt.0 txt.ll.!top = txt.ll txt.ll.!bot = txt.ll txt.ll.!top = changestr(' ', txt.ll.!top, ' ') txt.ll.!bot = changestr(' ', txt.ll.!bot, ' ') txt.ll.!top = changestr('*', txt.ll.!top, '///') txt.ll.!bot = changestr('*', txt.ll.!bot, '\\\') txt.ll.!top = txt.ll.!top || ' ' txt.ll.!bot = txt.ll.!bot || ' ' txt.ll.!top = changestr('/ ', txt.ll.!top, '/\') txt.ll.!bot = changestr('\ ', txt.ll.!bot, '\/') end ll
if slope then do do li = txt.0 to 1 by -1 ll = txt.0 - li + 1 txt.ll.!top = insert(, txt.ll.!top, 1, li - 1, ' ') txt.ll.!bot = insert(, txt.ll.!bot, 1, li - 1, ' ') end li end
return
exit
isTrue: procedure
return 1 == 1
isFalse: procedure
return \isTrue()
</lang> Output:
///////////////\ \\\\\\\\\\\\\\\/ ///\ ///\ \\\/ \\\/ ///\ ///\ ///////////////\ ///\ ///\ ///\ ///\ \\\/ \\\/ \\\\\\\\\\\\\\\/ \\\/ \\\/ \\\/ \\\/ ///////////////\ ///\ ///\ ///\ ///\ ///\ \\\\\\\\\\\\\\\/ \\\/ \\\/ \\\/ \\\/ \\\/ ///\ ///\ /////////\ ///\ ///\ \\\/ \\\/ \\\\\\\\\/ \\\/ \\\/ ///\ ///\ ///\ ///\ ///\ ///\ ///\ \\\/ \\\/ \\\/ \\\/ \\\/ \\\/ \\\/ ///\ ///\ ///////////////\ ///\ ///\ ///\ ///\ \\\/ \\\/ \\\\\\\\\\\\\\\/ \\\/ \\\/ \\\/ \\\/
simpler, shorter
This is a version of the above REXX program (with a minor bug fixed), text [*] has additional spacing between letters. <lang rexx>/*REXX pgm draws a "3D" image of text representation ("*" MUST be used).*/ Line.1 = '*****' Line.2 = '* *' Line.3 = '* * ***** * * * *' Line.4 = '***** * * * * *' Line.5 = '* * *** * *' Line.6 = '* * * * * * *' Line.7 = '* * ***** * * * *' Lines = 7 /*number of lines of text for 3D.*/
do j=1 for Lines /*build the artwork for the text.*/ Line.j.1 = changestr(' ', " "Line.j, ' ') Line.j.2 = Line.j.1 Line.j.1 = changestr('*', Line.j.1, '///')" " Line.j.2 = changestr('*', Line.j.2, '\\\')" " Line.j.1 = changestr('/ ', Line.j.1, '/\') Line.j.2 = changestr('\ ', Line.j.2, '\/') end /*j*/
do k=Lines by -1 to 1; m=Lines-k+1 /*indent the artwork*/ do n=1 for 2; Line.m.n = insert(, Line.m.n, 1, k-1, ' '); end end /*k*/
do i=1 for Lines /*show the artwork. */ say Line.i.1 /*top layer. */ say Line.i.2 /*shadow layer. */ end /*i*/</lang>
output when using the default input
///////////////\ \\\\\\\\\\\\\\\/ ///\ ///\ \\\/ \\\/ ///\ ///\ ///////////////\ ///\ ///\ ///\ ///\ \\\/ \\\/ \\\\\\\\\\\\\\\/ \\\/ \\\/ \\\/ \\\/ ///////////////\ ///\ ///\ ///\ ///\ ///\ \\\\\\\\\\\\\\\/ \\\/ \\\/ \\\/ \\\/ \\\/ ///\ ///\ /////////\ ///\ ///\ \\\/ \\\/ \\\\\\\\\/ \\\/ \\\/ ///\ ///\ ///\ ///\ ///\ ///\ ///\ \\\/ \\\/ \\\/ \\\/ \\\/ \\\/ \\\/ ///\ ///\ ///////////////\ ///\ ///\ ///\ ///\ \\\/ \\\/ \\\\\\\\\\\\\\\/ \\\/ \\\/ \\\/ \\\/
Scala
<lang Scala>def ASCII3D = {
val name = """ * ** ** * * * * * * * * * * * * * * * * * * * *** * *** * * * * * * * * * * * * * * ** ** * * *** * * * * """
// // Create Array // def getMaxSize( s:String ) : (Int,Int) = { var width = 0 var height = 0 val nameArray = s.split("\n") height = nameArray.size nameArray foreach {i => width = (i.size max width)} (width,height) } val size = getMaxSize( name ) var arr = Array.fill( size._2+1, (size._1*3)+(size._2+1) )( ' ' )
// // Map astrisk to 3D cube // val cubeTop = """///\""" val cubeBottom = """\\\/""" val nameArray = name.split("\n")
for( j <- (0 until nameArray.size) ) { for( i <- (0 until nameArray(j).size) ) { if( nameArray(j)(i) == '*' ) { val indent = nameArray.size - j arr(j ) = arr(j ) patch ((i*3 + indent), cubeTop, cubeTop.size) arr(j+1) = arr(j+1) patch ((i*3 + indent), cubeBottom, cubeBottom.size) } } } // // Map Array to String // var name3D = "" for( j <- (0 until arr.size) ) { for( i <- (0 until arr(j).size) ) { name3D += arr(j)(i) } name3D += "\n" } name3D
}
println(ASCII3D)</lang>
- Output:
///\ //////\ //////\ ///\ ///\/ ///\ ///\\\\\\\/ ///\\\\\\\/ ///\\\///\ ///\/ ///\\\///\ ///\/ ///\/ ///\/ ///\/ ///\/ ///\/ ///\/ \\///\ ///\/ /////////\/ ///\/ /////////\/ \\///\ ///\/ ///\\\///\/ ///\/ ///\\\///\/ ///\/ ///\/ ///\/ ///\/ ///\/ ///\/ ///\/ //////\\\\/ \\//////\ ///\/ \\///\ /////////\ ///\/ ///\/ \\\\\\/ \\\\\\/ \\\/ \\\/ \\\\\\\\\/ \\\/ ///\/ \\///\ \\\/
Tcl
<lang tcl>package require Tcl 8.5
proc mergeLine {upper lower} {
foreach u [split $upper ""] l [split $lower ""] {
lappend result [expr {$l in {" " ""} ? $u : $l}]
} return [join $result ""]
} proc printLines lines {
set n [llength $lines] foreach line $lines {
set indent [string repeat " " $n] lappend upper $indent[string map {"/ " "/\\"} [ string map {" " " " "*" "///"} "$line "]] lappend lower $indent[string map {"\\ " "\\/"} [ string map {" " " " "*" "\\\\\\"} "$line "]] incr n -1
} # Now do some line merging to strengthen the visual effect set p [string repeat " " [string length [lindex $upper 0]]] foreach u $upper l $lower {
puts [mergeLine $p $u] set p $l
} puts $p
}
set lines {
{***** *} { * *} { * *** *} { * * *} { * * *} { * *** *}
} printLines $lines</lang>
- Output:
///////////////\ ///\ \\\\\///\\\\\\\/ ///\/ ///\/ /////////\ ///\/ ///\/ ///\\\\\\\/ ///\/ ///\/ ///\/ ///\/ ///\/ /////////\ ///\/ \\\/ \\\\\\\\\/ \\\/
XPL0
Here's XPL0's "cheap hack." (Hats off to D!) <lang XPL0>include c:\cxpl\codes;
proc DrawBlock(X, Y); int X, Y; [Cursor(X+1, Y); Text(0, "///\");
Cursor(X, Y+1); Text(0,"/// \"); Cursor(X, Y+2); Text(0,"\\\ /"); Cursor(X+1, Y+3); Text(0, "\\\/");
];
int Data, D, X, Y; [ChOut(0, $C); \form feed, clears screen Data:= [%1000100011110000100000001110,
%1000100010001000100000010001, %0101000010001000100000010011, %0010000011110000100000010101, %0101000010000000100000011001, %1000100010000000100000010001, %1000100010000000111110001110];
for Y:= 0 to 6 do
[D:= Data(Y); for X:= 0 to 27 do [if D&1<<27 then DrawBlock(X*2+(6-Y)*2, Y*2); D:= D<<1; ]; ];
]</lang>
Output:
///\ ///\ /////////\ ///\ ///////\ /// \ /// \ ///////// \ /// \ /////// \ ///\ / ///\ / ///\\\\\///\/ ///\ / ///\\\\\///\/ /// \/ /// \/ /// \\\/// \ /// \/ /// \\\/// \ \///\///\\\ / ///\ / ///\ / ///\ / ///\ /////\ / /// /// \\\/ /// \/ /// \/ /// \/ /// \///// \/ \///\\\ / /////////\\\ / ///\ / ///\///\///\ / /// \\\/ ///////// \\\/ /// \/ /// /// /// \/ ///\///\/ ///\\\\\\\ / ///\ / /////\\\///\ / /// /// \ /// \\\\\\\/ /// \/ ///// \/// \/ ///\\\ \///\/ ///\ / ///\ / ///\\\ ///\ / /// \\\/// \ /// \/ /// \/ /// \\\/// \/ ///\ / ///\ / ///\ / ///////////\ \///////\\\ / /// \/ /// \/ /// \/ /////////// \ /////// \\\/ \\\ / \\\ / \\\ / \\\\\\\\\\\ / \\\\\\\ / \\\/ \\\/ \\\/ \\\\\\\\\\\/ \\\\\\\/
ZX Spectrum Basic
We have used an extended (non-ASCII) character in this example to produce an inverted space symbol (143 on the spectrum character table), for simplicity. We could substitute another character, and change the handler to cause a colour switch using a traditional space (ascii 32), but the output would still look the same.
<lang zxbasic>10 LET s$="BASIC": REM our language name 20 DIM b(5,5):REM our bigmap characters 30 FOR l = 1 TO 5: REM 5 characters 40 FOR m = 1 TO 5: REM 5 rows 50 READ b(l,m) 60 NEXT m 70 NEXT l
100 PAPER 0: REM black background 110 INK 2: REM our shadow will be red 120 CLS 130 LET r=9: REM shadow will start on row 5 140 LET c=2: REM shadow will start at column 2 150 GO SUB 2000: REM draw shadow 160 INK 6: REM our forground will be yellow 170 LET r=10: REM foreground will start on row 6 180 LET c=3: REM foreground will start on column 3 190 GO SUB 2000: REM display the language name
999 STOP
1000 REM convert to binary bigmap 1010 LET t=n: REM temporary variable 1020 LET g$="": REM this will contain our 5 character binary bigmap 1040 FOR z=5 TO 0 STEP -1 1050 LET d$=" ": REM assume next digit is zero (draw a space) 1060 IF t>=(2^z) THEN LET d$=CHR$(143): LET t=t-(2^z): LET sf=1: REM 143 is a block 1070 LET g$=g$+d$ 1080 NEXT z 1090 RETURN
2000 REM display the big letters 2010 FOR l=1 TO 5: REM our 5 rows 2020 PRINT AT r+l-1,c; 2030 FOR m=1 TO 5: REM bigmap for each character 2040 LET n=b(l,m) 2050 GO SUB 1000 2060 PRINT g$;: REM 5 character bigmap 2070 PRINT " ";: REM space between each letter 2080 NEXT m 2090 NEXT l 2100 RETURN
9000 DATA 30,17,30,17,30: REM B 9010 DATA 14,17,31,17,17: REM A 9020 DATA 15,16,14,1,30: REM S 9030 DATA 31,4,4,4,31: REM I 9040 DATA 14,17,16,17,14: REM C</lang>