13
\$\begingroup\$

You are given one-quarter of a map that is symmetrical over the x- and y-axes as input. The program should print the complete map.

The map can contain the following characters: -+/\|., and they should be turned as expected. The in data is always rectangular and small.

Example

$ cat in
+---
|./.
|/..

$ ./solution < in
+------+
|./..\.|
|/....\|
|\..../|
|.\../.|
+------+

Shortest code wins.

\$\endgroup\$
3
  • \$\begingroup\$ What exactly does small mean for the input data? That's a bit vague to quantify. \$\endgroup\$
    – Joey
    Commented Feb 9, 2011 at 10:05
  • \$\begingroup\$ @Joey Let's say the input is at most 16 rows and 40 characters. \$\endgroup\$
    – user475
    Commented Feb 9, 2011 at 10:17
  • \$\begingroup\$ I realised that I put no time limit, but if someone needs more than a second for his solution, I'd really like to see it. \$\endgroup\$
    – user475
    Commented Feb 9, 2011 at 10:18

15 Answers 15

4
\$\begingroup\$

Canvas, 5 4 bytes

║Q↷↷

First Canvas answer, so let's start with an easy one. :)

-1 byte thanks to @dzaima.

The slashes are automatically converted when mirroring or rotating in Canvas.
Could have been 1 byte (Try it online), but unfortunately it also transforms the dots . to single quotes ' when mirroring horizontally.

Try it online.

Explanation:

         # (Take the multi-line input implicitly as canvas object)
║        # Palindromize the canvas object (without overlap)
 Q      # Output it with a trailing newline (without popping)
  ↷↷    # Rotated the canvas object that's still on the stack by 90 degrees twice
         # (and output it implicitly as well at the end)
\$\endgroup\$
0
2
\$\begingroup\$

Windows PowerShell, 99 103 117 126 129

filter x{$_-split'/'-replace'\\','/'-join'\'}$input|%{$_+-join($_[40..0]|x)}|%{$_
$s=,($_|x)+$s}
$s

Notes:

  • This unfortunately needs two things that PowerShell is notoriously bad at while golfing: Reversing a string (or sequence of values) and transliterating stuff in a string. I'm fairly sure that this is at least twice as long as a Perl of Ruby solution.

Test:

> gc in| .\map.ps1
+------+
|./..\.|
|/....\|
|\..../|
|.\../.|
+------+

> gc in2
+\/
/\/
> gc in2| .\map.ps1
+\/\/+
/\/\/\
\/\/\/
+/\/\+

History

  • 2011-02-09 11:10 (129) – First attempt.
  • 2011-02-09 11:27 (126) – OFS to save the -join and stored 99..0 in a variable.
  • 2011-02-09 11:31 (117) – -replace works against arrays, so I don't need three -replaces but can do a -split, -replace, -join instead.
  • 2011-02-09 15:03 (105) – Instead of doing the same thing twice, do it once and reverse it. And putting an assignment into parentheses causes it to spit out its value to the pipeline :-)
  • 2011-02-09 15:08 (103) – I don't need $a anymore since 99..0 isn't used that often by now.
  • 2011-02-09 15:17   (99) – There doesn't need to be whitespace after the filter definition. Removed $x and instead collecting every line during the first run in an array and then outputting that for the second half.
\$\endgroup\$
2
\$\begingroup\$

Ruby - 88 87 chars

t=->s{s.tr'/\\\\','\\\\/'}
puts a=$<.map{|l|l.chop!+t[l.reverse]}
puts a.reverse.map &t

Test Run

D:\tmp>ruby cg_sym_map.rb < sym_map.in.
+------+
|./..\.|
|/....\|
|\..../|
|.\../.|
+------+
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Nice, I like the puts-assignment. \$\endgroup\$
    – user475
    Commented Feb 9, 2011 at 14:40
  • \$\begingroup\$ Ah, there's my demise ;-) I knew it would come eventually \$\endgroup\$
    – Joey
    Commented Feb 9, 2011 at 15:53
2
\$\begingroup\$

APL (Dyalog Classic), 25 23 22 21 19 bytes

