3D ASCII Block Building

82

Вызов

Напишите программу, которая принимает массив целых чисел 11x11 и строит построение блоков 3D ASCII, где каждое значение в массиве представляет высоту столбца блоков в координатах, соответствующих позиции массива. Отрицательная высота - это «плавающий» столбец - виден только верхний блок.

пример

                                                        __________________
                                        ___            /\__\__\__\__\__\__\
 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,      /\__\          /\/\__\__\__\__\__\__\
 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,     /\/__/         /\/\/__/__/__/__/__/__/
 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /\/\__\        /\/\/\__\      /\/\/__/
 1, 0, 0, 7,-7,-7,-7,-7, 7, 0, 0,    \/\/\__\      /\/\/\/__/     /\/\/__/
 0, 0, 0, 7,-7,-7,-7,-7, 7, 0, 0,     \/\/__/     /\/\/\/\__\    /\/\/__/
 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0,      \/\__\    /\/\/\/\/__/   /\/\/__/
 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0,       \/__/    \/\/\/\/\__\_  \/\/__/
 1, 0, 0, 4, 3, 2, 1, 0, 0, 0, 1,                 \/\/\/\/__/_\_ \/__/
 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,            ___   \/\/\/__/__/_\_         ___
 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,           /\__\   \/\/__/__/__/_\       /\__\
 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1,           \/\__\   \/__/__/__/__/       \/\__\
                                             \/\__\_________         ______\/\__\
                                              \/\__\__\__\__\       /\__\__\__\__\
                                               \/__/__/__/__/       \/__/__/__/__/

вход

Входными данными будет список из 121 целого числа, либо считанный из стандартного ввода (выбор разделителя на ваше усмотрение), либо переданный в виде массива (может быть 1D или 2D).

Высоты будут в диапазоне от -11 до 11.

Выход

Сгенерированное здание может быть записано в стандартный вывод, отображено непосредственно на экране или возвращено в виде строки, разделенной новой строкой.

Лидирующие и конечные пробелы разрешены.

Строительные Правила

Форма отдельного трехмерного блока выглядит следующим образом:

 ___
/\__\
\/__/

И куб блоков 2х2х2 выглядит так:

  ______
 /\__\__\
/\/\__\__\
\/\/__/__/
 \/__/__/

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

Интерпретация высоты столбцов может быть лучше всего объяснена, если посмотреть на 2D-представление сбоку.

HEIGHT:  1    2    3   -3   -2   -1
                  __   __
             __  |__| |__|  __
        __  |__| |__|      |__|  __
       |__| |__| |__|           |__|

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

Если вы хотите опробовать свое решение на нескольких входах, я собрал пару тестовых примеров здесь .

выигрыш

Это , поэтому выигрывает самое короткое представление (в байтах).

Джеймс Холдернесс
источник
9
Ох, мальчик, будь готов к 300+ байтовым решениям. Хороший вызов. +1
полностью человек
7
@totallyhuman Нет, у Денниса будет решение из 9 байтов для этого через 20 минут.
Диакон
3
Должна ли перспектива быть такой, как показано слева внизу от входных данных на переднем плане? Тот факт, что это не первый или последний элемент данных, усложняет задачу. Допустимо ли: 1. сохранить отображение как есть и вывести вывод с правым нижним столбцом на переднем плане или 2. нарисовать зеркальное отображение или поворот данных на 90 градусов? Любой из них заставил бы последний элемент данных соответствовать столбцу на переднем плане, что было бы проще.
Уровень Река St
3
Я чувствую склонность использовать реальный игровой движок (или его часть) для рендеринга фотографии и преобразования ее в ASCII
Stan Strum
@LevelRiverSt Это кажется разумным запросом - вы можете выбрать порядок из 121 входных элементов, который будет наиболее подходящим для вашего решения, при условии, что ваш порядок соответствует. Должна быть возможность создавать все виды макетов, которые могут быть созданы в порядке по умолчанию.
Джеймс Холдернесс

Ответы:

25

Древесный уголь , 70 69 68 байт

≔E¹¹⮌I⪪S,θF²F¹¹F¹¹F¹¹«J⁻⁻⁺λκ×μ³ι⁻λκ≔§§θλμη¿∨⁼±η⊕κ‹κη¿ι“↗⊟&⁹κUhnI”___

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

