Özyinelemeli dize değiştirme


25

Görev

Üç dize verilen bir program veya işlev yazın A, B, C, Biçinde her örneğinin Atekrarlı olarak değiştirildiği bir çıktı dizesi oluşturur C. Yinelemeli her adımda tüm çakışmayan örnekleri bir ikame tekrar aracı ikame Bolarak Adeğiştirilir (soldan sağa iştahla seçilen) Ckadar Bdaha fazla içerdiği A.

Giriş çıkış

  • G / Ç için varsayılan yöntemlerden birini kullanabilirsiniz .
  • Dizeler yalnızca yazdırılabilir ASCII karakterleri içerecektir (ve bunlardan herhangi birini içerebilir ).
  • BAsla boş bir dize olmayacak, Ave Colabilir.
  • Dizeler düz metin olarak kabul edilir, örneğin Bbir Regex kalıbı gibi davranamazsınız.
  • Bazı girdi kombinasyonları asla sona ermeyecektir. Programınız bu durumlarda her şeyi yapabilir.

Test durumları

Bunlar biçiminde: A/B/C\nOutput

Hello, world!/world!/PPCG
Hello, PPCG

Uppercase is up/up/down
Uppercase is down

ababababa/aba/ccc
cccbcccba

delete/e/{empty string}
dlt

{empty string}/no/effect
{empty string}

llllrrrr/lr/rl
rrrrllll

+-+-+-+/+-+/+
+

ababababa/aba/bada
badabbadbada

abaaba/aba/ab
abb

((())())())/()/{empty string}
)

Sonlanmayan örnekler:

grow/ow/oow

loop/lo/lo

3
Başka bir test örneği:((())())())/()/
Conor O'Brien,

@ ConorO'Brien eklendi
Leo

1
İlk başta, büyük / küçük harf duyarlı yapamadım. downpercase is down
Mühendis Toast

Yanıtlar:


7

05AB1E , 2 bayt

`:

Çevrimiçi deneyin!

açıklama

`    # split input to stack
 :   # replace (until string doesn't change)

Bu olabilir :için 1 byte biz boş dizeleri uğraşmak zorunda olmasaydı.


3
Doğru anlarsam, 4 baytlık çözümünüz geçerlidir. "Bazı girdi kombinasyonları hiçbir zaman sonlandırılmayacak. Programınız bu durumlarda her şeyi yapabilir."
Leo

@Leo. Haklısın O kısmı
gözden kaçırdım

1
Yani temelde :tüm zorluğu çözen bir yerleşik mi? Yerleşikleri yasaklamalıydım;)
Leo

@ Leo: Eğer boş dizgiler olmasaydı, tek bir yerleşik bunu çözebilirdi. Ve boş dizgelerin tek farkı, aksi takdirde işlemden dolaylı olarak çıkarılacak olan 3 girdi olduğunu belirtmemiz
gerekmesidir

Gibi bir şey mi bu da mümkündür?
Adnan

9

Python 2 , 43 bayt

lambda s,*l:eval('s'+'.replace(*l)'*len(s))

Çevrimiçi deneyin!

Formun bir dizesini değerlendirir

s.replace(*l).replace(*l).replace(*l) ...

Varsa sabit bir noktaya ulaşmak, orijinal dizenin uzunluğuna eşit olacak şekilde değişiklik yapmak yeterlidir.


7

ES6 (Javascript), 47, 43 bayt

  • Currying kullanarak 4 byte kaydedildi (Thanks @Neil!)

golfed

c=>b=>R=a=>(x=a.split(b).join(c))==a?x:R(x)

Dene

Q=c=>b=>R=a=>(x=a.split(b).join(c))==a?x:R(x)

function doit() {
  console.log(Q(C.value)(B.value)(A.value));
}
A: <input type="text" value="abaaba" id="A"/> B: <input type="text" value="aba" id="B"/> C: <input type="text" value="ab" id="C"/> <input type="submit" onclick="doit();" value="REPLACE"/>


Argümanları tersi sırayla kurutmakla 4 byte kazanabilirsiniz:c=>b=>g=a=>a==(a=a.split(b).join(c))?a:g(a)
Neil


@MetoniemSome combinations of inputs will never terminate. Your program can do anything in those cases.
zeppelin

@zeppelin Oh, anlıyorum.
Metoniem

5

Retina , 27 bayt

Bayt sayısı, ISO 8859-1 kodlamasını varsayar.

