Wizualizuj cyfry Kościoła


9

tło

Wizualizacja terminów rachunku λ

Słynny żongler lambda (i golfista kodu ) John Tromp opracował interesującą wizualizację terminów w rachunku λ. Jego słowami:

abstrakcje (lambda) są reprezentowane przez linie poziome, zmienne przez linie pionowe wychodzące z ich wiążącej lambda, a aplikacje przez poziome połączenia łączące zmienne skrajnie lewe.

Na przykład termin lambda λf.λx.f (f (f (fx))) odpowiada wizualizacji:

-------------------
 |   |   |   |
-------------------
 |   |   |   |   |
 |   |   |   |----
 |   |   |----
 |   |----
 |----
 |

Przeczytaj od góry do dołu:

  • Pierwsza linia pozioma reprezentuje pierwszą λ.
  • Cztery linie zstępujące z niego reprezentują fs w ciele.
  • Podobnie druga linia pozioma reprezentuje drugą λ, a pojedyncza nowa linia zstępująca z niej reprezentuje x w ciele.
  • Najbardziej wysunięta w prawo linia f i linia x są połączone poziomą linią reprezentującą aplikację (f x) .
  • Następna aplikacja to (f (f x)) i tak dalej.

Cyfry kościelne

Te cyfry Kościół to specyficzna sekwencja terminów w X-rachunku, biorąc pod następującym wzorem:

0 = λf. λx. x
1 = λf. λx. f x
2 = λf. λx. f (f x)
3 = λf. λx. f (f (f x))
...

Zadanie

Biorąc pod uwagę liczbę wejściową n , wydrukuj grafikę ASCII, która wizualizuje n- tą cyfrę Kościoła. Na przykład powyższy przykład jest wynikiem docelowym, gdy podano n = 4 . Dla n = 0 wydrukuj:

---

---
 |
 |

Przypadki testowe

Twoja odpowiedź musi wypisać dokładnie ten sam tekst (modulo końcowe znaki nowej linii), co ten fragment kodu stosu dla wszystkich liczb całkowitych n ≥ 0 :

To jest , więc wygrywa najkrótszy kod w bajtach.


Twój fragment kodu zawiera błąd.
Leaky Nun

@LeakyNun, która przeglądarka? Niektóre przeglądarki nie obsługują .repeat.
Conor O'Brien

Czy dozwolone są spacje końcowe?
Loovjo,

Nie, tylko końcowe znaki nowej linii. (To jest golf à la anarchy i wydaje mi się, że to najlepszy zestaw reguł dla wyzwań ascii-art .)
Lynn

Odpowiedzi:


4

Retina , 74 67 63 bajtów

Liczba bajtów zakłada kodowanie ISO 8859-1.

.
 |  
^
$.'$*----¶
\z
¶$` |
+`(.+\|) .+$
$&¶$1----
$
¶ |
  ¶
¶

Wprowadzanie jest jednoargumentowe , przy użyciu dowolnego znaku oprócz znaków liniowych jako cyfry.

Wypróbuj online!

Wyjaśnienie

.
 |  

Zaczynamy od przekształcenia każdej jednoznacznej cyfry w | (zwróć uwagę na końcowe spacje). To daje nam drugi wiersz wyniku (plus dwie końcowe spacje, jeśli wejście jest co najmniej 1).

^
$.'$*----¶

Dopasowujemy początek ciągu, aby wstawić pierwszy wiersz. Odbywa się to za pomocą niektórych funkcji substytucji specyficznych dla siatkówki. $*powtarza znak po prawej tyle razy, ile razy jego lewy fragment. $.'ocenia liczbę znaków po prawej stronie dopasowania. Ponieważ dopasowanie jest tylko początkiem ciągu, daje tyle, -ile znaków w ciągu i ---dołącza trzy kolejne. Jest aliasem dla wysuw. Mamy teraz dwie pierwsze linie.

\z
¶$` |

Teraz dołączamy kolejne dwie linie. Robimy to, dopasowując koniec łańcucha i dodając kanał, cały łańcuch ponownie, a następnie, |aby uzyskać poprawną czwartą linię.

+`(.+\|) .+$
$&¶$1----

Czas na aplikacje. Czołowe +marki Retina powtórzyć ten etap aż wyjście przestaje zmianę (w tym przypadku, ponieważ regex długo nie pasuje). Wyrażenie regularne dopasowuje całą ostatnią linię, pod warunkiem że zawiera |znak spacji. Przechwytujemy wszystko do grupy |(która będzie ostatnia do ostatniej) 1. Odpisujemy linię z powrotem $&, linefeed, następnie grupa 1 (usuwając w ten sposób ostatnią |), a następnie ----.

$
¶ |

To tylko dodaje ostatnią linię zawierającą tylko jeden |.

  ¶
¶

Wreszcie musimy pozbyć się końcowych spacji w drugiej linii.


2

JavaScript (ES6), 112 bajtów

f=
n=>`${d=`-`.repeat(n*4+3)}
${(b=` |  `.repeat(n)).slice(0,-2)}
${d}
${b} |
${b.replace(/ \|  /g,`$' |----
`)} |`
;
<input id=i type=number min=0 oninput=o.textContent=f(this.value)>
<pre id=o></pre>


Czy wszystkie nowe linie są konieczne? Czy też jest f=konieczne?
NoOneIsHere

@NoOneIsHere Nowe wiersze są częścią ciągu szablonu. Nie f=jest to część odpowiedzi, jest ona potrzebna tylko dla fragmentu i nie jest liczona jako część bajtu ogółem.
Neil,

2

Python, 201 bajtów

from pylab import*
n=input()
p=array(list(' -|\n'))
a=zeros((n+5,n*4+4),int)
for k in range(n):l=4*k+5;a[:-k-1,l]=2;a[-k-2,l-3:l+1]=1
a[:,1]=2
a[1,-3]=0
a[0]=a[2]=1
a[:,-1]=3
print''.join(ravel(p[a]))

1

Python 2, 138 bajtów

def f(n,a=1):
 if ~n:b="---\n";c=" |";d="  "+c;print("-"*n*4+b+c*(n>0)+d*(n-1)+"\n"+"-"*n*4+b+c+d*n+"\n")*a+c+d*(n-1)+"-"*4*(n>0);f(n-1,0)

Funkcja zawiera dodatkowy parametr, ale służy wyłącznie do użytku wewnętrznego. Ma wartość domyślną i należy ją pominąć podczas wywoływania funkcji. Mam nadzieję, że to nie narusza zasad.

Funkcja rysuje pierwsze 5 wierszy, a następnie rekurencyjnie wywołuje się w celu narysowania pozostałych wierszy.

Wypróbuj online

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.