APL trenlerini açıkça parantez içine alın


19

APL'de trenler adı verilen zımni işlevler yazabilirsiniz . Nasıl çalıştıkları bu zorluk için önemsizdir. İşlev olarak kullanılarak gruplandırılabilecekleri farklı yollar şunlardır :

⍴      -> ⍴
⍴⍴     -> ⍴⍴
⍴⍴⍴    -> ⍴⍴⍴
⍴⍴⍴⍴   -> ⍴(⍴⍴⍴)
⍴⍴⍴⍴⍴  -> ⍴⍴(⍴⍴⍴)
⍴⍴⍴⍴⍴⍴ -> ⍴(⍴⍴(⍴⍴⍴))
...

Emir aynı kalır. Prosedür, kesinlikle 3'ten fazla fonksiyon olduğu sürece, son 3 fonksiyonun bir fonksiyonda gruplandırılmasıdır. Yuvalanmış bir trenle karşılaşırsak, devam etmeden önce bunu parantez içine alırız. İşte uygulanan prosedür ⍴⍴⍴⍴⍴⍴:

Step 0: ⍴⍴⍴⍴⍴⍴
There are strictly more than 3 functions, repeat.
Step 1: ⍴⍴⍴(⍴⍴⍴)
There are strictly more than 3 functions, repeat.
Step 2: ⍴(⍴⍴(⍴⍴⍴))
There are 3 or less functions, we're done.

İşte aynı prosedür uygulanır ⍴⍴⍴(⍴⍴)⍴(⍴⍴⍴⍴(⍴⍴⍴))⍴⍴:

Step 0: ⍴⍴⍴(⍴⍴)⍴(⍴⍴⍴⍴(⍴⍴⍴))⍴⍴
There are strictly more than 3 functions, repeat.
We have met a nested train, applying procedure to that first:
  Step 0: ⍴⍴⍴⍴(⍴⍴⍴)
  There are strictly more than 3 functions, repeat.
  We have met a nested train, applying procedure to that first:
    Step 0: ⍴⍴⍴
    There are 3 or less functions, we're done.
  Step 1: ⍴⍴(⍴⍴(⍴⍴⍴))
  There are 3 or less functions, we're done.
Step 1: ⍴⍴⍴(⍴⍴)⍴((⍴⍴(⍴⍴(⍴⍴⍴)))⍴⍴)
There are strictly more than 3 functions, repeat.
We have met a nested train, applying procedure to that first:
  Step 0: ⍴⍴
  There are 3 or less functions, we're done.
Step 2: ⍴⍴⍴((⍴⍴)⍴((⍴⍴(⍴⍴(⍴⍴⍴)))⍴⍴))
There are strictly more than 3 functions, repeat.
Step 3: ⍴(⍴⍴((⍴⍴)⍴((⍴⍴(⍴⍴(⍴⍴⍴)))⍴⍴)))
There are 3 functions or less, we're done.

Giriş

Bu zorluk için girdi basitleştirilecektir. Bu, parantezleri açmak ve kapatmak için 2 farklı karakter ve işlevler için parantez için seçilenlerden farklı 1 karakter seçebileceğiniz anlamına gelir. Seçtiğiniz karakterlerin tutarlı olması gerekir. Giriş boş olmayacak ve içeriği olmayan parantez içermeyecektir (örn. ()).

Çıktı

Yine, 3 farklı karakter, 2 parantez ve 1 işlev için seçebilirsiniz. Giriş için seçilenlerle aynı olmaları gerekmediğini, ancak tutarlı olmaları gerektiğini unutmayın.

kurallar

  • Girişte yalnızca bir işlevi içine alan parantezler varsa, bunları çıktıdan kaldırmanız gerekir. Çıktınız gereksiz parantez içeremez (yani yalnızca bir işlevi veya tüm çıktıyı kapsayan).
  • Çözümünüz bu zorluk için geçerli olduğu sürece burada kullanılan algoritmayı uygulamanız gerekmez.
  • Giriş ve çıkış, Giriş ve Çıkış bölümlerinde açıklanan formattaki dizelerdir. Girişin en az bir karakteri olacaktır.
  • Kullanılması standart boşluklar kesinlikle yasaktır.
  • Bu , bu yüzden en kısa cevap kazanır. Ancak, bu dil başına bir yarışma olduğu ve bu görevin diğer dillerde yazılan kodla karşılaştırıldığında daha uzun kodla sonuçlanacağı dillerde yanıt vermeyi teşvik etmek için kabul edilen bir cevap olmayacaktır.

Test senaryoları

Burada kullanılan karakterlerdir ()⍴, bunları seçtiğiniz karakterlerle değiştirmelisiniz.