+`(.+)(?=.*¶\1¶(.*))
$2
G1`

Giriş satır besleme ile ayrılmalıdır.

Çevrimiçi deneyin! (Kolaylık sağlamak için, her çizginin eğik çizgiyle ayrılmış test durumları olduğu bir test paketi giriş biçimi kullanır.)


4

C #, 44 Bayt

Kısa versiyon:

r=(a,b,c)=>a==(a=a.Replace(b,c))?a:r(a,b,c);

Örnek Program:

using System;

namespace ConsoleApplication1
{
    class Program
    {
    static void Main(string[] args)
        {
            Func<string, string, string, string> r = null;
            r=(a,b,c)=>a==(a=a.Replace(b,c))?a:r(a,b,c);

            Action <string, string, string, string> test =
                (a, b, c, answer) =>
                {
                    var result = r(a, b, c);
                    Console.WriteLine("A: \"{0}\"\r\nB: \"{1}\"\r\nC: \"{2}\"\r\nResult: \"{3}\"\r\n{4}\r\n\r\n",
                        a, b, c, result, result == answer ? "CORRECT" : "INCORRECT"
                        );
                };

            test("Hello, world!", "world!", "PPCG", "Hello, PPCG");
            test("Uppercase is up", "up", "down", "Uppercase is down");
            test("ababababa", "aba", "ccc", "cccbcccba");
            test("delete", "e", "", "dlt");
            test("", "no", "effect", "");
            test("llllrrrr", "lr", "rl", "rrrrllll");
            test("+-+-+-+", "+-+", "+", "+");
            test("ababababa", "aba", "bada", "badabbadbada");
            test("abaaba", "aba", "ab", "abb");
            test("((())())())", "()", "", ")");


            Console.WriteLine("Press any key...");
            Console.ReadKey();
        }
    }
}

Açıklama: İşlev, aşağıdakilerden yararlanarak return anahtar sözcüğü ve küme parantezlerinden kaçınarak, kuyruk özyinelemeli bir ifade olarak yazılır:

  • Parantez içindeki bir atama atanan değeri döndürür.
  • Eşitlik kontrolünün sol tarafı, sağ taraftaki atamadan önce değerlendirilir ve satır içi öncesi / sonrası karşılaştırmamızı sağlar ve sonuçlara erişir.

Bu, onu tek bir ifadede tutmamızı sağlar.

EDIT: r işlevinin türünü çıkarmaya geri döndü, çünkü bu kabul edilebilir görünüyor. Dizileri kullanan tür bildirimi ile, 68 karakterdir. Olmadan, 44 karakterdir.


İşlev yalnızca belirli bir ad verilirse çalışırsa, işlevi bu adı vermek için bayt harcamalısınız. r=Bir bildirim için 2 bayt mı yoksa daha fazlası mı olduğu hemen belli değil (kısmen kuralları tam olarak bilmediğimden, kısmen de C # 'u uygulayacak kadar iyi bilmediğim için).

Evet, bir başkasının yorumunu farklı bir girişle ilgili okuduktan sonra düzelttim. Çeşitlerin de belirtilmesi gerektiği için çok daha fazlası. Bunu kaydetmek için bir dizi kullanmaya ve özyinelemeli çağrıdaki baytları kaydetmeye geçtim.
Daniel,

Doğru çıktıyı üretme ile ne demek istiyorsun ? Girişin çıktısını almanız gerektiğini sanmıyorum, aslında diğer cevapların bazıları bunu yapmıyor. Girdiyi çıkarmam gerektiğini söyleyen bir yorumu kaçırdım mı?
Auhmaan

Boş ver, sorunu buldum, özyinelemeli değil.
Auhmaan

2

Japt , 15 bayt

@¥(U=UqV qW}a@U

Çevrimiçi test edin!

Nasıl çalışır

@¥(U=UqV qW}a@U  // Implicit: U, V, W = input strings
            a@U  // Return the first non-negative integer mapped by the function X => U
@          }     // that returns truthily when mapped through this function:
     UqV qW      //   Split U at instances of V, and rejoin with W.
  (U=            //   Set U to this new value.
 ¥               //   Return (old U == new U). This stops the loop when U stops changing.
                 // Implicit: output result of last expression

Japt yerleşik bir özyinelemeli yerine yerleşik, ancak ilk girdisini regex olarak görüyor. Girdilerin yalnızca alfasayısal karakterler içerdiği garanti edilirse, bu üç baytlık çözüm işe yarayacaktı:

eVW

Giriş haricinde herhangi bir karakter içermesine izin olsaydı ^, \ya ]bu 12 byte çözüm yerine geçerli olacaktır:

