Bazı dominoları devir!


22

Bazı ilham için bu soruya teşekkürler

Bu meydan biz bir dize olarak domino bir çizgiyi temsil edecek |, /ve \. Girdi olarak size bir dizi domino verilecek ve yerleştiklerinde nasıl göründüklerini belirlemelisiniz. İşte Dominoların nasıl düştüğünün kuralları

  • |Sol düşmüş bir dominodan kalan bir ayakta domino da düşmüş bir domino \haline gelecektir.

  • Duran bir domino, |sağ düşmüş bir domino hakkı /, aynı zamanda sağ düşmüş bir domino olacak.

  • Bir ayakta domino düşmüş bir sol \ve sağ düşmüş bir /domino arasındaysa, ayakta kalacaktır.

Bu kurallar düzenleme artık değişmedene kadar tekrar tekrar uygulanır.

Tek bir girdinin sonuçlarına nasıl ulaşabileceğine dair bir örnek

|||||||\/|||||||\||\|||/||||||\|||||

||||||\\//|||||\\|\\|||//||||\\|||||
|||||\\\///|||\\\\\\|||///||\\\|||||
||||\\\\////|\\\\\\\|||////\\\\|||||
|||\\\\\////|\\\\\\\|||////\\\\|||||
||\\\\\\////|\\\\\\\|||////\\\\|||||
|\\\\\\\////|\\\\\\\|||////\\\\|||||

\\\\\\\\////|\\\\\\\|||////\\\\|||||

Göreviniz bir girişin sonucunu bulan ve çıkaran kod yazmaktır. Girişin her zaman geçerli olduğunu ve en az 2 karakter içerdiğini varsayabilirsiniz.

Bu bu nedenle cevaplar daha az byte'ın daha iyi olmasıyla byte olarak puanlanacaktır.

Test durumları

|||/||||  -> |||/////
|||\||||  -> \\\\||||
|/||||\|  -> |///\\\|
||/|||\|  -> ||//|\\|
||\|||/|  -> \\\|||//

6
Ters eğik çizgi kaçan! (Başka semboller kullanabilir miyiz?)
Arnauld

1
@Arnauld Hayır, eğik çizgileri kullanmalısınız.
Buğday Sihirbazı,

1
Neyin kaçıp neyin çıkmayacağını çözemiyorum.
Ocak'ta

Giriş hiç boş dize mi, yoksa tek bir karakter mi olacak?
Doorknob

3
`///////// | | \ gibi şeylerin kararlı olarak kabul edilmesi gerektiğinden daha fazla beni rahatsız ediyor.
MooseBoys

Yanıtlar:


13

Retina , 32 bayt

+`(/.\\)|(/)\||\|(\\)
$1$2$2$3$3

Çevrimiçi deneyin!

açıklama

+O dizeyi değiştirmek için başarısız kadar döngüde değiştirme çalışmasına Retina söyler. Her bir yedek düşen dominoların bir adımını hesaplar. Değişimin kendisi bir arada gerçekten üç değişiklik, ancak bu aynı anda gerçekleşmelerini sağlar:

(/.\\)...
$1

Bu sadece maçları /|\(yanı sıra /\\ve /\\ancak bu madde yok) ve reinserts bunu değişmeden. Bunun amacı, |her iki taraftaki düşmüş dominoların üzerinden atlamaktır, çünkü bu, diğer iki durumda ayrı ayrı görünen davaları dışlamaktan daha kısadır.

...(/)\|...
$2$2

Bu eşleşir /|ve dönüşür //.

...\|(\\)
$3$3

Bu eşleşir |\ve dönüşür \\.


Bunun geldiğini görmedim diyemem. Retina kesinlikle iş için iyi bir araçtır.
Buğday Sihirbazı,

@WheatWizard Çözmesi kolaydır, ancak muhtemelen tüm kaçan ve $1$2$2$3$3golf dillerini yenmek için çok ayrıntılı .
Martin Ender

5

Python 2 , 115 114 111 108 98 95 bayt

Ovs sayesinde -1 bayt

a=input()
for i in range(4)*len(a):a=a.replace('//|x||\ \\'[i::4],'/\/x|\/ \\'[3-i::4])
print a

Çevrimiçi deneyin!