(⌽⍪⊖){⊃3⌽⍵∪'/\'}¨,⌽

Try it online!

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

Charcoal, 5 4 bytes

S‖M⌈

-1 byte thanks to @Neil.

Charcoal automatically handles reflecting the slashes correctly.

Try it online (verbose) or Try it online (pure).

Explanation:

Take the input as a string:

InputString()
S

Reflect mirror it both towards the right and downwards (:⌈ is a builtin for :Right, :Down):

ReflectMirror(:⌈)
‖M⌈
\$\endgroup\$
7
  • \$\begingroup\$ @ASCII-only has since added some more multidirectionals including which gives you right and down in a single byte. \$\endgroup\$
    – Neil
    Commented Jan 27, 2019 at 11:52
  • \$\begingroup\$ @Neil How do you use in the Verbose code? :RightDown will of course not be the result we'd want. \$\endgroup\$ Commented Jan 27, 2019 at 12:04
  • \$\begingroup\$ Multidirectionals just take a : prefix in Verbose mode. \$\endgroup\$
    – Neil
    Commented Jan 27, 2019 at 12:16
  • \$\begingroup\$ @Neil So :Right:Down, or ::RightDown, or something else? Neither of these two results will give a in the encoded version with the -vl argument, though. What would the verbose code have to become to get S‖M⌈ when using the -vl arg? \$\endgroup\$ Commented Jan 27, 2019 at 16:28
  • \$\begingroup\$ ReflectMirror(:⌈) \$\endgroup\$
    – Neil
    Commented Jan 27, 2019 at 17:10
1
\$\begingroup\$

Golfscript - 32 chars

n%{{.-1%{.3%2=115*^}%+}%zip}2*n*

Due to the symmetry of the problem, we repeat twice {flip horizontally, transpose (zip)}. As a bonus, you can change the value 2 to a larger number to repeat the image more.

Character transposition is done as x^=155 if x%3==2, due to the restricted character space. There's also {.5^3%(45+} at the same length.

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

Perl, 80 chars

print reverse map{s@.*@($b=$&)=~y:/\\:\\/:,$&.reverse$b@e;print;y@/\\@\\/@;$_}<>
\$\endgroup\$
1
\$\begingroup\$

Shell Scripting!!

#!/bin/sh

rm temp
touch temp
file=$1
for STRING in `cat $1`
do
   printf $STRING >> temp
   for ((COUNT=0; COUNT<${#STRING}; COUNT++))
   do
      RECORD[$COUNT]=${STRING:$COUNT:1}
   done
   for ((REV_COUNT=${#STRING}; REV_COUNT>=0; REV_COUNT--))
      do
        if [ "${RECORD[$REV_COUNT]}" = "\\" ]; then
            printf "/" >> temp
        elif [ "${RECORD[$REV_COUNT]}" = "/" ]; then
            printf "\\" >> temp
        else
           printf "${RECORD[$REV_COUNT]}" >> temp
        fi
      done
   echo >> temp
done
cat temp
tac temp > temp2
for STRING in `cat temp2`
do
   for ((COUNT=0; COUNT<${#STRING}; COUNT++))
   do
      RECORD[$COUNT]=${STRING:$COUNT:1}
   if [ "${RECORD[$COUNT]}" = "\\" ]; then
            printf "/"
   elif [ "${RECORD[$COUNT]}" = "/" ]; then
            printf "\\"
   else
           printf "${RECORD[$COUNT]}"
   fi
   done
echo
done

I/O

./solution in

+------+
|./..\.|
|/....\|
|\..../|
|.\../.|
+------+
\$\endgroup\$
1
\$\begingroup\$

CJam, 26 bytes

CJam is newer than this challenge, so this answer is not eligible for the green checkmark, but it was a fun exercise anyway

qN/{{_W%"\/"_W%er+}%z}2*N*

Test it here.

Explanation

qN/{{_W%"\/"_W%er+}%z}2*N*
qN/                        "Read STDIN and split on newlines.";
   {                 }2*   "Execute this block twice.";
    {             }%       "Map this block onto each line.";
     _W%                   "Duplicate and reverse.";
        "\/"               "Push the string '\/'.";
            _W%            "Duplicate and reverse.";
               er          "Character transliteration, swaps slashes and backslashes.";
                 +         "Append to first half of the line.";
                    z      "Zip, i.e. transpose the map.";
                        N* "Join with newlines.";

The transposing at the end leads the the second flipping to be performed along the columns. At the end we transpose the map again, so we end up with the original orientation.

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

Powershell, 95 bytes

Inspired by Joey's answer.

filter x{$_;$_[40..0]|%{$_-split'/'-replace'\\','/'-join'\'}},($args|%{-join(,($_|% t*y)|x)})|x

Note: 40 because the author posts the comment Let's say the input is at most 16 rows and 40 characters.

Test script:

$f = {

filter x{$_;$_[40..0]|%{$_-split'/'-replace'\\','/'-join'\'}}
,($args|%{-join(,($_|% t*y)|x)})|x

}

@(
    ,( ("+---",
        "|./.",
        "|/.."),
        "+------+",
        "|./..\.|",
        "|/....\|",
        "|\..../|",
        "|.\../.|",
        "+------+")
    ,( ("+\/",
        "/\/"),
        "+\/\/+",
        "/\/\/\",
        "\/\/\/",
        "+/\/\+")
    ,( ("+---",
        "|...",
        "|..\"),
        "+------+",
        "|......|",
        "|..\/..|",
        "|../\..|",
        "|......|",
        "+------+")
) | % {
    $m,$expected = $_
    $result = &$f @m
    "$result"-eq"$expected"
    $result
}

Output:

True
+------+
|./..\.|
|/....\|
|\..../|
|.\../.|
+------+
True
+\/\/+
/\/\/\
\/\/\/
+/\/\+
True
+------+
|......|
|..\/..|
|../\..|
|......|
+------+
\$\endgroup\$
1
\$\begingroup\$

MS-SQL 2017, 243 bytes

input:

DECLARE @s VARCHAR(100) ='+---'+CHAR(10)+'|...'+CHAR(10)+'|..\';

compressed:

declare @t TABLE(l INT IDENTITY(1,1),s CHAR(40));INSERT INTO @t(s)SELECT value+TRANSLATE(REVERSE(value),'\/','/\')FROM STRING_SPLIT(@s,char(10));SELECT s FROM(SELECT l,s FROM @t UNION ALL SELECT 1e3-l,TRANSLATE(s,'\/','/\')FROM @t)b ORDER BY l

human readable:

declare @t TABLE(l INT IDENTITY(1,1),s CHAR(40));
INSERT INTO @t(s)
  SELECT value+TRANSLATE(REVERSE(value), '\/', '/\')
  FROM STRING_SPLIT(@s,char(10));

SELECT s 
FROM(
   SELECT l, s FROM @t 
   UNION ALL 
   SELECT 1e3-l, TRANSLATE(s, '\/', '/\') FROM @t
  )b 
ORDER BY l

output (as text in ex.management studio):

+------+                                
|......|                                
|..\/..|                                
|../\..|                                
|......|                                
+------+                                

(6 rows affected)
\$\endgroup\$
1
\$\begingroup\$

Vyxal, 5 bytes

øṀ¶+∞

Try it Online!

øṀ    # Vertically mirror, flipping /\
  ¶+  # Append a newline
    ∞ # Palindromise
\$\endgroup\$
0
\$\begingroup\$

Ruby - 105

t=->s{s.tr '/\\\\','\\\\/'}
$<.read.split.map{|l|print l+=t[l.reverse]+"
"
l}.reverse.map{|l|print t[l]}
\$\endgroup\$
0
\$\begingroup\$

Golfscript - 44 chars

n%{.-1%'/'/{'\\'/'/'*}%'\\'*+}%.-1%{-1%}%+n*

result

$ cat in2
+-/|/\
/\|//-
$ cat in2 | golfscript codegolf-761.gs 
+-/|/\/\|\-+
/\|//--\\|/\
\/|\\--//|\/
+-\|\/\/|/-+

Another script that only work for example and does not flip for '\' - 32 chars

n%{.-1%'/'/'\\'*+}%.-1%{-1%}%+n*

result

$ cat in
+---
|./.
|/..
$ cat in | golfscript codegolf-761.gs 
+------+
|./..\.|
|/....\|
|\..../|
|.\../.|
+------+
$ 
\$\endgroup\$
5
  • \$\begingroup\$ `\` needs to be flipped as well. \$\endgroup\$
    – Nabb
    Commented Feb 9, 2011 at 12:51
  • \$\begingroup\$ @Nabb, thanks, that made my code huge :P \$\endgroup\$
    – YOU
    Commented Feb 9, 2011 at 13:12
  • \$\begingroup\$ Mark: Use variables for repeated strings if it makes it shorter. Although there are a few other tricks that you can try to figure out before I post my answer later. \$\endgroup\$
    – Nabb
    Commented Feb 9, 2011 at 13:22
  • \$\begingroup\$ @Nabb, Thanks, I will try to figure out and let me have 30 minutes :D \$\endgroup\$
    – YOU
    Commented Feb 9, 2011 at 13:26
  • \$\begingroup\$ @Nabb, I still couldn't figure out, you may post yours. \$\endgroup\$
    – YOU
    Commented Feb 9, 2011 at 13:55
0
\$\begingroup\$

Haskell, 76 bytes

c '/'='\\';c '\\'='/';c x=x;i=(c<$>)
q#x=x++q(reverse x)
f=((i<$>)#).map(i#)

Try it online!

-- Only / and \ get converted, all other chars are passed as is
c '/'='\\';c '\\'='/';c x=x

-- "Invert" the string (that is switch all / and \ in it)
-- Just map our conversion function over the string
i = (c<$>)

-- Helper: Concatenate a list with its reversed copy (with the given function applied to the copy)
q # x = x ++ q (reverse x)

-- the resulting function:
f = ((i<$>)#) . -- produce the lower half of the image by reversing the upper half and inverting slashes in each line
    map (i#) -- produce the upper half or the image (by concating each input line with its reversed, inverted version)
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.