Oğlumun mektuplarını bulmasına yardım et


17

Arka fon

Dört yaşındaki çocuğumun hahamından aldığı bir oyuna dayanarak.

"Amaç", harfleri belirli bir sırada "bulmak" tır aecdb. Size, örneğin bir kart yığını verilir daceb. Yığında, döngüsel olarak da olsa, verilen sırayla arama yapabilirsiniz. İhtiyacınız olan bir mektupla karşılaştığınızda, bunu yığının dışına çıkarırsınız.

Amaç

Bir sipariş ve bir yığın verildiğinde (birbirinin kopyasız permütasyonları), oyunu oynarken gördüğünüz üst yığın harflerinin sırasını (tümü yazdırılabilir ASCII'dir) bulun.

Adım adım örnek

aecdbYığın verildiğinde siparişi bulmamız gerekiyor daceb:

Yığının Üst d: Biz (arıyoruz Ne a), biz dizisine eklemek için: dve yığını almak döndürmek: acebd.

Yığının üstü a: Evet! bu yüzden diziye ekleriz: dave yığından: kaldırırız cebd.

Yığının Üst c: Biz (arıyoruz Ne e), biz dizisine eklemek için: dacve yığını almak döndürmek: ebdc.

Yığının üstü e: Evet! bu yüzden diziye ekleriz: daceve yığından: kaldırırız bdc.

Yığının Üst b: Biz (arıyoruz Ne c), biz dizisine eklemek için: dacebve yığını almak döndürmek: dcb.

Yığının Üst d: Biz (arıyoruz Ne c), biz dizisine eklemek için: dacebdve yığını almak döndürmek: cbd.

Yığının üstü c: Evet! bu yüzden diziye ekleriz: dacebdcve yığından: kaldırırız bd.

Yığının Üst b: Biz (arıyoruz Ne d), biz dizisine eklemek için: dacebdcbve yığını almak döndürmek: db.

Yığının üstü d: Evet! bu yüzden diziye ekleriz: dacebdcbdve yığından: kaldırırız b.

Yığının üstü b: Evet! bu yüzden diziye ekleriz: dacebdcbdbve yığından: kaldırırız .

Ve işimiz bitti. Sonuç dacebdcbdb.

Referans uygulaması

def letters(target, stack):
    string = ''
    while stack:
        string += stack[0]
        if stack[0] == target[0]:
            stack.pop(0)
            target = target[1:]
        else:
            stack.append(stack.pop(0))
    return string

print letters('aecdb', list('daceb'))

Çevrimiçi deneyin!

Test senaryoları

try, yrtyrtyry

1234, 43214321432434

ABCDEFGHIJKLMNOPQRSTUVWXYZ, RUAHYKCLQZXEMPBWGDIOTVJNSFRUAHYKCLQZXEMPBWGDIOTVJNSFRUHYKCLQZXEMPWGDIOTVJNSFRUHYKLQZXEMPWGIOTVJNSFRUHYKLQZXMPWGIOTVJNSRUHYKLQZXMPWIOTVJNSRUYKLQZXMPWOTVNSRUYQZXPWOTVSRUYQZXPWTVSRUYQZXWTVSRUYZXWTVSUYZXWTVUYZXWVYZXWYZXYZ

?, ??

a, a a a

abcd, abcdabcd

Yanıtlar:


5

Üç farklı yöntem eşit bayt sayımı vermektedir.

Python 2 , 59 bayt

s,t=input()
for c in s*99:
 if c in t:print c;t=t.lstrip(c)

Çevrimiçi deneyin!

Her karakteri kendi satırına yazdırır.


Python 2 , 59 bayt

lambda s,t:[c==t[0]and t.pop(0)or c for c in s*99if c in t]

Çevrimiçi deneyin!

Listeleri girdi olarak alır ve bir liste çıkarır.


Python 3 , 59 bayt

def f(s,t):
 for c in t:p,q=s.split(c);s=q+p;print(end=p+c)

Çevrimiçi deneyin!


1
Hm, ilk iki versiyondan şüpheliyim ... neden 99özellikle?
Outgolfer Erik

@EriktheOutgolger En az yazdırılabilir ASCII karakter sayısıdır ve her girişin uzunluğu da en azdır.
xnor

5

APL (Dyalog Klasik) , 21 bayt

∊⊢,⊢∘⊂~¨(,\⊣⊂⍨1,2>/⍋)

Çevrimiçi deneyin!

Bu eşdeğer bir tren {∊⍵,(⊂⍵)~¨(,\⍺⊂⍨1,2>/⍺⍋⍵)}

sol argümanda sağ argüman permütasyonunu verir

1,2>/birbirini takip eden çiftleri karşılaştırmak >ve başına a 1

⍺⊂⍨gruplara ayırmak için yukarıdaki boole maskesini kullanın ; Maskedeki 1'ler yeni bir grubun başlangıcını işaretler

,\ grupların birikimli birleşmeleri

(⊂⍵)~¨ her birinin tamamlayıcısı

⍵, başa getirebilir

tek bir dize olarak düzleştir


4

Toplu, 155 bayt

@set/pt=
@set/ps=
@set r=
:l
@set c=%s:~,1%
@set r=%r%%c%
@if %c%==%t:~,1% set t=%t:~1%&set c=
@set s=%s:~1%%c%
@if not "%t%"=="" goto l
@echo %r%

Hedefi ve yığını STDIN'de girdi olarak alır.


4

JavaScript (ES6), 54 bayt

Hedefi bir dize ve yığını bir karakter dizisi olarak alır. Bir dize döndürür.

f=(t,[c,...s])=>t&&c+f(t.slice(c==t[0]||!s.push(c)),s)

Test senaryoları

Nasıl?

Her yinelemede, cyığının üstündeki karakteri çıkarırız ve nihai sonuca ekleriz. Biz de durumu parametreleri sonucuna bağlı yinelemeli çağrı yapmak c == t[0], t[0]sonraki beklenen karakterdir.

Eğer ceşleşmeleri t[0]:

  • chedef dizeden geçirerek kaldırıyoruzt.slice(1)
  • kaldırır cgeçirilerek istiften sdeğişmeden

Eğer ceşleşmiyor t[0]:

  • hedef dizeyi değiştirerek değiştirdik t.slice(0)
  • Biz itme cyığının sonunda geri



3

Haskell , 49 46 bayt

q@(a:b)#(c:d)|a==c=a:b#d|e<-d++[c]=c:q#e
a#_=a

Çevrimiçi deneyin!

Oldukça basit. Sol argüman "hedef", sağ argüman ise yığın. Hedefin başı, yığının üst kısmıyla eşleşirse, başa ekleriz ve hedefin geri kalanıyla ve yığıyla tekrarlanırız (öğeyi tekrar eklemeden). Aksi takdirde, üst öğeyi yığının sonuna kadar okuyarak üst öğenin başına ekleriz ve aynı hedefle tekrarlarız. Hedef boş olduğunda desen eşleşmesi ikinci satırı seçer ve boş liste döndürülür.

EDIT: @GolfWolf ve @Laikoni sayesinde -3 bayt!





1
@GolfWolf İkinci çözümünüz (ve Laikoni'nin) çalışmıyor. (:) ve (#) ile operatör önceliği nedeniyle "yrtyry" yerine "ytrty" üretir
user1472751

1

Temiz , 85 bayt

import StdEnv
g l[u:v][a:b]|a==u=g[a:l]v b=g[a:l][u:v](b++[a])
g l[]_=reverse l
f=g[]

Çevrimiçi deneyin!

Kısmi işlev falma [Char]ve [Char]ilk argümanın hedef, ikincisi de yığın olduğunu tanımlar .


1

Java 8, 88 bayt

a->b->{for(int c:a)for(char t=0;c!=t;System.out.print(t)){t=b.poll();if(c!=t)b.add(t);}}

char[]Ve java.util.LinkedList<Character>( java.util.Queueuygulama) gibi girdiler

Açıklama:

Çevrimiçi deneyin.

a->b->{                        // Method with two parameters and no return-type
  for(int c:a)                 //  Loop over the characters of the char-array
    for(char t=0;c!=t;         //   Inner loop until we've found the character in the queue
        System.out.print(t)){  //     After every iteration: print the char `t`
      t=b.poll();              //    Remove the top of the queue, and save it in `t`
      if(c!=t)                 //    If this is not the character we're looking for:
        b.add(t);}}            //     Add it at the end of the queue again

1

> <> , 38 32 bayt

Düzenleme: Deniz mavisi pelikan burada giriş yöntemleri takas çok daha iyi bir ><>yaklaşım var

0[i:0(1$.
\~~l]1+{$[&
/?=&:&:o:{

Çevrimiçi deneyin!

Harflerin sırasını -s bayraktan, yığını da girdi yoluyla alır.

Nasıl çalışır:

0[.... Creates a new empty stack
...... This puts the order of the letters safely away
......

..i:0(1$. Takes input until EOF (-1). This means input is in reverse
..~...    And then teleports to the ~ on this line
......

......      Gets the first character from the beginning of the order
\.~l]1+{$[& And stores it in the register before going to the next line
/.....

......     Output the bottom of the stack
......     Checks if the bottom of the stack is equal to the current character
/?=&:&:o:{ If so, go to the second line, else cycle the stack and repeat

0.....      Pop the extra 0 we collected
\~~l]1+{$[& Pop the value that was equal and get the next character from the order
/.....      And go down to the last line. This will end with an error (which could be avoid with a mere 4 extra bytes


1

> <> , 21 16 bayt

i$\~~
=?\$:{::o@

Çevrimiçi deneyin!

Boş alanları kullanmak ve ekstra kod yeniden yönlendirmesini kaldırmak için akış değiştirildi. (-5 bytes) - @JoKing sayesinde

> <> , 21 bayt

i:{:@=?v:o$!
o~i00. >

Çevrimiçi deneyin!

Diğer> <> yanıtı burada bulabilirsiniz.

açıklama

Yığın, -s bayrağını kullanan ilk karakter kümesiyle başlar. Girdi, kullanıcıya verilen karakter sırasıdır. Bu açıklama kodun akışını izleyecektir.

i$\        : Take input, swap the top 2 stack items then move to line 2;
             [1,2,3] -> [1,2,4,3]
  \$:      : Swap the top 2 stack items then duplicate the top item;
             [1,2,4,3] -> [1,2,3,4,4]
     {::o  : Move the stack items 1 left then duplicate the stack top twice and print one;
             [1,2,3,4,4] -> [2,3,4,4,1,1]
=?\      @ : Swap the top three stack items left 1 then do an equal comparison, if equality move to line 1 else continue;
             [2,3,4,4,1,1] -> [2,3,4,1,1,4] -> [2,3,4,1]
  \~~      : Remove the top 2 stack items;
             [2,3,4,1] -> [2,3]

Oh evet, bu şekilde girmek daha mantıklı lol
Jo King

17 bayta ne dersiniz ?
Jo King

1
@JoKing - Bu gereksiz yönlendirmeyi ortadan kaldırmak için çok güzel bir değişiklik olsa da, fazladan bir bayt almaya karşı koyamadım: P
Teal pelican

0

Perl, 62 bayt

sub{$_=$_[1];for$x(@{$_[0]}){/\Q$x\E/;$z.="$`$&";$_="$'$`"}$z}

İlk bağımsız değişkenini, sırasını, bir karakter listesi, ikincisi ise yığını dize olarak alır.

Ungolfed:

sub {
    $_ = $_[1];
    for $x (@{$_[0]}) {
        /\Q$_\E/;
        $z.="$`$&";
        $_ = "$'$`"
    }
    $z
}

Tüm bu belirsiz normal ifade değişkenlerinin ne için olduğunu hiç merak ettiniz mi? Açıkçası, bu tam zorluk için tasarlandılar. Mevcut karakterle eşleşiriz $x(maalesef normal bir özel karakter olması durumunda kaçması gerekir). Bu, dizeyi uygun şekilde "maçtan önce" $`, "maç" $&ve "maçtan sonra " olarak ayırır $'. Döngüsel aramada, maçtan önce her karakteri açıkça gördük ve yığına geri koyduk. Mevcut karakteri de gördük ama geri koymadık. Böylece "maçtan önce" yi "görülen" listeye $zekliyoruz ve "maçtan sonra" ve ardından "maçtan önce" yığınının yığınını oluşturuyoruz.


0

SNOBOL4 (CSNOBOL4) , 98 bayt

	S =INPUT
	L =INPUT
R	S LEN(1) . X REM . S	:F(END)
	OUTPUT =X
	L POS(0) X =	:S(R)
	S =S X	:(R)
END

Çevrimiçi deneyin!

Her harfi bir satırsonuna yazdırır. Her şeyi aynı satıra yazdırmak için bu sürümü kullanın . Girdiyi yeni satırla ayırarak yığın, sonra hedef alır.

	S =INPUT			;*read stack
	L =INPUT			;*read letters
R	S LEN(1) . X REM . S	:F(END)	;*set X to the first letter of S and S to the remainder. If S is empty, goto END.
	OUTPUT =X			;*output X
	L POS(0) X =	:S(R)		;*if the first character of L matches X, remove it and goto R
	S =S X	:(R)			;*else put X at the end of S and goto R
END

0

Perl, 44 bayt

İçerir +4 için-lF

STDIN'de girişi hedef olarak verin ve ardından yığınlayın (bu, örneklerin ters sıralamasıdır):

(echo daceb; echo aecdb) | perl -lF -E '$a=<>;say,$a=~s/^\Q$_//||push@F,$_ for@F'

Sondaki bir yeni satırın sakıncası yoksa bu 40işe yarar :

(echo daceb; echo aecdb) | perl -plE '$_=<>=~s%.%s/(.*)\Q$&//s;$_.=$1;$&%reg'
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.