⍴                          -> ⍴
⍴                          -> ⍴
⍴⍴                         -> ⍴⍴
⍴⍴⍴                        -> ⍴⍴⍴
⍴⍴⍴⍴                       -> ⍴(⍴⍴⍴)
⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴⍴            -> ⍴⍴(⍴⍴(⍴⍴(⍴⍴(⍴⍴(⍴⍴(⍴⍴⍴))))))
⍴⍴⍴⍴⍴(⍴⍴⍴)⍴⍴(⍴(⍴⍴⍴)⍴⍴⍴)⍴⍴⍴ -> ⍴(⍴⍴(⍴⍴((⍴⍴⍴)⍴(⍴(⍴(⍴⍴⍴)(⍴⍴⍴))(⍴⍴⍴)))))
(⍴⍴⍴)(⍴⍴⍴)(⍴⍴⍴)            -> (⍴⍴⍴)(⍴⍴⍴)(⍴⍴⍴)
(⍴⍴⍴)(⍴⍴⍴)⍴⍴⍴              -> (⍴⍴⍴)(⍴⍴⍴)(⍴⍴⍴)
⍴⍴(⍴)⍴⍴                    -> ⍴⍴(⍴⍴⍴)
((⍴⍴))                     -> ⍴⍴
⍴⍴((⍴⍴))⍴⍴                 -> ⍴⍴((⍴⍴)⍴⍴)

Bu meydan okuma Sandbox'ta yayınlandı. Gerekli ayrıcalığa sahipseniz, korumalı alan yayınını burada görüntüleyebilirsiniz .


2
Bence Fully açıkça açıkça daha iyi bir başlık .
17'de


@ Adám Ben bu referans cevap bekliyordum, ama yine de çok upvotes alamazsınız;)
Outgolfer Erik

@ Adám Başlığın Açıkça anlaşılan kısmı, gereksiz parantezleri kaldırmanız gerektiği anlamına gelir. Tamamen bir meydan okumayı cevapladığınızda yapmanız gereken bir şeydir; p
Outgolfer Erik

Bu fonksiyonun her zaman idempotent olacağı doğru mu?
Esolanging Fruit

Yanıtlar:


7

APL (Dyalog Klasik) , 71 68 65 63 bayt

0{⍵≡⍕⍵:⍵⋄⍬≡⍵:'⍬'1=≢⍵:⍺∇⊃⍵⋄3≥≢⍵:⍺⌽')(',⍣⍺∊1∇¨⍵⋄⍺∇¯3(↓,∘⊂1∇↑)⍵}⍎

Çevrimiçi deneyin!

Ben I / O için seçtik karakterlerdir '(', ')'ve '⍬'.

Bu çözümün kendisi bir APL trenidir.

girişi yuvalanmış bir dizi gibi ayrıştırır - yapraklar gibi boş sayısal vektörlere ( ) sahip bir ağaç .

Dfn (yani lambda - { }) ağacı özyinelemeli olarak hareket ettirir ve uygun şekilde parantez içine alınmış bir dizeye dönüştürür. Sol argüman gerekirse parantezlerin geçerli düzeye eklenip eklenmeyeceğini kontrol eder.

Dfn, doğru bağımsız değişkene dayalı olarak aşağıdaki durumları işler:

  • zaten bir dize ( ⍵≡⍕⍵) ise, döndür

  • eğer öyleyse karakteri geri ver'⍬'

  • eğer bir singleton ise, sadece daha derine inin ( özyinelemeli bir aramanın sembolüdür)

  • uzunluğu ≤3 ise, öğelerin her biri için tekrarlayın ve ()gerekirse çevirin

  • Aksi takdirde, 3 kuyruk için geri alma, 3 kuyruk hariç hepsini geri alma ve tekrar geri alma


Çoğu Unicode olmak üzere 63 karaktere benziyor. Hangi karakter kodlaması bunun için 63 bayt üretir? UTF8'de 141 bayt yapıyorum.
Corey



@ Adám Bunun için teşekkürler. Baktım ama bu cevabı almak için ne arayacağımı bilmiyordum.
Corey

3

Python 2 , 224 208 204 bayt

Bay Xcoder sayesinde -16 bayt ovs sayesinde -4 bayt

r=str.replace
p='p'
def c(l):
 while len(l)>3:l=l[:-3]+(l[-3:],)
 return l and map(c,l)or l
print r(r(r(r(r(`c(eval(r(r(r(input(),'(p)',p),p,'[],'),')','),')))`,'[]',p),*'[('),*'])'),' ',''),',','')[1:-1]

Çevrimiçi deneyin! veya Tüm test senaryolarını deneyin

Kod 3 ana adıma ayrılabilir:
Girdiyi iç içe bir listeye dönüştürme ve değiştirme (p)->p. Tek işlev pboş bir listeyle değiştirilecektir.

eval(r(r(r(input(),'(p)',p),p,'[],'),')','),'))

Geçerli listeye "3 veya daha az" kuralını uygulamak ve tüm alt listelerde kendisini çağırmak için özyinelemeli bir işlev.