R-dizelerini kullanarak 114 bayt .
ovs

Sen kaldırabilir b=0;ve tekrarlamalarını değiştirmek btarafından idiki bayt tasarruf etmek!
Lynn

4

V , 23 bayt

òÓ¯À<!|¨Ü©ü¨¯©|ÜÀ!/±±²²

Çevrimiçi deneyin!

Gerçekten, bu retina cevabına çok benziyor, sadece çirkin görünüyor. Regex sıkıştırması kullanır.

HexDump:

00000000: f2d3 afc0 3c21 7ca8 dca9 fca8 afa9 7cdc  ....<!|.......|.
00000010: c021 2fb1 b1b2 b2                        .!/....

Açıklama:

òDize değişmeyene kadar V'nin çalışmasını söyler. Gerisi sıkıştırılmış bir regex. Hadi bunu vim eşdeğerine çevirelim ...

:s/\v\/@<!\|(\\)|(\/)\|\\@!/\1\1\2\2/g

:s/                                     " Substitute...
   \v                                   " Turn on magic (use less escaping)
          \|                            " A bar
            (\\)                        " Followed by a captured backslash
       @<!                              " That is not preceded by
     \/                                 " A forward slash
                |                       " OR...
                 (\/)                   " A captured forward slash
                     \|                 " Followed by a bar
                       \\@!             " That is not followed by a backslash
                           /            " Replace this with
                            \1\1        " Pattern 1 twice (will be empty if we matched the second path)
                                \2\2    " Pattern 2 twice (will be empty if we matched the first path)
                                    /g  " Replace every match on this line

4

SNOBOL4 (CSNOBOL4) , 117 115 112 111 bayt

	D =INPUT
S	D '/|\' ='_'	:S(S)
	E =D
	D '/|' ='//'
	D '|\' ='\\'
	D E	:F(S)
R	D '_' ='/|\'	:S(R)
	OUTPUT =D
END

Çevrimiçi deneyin!

Rod'un python'una verilen kredi, test etme yerine değişiklikleri görmek için ikinci bir değişken olan durdurma koşulu fikrine cevap verir D '/|' | '|\'.

	D =INPUT		;* read input
S	D '/|\' ='_'	:S(S)	;* replace '/|\' with '_', recursively
	E =D			;* set E to D, this is the while loop
	D '/|' ='//'		;* topple right
	D '|\' ='\\'		;* topple left
	D E	:F(S)		;* if D doesn't match E, goto S
R	D '_' ='/|\'	:S(R)	;* replace '_' with '/|\' (inverse of statement S)
	OUTPUT =D		;* output
END

3

Haskell , 114 107 bayt

until=<<((==)=<<)$g
g s=t<$>zip3('|':s)s(tail s++"|")
t(l,'|',r)|l<'0',r/='\\'=l|r=='\\',l>'/'=r
t(_,e,_)=e

Çevrimiçi deneyin! İlk satır anonim bir işlevi tanımlar.

Açıklama:

  • until=<<((==)=<<)$gsonuç artık değişinceye kadar işlevi giriş dizgisine uygulayan bir sabitleme noktası işlevidir ( açıklama için buraya bakınız ) g.
  • zip3('|':s)s(tail s++"|")Her domino için yaratır, karakter dizisinde karakter s, önceden ve sonra gelen domino ile üçlü |, kenarlarda dolgulu. Örneğin /\|, [(|,/,\),(/,\,|),(\,|,|)](kaçmayı gözardı ederek) olur.
  • Ardından, fonksiyon tüçlü parçanın merkez parçasının yeni konumunu hesaplamak için üçlülerin her birine uygulanır.


2

Prolog (SWI) , 132 bayt

+[]-->[].
+[47,124,92|T]-->"/|\\",+T.
+[47,47|T]-->"/|",+T.
+[92,92|T]-->"|\\",+T.
+[X|T]-->[X],+T.
X+Y:- +(N,X,[]),!,(X=N,Y=N;N+Y).

Çevrimiçi deneyin!

Bu program, +/2eğer ikinci argüman ilkenin oturmuş haliyse doğru olan bir ifadeyi tanımlar . Her iki argüman karakter kodlarının listesidir.

açıklama

