Нарисуйте кривую Гильберта, используя косую черту

30

Кривая Гильберта является пространство начинка фрактала , который может быть представлен в виде системы Lindenmayer с последующими поколениями , которые выглядят следующим образом :
Кривая Гильберта
Благодаря http://www.texample.net/tikz/examples/hilbert-curve/ для изображения.

Цель

Напишите самую короткую возможную программу (в байтах), которая берет положительное целое число n из стандартного ввода и выводит кривую Гильберта n-го порядка в стандартный вывод, используя только прямую косую черту, обратную косую черту, пробел и символ новой строки.

Например, если вход является 1выходом, должен быть

 \
\/

Если вход является 2выходом, должен быть

  /
  \/\
/\   \
 / /\/
 \ \
  \/

Если вход является 3выходом, должен быть

       \
     /\/
    /   /\
    \/\ \ \
  /\  / / /
 / /  \/  \/\
 \ \/\  /\   \
\/   / / / /\/
  /\/ /  \ \
  \   \/\ \/
   \/\   \
     / /\/
     \ \
      \/

И так далее. (Они выглядят лучше, если вы вставите их во что-нибудь с меньшим межстрочным интервалом.)

Выходные данные не должны содержать переводы строк выше или ниже конечных точек кривой, а также пробелы в конце строк.

Кальвин Хобби
источник

Ответы:

10

Рубин, 247 230 205 символов

r=?D
y=d=0
z=(1..2*x=2**gets.to_i.times{r.gsub!(/\w/){$&<?H?'-H~+D~D+~H-':'+D~-H~H-~D+'}}-1).map{' '*2*x}
r.bytes{|c|c>99?(z[y-=s=-~d/2%2][x-=1-d/2]='/\\'[d%2]
x+=d/2
y+=1-s):d-=c
d%=4}
puts z.map &:rstrip

Подход ASCII-turtle с использованием представления Линденмайера (попробуйте здесь ).

Большое спасибо @Ventero за еще немного игры в гольф.

Говард
источник
Разберитесь в этом немного больше, надеюсь, вы не возражаете: ideone.com/kvcPWT - .map(&:rstrip)нужно было добавить, чтобы выполнить требование «без пробелов».
Вентеро
@ Ventero Спасибо. Надеюсь, вы не возражаете, что я принял ваше решение - вы можете даже отбросить паратезы вокруг аргумента карты.
Говард
Ах, конечно! Я также только что понял, что можно встроить определение xи сократить назначение для yи d, в общей сложности до 205 символов (см. Ту же ссылку, что и раньше).
Вентеро
12

Питон, 282

from numpy import*
def r(n):
 x=2**n-2;b=3*x/2+1;c=x/2+1;a=zeros((x*2+2,)*2,int);a[x+1,x+1]=1;a[b,x/2]=a[x/2,b]=-1
 if n>1:s=r(n-1);a[:x,c:b]=rot90(s,3)*-1;a[c:b,:x]|=rot90(s)*-1;a[c:b,x+2:]|=s;a[x+2:,c:b]|=s
 return a
for l in r(input()):print''.join(' /\\'[c] for c in l).rstrip()

При этом используется рекурсивный подход для построения кривой Гильберта n-го порядка из предыдущей кривой. Кривые представлены в виде двумерного массива для лучшей нарезки и манипуляции.

Вот некоторые примеры:

$ python hilbert.py
2
  /
  \/\
/\   \
 / /\/
 \ \
  \/
$ python hilbert.py
3
       \
     /\/
    /   /\
    \/\ \ \
  /\  / / /
 / /  \/  \/\
 \ \/\  /\   \
\/   / / / /\/
  /\/ /  \ \
  \   \/\ \/
   \/\   \
     / /\/
     \ \
      \/
$ python hilbert.py
4
              /
              \/\
            /\   \
           / / /\/
           \ \ \  /\
         /\/  \/  \ \
        /   /\  /\/ /
        \/\ \ \ \   \/\
      /\  / /  \ \/\   \
     / /  \/ /\/   / /\/
     \ \/\  /   /\/ /   /\
   /\/   /  \/\ \   \/\ \ \
  /   /\/ /\  / / /\  / / /
  \/\ \  / /  \/ / /  \/  \/\
/\   \ \ \ \/\   \ \/\  /\   \
 / /\/  \/   / /\/   / / / /\/
 \ \  /\  /\/  \  /\/ /  \ \
  \/  \ \ \  /\/  \   \/\ \/
    /\/ / / /   /\ \/\   \
    \   \/  \/\ \ \  / /\/
     \/\  /\  / / /  \ \
       / / /  \/  \/\ \/
       \ \ \/\  /\   \
        \/   / / / /\/
          /\/ /  \ \
          \   \/\ \/
           \/\   \
             / /\/
             \ \
              \/
GRC
источник
5

Malsys - 234 221 персонажа

Здесь чувствую запах некоторых L-систем :) Malsys - онлайн-переводчик L-систем. Это не очень серьезная статья, но мне показалось, что это решение несколько интересное.

Синтаксис Malsys не очень хорош для игры в гольф, так как он содержит много длинных ключевых слов, но все же он довольно короткий, читаемый и выразительный.

lsystem HilbertCurveAscii {
    set symbols axiom = R;
    set iterations = 5;
    set rightAngleSlashMode = true;
    interpret F as DrawLine;
    interpret + as TurnLeft;
    interpret - as TurnRight;
    rewrite L to + R F - L F L - F R +;
    rewrite R to - L F + R F R + F L -;
}
process all with HexAsciiRenderer;