eV®"[{Z}]"ÃW

2

C #, 33 49 bayt

Muhtemelen, C # ile yazılmış küçük snippet'lerden biri ... Ve bu yana Replaceyerli stringyapı, gerek yoktur usings ( VS yerleşik En azından üzerinde özellik, C # Interactive ... )

Ayrıca, Bher zaman bir değeri olduğundan, kodun doğrulanması gerekmez.


golfed

(a,b,c)=>{while(a!=(a=a.Replace(b,c)));return a;}

Ungolfed

(a, b, c) => {
    while( a != ( a = a.Replace( b, c ) ) );

    return a;
}

Tam kod

using System;

namespace Namespace {
    class Program {
        static void Main( string[] args ) {
            Func<string, string, string, string> func = (a, b, c) => {
                // Recursively ( now truly recursive ) replaces every 'b' for 'c' on 'a',
                // while saving the value to 'a' and checking against it. Crazy, isn't it?
                while( a != ( a = a.Replace( b, c ) ) );

                return a;
            };

            int index = 1;

            // Cycle through the args, skipping the first ( it's the path to the .exe )

            while( index + 3 < args.Length ) {
                Console.WriteLine( func(
                    args[index++],
                    args[index++],
                    args[index++]) );
            }

            Console.ReadLine();
        }
    }
}

Bültenleri

  • v1.1 -+19 bytes - Sabit çözüm özyinelemeli değil.
  • v1.0 -  33 bytes- İlk çözüm.

1
C # görüyorum # Oy ver
Nelz

@ NelsonCasanova Bana benziyor.
Metoniem

Does Replaceözyinelemeli değiştirme işlemini?
Laikoni

@Likonik no. Örneğin, "((())())())".Replace("()", "")geri döner (())).
Auhmaan

O zaman bu çözüm meydan okuma kuralları kapsamında geçerli değildir. Düşüşleri önlemek için silmeli, sonra özyinelemeli değiştirme işlemek için çözümünüzü düzeltmeli ve sonunda geri almalısınız.
Laikoni

1

İşlem, 75 72 bayt

void g(String a,String[]s){for(;a!=(a=a.replace(s[0],s[1])););print(a);}

Sonuçları yazdırır. Gibi arag("llllrrrr", new String[]{"lr","rl"});

void Q110278(String a, String[]s){             //a is the string to be replaced
                                               //s is the array containing the subsitution

  for(; a!=                                    
            (a = a.replace(s[0], s[1])) ;);

  //for-loop where we continuously perform substitution on a
  //until a is equal to substituted a


  //at the end, print the final version of a
  print(a);
}

1

Mathematica, 35 32 Bayt

#//.x_:>StringReplace[x,#2->#3]&

Dizi olarak verilen argümanlar. İçin sonlandırır asla growörneğin, döner loopiçin loopörnek. Martin önerisi sayesinde üç bayt kapalı.


FixedPointçok uzun olma eğilimindedir ve aşağıdakilerle öykünebilir //.:#//.x_:>StringReplace[x,#2->#3]&
Martin Ender

@ Martininder teşekkürler. ReplaceRepeatedDizelerde çalışmak için iyi bir yol !
Simmons Simmons

btw, bu sadece döngü $RecursionLimitsüreleri olacaktır , 2^16varsayılan ayardır, cevabınızı etkilemeyecektir
ngenisis

@ngenesis Bu ReplaceRepeatedkontrol tarafından emin değilim $RecursionLimit- Ben sadece limitini 20'ye ayarlayarak test ettim ve program hala sonlandırılmamış girdiler için döngüye girer ..
A Simmons