≔E¹¹⮌I⪪S,θ

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

F²F¹¹F¹¹F¹¹«

Переберите i) верхние линии и тела k) высота l) ряды m) столбцы. (Цикл по первым верхним строкам, а затем по телам позволяет избежать перезаписи тел верхними строками.)

J⁻⁻⁺λκ×μ³ι⁻λκ

Прыгните в положение куба.

≔§§θλμη

Получить высоту в текущей строке и столбце.

¿∨⁼±η⊕κ‹κη

Проверьте, следует ли рисовать куб на этой высоте для этой строки и столбца.

¿ι“↗⊟&⁹κUhnI”___

Нарисуйте тело или вершину куба.

Нил
источник
Когда я меняю первый 3на a 33, я получаю только 11 блоков в башне. В общем, башни, кажется, ограничены в 11. Как это происходит?
Фабиан Релинг
@Fabian Я немного растерялся, это F¹¹F¹¹F¹¹не было подсказкой ...
Нил
Я не знаю этот язык программирования, я просто немного поигрался со ссылкой TIO.
Фабиан Релинг
30

C  376   350   313   309  285 байт

Спасибо @Jonathan Frech за сохранение четырех байтов!

#define F for(
char*t,G[26][67],*s;i,j,e,k,v,x,y;b(){F s="\\/__//\\__\\ ___ ";*s;--y,s+=5)F e=5;e--;*t=*s<33&*t>32?*t:s[e])t=G[y]+x+e;}f(int*M){F;e<1716;++e)G[e/66][e%66]=32;F k=0;++k<12;)F i=0;i<11;++i)F j=11;j--;v+k||b())x=i+j*3+k,y=14+i-k,(v=M[i*11+j])>=k&&b();F;++e<26;)puts(G+e);}

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

раскатали:

#define F for(

char *t, G[26][67], *s;
i, j, e, k, v, x, y;

b()
{
    F s="\\/__//\\__\\ ___ "; *s; --y, s+=5)
        F e=5; e--; *t=*s<33&*t>32?*t:s[e])
            t = G[y]+x+e;
}