def c(l):
 while len(l)>3:l=l[:-3]+(l[-3:],)
 return l and map(c,l)or l

İstenen çıktı biçimini biçimlendirmek için birçok yer değiştirir

r(r(r(r(r(`c(...)`,'[]',p),*'[('),*'])'),' ',''),',','')[1:-1]


1
Bu basitleştirmez ((pp))(veya p((pp))p).
Martin Ender

2

CJam , 56 bayt

APL'yi yener!

lW%~]]]{{_,{K_,({~}|}&}%{_,3>}{3/(aa\+:~}w}:K~~`1>W<W%S/

Çevrimiçi deneyin!

Bu işe yarıyor (sanırım) ve neden olduğu hakkında hiçbir fikrim yok ...

Girdi karakterler ][Tiçin ()⍴, ve çıkış karakterler ][0için ()⍴evet, onlar beklediğiniz tersine çevrilir bu araçlar (; örneğin, geçmek olabilirTTT]TT[T]TTTT]TTT[[TT ).

Üst Düzey Genel Bakış

Program giriş ile geriye doğru çalışır, çünkü daha uygundur. Girdiyi ayrıştırmak için CJam'ın ayrıştırıcısından yararlanırız - girdiyi tersine çevirme ve yürütme, girdinin (geriye doğru) ayrıştırılmış biçimini sağlar.

Daha sonra bir prosedür tanımlarız K. Ksunumumuzun çoğunu yapar ve şu şekilde çalışır:

  • Girdi dizisi, sıfırların ve boş olmayan alt dizilerin bir karışımı olacaktır. Alt dizileri tanımlayın ve yinelemeli olarak uygulayınK olarak bunlara . Sonuç başka bir dizi olmalıdır ve bu dizi yalnızca tek bir öğeden oluşuyorsa, onu paketinden çıkarın (bu, gereksiz parantezlerden kurtulur).
  • Sonuç üçten fazla öğeye sahip olduğu sürece, ilk üçünü (son üçü değil; girdinin geriye doğru işlendiğini hatırlayın) tek bir listede gruplandırın.
  • Sonucu döndür.

KGirdiye uygulayarak , girdinin uygun şekilde parantez haline getirilmiş biçimini alıyoruz (dikkat edilmesi gereken tek şey, girdiyi tek bir liste listesine sarmamız ve daha sonra paketini açmamızdır; bunun nedeni, tekil paketleri açan snippet'i istememizdir yalnızca alt dizilerine değil, üst düzey programa da başvurmak). Daha sonra, sonucumuzu elde etmek için minimum biçimlendirme uygularız.

Golf bitleri için bazı açıklamalar

En gurur duyduğum golf, ,tamsayılar ve diziler arasında kontrol yapmaktır.

  • Yığının tepesi bir tamsayı n ise , [0..n), aralığını oluşturur . Karşılaşacağımız tek tamsayı olduğu için , bu bize her zaman falsey olan boş listeyi verir .0[]
  • Yığının üst kısmı bir diziyse ,uzunluğunu alır. Karşılaştığımız tüm diziler boş olmayacağından, bu bize her zaman pozitif bir tamsayı verir, bu doğrudur.

İlgilenebilecek başka bir golf, dizinin ilk üç öğesini gruplamak için kullandığım yöntemdir; "Turing tam dil tercüman kodu golf" gönderimime biraz benziyor . CJam'in bir diziyi iki parçaya ayırmak için kısa bir yolu yoktur (orijinal diziyi ve dizini yığının üzerinde tutarken ilk parçayı ve sonra diğer parçayı dilimlemeyi deneyebilirsiniz, ancak bu çok iyi çalışmaz) , yani bunun yerine ne yaptığım 3/, hangi bir dizi 3 bloklar halinde gruplandırır. Sonra ilk öğeyi pop (, dizi iki kez sarın aave sonra listenin başına ekleyebilirsiniz \+. Diziyi iki kez sarmamızın nedeni, dizinin :~geri kalanını da bölümlere ayırdığımız için bir katman çıkarmamız gerektiğidir.


Nitpick: Bu , yerleşik olmayan APL'yi yener .
Outgolfer Erik

@EriktheOutgolfer Yeterince adil.
Esolanging Fruit

0

JavaScript (ES6), 149 146 bayt

i='a';f=s=>s==(s=s[R='replace'](/\((\w+)\)/,(q,t)=>(f[q=i+=0]=f(t),q)))&&s==(s=s[R](/(?!^)((a0+|p){3})$/,"($1)"))?s[R](/a0+/g,t=>`(${f[t]})`):f(s)
<textarea cols=80 id=I>ppp(pp)p(pppp(ppp))pp</textarea><br>
<button onclick=O.innerText=f(I.value)>Run</button><br>
<pre id=O></pre>

Kullanır ()p, ancak farklı bir harf kullanmanıza rağmen psonuna doğru değiştirebilirsiniz .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.