ASCII Doodling: лазер в коробке


31

Иногда, когда я рисую, я рисую прямоугольник, начинаю с диагонали от одного из углов, а затем просто прослеживаю линию, «отражая» ее всякий раз, когда я сталкиваюсь с стороной прямоугольника. Я продолжаю с этим, пока не достигну другого угла прямоугольника (и надеюсь, что соотношение сторон моего прямоугольника не было иррациональным;)). Это все равно что проследить путь лазерного луча в коробку. Вы должны получить результат этого с помощью ASCII art.

В качестве примера рассмотрим поле ширины 5и высоты 3. Мы всегда будем начинать в верхнем левом углу. В #отмечает границу окна. Обратите внимание, что ширина и высота относятся к внутренним размерам.

#######    #######    #######    #######    #######    #######    #######
#\    #    #\    #    #\   \#    #\  /\#    #\  /\#    #\/ /\#    #\/\/\#
# \   #    # \  /#    # \  /#    # \/ /#    # \/ /#    #/\/ /#    #/\/\/#
#  \  #    #  \/ #    #  \/ #    # /\/ #    #\/\/ #    #\/\/ #    #\/\/\#
#######    #######    #######    #######    #######    #######    #######

Соревнование

Учитывая (положительную) ширину и высоту коробки, вы должны получить окончательный результат трассировки лазера. Вы можете написать программу или функцию, принимая ввод через STDIN (или ближайшую альтернативу), аргумент командной строки, аргумент функции и выводить результат через STDOUT (или ближайшую альтернативу) или через возвращаемые функцией значения или аргументы.

Вы можете использовать любой удобный список, строковый или числовой формат для ввода. Вывод должен быть одной строкой (если вы не распечатаете ее в STDOUT, что вы, конечно, можете делать постепенно). Это также означает, что вы можете сначала взять высоту, а затем ширину - просто укажите точный формат ввода в своем ответе.

Ни в одной строке вывода не должно быть ни начальных, ни конечных пробелов. При желании вы можете вывести один завершающий символ новой строки.

Вы должны использовать пространство, /, \и #и воспроизводить тестовые случаи точно так , как показано на рисунке.

Тестовые случаи

2 2
####
#\ #
# \#
####

3 2
#####
#\/\#
#/\/#
#####

6 3
########
#\    /#
# \  / #
#  \/  #
########

7 1
#########
#\/\/\/\#
#########

1 3
###
#\#
#/#
#\#
###

7 5
#########
#\/\/\/\#
#/\/\/\/#
#\/\/\/\#
#/\/\/\/#
#\/\/\/\#
#########

22 6
########################
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
# /\  /\  /\  /\  /\  /#
#/  \/  \/  \/  \/  \/ #
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
########################

1
Возможно, хороший дополнительный вопрос, после того, как этот закончит свой курс, состоит в том, чтобы решить эту задачу с помощью коробок произвольной формы и отправных точек.
Sanchises

@sanchises Я действительно обдумал это (и мог бы опубликовать его), но я решил пойти с прямоугольником в надежде, что кто-то может придумать явную формулу. Я также рассматривал несколько отправных точек, которые Xбыли бы необходимы для пересечений. Возможно, в следующий раз. ;)
Мартин Эндер

2
Соответствующий: i.imgur.com/6tXrIfw.webm
orlp

Это было бы идеально для анимации. «Анимация 1 серия (одна косая черта) 1 цикл / бесконечно)»
Мартейн

Ответы:


20

Pyth, 43 41 39 байт

K*\#+2QKVvzp<*QXX*dyivzQN\\_hN\/Q\#\#)K

Попробуйте онлайн: Pyth Compiler / Executor . Введите числа в следующем порядке: высота первой строки, ширина второй строки.

Спасибо isaacg, который помог сэкономить два байта.

Объяснение:

Мое решение не отслеживает лазер, оно использует простой шаблон, который включает в себя gcd. Если m, nразмеры коробки, пусть d = gcd(m, n). Размер рисунка точно 2*d x 2*d.

Например, повторяющийся шаблон для 7 5

#########
#\/\/\/\#
#/\/\/\/#
#\/\/\/\#
#/\/\/\/#
#\/\/\/\#
#########

является

\/
/\

( gcd(7, 5) = 1размер рисунка есть 2 x 2)

И повторяющийся узор для 22 6

########################
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
# /\  /\  /\  /\  /\  /#
#/  \/  \/  \/  \/  \/ #
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
########################

является

\  /
 \/ 
 /\
/  \

( gcd(22, 6) = 2размер рисунка есть 4 x 4)

Мое решение выполняет следующие действия для каждой из линий: оно просто генерирует одну строку шаблона, повторяет ее несколько раз и обрезает ее в конце так, чтобы она помещалась в поле.