Bu çözüm, bir sonraki adımın ne olduğunu bulmak için bir DCG kullanır ve ardından bir sonraki adım mevcut adımla aynı olana kadar bir sonraki adımı tekrar tekrar hesaplar.

DCG

+[]-->[].
+[47,124,92|T]-->"/|\\",+T.
+[47,47|T]-->"/|",+T.
+[92,92|T]-->"|\\",+T.
+[X|T]-->[X],+T.

Bu beş kod satırı +, dominoların devrilmesinin tek bir basamağını hesaplamak için programda kullanılan bir DCG (Kesin Cümle Dilbilgisi) kuralını tanımlar. Prolog'daki DCG'ler, sağ tarafı dizeyle eşleşen kuralın ilk örneğini bulup, bu işlem sırasında soldaki kuralın argümanını belirleyerek çalışır. Bir vaka eşleşmezse başarısız olur ve daha sonraki bir vakayı dener.

+[]-->[].

Bu çizgi +kuralın temelini temsil eder . Sadece şu anda domino yoksa o zaman bir sonraki adımda hala domino olmayacağını belirtir.

+[47,124,92|T]-->"/|\\",+T.

Bu program karakter kodlarının listeleri ile münhasıran fırsatlar beri dikkat etmek önemlidir bunun için karakter kodları /, \ve |47, 92 ve 124 sırasıyla. +Kuralın bu örneği /|\dizgiyi işler .

+[47,47|T]-->"/|",+T.

Bu dava, sağa düşen domino ile sağa düşen dominoyu ele alıyor. Davadan sonra geldiği /|\için bu olasılık için kullanılmayacaktır.

+[92,92|T]-->"|\\",+T.

Soldan düşen domino için davayı ele alır ve soldan dominoya çarpar.

+[X|T]-->[X],+T.

Bu joker durumdur. Yukarıda anlatılanların dışında başka hiçbir şey değişmediğinden, giriş dizesinde kalan metin olduğu sürece, yukarıdaki durumlardan hiçbiriyle uyuşmadığı sürece çıktıya kopyalar.

Tahmin etmek

X+Y:- +(N,X,[]),!,(X=N,Y=N;N+Y).

Ana yüklem iki argüman alır, ilki ilk domino düzeneği, ikincisi yerleşik domino. Bu Prolog olduğundan, ikincisi belirlenemez ve program bunu hesaplar. Kendi başına +(N,X,[])belirti oldukça basittir , DCG'yi çağırır ve onu depolayan dominoların bir sonraki basamağını hesaplar N. (X=N,Y=N;N+Y)çekler domino sonraki adım akım aynıdır ve eğer o ayarlarsa Ydomino yerleşmiş olmalı beri kendisine ve eğer değilse o domino sonraki adıma aynı yüklemi çağıran recurses Nyerine X.



1

yüz , 166 bayt