f(int*M)
{
    F; e<1716; ++e)
        G[e/66][e%66] = 32;

    F k=0; ++k<12;)
        F i=0; i<11; ++i)
            F j=11; j--; v+k||b())
                x = i+j*3+k,
                y = 14+i-k,
                (v=M[i*11+j])>=k && b();

    F; ++e<26;)
        puts(G+e);
}
Steadybox
источник
Не 26*66может быть 1716?
Джонатан Фрех
@JonathanFrech Конечно, я забыл об этом.
Steadybox
*s==32-> *s<33.
Джонатан Фрех
for(e=k=1;e;++k)for(e=-> for(k=1;e;++k)for(e=.
Джонатан Фрех
#define B b(...)&++e-> #define B++e&b(...)(при условии b, не зависит от того e, что я думаю, это не так).
Джонатан Фрех
9

JavaScript (ES6), 277 251 байт

a=>(n=55,$=f=>[...Array(n)].map((_,i)=>f(i)),S=$(_=>$(_=>' ')),n=11,$(l=>$(z=>$(y=>$(x=>(x=10-x,X=x*3+y+z,Y=y-z+n,Z=a[y][x])<=z&&Z+z+1?0:l?['/\\__\\','\\/__/'].map(s=>S[++Y].splice(X,5,...s)):S[Y].splice(X+1,3,...'___'))))),S.map(r=>r.join``).join`
`)

Сохранено 26 байт по предложению @ Neil .

Ungolfed

a=>(
    n=55,
    $=f=>[...Array(n)].map((_,i)=>f(i)),
    S=$(_=>$(_=>' ')),
    n=11,
    $(l=>
        $(z=>$(y=>$(x=>(
            x=10-x,
            X=x*3+y+z,
            Y=y-z+n,
            Z=a[y][x],
            Z<=z && Z+z+1 || (
                l
                ? ['/\\__\\','\\/__/'].map(s=>S[++Y].splice(X,5,...s))
                : S[Y].splice(X+1,3,...'___')
            )
        ))))
    ),
    S.map(r=>r.join``).join`\n`
)
darrylyeo
источник
2
,$(w=>$(z=>$(y=>$(x=>(Z=a[y][x=10-x,X=x*3+y+z,Y=y-z+n,x])<=z&&Z+z+1?0:w?['/\\__\\','\\/__/'].map(s=>S[++Y].splice(X,5,...s)):S[Y].splice(X+1,3,...'___'))))),кажется, чтобы сохранить 26 байтов.
Нил
@ Нил Бриллиант! Рисование всех верхних линий сначала избавляет меня от необходимости проверять наличие пробелов.
darrylyeo
6

Python 2 , 243 байта

a=input()
s=eval(`[[' ']*55]*23`)
for h in range(7986):
 k=h%3;x=h/3%11;y=h/33%11;z=h/363%11;i=h/3993;u=y+z-x*3+30;v=y-z+10
 if~-(z>=a[y][10-x]!=~z):
	if i*k:s[v+k][u:u+5]='\//\____/\\'[k%2::2]
	if~-i:s[v][u+1+k]='_'
for l in s:print''.join(l)

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

Python перевод подхода Нейла на уголь.

Линн
источник
Приятно видеть решение Python для гольфа для этого. Мой Python доказательство концепции было более 900 байтов!
Джеймс Холдернесс
3
+1+k-> -~k.
Джонатан Фрех
5

Tcl, 380 409 байтов

Пользователь sergiol очень старался разобраться в этом:

set X [read stdin]
proc L {a b c d e s} {time {incr z
set y -1
time {incr y
set x -1
time {if {abs([set Z [lindex $::X [expr ($y+1)*11-[incr x]-1]]])==$z|$z<$Z} {set s [string repl [string repl $s [set i [expr -3*$x+57*$y-55*abs($z)+701]] $i+$b $a] [incr i $c] $i+$e $d]}} 11} 11} 12
set s}
puts [L /\\__\\ 4 56 \\/__/ 4 [L "" -1 -55 ___ 2 [string repe [string repe \  55]\n 23]]]

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

Оригинальный контент

set xs [read stdin]
proc L {a b c d e s} {set z 0
while {[incr z]<12} {set y -1
while {[incr y]<11} {set x -1
while {[incr x]<11} {set Z [lindex $::xs [expr ($y+1)*11-$x-1]]
if {abs($Z)==$z||$z<$Z} {set i [expr -3*$x+57*$y-55*abs($z)+701]
set s [string repl [string repl $s $i $i+$b $a] [incr i $c] $i+$e $d]}}}}
set s}
puts [L /\\__\\ 4 56 \\/__/ 4 [L "" -1 -55 ___ 2 [string repe [string repe \  55]\n 23]]]

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

Увы, это то, что есть. Это немного легче для глаз, когда «не в гольфе»

set s [string repeat [string repeat " " 55]\n 23]

proc loops {s0 i0 io s1 i1} {
  set z  0; while {[incr z] < 12} {
  set y -1; while {[incr y] < 11} {
  set x -1; while {[incr x] < 11} {
    set Z [lindex $::xs [expr {($y+1) * 11 - $x - 1}]]
    if {abs($Z) == $z || $z < $Z} {
        set i [expr {-3*$x + 57*$y - 55*abs($z) + 701}]
        set ::s [string replace $::s $i $i+$i0 $s0]
        incr i $io
        set ::s [string replace $::s $i $i+$i1 $s1]
    }
  } } }
}

loops ""      -1 -55 \
       ___     2
loops /\\__\\  4  56 \
      \\/__/   4

puts $s

Строит строку в соответствии с требованиями. Принимает массив из стандартного ввода. Идет снизу вверх, спереди назад, справа налево поверх строковых данных. Делает это в два прохода, один раз для верхнего края и снова для остальной части тела каждого куба.

Я пытался уменьшить его, используя сладкое функциональное лямбда-моджо, но, увы, это увеличило его.

Dúthomhas
источник
Вы можете поиграть в
sergiol
Больше игры в гольф: tio.run/…
sergiol
Больше: tio.run/…
sergiol
Еще больше: tio.run/…
sergiol
Еще больше: tio.run/##lVHtboJAEPx/…
sergiol