Sayı dizesini daraltma


12

Herhangi bir uzunlukta 1ve 2herhangi bir uzunlukta bir dize verildiğinde , bu kriteri izleyerek dizeyi son bir forma küçültmenin kaç adım gerektiğini hesaplayan bir kod yazın ( artık bir işlev olması gerekmiyor , her şey iyi olacak):

Dize ise 112112, bu araçlar böyle bir 1, iki 1'leri ve bir 2 yazdırmak zorunda: 1112. İşlemi tekrar yapacağınız zaman 1 ve 2 yazdırmanız gerekir 12. Sonra bir tane yazdırın, elde edin 2. Bu son biçimdir, çünkü bu dize artık değişmeyecektir. 3Nihai forma ulaşmak için 3 adıma ihtiyacınız olduğu için kodunuz çıkacaktır .

Diğer Kurallar

  • Dizenin uzunluğu eşit değilse, son sayıya dokunulmaz.

  • Artık değiştirilemeyen (gibi 222222) her dize son biçim olarak kabul edilir.

  • Herhangi bir harici kaynak kullanamazsınız.

  • Kodunuz 1ve öğelerinin her dizesiyle çalışmalıdır 2.

  • Kod golfü olduğu için en kısa kod kazanır.

  • Kodunuz her adımda yazdırılmalıdır.

  • Her giriş yöntemi iyi olacaktır.

Örnekler

Input >> 122122122121212212

Your code has to print:
211222111111222
11222111222
122111222
2111222
111222
1222
222
Steps:7 (you can omit the "Steps")
---- ---- ---- ----
Input >> 22222221

Your code has to print:
22222211
2222221
2
---- ---- ---- ----
Input >> 2222

Your code has to print:
0

EDIT: Ağır düzenlenmiş. Bunun için çok üzgünüm.


3
"Dizeniz 112112 ise, bu 1, iki 1s ve 2 yazdırmanız gerektiği anlamına gelir: 1112." Anlamıyorum. "
Fabinout

7
Yüksek sesle okumaya çalışın. "Bir", "iki" ve "bir iki". "1 kez 1", "2 kez 1" ve "1 kez 2" demek istedim.
Vereos

5
Normal ifadeler "yararlı bile değilse", neden yasaklıyorsunuz?
JB

1
Normal ifade kısıtlaması kaldırıldı.
Vereos

1
@ProgramFOX "bir 1, iki 1 ve 2": 1 11 2. Her iki sayı bir çifttir: çiftin ilk numarası, çiftteki ikinci sayının kaç kez oluşturulacağını söyler. Bir çift ortağı olmayan herhangi bir son tek basamak olduğu gibi işlenir.
apsillers

Yanıtlar:


7

Ruby 1.9+, 73 karakter

Normal ifade kuralını aptalca ve keyfi olarak görüyorum, işte burada normal bir regex tabanlı çözüm:

gets
($.+=1;puts$_.gsub!(/(.)(.)/){$2*$1.to_i})until~/^(22)*[12]?$/
p~-$.

Test sürüşü:

$ ruby 21.rb <<< 122122122121212212
211222111111222
11222111222
122111222
2111222
111222
1222
222
7

Son satır adım sayısıdır.

Düzenleme: Normal ifade kısıtlaması Vereos tarafından kaldırıldı.


3

C - 156 154

Burada ilk kod golf!

f(char*s,c){puts(s);char*a=s,*b=s,m=50,x,y;while(*a){
x=*a++;y=*a++;if(y)m&=x&y;*b++=y?:x;x-49?*b++=y:(*b=0);}
*b=*a;return m/50?printf("%i",c),c:f(s,c+1);}

Ölçek:

char c[] = "12211122211222221";
f(c,0);

Çıktı:

12211122211222221
21112211222221
111221222211
121122221
21222211
1122221
122221
22211
22111
2211
221
10

2

GolfScript: 69 karakter