\|/,cm_/o>AvI[IIcP/+PP|m_/m*/Sl*Im1/11:~-_I|'|?_1-_P|?_1`I-III_|+II|'I.C:1-_I|?_C'|-_P|?_C_|'I-_I|`I?_!'I.C:!'|'|-III+II|'I:C_|-PPP+PPI'I?I~_I-PPP+PP|-**1?*~Sl*Iw*I*>

Komut satırı argümanı olarak girdi alır ve STDOUT'a çıkar. Bu, yalnızca 86494f6 numaralı taahhütte ve bu taahhütte belirtilen bir hata nedeniyle işe yarar.

Estetik için sarılmış:

\|/,cm_/o>AvI[IIcP/+PP|m_/m*/Sl*Im1/11:~-_I|'|?_1-_P|?_1`I
-III_|+II|'I.C:1-_I|?_C'|-_P|?_C_|'I-_I|`I?_!'I.C:!'|'|-III
+II|'I:C_|-PPP+PPI'I?I~_I-PPP+PP|-**1?*~Sl*Iw*I*>

Ve unungolfed / yorumladı:

\|/,cm_/o>              ( setup )

AvI[II                  ( store input into I )
cP/+PP|m_/              ( store 92, ascii for \, into P, meaning prev char )
m*/Sl*Im1/11            ( store length of input into counter variable * )

( main loop: )
:~

    -_I|'|?_1           ( branch to 1 if the character is not \ )
    -_P|?_1             ( also branch to 1 if the previous character wasn't | )
    `I-III_|+II|'I      ( we have a sequence |\ so prev needs to be toppled )
    .C                  ( jump to C, the "continue" label at end of loop )

    :1
    -_I|?_C             ( branch to C if the character is not | )
    '|-_P|?_C           ( also branch to C if the previous character wasn't / )
    _|'I-_I|`I?_!       ( branch to ! if the next character isn't \ )
    'I.C:!              ( otherwise, skip the next \ and branch to continue )
    '|'|-III+II|'I      ( if all conditions hold we have /|| or /|/ so topple )

    :C
    _|                  ( reset pointer to source )
    -PPP+PPI            ( update prev variable )
    'I                  ( step through data )

?I~

_I-PPP+PP|-**1          ( reset input/prev and decrement counter )
?*~                     ( repeat main loop as many times as there are chars )

Sl*Iw*I*>               ( output final string to stdout )

Burada, birkaç ekstra bayt gibi tıraş eden birkaç ince numara var.

  • değişkenlerin isimlendirilmesi | ve /, ASCII değerlerine daha sonra kodun içindekiler aracılığıyla erişilen

  • '|ayarlamak için ikinci satırda yerine orada denir ana döngü, ilk satırda | ana döngünün ikinci bölümünde kullanım için işaretçi


1

Perl 5 , 52 + 1 (-p) = 53 bayt

Mik sayesinde -6 bayt

Muhtemelen Perl için mümkün olan en iyi şey değil, ama bu benim yapabileceğim şeydi.

0while(s/(?<!\/)\|(?=(\\))|(?<=(\/))\|(?!\\)/$1$2/g)

açıklama

while(
  s/
    (?<!\/)\|(?=(//)) # If there's a | that precedes a \ but doesn't follow a /, capture /
      | # Or
    (?<=(\/))\|(?!//)/ # If there's a | that follows a / doesn't precede a \, capture /
  /$1$2/ # Replace all | with capture group 1 or 2, as one of the two will always be empty
  g # Repeat as much as possible for this string
)

Çevrimiçi deneyin!


-p-aihtiyacını ortadan kaldırmak yerine print;; whilekukla bir ifadeye sonek olarak kullanmak (örn. 0) başka bir 2 bayt daha kurtarır
mik

Teşekkürler @mik, bu numaralardan haberim yoktu. Ayrıca, regex'i bazı baytları kurtarmak için başka bir şeyle sınırlandırabileceğimin farkındayım. Bunu daha sonra alabilirim.
Geoffrey H.

1

Perl 5 , 44 (kod) + 1 ( -p) = 45 bayt

1while s,(/)\|(?!\\)|(?<!/)\|(\\),$1$1$2$2,g

Çevrimiçi deneyin!

açıklama

1while s,                        ,        ,g   while anything found substitute globally
         (/)\|(?!\\)              $1$1         /| that is not followed by \ to //
                    |                          or
                     (?<!/)\|(\\)     $2$2     |\ that is not preceded by / to \\


0

Yakut , 83 bayt

Teknik olarak aldatılabilir 9.times , hatta sadece 999.timesama ucuz olmak istemiyorum :)

Hala dev golf potansiyeli var. (Not: y while undoneçok daha uzun x.size.times)

->x{x.size.times{x.gsub! /\/\|\\?|\|\\/,'/|\\'=>'/|\\','/|'=>'//','|\\'=>'\\\\'}
x}

Çevrimiçi deneyin!


0

R , 114 bayt

function(d){g=gsub
for(i in 1:nchar(d))d=g("/|","//",g("|\\","\\\\",g("/|\\","_",d,f=T),f=T),f=T)
g("_","/|\\",d)}

Çevrimiçi deneyin!

Çıkış dizesini döndürür.


0

C (gcc) , 183 bayt

D,i;f(char*S){char*s=malloc(-~strlen(S));for(D=1;D--;strcpy(S,s))for(strcpy(s,S),i=0;s[i];i++)s[i]>92&&(S[-~i]==92&&S[~-i]!=47&&(s[i]=92,D=1)||S[~-i]==47&&S[-~i]!=92&&(s[i]=47,D=1));}

Çevrimiçi deneyin!

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.