Медленно сходящийся зигзаг


23

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

#
 #
  #
   #
    #
   #
  #
 #
  #
   #
  #

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

Зигзаг начинается в столбце 1и для каждой строки перемещается вправо на один столбец, пока не достигнет столбца n(где nнаходится вход). Затем он перемещается влево 2, затем вправо n-1, затем влево 3, где две границы сходятся, пока зигзаг не заканчивается в средней колонке ( (n+1)/2).

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

Пример выше - это тестовый пример для 5.

Ниже приведены отдельные тестовые случаи:

3
#
 #
  #
 #

7
#
 #
  #
   #
    #
     #
      #
     #
    #
   #
  #
 #
  #
   #
    #
     #
    #
   #
  #
   #
    #
   #

1

#

Разрешены ли начальные (но последовательные, т.е. не разрушающие форму) пробелы?
Эрик Outgolfer

@EriktheOutgolfer Я собираюсь сказать нет для этого.
HyperNeutrino

Ответы:


15

C (gcc) , 89 байт

f(n,a,b){puts("0");for(a=n;--a>n/2;)for(b=n-2*a;b<=2*a-n;)printf(" %*d\n",a-abs(b++),0);}

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

Работает, анализируя последовательность количества пробелов как (для n = 7):

          0
1 2 3 4 5 6 5 4 3 2 1
    2 3 4 5 4 3 2
        3 4 3

И для n = 3:

  0
1 2 1

Мы можем видеть, что среднее число ( aв коде) начинается с [n-1, n / 2). Тогда разница между первым и средним числом:

a  n  b  2a-n
-------------
6  7  5  5
5  7  3  3
4  7  1  1
2  3  1  1

Так что, если мы bпройдем через [- (2a-n), 2a-n], a-abs(b)получим нам нужную последовательность По сути, это то, что делает код.




3

Желе , 14 байт

ṖṖṚ$ÐĿẎ0;⁶ẋp1Y

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

Полная программа.

Использует 1.

-1 спасибо Джонатану Аллану .
-1 спасибо Джонатану Аллану .


’R-> для байта.
Джонатан Аллан

@JonathanAllan О, конечно, спасибо. Я пытался избежать этого в более ранней версии и забыл это ...
Эрик Outgolfer

”X-> 1для другого.
Джонатан Аллан

@JonathanAllan Хех другой вид, видимо ... Я тоже старался избегать целых чисел.
Эрик Outgolfer

3

Haskell , 72 байта

g[]=[]
g a=a++g(reverse$init a)
r="#":map(' ':)r
("#":).g.tail.(`take`r)

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

Мы определяем бесконечный список rкак диагональ #s, начиная с верхнего левого угла.

Затем мы определяем функцию, gкоторая выполняет основную работу. gвозьмет список и несколько раз обратит его и удалит его первый элемент, пока список не станет пустым, затем объединит результат каждого действия.

Наша основная функция здесь - это функция без точек. Эта функция начинается с извлечения nэлементов из бесконечного списка r, затем отбрасывает первый элемент и применяет его g. Последнее, что мы должны добавить #назад в начало, это потому, что спецификации вопроса немного странные, я не уверен, почему первая диагональ всегда на одну длиннее, чем должна быть, но это так, поэтому мы должны добавить аа #.


@nimi Я закончил делать ("#":).g.init.(дубль, r)но спасибо!
Пшеничный волшебник



2

05AB1E , 6 байтов

LN71SΛ

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

     Λ     use the canvas function with

L          a range list [1 .. input] as lengths for each path 

 N         a "0" as character to be printed 
           (N is the index variable used by loops. If there was no loop yet, its
           default value is 0. By using N, I avoid an extra space between 0 and 71)

  71S      and the directions 7 and 1 (NW and NE), that alternate automatically until
           the range list is finished.

Нет, я сначала попробовал, но он рисует оба направления, прежде чем продолжить со следующим элементом списка диапазонов, когда я удаляю S. Так что на выходе станет вдвое больше. Я еще не знал о + и ×. Они создают действительно интересные шаблоны, когда вы объединяете их с числами
Дориан,

Ах, ты действительно прав. Виноват. Я видел, что это работает без S, но не уделял достаточного внимания выводу ..>.> И, +и ×в основном встроены для [0,4,4,0,2,6,6,2]и [1,5,5,1,3,7,7,3]. И 8вернется к исходной точке, с которой вы начали. Здесь немного больше информации.
Кевин Круйссен



1

JavaScript, 127 байт

Вычисляет цель ( g), чтобы добраться до. Когда эта цель достигнута, развернитесь к следующей цели. Также используется хитрость, чтобы избежать использования Math.round(), добавляя 0.5к каждому неравному числу.

f=n=>{c=0;for(i=0;i<n;i++){m=i/2;g=i%2==0?n-m:m+1.5;while(c!=g){c>g?c--:c++;console.log(' '.repeat(c-1)+'#'+' '.repeat(n-c))}}}

f=n=>{c=0;for(i=0;i<n;i++){m=i/2;g=i%2==0?n-m:m+1.5;while(c!=g){c>g?c--:c++;console.log(' '.repeat(c-1)+'#'+' '.repeat(n-c))}}}

f(5);


1

Haskell, 74 байта

f[x]=[x]
f s=s++tail(f$reverse$tail s)
g n=f[(' '<$[2..x])++"#"|x<-[1..n]]

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

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

    [(' '<$[2..x])++"#"|x<-[1..n]]     -- build the first diagonal, e.g. for n=3:
                                         -- ["#", " #", "  #"]
  f                                      -- call f, which is

