Questo è stato immensamente divertente. Grazie per aver pubblicato questa sfida.
Divulgazione completa: il linguaggio (Hexagony) non esisteva al momento della pubblicazione di questa sfida. Tuttavia, non l'ho inventato e il linguaggio non è stato progettato per questa sfida (o qualsiasi altra sfida specifica).
){_2"_{\"{{""}"{'2//_.\><*\"\/_><[\]/3\'\_;|#__/(\2\'3_'}(#:|{$#{>_\//(#={/;01*&"\\_|[##={|}$_#></)]$_##|){*_.>.(/?#//~-="{}<_"=#/\}.>"%<.{#{x\"<#_/=&{./1#_#>__<_'\/"#|@_|/{=/'|\"".{/>}]#]>(_<\'{\&#|>=&{{(\=/\{*'"]<$_
Disposto esagonalmente:
) { _ 2 " _ { \ "
{ { " " } " { ' 2 /
/ _ . \ > < * \ " \ /
_ > < [ \ ] / 3 \ ' \ _
; | # _ _ / ( \ 2 \ ' 3 _
' } ( # : | { $ # { > _ \ /
/ ( # = { / ; 0 1 * & " \ \ _
| [ # # = { | } $ _ # > < / ) ]
$ _ # # | ) { * _ . > . ( / ? # /
/ ~ - = " { } < _ " = # / \ } .
> " % < . { # { x \ " < # _ /
= & { . / 1 # _ # > _ _ < _
' \ / " # | @ _ | / { = /
' | \ " " . { / > } ] #
] > ( _ < \ ' { \ & #
| > = & { { ( \ = /
\ { * ' " ] < $ _
Il programma in realtà non utilizza l' #
istruzione, quindi ho usato quel personaggio per mostrare quali celle sono veramente inutilizzate.
Come funziona questo programma? Dipende. Vuoi la versione corta o lunga?
Breve spiegazione
Per illustrare cosa intendo per "linea" e "segmento" nella seguente spiegazione, prendere in considerazione questa dissezione dell'output previsto:
segments →
│ │ │ │ │ │x lines
─┼───┼─┼─────────┼─┼───┼─ ↓
│ │ │ │ │xxx│
─┼───┼─┼─────────┼─┼───┘
│ │ │ │x│
─┼───┼─┼─────────┼─┘
│ │ │xxxxxxxxx│
─┼───┼─┼─────────┘
│ │x│
─┼───┼─┘
│xxx│
─┼───┘
x│
Detto questo, il programma corrisponde al seguente pseudocodice:
n = get integer from stdin
# Calculate the number of lines we need to output.
line = pow(2, n+1)
while line > 0:
line = line - 1
# For all segments except the last, the character to use is spaces.
ch = ' ' (space, ASCII 32)
# The number of segments in each line is
# equal to the line number, counting down.
seg = line
while seg > 0:
seg = seg - 1
# For the last segment, use x’s.
if seg = 0:
ch = 'x' (ASCII 120)
# Calculate the actual segment number, where the leftmost is 1
n = line - seg
# Output the segment
i = pow(3, number of times n can be divided by 2)
i times: output ch
output '\n' (newline, ASCII 10)
end program
Lunga spiegazione
Fare riferimento a questo diagramma del percorso del codice con codice colore.
L'esecuzione inizia nell'angolo in alto a sinistra. La sequenza di istruzioni ){2'"''3''"2}?)
viene eseguita (più alcune cancellazioni ridondanti, come "{
ecc.) Perseguendo un percorso abbastanza contorto. Iniziamo con il puntatore a istruzioni n. 0, evidenziato in cremisi. A metà strada, passiamo al numero 1, iniziando nell'angolo in alto a destra e dipinto in verde foresta. Quando IP # 2 inizia in blu fiordaliso (al centro a destra), il layout della memoria è questo:
Durante l'intero programma, i bordi etichettati 2a e 2b avranno sempre il valore 2
(li usiamo per calcolare 2ⁿ⁺¹ e dividiamo per 2, rispettivamente) e il bordo etichettato 3 sarà sempre 3
(lo usiamo per calcolare 3ⁱ).
Entriamo in affari quando entriamo nel nostro primo anello, evidenziato in blu fiordaliso. Questo loop esegue le istruzioni (}*{=&}{=
per calcolare il valore 2ⁿ⁺¹. Quando il loop termina, viene preso il percorso marrone della sella, che ci porta al puntatore di istruzioni n. 3. Questo IP si limita a dilagare lungo il bordo inferiore verso ovest in giallo dorato e presto passa il controllo a IP # 4.
Il percorso fucsia indica come IP # 4, iniziando in basso a sinistra, procede rapidamente alla linea di decremento , imposta ch su 32
(il carattere spazio) e seg su (il nuovo valore di) linea . È a causa del decremento iniziale che in realtà iniziamo con 2ⁿ⁺¹ − 1 e alla fine sperimentiamo un'ultima iterazione con il valore 0. Quindi entriamo nel primo ciclo nidificato .
Rivolgiamo la nostra attenzione all'indaco ramificato, dove, dopo un breve decremento di seg , vediamo ch aggiornato x
solo se seg è ora zero. Successivamente, n viene impostato su line - seg per determinare il numero effettivo del segmento in cui ci troviamo. Immediatamente entriamo in un altro loop, questa volta nel bel colore del pomodoro.
Qui, scopriamo quante volte n (il numero di segmento corrente) può essere diviso per 2. Finché il modulo ci dà zero, incrementiamo i e dividere n per 2. Quando siamo soddisfatti n non è più così divisibile , ci ramifichiamo nel grigio ardesia, che contiene due anelli: prima aumenta 3 alla potenza dell'i che abbiamo calcolato, quindi emette ch molte volte. Si noti che il primo di questi loop contiene a[
istruzione, che commuta il controllo su IP # 3 - quello che stava facendo solo piccoli passi lungo il bordo inferiore in precedenza. Il corpo del loop (moltiplicando per 3 e decrementando) viene eseguito da un IP # 3 solitario, imprigionato in un infinito ciclo verde oliva scuro lungo il bordo inferiore del codice. Allo stesso modo, il secondo di questi loop grigio ardesia contiene ]
un'istruzione, che attiva IP # 5 per produrre ch e decremento, mostrato qui in rosso indiano scuro. In entrambi i casi, quei puntatori di istruzioni intrappolati nella servitù eseguono obbedientemente una iterazione alla volta e restituiscono il controllo a IP # 4, solo per dare il momento in cui il loro servizio verrà richiamato ancora una volta. Il grigio ardesia, nel frattempo, si unisce ai suoi fratelli fucsia e indaco.
Poiché seg inevitabilmente raggiunge lo zero, il ciclo indaco esce nel percorso verde prato, che semplicemente emette il carattere di nuova riga e si fonde rapidamente nel fucsia per continuare il ciclo di linea . Al di là dell'iterazione finale del loop di linea si trova il percorso ebon sable breve della terminazione finale del programma.
(,],~3^#@~.)@]
invece di(1,[:,1,"0~3*])
salvare 1 byte. E se stai bene con!
l'output charu:32+
invece di' #'{~
salvarne un altro.