<[LAM] 24-12-2016> [sergiol] proposes in your page an exercise of code golf: make an ascii keyboard (according this https://codegolf.stackexchange.com/questions/103033/a-keyboard-so-real-you-can-almost-taste-it%|%code golf page%|%). The result must be this: ====== ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ________ ||` |||1 |||2 |||3 |||4 |||5 |||6 |||7 |||8 |||9 |||0 |||- |||= |||BS || ||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||______|| |/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/______\| ________ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ||TAB |||Q |||W |||E |||R |||T |||Y |||U |||I |||O |||P |||[ |||] |||\ || ||______|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|| |/______\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\| _________ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ________ ||CAPS |||A |||S |||D |||F |||G |||H |||J |||K |||L |||; |||' |||ENTER || ||_______|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||______|| |/_______\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/______\| ___________ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ___________ ||SHIFT |||Z |||X |||C |||V |||B |||N |||M |||, |||. |||/ |||SHIFT || ||_________|||__|||__|||__|||__|||__|||__|||__|||__|||__|||__|||_________|| |/_________\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|/_________\| ====== I found this was a funny way to push the boundaries of tcl (and of my knowledge about it). For example, after this exercise i've learned(suffered) a lot about the delicate relationship among spaces and brackets. This is my best anwser ... * One line: ====== foreach z {S R M} w {set "regsub -all" "string map"} {interp alias {} $z {} {*}$w};foreach x {"`1234567890-=¿BS ¿" "¿TAB ¿QWERTYUIOP\[\]\\" "¿CAPS ¿ASDFGHJKL;'¿ENTER¿" "¿SHIFT ¿ZXCVBNM,./¿SHIFT ¿"} {S h [M {\\ _ / _ | \ } [S g [M {||_ |/_ _|| _\\|} [M {||| \\|/} [S f [R {[^\n|]} [S b [M {|||| |||} [R {¿(\S+\s*)¿|(.)} $x {||\1\2 ||}]]] _ ]]]]]];puts $h\n$b\n$f\n$g} ====== * More readable: ====== foreach z {S R M} w {set "regsub -all" "string map"} { interp alias {} $z {} {*}$w } foreach x {"`1234567890-=¿BS ¿" \ "¿TAB ¿QWERTYUIOP\[\]\\" \ "¿CAPS ¿ASDFGHJKL;'¿ENTER¿" \ "¿SHIFT ¿ZXCVBNM,./¿SHIFT ¿" } { S h [M {\\ _ / _ | \ } \ [S g [M {||_ |/_ _|| _\\|} \ [M {||| \\|/} [S f \ [R {[^\n|]} [S b [M {|||| |||} \ [R {¿(\S+\s*)¿|(.)} $x {||\1\2 ||}]]] _ ]] ] ] ] ] puts $h\n$b\n$f\n$g } ====== ---- [AMG]: In the readable version, the first three line continuation backslashes are unnecessary. The enclosing braces already protect against the newlines being interpreted as command delimiters. I thought about suggesting replacing the double quotes on those same (four) lines with braces to avoid having to protect [[ and ]] with backslash, but that actually doesn't work because it is not possible to use brace quoting to construct a string which ends with an odd number of backslashes. Here's a perhaps more readable alternative to the first line which has the same number of characters: ====== foreach z {S R M} w {set "regsub -all" "string map"} { ;# original foreach {z w} {S set R {regsub -all} M {string map}} { ;# alternative ====== When I make complex value lists to [[[foreach]]], I tend to indent them like so: ====== foreach x { "`1234567890-=¿BS ¿" "¿TAB ¿QWERTYUIOP\[\]\\" "¿CAPS ¿ASDFGHJKL;'¿ENTER¿" "¿SHIFT ¿ZXCVBNM,./¿SHIFT ¿" } { .... } ====== <>Code golf