f s = s ++                               -- the input list, followed by
           tail                          -- all but the first element of
                f                        -- a recursive call with
                  reverse                -- the reverse of
                          tail s         -- all but the first element of the input 
                                         -- list
f[x]=[x]                                 -- base case: stop if the input list a
                                         -- singleton list

Каждый рекурсивный вызов fдобавляет следующую диагональ.



1

Шелуха , 19 байт

mo`:'#R' ∫`Ṙ¢e1_1tṫ

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

объяснение

Это чувствует себя немного неуклюжим.

mo`:'#R' ∫`Ṙ¢e1_1tṫ  Input is n (e.g. 5)
                  ṫ  Range from input to 1: [5,4,3,2,1]
                 t   Drop first element: [4,3,2,1]
             e1_1    The list [1,-1]
            ¢        repeated infinitely: [1,-1,1,-1,..
          `Ṙ         Clone with respect to the list above: [1,1,1,1,-1,-1,-1,1,1,-1]
         ∫           Cumulative sum: [0,1,2,3,4,3,2,1,2,3,2]
mo                   For each element k (e.g. 3) do this:
      R'             Repeat space k times: "   "
  `:'#               Append '#': "   #"
                     Print implicitly separated by linefeeds.


1

Сетчатка , 71 байт

.+
$* 
^
:>
 $
:
;{*T`:<>`_#
( ) >(:)|( )<
$1<$2$3
(:)( )<|>( )
$2$1$3>

Попробуйте онлайн! Объяснение: Первые три этапа преобразуют ввод в форму, :> :где количество символов между :s является номером ввода. Последние два этапа затем отказов >(или <, при движении влево) между :s. Четвертый этап зацикливает отскок, каждый раз печатая необходимые части строки. ;Останавливает строку из печатается после цикла.


1

05AB1E , 16 байтов

Î<L¤F¦})˜Ôð×X«»

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

объяснение

Î<L               # push 0 and range [1 ... input-1]
   ¤              # get the last element of the list
    F             # that many times do
     Â            # bifurcate
      ¦           # remove the head
       })˜        # end loop and wrap in flattened list
          Ô       # remove consecutive duplicates
           ð×     # repeat space a number of times corresponding to each number in the list
             X«   # append 1 to each
               »  # join on newline

1

K (Kona), 27 байтов

`0:{|x$"#"}'1,,/{1_|x}\-2-!

Создает базовую числовую последовательность, многократно обращая и опуская головку вектора до тех пор, пока она не станет пустой.


3
Добро пожаловать в PPCG.SE! Просто чтобы вы знали, вы можете поместить свой код в онлайн-интерпретатор TIO (попробуйте онлайн) и дать ссылку на него, чтобы люди могли попробовать ваш код. tio.run/#k-kona он даже предоставит вам отформатированный пост PPCG для отправки здесь.
Notts90

0

PHP, 65 байт

<?while(--$n||$n=$d=--$argn)echo str_pad("X
",2+$x-=$d&1?:-1);?>X

Запустите как трубу с -nFили проверьте это онлайн .

объяснение:

первая итерация: $nесть NULL, поэтому не --$nимеет никакого эффекта и оценивает NULL
-> set $nи $dпредварительно уменьшенный аргумент
1. увеличение $xдля четного $d, уменьшение для нечетного $d
2. печатьX , символ новой строки и $xпробелы

дальнейшие итерации: декремент $n; когда он попадает 0, сбросьте $n$d ) до предварительно уменьшенного аргумента

финал: напечатать еще один X.



0

Python 2, 159, 145, 141, 136 байт.

print"".join([" "*p+"#\n"for p in(lambda l:[sum(l[:i])for i in range(len(l))])(sum([i*[1-i%2*2]for i in range(input())[::-1]],[])+[1])])

Уже есть довольно хорошие версии Python для этой проблемы, но я подумал, что все равно выложу свою ужасную однострочную версию. (Без точек с запятой!)

Изменить: 14 байтов вниз, используя сумму вместо понимания двойного списка

Редактировать: только что заметил, в Python 2 вы можете использовать ввод вместо raw_input. Я всегда просто использовал последнее.


0

Математика, 142 102 байта (независимый)

Это решение имеет матовый вкус:

UnitVector[#,1-Sum[(-1)^Floor[#+1/2-Sqrt[9/4+#*#-#-2x]],{x,k}]]~Table~{k,0,#(#-1)/2}/.{0->" ",1->"X"}&

Это в основном вычисляет, в каком сегменте мы находимся (инвертируя функцию треугольного числа), а затем перемещаясь влево или вправо, добавляя степень -1.

Вы можете проверить это в песочнице Wolfram Code Sandbox , вставив код, например, UnitVector[#,1-Sum[(-1)^Floor[#+1/2-Sqrt[9/4+#*#-#-2x]],{x,k}]]~Table~{k,0,#(#-1)/2}/.{0->" ",1->"X"}&@6//MatrixFormи нажав Shift + Enter или Numpad Enter или нажав Gear -> «Оценить ячейку».


Это имеет ту же длину, что и мой исходный неверный порт решения Erik's Python 2 (этот порт дает выход для входного значения выше):

(Print[X];l=Range@#;Do[Do[Print[StringRepeat[" ",l[[j]]]<>"X"],{j,Length@l}];l=l[[-2;;1;;-1]],{i,#}])&

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