Çünkü ReplaceRepeatedayrı bir seçenek var (ki bu //.sözdizimi ile kullanılamaz ) MaxIterations. Bu varsayılan olarak 2 ^ 16'dır. (cc @ngenisis)
Martin Ender

1

Ruby, 29 bayt

->a,b,c{1while a.gsub! b,c;a}

3 argüman verildiğinde, artık yerine geçecek bir şey kalmayıncaya kadar ilkine yer değiştirme uygulayın.

açıklama

  • 1önce whilesadece bir nop
  • gsub!dizeyi döndürür ya nilda yer değiştirme olmadıysa


1

/// , 3 bayt

///

İlk eğimden sonra B dizesini, ikinciden sonra C ve sonunda A harfini koyun:

/<B>/<C>/<A>

Çevrimiçi deneyin!


Bunun girişleri kabul etmenin kabul edilebilir bir yolu olduğunu düşünmüyorum
Leo,

Bildiğim kadarıyla, ///girişi başka hiçbir şekilde kabul etmiyor.
steenbergh

2
Peki, bunun kabul edilebilir olup olmadığını tartışmanın ilginç olacağını düşünüyorum, o zaman :) Her neyse, gönderiminizle ilgili başka bir sorun fark ettim: /giriş dizgilerinden herhangi biri varsa bir işe yaramaz
Leo

1

JavaScript (Firefox 48 veya önceki sürüm), 43 bayt

c=>b=>g=a=>a==(a=a.replace(b,c,'g'))?a:g(a)

Ters sırayla curried argümanlar alır. Firefox, replaceregexp işaretlerini belirten standart olmayan bir üçüncü parametreye sahipti. Bu parametre Firefox 49'da kaldırıldı.


0

SmileBASIC, 72 68 bayt

I=0DEF R A,B,C
I=INSTR(A,B)?A*(I<0)A=SUBST$(A,I,LEN(B),C)R A,B,C
END

SmileBASIC'te işlev yapmanın nadir görülen durumlarından biri aslında SHORTER'dir.


0

Javascript 130 bayt

f=(a,b,c)=>a.indexOf(b)<0?a:f(eval("a.replace(/"+b.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g,"\\$&")+"/g,c)"),b,c)

Javascript, yalnızca bir regex verirseniz hepsini eşzamanlı olarak değiştirir. Bu regex'in tüm değerler için çalışmasını sağlamak için, regex için kullanılan tüm karakterlerin çıkış karakteriyle değiştirilmesi gerekir. Son olarak, A'daki tüm B örneklerini C ile değiştirmek ve onu tekrar işleve geri vermek için değerlendirme yapılır.



0

Çedar, 37 bayt

(a,b,c)f->a has b?f(a.sub(b,c),b,c):a

Telefonda bu yüzden TIO bağlantısını eklemek biraz zor. Temelde, kontrolün a olduğu durumlarda özyinelemeyi kullanır. Çözüm olabilirdi (a,b,c)->a.sub(Regex{b,"cr"},c)ama bir nedenden dolayı işe yaramıyor.


Alt tüm veya sadece ilk yerini mi alıyor?
f Febnɛtɪk

@LliwTelracs çünkü dizeler
.sub hepsinin

Bu işe görünmüyor mu? Çevrimiçi deneyin!
Conor O'Brien,

@ ConorO'Brien üçlü saçma sapan hata tarafı kapalı
Downgoat




0

Java - 157 bayt

String r(String f){if(f.length()<1)return "";String[]x=f.split("/");if(x[0].contains(x[1]))return r(x[0].replace(x[1],x[2])+'/'+x[1]+'/'+x[2]);return x[0];}

Boş giriş için boş bir dize döndürür.

Boş StackOverflowExceptionolduğunda hatalı bir şekilde çöküyor Bveya bunun gibi verilerle besleniyor A/A/A.

Nasıl çalışır:

r("ABCD/A/F") returns value of r("FBCD/A/F") which returns FBCD
If there is no more characters to be replaced it returns the final output

Yorumsuz kodlanmamış kod:

String r (String f) {
    if(f.length() < 1)
        return ""; // For empty input return empty output
    String[] x = f.split("/"); // Get all 3 parameters
    if (x[0].contains(x[1])) // If input contains replaced value
        return r(x[0].replace(x[1],x[2])+'/'+x[1]+'/'+x[2]); // Return value of r() with one character replaced
    return x[0]; // If nothing to replace return the output(modified input)
}

0

AutoHotkey, 87 bayt

StringCaseSense,On
Loop{
IfNotInString,1,%2%,Break
StringReplace,1,1,%2%,%3%
}
Send,%1%

%1%, %2%Ve %3%bir işleve geçirilen ilk 3 argümanları olan
bir işlev değişken argüman bekliyorsa, %s bırakılan
onsuz, gibi şeyler olsun, küçük harf duyarlılığı ayarını değiştirme 19 bayt maliyeti ama downpercase is down.

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.