K*\#+2QK   implicit: Q is the second input number (=width)
K          K = 
 *\#+2Q        "#" * (2 + Q)
       K   print K (first line)

Vvzp<*QXX*dyivzQN\\_hN\/Q\#\#)K  implicit: vz is the first input number (=height)
VQ                               for N in [0, 1, ..., vz-1]:
           ivzQ                             gcd(vz,Q)
          y                               2*gcd(vz,Q)
        *d                           string with 2*gcd(vz,Q) space chars
       X       N\\                   replace the Nth char with \
      X           _hN\/              replace the -(N+1)th char with /
    *Q                               repeat Q times
   <                   Q           only use the first Q chars
  p                     \#\#       print "#" + ... + "#"
                            )    end for
                             K   print K

Поскольку Xподдерживает «назначение» для строк, вы можете изменить , m\ чтобы *dи удалить s.
Исаак

@isaacg Хороший звонок. Я думал об использовании *\ вместо m\ краткого, но откажусь от него, потому что он имеет тот же размер. Не думал о переменной dи ненужной s.
Якуб

11

C, 256 байт

f(w,h){int i,j,x=1,y=1,v=1,u=1;char b[h+2][w+3];for(i=0;i<w+3;i++)for(j=0;j<h+2;j++)b[j][i]=!i||!j||i>w||j>h?i>w+1?0:35:32;while((x||y)&&(x<=w||y<=h))v=x&&w+1-x?v:(x-=v,-v),u=y&&h+1-y?u:(y-=u,-u),b[y][x]=v/u<0?47:92,x+=v,y+=u;for(i=0;i<h+2;i++)puts(b[i]);}

Я, вероятно, могу получить это меньше 200, и я добавлю объяснение позже, но у меня может быть бумага, которая должна быть через несколько часов, которую я должен сделать вместо этого.


27
Ложные интернет-баллы стоят больше, чем образовательная степень, я в этом уверен.
Адам Дэвис


5

J 85 байт

Пусть g = gcd(w,h). Функция заполняет элементы w/g by h/gматрицы g by gплитками, имеющими /'s \' и 's' в их диагонали и анти-диагонали. Получившийся массив 4D выровняется в 2D (внутри коробки), затем окружен символами #«s». ( 0 1 2 3Вместо номеров используются цифры , а [space] / \ #в конце номера заменяются символами.)

Прямое вычисление внутренней координаты на основе позиции может привести к несколько более короткому решению.

' \/#'echo@:{~3,.~3,.3,~3,,$[:,[:,"%.0 2 1 3|:((,:2*|.)@=@i.@+.){~[:(2&|@+/&:i.)/,%+.

Использование:

   6 (' \/#'echo@:{~3,.~3,.3,~3,,$[:,[:,"%.0 2 1 3|:((,:2*|.)@=@i.@+.){~[:(2&|@+/&:i.)/,%+.) 22
########################
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
# /\  /\  /\  /\  /\  /#
#/  \/  \/  \/  \/  \/ #
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
########################

Попробуйте это онлайн здесь.


0

Desmos Calculator - неконкурентоспособен, чтобы помочь дальнейшим знаниям

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

Входы:

h as height of box, with 0-indexing
w as width of box, with 0-indexing

полупродукты:

Let b = gcd(h,w),
Let c = |b-h%2b| Or |b-mod(h,2b)|

Формула сокращенно:

(|b-(x+y)%2b|-c)(|b-(x-y)%2b|-c)=0

Выходы:

x as x position, 0-indexed, where the ball will land when released
y as y position, 0-indexed, where the ball will land when released

Как это работает:

(|b-(x+y)%2b|-c)*(|b-(x-y)%2b|-c)=0
                ^ OR operation - |b-(x+y)%2b|-c=0 or |b-(x-y)%2b|-c=0
|b-(x+/-y)%2b|-c = 0
|b-(x+/-y)%2b| = c
|b-(x+/-y)%2b| = c means (b-(x+/-y))%2b = + or -c 
b-(x+/-y)%2b = +/- c -> b +/- c = (x+/-y)%2b -> (x+/-y) = n*2*b + b +/- c 
Where n is integer.  This will force patterns to repeat every 2b steps in x and y.  
Initial pattern n=0: (x +/- y) = b +/- c -> y = +/- x + b +/- c
In the x positive and y positive plane only, these correspond to lines of positive and 
negative slope, set at intercept b, offset by c on either side.

Программа не соответствует окончательному критерию - генерирует ASCII-искусство, состоящее из прямоугольников и линий, поэтому я представляю информацию как неконкурентную, чтобы помочь другим выполнить задачу. Обратите внимание, что чтобы заставить Desmos работать, когда c = 0 или c = b, был введен небольшой коэффициент смещения 0,01, так как Desmos, кажется, имеет границы Mod (A, B), равные (0, B) вместо [0, B )

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.