0\{\)\.p.[]\{~10base{.,1>{(\(@\{''+*}++~@\+\.}{~+0.}if}do;}~.@=!}do;(

İç döngünün her yinelemesi dizedeki ilk 2 sayıyı bulur ve bunları formun bir bloğunu oluşturmak için kullanır {num1 num2 '' + *}. Bu blok değerlendirildiğinde, bu sayıların istenen okumasını alırız. Başka karakter kalmayıncaya kadar bunu tekrarlayın. Ardından, yineleme sayısını ve yazdırmayı takip ederken bu döngüyü tekrarlayın.

Örneklem:

echo '12211122211222221' | ruby golfscript.rb g.gs
"12211122211222221"
"21112211222221"
"111221222211"
"121122221"
"2122221"
"1122221"
"122221"
"22211"
"22111"
"2211"
"221"
10

2

Python - 126

def f(s):
 j=0
 while 1:
    n="";i=0
    for c in s:n+=c*i;i=[int(c),0][i>0]
    if i:n+=`i`
    if s==n:break
    s=n;print s;j+=1
 print j

Bu, giriş değerini yazdırmaz. Gerekirse, daha print s;önce sağa geçinn="";

Not: "fonksiyon" dediniz, yani bu bir fonksiyon. İşlev olmayan bir sürüm (127 karakter):

s=raw_input();j=0
while 1:
    n="";i=0
    for c in s:n+=c*i;i=[int(c),0][i>0]
    if i:n+=`i`
    if s==n:break
    s=n;print s;j+=1
print j

(Eğer kullanıcı daha sonra 118 (ilk satırda tırnak arasına veri yapıştır) numarasını yapıştırmak olabilir ):

s="";j=0
while 1:
    n="";i=0
    for c in s:n+=c*i;i=[int(c),0][i>0]
    if i:n+=`i`
    if s==n:break
    s=n;print s;j+=1
print j

Örnek çalışma:

211222111111222
11222111222
122111222
2111222
111222
1222
222
7

Bonus olarak, bu çözümlerin her biri daha büyük sayılar (9'a kadar) içeren dizeler için çalışır, ancak bazı dizeler daha büyük ve daha büyük çıktılar üretir (örneğin, 99)


1

JavaScript, 107

(örneğin Firefox'ta olduğu gibi ok işlevi desteği gerekir)

for(p=prompt,s=p(),k=0;r=s.match(/.?.?/g).map(a=>a>2?a[1]+(a<13?'':a[1]):a).join(''),p(s),r!=s;s=r)k++;p(k)
  • s giriş dizesi

  • Her turda, regex'i iki karakterli dizelerden oluşan bir diziye .?.?patlamak için kullanırız s, ardından mapbu dizeleri azaltılmış formlarına dönüştürür ve diziyi tekrar birleştiririz

  • r önceki turla karşılaştırmak için geçerli turun sonucunu saklar s

  • k yuvarlak sayaç

  • Kullanıcıya bir mesaj sunabileceğinden, hem giriş hem de çıkış mekanizması olarak korkunç bir şekilde kötüye kullanıyoruz prompt(diğer adıyla p)


for(p=prompt,s=p(),k=0;
    r=s.match(/.?.?/g).map(
        a=>
            a>2?                     // if a is more than one char
                a[1]+(a<13?'':a[1])  // double the second char if the first char is 2
               :a                    // if not two chars, return a
    ).join(''),                      // glue new array together
     p(s),                           // print s
     r!=s;                           // test if string has changed
    s=r)
        k++;
p(k)

1

Perl - 50 (+2) bayt

$a-=print while"$_"ne(s/(.)(.)/$2x$1/ge,$_);$_=-$a

-plKomut satırı anahtarları gerektirir .

Örnek kullanım:

$ more in.dat
122122122121212212

$ perl -pl rev-count.pl < in.dat
211222111111222
11222111222
122111222
2111222
111222
1222
222
7

$ more in.dat
22222221

$ perl -pl rev-count.pl < in.dat
22222211
2222221
2

$ more in.dat
2222

$ perl -pl rev-count.pl < in.dat
0

1

PHP, 240

<?php
$s=$_GET['i'];$h=$s;for($t=1;$h!=r($h);$t++){echo$h.'<br>';$h=r($h);}echo r($s)==$s?0:$h.'<br>'.$t;function r($c){for($i=0;$i<strlen($c)-1;$i+=2){$s.=$c[$i]==1?$c[$i+1]:$c[$i+1].$c[$i+1];if($i+3==strlen($c))$s.=$c[$i+2];}return$s;}?>

Örnek: http://skyleo.de/codegolf.php?i=211222111111222

211222111111222
11222111222
122111222
2111222
111222
1222
222
7

Codegolf ._ 'da biraz kötüyüm. Belki sadece Java ve PHP kullanmamalıyım (ve daha karmaşık düşünmeliyim)


1
CodeGolf en karmaşık çözümü bulmak değil, en basit çözümü bulmakla ilgilidir.
primo

str_splitPHP'de bir dizide olduğu gibi bir dizede tek tek karakterlere erişebildiğiniz için gerçekten yapmanız gerekmez .
Gareth

Evet, bir süre sonra kendimi düşündüm, ama düzenlemek için çok tembeltim. Ama şimdi değiştirdim.
Leo Pflug

0

R, 158

s=utf8ToInt(scan(,""))-48;i=0;while(any(!!s-2)){t=(a<-sum(s|T))%%2;u=s[seq(a-t)];cat(s<-c(rep(u[c(F,T)],u[c(T,F)]),s[a*t]),"\n",sep="");i=i+1};cat("Steps:",i)

Misal:

122122122121212212

211222111111222
11222111222
122111222
2111222
111222
1222
222
Steps: 7

0

MATEMATİKA, 117

s="122122122121212212";
Grid@FixedPointList[(Partition[#,2,2,1,{}]/.{{1,1}->{1},{1,2}->{2},{2,1}->{1,1}}//Flatten)&,FromDigits/@Characters@s]

122122122121212212
211222111111222
11222111222
122111222
2111222
111222
1222
222
222

0

POWERSHELL, 2

OP'nin yorumlarında Vereos'un "Kodunuzu kısaltan herhangi bir giriş yöntemini kullanabilirsiniz" yanıtı soruma dayanarak, aşağıdaki komut dosyası sonucu elde eder:

$a

"122122122121212212" için örnek çalışma:

# Input method is to assign answer to $a:
$a = @"
211222111111222
11222111222
122111222
2111222
111222
1222
222
Steps: 7
"@

# Execute script
$a

# Answer follows:
211222111111222
11222111222
122111222
2111222
111222
1222
222

Açıkçası bu ciddi bir giriş değil - amacı, herhangi bir giriş yöntemine izin vermek cevabı vermek için gereken gerçek kodu önemsizleştirebileceğimi göstermektir. Bu nedenle, giriş yönteminin daha titiz bir şekilde belirlenmesi gerekir.


0

J, 41 karakter

Bir işlev olarak (ew parens! Onlar için çok mutlu değil):

(,":@#)@}:@(([:;_2&(<@((".@[#])/)\))^:a:)
Parçalarına ayrıştırılmış görünüm
                _2&(            )\          NB. on non-overlapping 2-grams:
                       (      )/            NB.   insert between the two chars:
                        ".@[                NB.     read left operand ([) as a number
                            #]              NB.     and repeat right this many times,
                    <@(           )         NB.   then put it in a box
            ([:;                   )        NB. open and concatenate the boxes
           (                        ^:a:)   NB. repeat until fixpoint (keeping intermediates)
        }:@                                 NB. drop first element (the input)
(,":@#)@                                    NB. append length of array (# steps)
Örnek çalışma
   (,":@#)@}:@(([:;_2&(<@((".@[#])/)\))^:a:) '1121121'
1121121
11121  
121    
21     
11     
5      
   (,":@#)@}:@(([:;_2&(<@((".@[#])/)\))^:a:) '122122122121212212'
122122122121212212
211222111111222   
11222111222       
122111222         
2111222           
111222            
1222              
7                 

0

Perl, 107 karakter

Diğer perl kodu bunu açıkça aşıyor, ancak değdiğine göre, işte burada. Ekstra bir karakter pahasına -l anahtarını kullandım:

$_=<>;while(1){$l=$_;$_=join"",map{($a,$b)=split//;$b?$b x$a:$a}grep/./,split/(..?)/;last if$l eq$_;print}

Bunun daha okunaklı bir versiyonu:

$x = <>; while(1) { $l = $x; $x = join "", map{ ($a,$b) = split//, $_; $b ? $b x $a: $a } grep /./, split /(..?)/, $x; last if $l eq $x; print $x}
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.