Fueue , 423 bayt
Fueue koşu programı olduğu bir kuyruk tabanlı esolang olduğunu olduğunu kuyruk.
)$$4255%%1(~):[)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]](H-):~:[)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:](106328966328112328136317639696111819119696281563139628116326221310190661962811611211962861109696289611619628116111612896281115421063633063961111116163963011632811111819159628151213262722151522061361613096119619190661966311961128966130281807072220060611612811961019070723232022060611
Çevrimiçi deneyin!
Nasıl çalışır
Bu açıklama elden çıkmış olabilir veya olmayabilir . Öte yandan, insanların izleyebileceğini umduğum şekilde nasıl daha kısa açıklayacağımı bilmiyorum .
Fue hile sayfası
Bu programda kullanılmayan birkaç özellik dahil, ayrıntılar için esolang wiki makalesine bakın .
İlk program, aşağıdaki öğeleri içeren sıranın başlangıç durumudur:
- Tamsayı değişmezleri (yalnızca kaynakta negatif değil, ancak negatif olanlar hesaplanabilir), bunları yürütmek bir karakter yazdırır.
- Köşeli ayraç sınırlı yuvalanmış bloklar, inert (bazı işlevler üzerine etki etmedikçe bozulmadan korunur).
- İşlevler, argümanları hemen sırada onları takip eden elemanlardır:
+*/-%
: tamsayı aritmetiği ( -
tekdüze, %
mantıksal olumsuzlama). Sayı bağımsız değişkenleri verilmezse eylemsiz.
()<
: elemanı parantez içine alın, parantezleri bloktan çıkarın, bloğa son eleman ekleyin. İkincisi, bir blok tarafından takip edilmedikçe etkisizdir.
~:
: takas, çoğalt.
$
: kopyala (sayı + eleman alır). Sayı olmadan önce inert.
H
: programı durdur.
[]
Yuva içindeyken , ()
yapma - ikincisi sadece ayrı işlevlerdir.
Yürütme izleme sözdizimi
Boşluk, rakamlar hariç, Fueue'da isteğe bağlıdır. Aşağıdaki uygulama izlerinde, özellikle program yapısını önermek için kullanılacaktır:
- Bir fonksiyon yürütüldüğünde, onu ve argümanlarını çevreleyen elementlerden boşluklu bırakacağız. Eğer bazı argümanlar karmaşıksa, aralarında bir boşluk da olabilir.
- Birçok uygulama izi, önemli veri manipülasyonunu yapan bir bölümden sağa ayrılarak solda bir "gecikme bloğu" na ayrılmıştır. Bir sonraki bölüme bakınız.
Kıvrımlı parantezler {}
(Fueue'da kullanılmaz) izlerde matematiksel ifadelerin tamsayı sonucunu temsil etmek için kullanılır. Bu, Fueue'nun yalnızca negatif olmayan değişmezlere sahip olması nedeniyle negatif sayıları içerir - -
olumsuzlama işlevidir.
Çeşitli meta değişkenli isimler ve ...
değerleri ve kısaltmaları belirtmek için kullanılır.
Gecikme taktikleri
Sezgisel olarak, yürütme kuyruğun etrafında dönerek kısmen içinden geçenleri değiştirir. Bir işlevin sonuçları bir sonraki döngüye kadar tekrar uygulanamaz. Programın farklı bölümleri, etkileşime girmedikleri sürece paralel olarak etkin bir şekilde gelişir.
Sonuç olarak, kodun birçoğu senkronizasyona, özellikle programın parçalarının doğru zamana kadar ertelenmesine adanmıştır. Bunu yapmak için birçok seçenek var; bu kısımlar, sadece yürütme döngülerinin döngüsel olarak izlenerek anlaşılması mümkün olan okunamayan damlalara dönüşme eğilimindedir.
Bu taktikler aşağıda her zaman ayrı ayrı belirtilmeyecektir:
)[A]
A
bir döngü için gecikmeler . (Muhtemelen en kolay ve en okunabilir yöntem.)
~ef
elemanları değiştirir e
ve f
bu da onların uygulanmasını geciktirir. (Muhtemelen en az okunabilen, ancak küçük gecikmeler için genellikle en kısa olanıdır.)
$1e
tek bir elemanı geciktirir e
.
-
ve %
sayıları geciktirmek için yararlıdır (ikincisi için 0
ve 1
.)
- Bir satırda birkaç eşit elementi geciktirirken,
:
veya $
bunları tek bir diziden oluşturmak için kullanılabilir.
(n
n
sonradan rahatlıkla çıkarılabilen braketler halinde sarılır . Bu özellikle sayısal hesaplamalar için çok önemlidir, çünkü sayılar ilk önce bir bloğa koymadan kopyalanamayacak kadar kararsızdır.
Genel yapı
Açıklamanın geri kalan kısmı, her biri koşu programın bir bölümü için yedi bölüme ayrılmıştır. Birçoğunun kendilerini tekrar ettiği daha büyük döngüler, onları tüm sıra boyunca tek geçişlerin "döngülerinden" ayırt etmek için "yinelemeler" olarak adlandırılır.
İlk programın aralarına nasıl bölündüğü:
A: )$$4255%%1(~
B: ):[)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
C:
D: (H-
E:
F:
G: ):~:[)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:](106328966328112328136317639696111819119696281563139628116326221310190661962811611211962861109696289611619628116111612896281115421063633063961111116163963011632811111819159628151213262722151522061361613096119619190661966311961128966130281807072220060611612811961019070723232022060611
Programın sonundaki büyük rakam geri kalanı tersine, her ASCII değerinden 30 çıkarılmış karakter başına iki hane 10
kodlar (yani, a kodları (
).
Daha yüksek bir seviyede, bu programdaki verileri (bignumdan başlayarak) sağdan sola doğru akarken, kontrolün soldan sağa doğru aktığını düşünebilirsiniz. Bununla birlikte, daha düşük bir seviyede Fueue, kod ve veri arasındaki ayrımı her zaman karıştırır.
- Kısım G , ilk önce en az anlamlı basamağı ayırarak bignumu ASCII rakamlarına dönüştürür (örneğin
0
tamsayı olarak 48
rakam). Her 15 döngüde bir rakam üretiyor.
- F bölümü, E bölümü tüketene kadar üretilen rakam ASCII değerlerini (her biri bir blok içinde) içerir.
- E bölümü, üretilen rakamları her defasında iki kez tutar, bunları form bloklarına eşleştirir ve
[x[y]]
ayrıca her bir çiftin kodlanmış karakterini yazdırır.
- Kısım D, kademeli olarak
[x[y]]
bloklardan, tüm basamakları içerdiği zaman, hepsini yazdırmak için çalıştırılabilir, sonra tüm programı durduracak şekilde inşa edilen derinlemesine yuvalanmış bir bloktan oluşur .
- C bölümü, D bölümünün yapımını idare eder ve E bölümünü de yeniden oluşturur.
- Bölüm B, her 30 döngüde bir C bölümünü ve ayrıca kendisini yeniden oluşturur.
- Bölüm A, diğer bölümlerin son yinelemesine kadar döngüleri geri sayıyor. Sonra B bölümünü iptal eder ve D bölümünü çalıştırır.
Bölüm A
Bölüm A, programın sonunu planlayan işler. Tek bir takas fonksiyonuna indirgemek 4258 devir alır ~
, bu daha sonra ana döngüsünü durduran ve bunun yerine D bölümünü çalıştırmaya başlayan B bölümüne ayar yapar.
)$ $4255% %1 (~
)$%%%...%% %0 [~]
)$%%%...% %1 [~]
⋮
)$ %0 [~]
) $1[~]
)[~]
~
- Bir
$
fonksiyon aşağıdakilerden 4255 kopyalarını yaratır %
iken (
sarar ~
parantez içinde.
- Her döngü,
%
aşağıdaki sayıyı 0
ve arasında değiştirmek için kullanılır 1
.
- Hepsi
%
kullanıldığında $1
, [~]
(etkin bir NOP) ' nin 1 kopyasını oluşturur ve bir sonraki döngüde )
parantezleri kaldırır.
B bölümü
Bölüm B her 30 döngüde bir kendini yenilemenin yanı sıra yeni bir C bölümü yinelemesini de ele alır.
) : [)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
) [)$$24%%0:<[~:)~)]~[$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]] [BkB]
)$ $24% %0 :< [~:)~)] ~ [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<] [BkB]
)$ %...%%% %1 < < [~:)~)] [BkB] [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]
)$ %...%% %0 < [~:)~)[BkB]] [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]
)$ %...% %1 [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
⋮
) $1 [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]]
) [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]] (1)
~:) ~)[BkB] [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]
) : [BkB] ) [$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<] (2)
) [BkB] [BkB] $11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<
- Bir
:
, aşağıdaki büyük bloğu kopyalar (bir kopya olarak kısaltılır [BkB]
), sonra )
parantezleri ilk kopyadan kaldırır.
$$24%%0
A bölümündeki ile benzer bir geri sayım ayarlar.
- Bu geri sayıma başlar,
:<
dönüşür <<
ve ~
bloklardan ikisini değiştirir, kodun sonuncusunu yeni bir C bölümüne yerleştirir.
- İki
<
işlev, iki son bloğu birinciye yerleştirir - bu normal yinelemelerde gereksizdir, ancak ~
A bölümünün sonunda işini yapmasına izin verir .
- (1) Geri sayım tamamlandığında,
)
dış braketleri çıkarır. Daha sonra ~:)
dönüşür ):
ve ~)
a )
bölümünün C kodunun başına geçer.
- (2) Bölüm B şimdi tekrar başlangıç döngüsünde, a
)
ise bölüm C'nin yeni bir C bölümünün yeni bir yinelemesini başlatmak için braketleri çıkarmak üzere.
Son yinelemede, ~
A bölümü yukarıda (1) noktasında belirir:
~ ) [~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]] (1)
[~:)~)[BkB][$11~)~<[[+$4--498+*-:~-10)):])<~][)))~]<]] )
~
Swap )
kesitini B engelleyen blok arasında ve bölüm C içine yeniden çalıştırılan.
Bölüm C
C bölümü, D basamaklı bloğuna yeni rakam karakter çiftlerinin birleştirilmesini ve E bölümünün yeni yinelemelerinin yaratılmasını sağlar.
Aşağıda, hanelerin ASCII kodları ile birlikte x
ve bunları y
temsil eden tipik bir yineleme görülmektedir . İlk yinelemede, gelen "D" ve "E" elementleri başlangıçtır [H]
ve -
bunun yerine, önceki herhangi bir E bölümü rakam karakter çiftleri üretmek için çalıştırılmaz.
C D E
$11~ ) ~<[[+$4--498+*-:~-10)):])<~] [)))~] < [)))~[...]] [x[y]]
~~~ ~~~ ~~~ ~~) [[+$4--498+*-:~-10)):])<~] < [)))~] [)))~[...][x[y]]]
~~~ ~~~ ) ~ [[+$4--498+*-:~-10)):])<~] [)))~[)))~[...][x[y]]]]
~~~ ~ ) [)))~[....]] [[+$4--498+*-:~-10)):])<~]
~~[)))~[....]] )[[+$4--498+*-:~-10)):])<~]
[)))~[....]] ~[+$4--498+*-:~-10)):])<~
- Bu, bu cevap için keşfettiğim farklı bir senkronizasyon yöntemini kullanıyor. Bir
~
satırda birkaç takas işleviniz olduğunda, sıra her çevrimde yaklaşık 2 / 3'üne daralacaktır (çünkü biri ~
ikiyi değiştirir), ancak zaman zaman izlerini~
sürdüğü geriye kalanı dikkatlice değiştirir.
$11~
böyle bir satır üretir. Bir sonraki ~
sürüntüler <
şu bloğun karşısında. <
Sonunda bir diğeri , D bloğuna yeni bir rakam çifti bloğu (ASCII kodları olarak x ve y rakamları) ekler.
- Bir sonraki döngüde,
~
satırın aşağıdakini ~~
değiştiren bir kalanı vardır . Diğer bölüm D'yi bir bloğa ekler .~
)
<
[)))~]
- Daha sonra değiştirilen
~
kendisi aşağıdaki bloğu yeni bölüm E kodu ile bölüm D bloğu boyunca değiştirir. Ardından yeni bir artık ~
bir takas )
karşısında ve son olarak geçen ~~
de ~
tıpkı bölümüne E genelinde bunlardan satır takası biri )
kendi parantez kaldırmıştır.
Nihai yineleme, bölüm A takımından ~
bir takas etmiştir )
bölüm B genelinde ve Ancak bölüm C. içine, C bölümü yüzden zaten kayboldu ve olduğu kısa ömürlü olduğunu )
uçları yukarı bölümünde D. başında
Bölüm D
Bölüm D, son büyük rakamı basmak ve programı durdurmak için kullanılır. Program çalışmasının çoğunda, B – G bölümlerinin bina üzerinde işbirliği yaptığı inert bir bloktur.
(H -
[H]-
⋮
[)))~[H-]] After one iteration of section C
⋮
[)))~[)))~[H-][49[49]]]] Second iteration, after E has also run
⋮
) [)))~[...]] [49[48]] Final printing starts as ) is swapped in
))) ~[...][49[48]]
)) )[49[48]] [...]
)) 49 [48][...] Print first 1
) )[48] [...]
) 48 [...] Print 0
)[...] Recurse to inner block
...
⋮
)[H-] Innermost block reached
H - Program halts
- Programın ilk döngüsünde
(
, durma işlevini H
parantez içinde sarar . Bir -
iz, bir rakam çifti yerine ilk yineleme için kukla eleman olarak kullanılacaktır.
- Dahil edilen ilk gerçek hane çifti sayıdaki sonuca
[49[49]]
karşılık gelir 11
.
- En son basamak çifti
[49[48]]
( sayının 10
başlangıcına karşılık gelir ) aslında bloğa dahil değildir, ancak bu , her ikisine de dönüşen eşdeğer olan )[A[B]]
ve hiçbir fark )[A][B]
yaratmaz A[B]
.
Son yinelemeden sonra, )
B bölümünden sağa doğru değiştirilen bölüm D bloğu kapandı. )))~
Her alt bloğun başında tüm parçaları doğru sırayla yürütülür emin olur. Sonunda en içteki blok H
programı durdurur.
Bölüm E
E Bölümü, G bölümü tarafından üretilen ASCII hanelerinin çiftlerini birleştirir ve her ikisi de karşılık gelen kodlanmış karakteri basar ve kombine çifti sol ve C ve D bölümlerine bırakarak bir blok gönderir.
Yine aşağıda, rakamların ASCII kodları ile birlikte x
ve onu y
temsil eden tipik bir yineleme görülmektedir .
E F
~ [+$4--498+*-:~-10)):] ) < ~ [y] [x]
) [+$4--498+*-:~-10)):] < [x] [y]
+ $4- - 498 +*- :~ -10 ) ) : [x[y]]
+--- -{-498} +*- ~~{-10} ) ) [x[y]] [x[y]]
+-- - 498 +* -{-10} ~ ) x [y] [x[y]]
+- -{-498} + * 10 x )[y] [x[y]]
+ - 498 + {10*x} y [x[y]]
+ {-498} {10*x+y} [x[y]]
{10*x+y-498} [x[y]]
[x[y]]
- Gelen rakam blokları değiştirilir, ardından y bloğu x bloğuna eklenir ve tüm çift blok kopyalanır. C ve D bölümlerinin sonuna kadar bir kopya bırakılacaktır.
- Diğer kopya tekrar kilitlenir, daha sonra
10*x+y-498
şifrelenmiş karakterin ASCII değerini hesaplamak için bir aritmetik fonksiyon sırası uygulanır . 498 = 10*48+48-30
, 48
S ASCII kodlama geri x
ve y
süre 30
gelen kodlama kaymalar 00–99
için 30–129
tüm yazdırılabilir ASCII içerir.
- Sonuçta ortaya çıkan sayı, karakterini yazdıran yürütmek için bırakılır.
Bölüm F
Bölüm F, ASCII basamak kodlarını içeren inert bloklardan oluşur. Programın çoğu çalışması için burada en fazla iki tane olacak, çünkü E bölümü bunları G ile aynı hızda kullandığı için. Ancak, son baskı aşamasında bazı fazlalık 0
rakamlar burada toplanacaktır.
[y] [x] ...
Bölüm G
Kısım G, programın sonunda büyük sayının ayrılmasından, en az önce en az haneden önce ayrılmasından ve ASCII kodlarının diğer bölümlere bırakılmasıyla blok gönderilmesinden sorumludur.
Durma kontrolü olmadığından, 0
sayı 0'a düştüğünde rakamlar üretmeye devam eder , D bölümü H
fonksiyonun tamamı ile duruncaya kadar .
[BkG]
Yeni yinelemeleri başlatmak için kendi kendini çoğaltması için kullanılan büyük başlangıç kod bloğunun bir kopyasını kısaltır.
İlk döngülerde ilklendirme:
) :~ : [)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:] ( 106328966328112328136317639696111819119696281563139628116326221310190661962811611211962861109696289611619628116111612896281115421063633063961111116163963011632811111819159628151213262722151522061361613096119619190661966311961128966130281807072220060611612811961019070723232022060611
) ~ ~ [)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:] [BkG] [10...11]
) [)[):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):]~:] ~ [BkG] [10...11]
) [):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):] ~ : [10...11] [BkG]
Tipik yineleme, N
bölünecek sayıyı belirtir:
) [):~[)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+:5):] ~ : [N] [BkG]
) :~ [)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/]+ :5 ) : [N] : [BkG]
) ~ ~ [)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/] +5 5 ) [N] [N] [BkG] [BkG]
) [)~:~~([:~)*[):~[$1(+48]):~+]-:~~)10)~~]/] ~ 10 N [N] [BkG] [BkG]
) ~:~ ~ ( [:~)*[):~[$1(+48]):~+]-:~~)10)~~] / N 10 [N] [BkG] [BkG]
) ~ : [:~)*[):~[$1(+48]):~+]-:~~)10)~~] ( {N/10} [N] [BkG] [BkG]
) [:~)*[):~[$1(+48]):~+]-:~~)10)~~] : [{N/10}] [N] [BkG] [BkG]
:~ )*[):~[$1(+48]):~+]- :~ ~)10 ) ~ ~ [{N/10}] [{N/10}] [N] [BkG] [BkG]
~~) *[):~[$1(+48]):~+]- ~~10 ) ) [{N/10}] ~ [{N/10}] [N] [BkG] [BkG]
) ~ * [):~[$1(+48]):~+] -10 ~ ) {N/10} [N] [{N/10}] [BkG] [BkG]
) [):~[$1(+48]):~+] * {-10} {N/10} ) [N] [{N/10}] [BkG] [BkG]
) :~ [$1(+48]) :~ + {-10*(N/10)} N [{N/10}] [BkG] [BkG]
) ~ ~ [$1(+48] ) ~ ~ {N%10} [{N/10}] [BkG] [BkG]
) [$1(+48] ~ ) {N%10} ~ [{N/10}] [BkG] [BkG]
$1( + 48 {N%10} ) [BkG] [{N/10}] [BkG]
( {48+N%10} BkG [{N/10}] [BkG] New iteration starts
[{48+N%10}] ....
- Buradaki gecikme bloğu özellikle kıllı. Bununla birlikte, tek yeni gecikme numarası iki çevrimi geciktirmek
+:5
yerine kullanmaktır . Ne yazık ki programdaki s yalnızca bir tanesi bu yardımcı oldu.--10
10
10
[N]
Ve [BkG]
bloklar çoğaltılır, daha sonra bir kopyası N
bölünür 10
.
[{N/10}]
yineleniyor, daha sonra aritmetik fonksiyonlar son basamağının ASCII kodu hesaplamak için kullanılır N
olarak 48+((-10)*(N/10)+N)
. Bu ASCII koduna sahip blok F bölümü için bırakılmıştır.
- Diğer bir kopyası yeni bir yinelemenin başlangıcını ayarlamak
[{N/10}]
için [BkG]
bloklar arasında değiştirilir .
Bonus quine (540 bayt)
)$$3371%%1[~!~~!)!]):[)$$20%%0[):]~)~~[)$$12%%0[<$$7%~~0):~[+----48+*-~~10))]<]<~!:~)~~[40~[:~))~:~[)~(~~/[+--48):]~10]+30])):]]][)[H]](11(06(06(21(21(25(19(07(07(19(61(96(03(96(96(03(11(03(63(11(28(61(11(06(06(20(18(07(07(18(61(11(28(63(96(11(96(96(61(11(06(06(19(20(07(07(18(61(30(06(06(25(07(96(96(18(11(28(96(61(13(15(15(15(15(22(26(13(12(15(96(96(19(18(11(11(63(30(63(30(96(03(28(96(11(96(96(61(22(18(96(61(28(96(11(11(96(28(96(61(11(96(10(96(96(17(61(13(15(15(22(26(11(28(63(96(19(18(63(13(21(18(63(11(11(28(63(63(63(61(11(61(42(63(63
Çevrimiçi deneyin!
Hangi yöntemin en kısa olacağından emin olamadığım için, ilk önce karakterleri (
s ile ayırarak iki basamaklı sayılar olarak kodlamayı denedim . Çekirdek kod biraz daha kısa, ancak% 50 daha büyük veri sunumu bunu telafi ediyor. Diğerleri kadar golf oynamadım, fark ettim dediğimde durduramadım. Bir avantaja sahiptir: Bignum desteğine sahip bir uygulama gerektirmez.
Genel yapısı, ana yapıya biraz benzemektedir. Veri gösterimi doğrudan F bölümünü doldurduğu için G Bölümü eksik. Bununla birlikte, bölüm E, iki basamaklı sayıların rakamlarını yeniden oluşturmak için benzer bir divmod hesaplaması yapmalıdır.