http://malsys.cz/g/3DcVFMWn

Переводчик: http://malsys.cz/Process

Гольф версия:

lsystem H{set symbols axiom=R;set iterations=3;set
rightAngleSlashMode=1;interpret.as DrawLine;interpret+as
TurnLeft;interpret-as TurnRight;rewrite L to+R.-L.L-.R+;rewrite
R to-L.+R.R+.L-;}process H with HexAsciiRenderer;

А как насчет Ascii шестиугольной кривой Госпера? :)

      ____
 ____ \__ \
 \__ \__/ / __
 __/ ____ \ \ \
/ __ \__ \ \/
\ \ \__/ / __
 \/ ____ \/ /
    \__ \__/
    __/

http://malsys.cz/g/ae5v5vGB

NightElfik
источник
2

JavaScript (ES6) 313 340

Редактировать Некоторые символы удалены с использованием очень плохих методов - например, глобальная переменная w вместо возвращаемого значения из функции H

Преобразование положения x, y в расстояние d (см. Википедию ) для каждого значения x, y и проверка, соединены ли ближайшие положения,

Тест в консоли FireFox. Вход через всплывающее окно, вывод через console.log.

Там нет пробелов и новых строк выше или ниже изображения. Но каждая строка заканчивается новой строкой, я думаю, что это правильный способ сделать художественный образ Ascii.

n=1<<prompt(),d=n-1
H=(s,x,y)=>{for(w=0;s>>=1;)p=x&s,q=y&s,w+=s*s*(3*!!p^!!q),q||(p&&(x=s-1-x,y=s-1-y),[x,y]=[y,x])}
for(r=t='';++r<d+n;t+='\n')for(r>d?(x=r-d,f=x-1):(f=d-r,x=0),t+=' '.repeat(f),z=r-x;x<=z;)
h=H(n,y=r-x,x)|w,H(n,y,x-1),x?t+=' \\'[h-w<2&w-h<2]:0,H(n,y-1,x++),y?t+=' /'[h-w<2&w-h<2]:0
console.log(t)
edc65
источник
Вы можете сохранить некоторые символы, используя alertвместо console.log. У вас также есть дополнительный пробел после forчетвертой строки, и вы должны быть в состоянии избавиться от этого последнего разрыва строки.
Боб
@Bob да, на самом деле я могу сэкономить еще около 15 символов, я все равно бросил видеть, что мне больше 300. Мне не нравится использовать «alert», потому что изображение совершенно неузнаваемо без шрифта с фиксированным шагом
edc65
2

Perl, 270 символов

Супер гольф

$_=A,%d=<A -BF+AFA+FB- B +AF-BFB-FA+>,$x=2**($n=<>)-2;eval's/A|B/$d{$&}/g;'x$n;s/A|B//g;map{if(/F/){if($r+$p==3){$y+=$p<=>$r}else{$x+=$r<2?$r-$p:$p-$r}$s[($r-1)%4>1?$x--:$x++][$r>1?$y--:$y++]=qw(/ \\)[($p=$r)%2]}else{($r+=2*/-/-1)%=4}}/./g;map{print map{$_||$"}@$_,$/}@s

Не так много в гольфе

$_=A,%d=<A -BF+AFA+FB- B +AF-BFB-FA+>,$x=2**($n=<>)-2;
eval's/A|B/$d{$&}/g;'x$n;
s/A|B//g;
map{if(/F/){
    if($r+$p==3){$y+=$p<=>$r}else{$x+=$r<2?$r-$p:$p-$r}
        $s[($r-1)%4>1?$x--:$x++][$r>1?$y--:$y++]=qw(/ \\)[($p=$r)%2]
    }else{
        ($r+=2*/-/-1)%=4
    }
}/./g;
map{print map{$_||$"}@$_,$/}@s

Вероятно, я бы больше проиграл, если бы я лучше понял Perl. Использует системный подход Lindenmayer с использованием правил производства, определенных в строке 1.

killmous
источник
2

APL (Dyalog Unicode) , 90 байтов SBCS

⎕∘←¨' +$'r''¨↓1↓∘⍉∘⌽⍣4' /\'[{3|(⊢+⍉)2@(¯1 0+3 1×s÷2)s⊢(¯.5×≢⍵)⊖(2×s←⍴⍵)↑⍵,⍨-⊖⍵}⍣⎕⊢2 2⍴0]

Попробуйте онлайн!

2 2⍴0 матрица нулей 2x2

{ }⍣⎕ введите N и примените функцию N раз

⍵,⍨-⊖⍵ объединить слева от матрицы вертикально перевернутую и отрицательную копию себя

(2×s←⍴⍵)↑заполнить нулями, чтобы размеры (запоминаемые как s) были в два раза больше аргумента

¯.5×≢⍵ повернуть вниз, чтобы центрировать его вертикально, зажатый между нулями заполнения

2@(¯1 0+3 1×s÷2) поставить 2-е в определенных местах - это косые черты между меньшими экземплярами фрактала

(⊢+⍉) добавить матрицу с ее транспонированным я

3|по модулю 3; мы использовали отрицание, поэтому обратите внимание, что -1≡2 (мод 3) и -2≡1 (мод 3)

' /\'[ ] использовать элементы матрицы в качестве индексов в строке ' /\'

1↓∘⍉∘⌽⍣4 обрезать пустое поле шириной в 1 элемент со всех сторон

разбить на линии

' +$'⎕r''¨ убрать завершающие пробелы из каждого (этот вызов требует этого)

⎕∘←¨ выводить каждый

СПП
источник