Kecilkan string nomor

12

Mengingat string 1dan 2dari setiap panjang, menulis beberapa kode (tidak harus menjadi fungsi lagi, semuanya akan baik-baik saja) yang menghitung berapa banyak langkah apakah itu perlu untuk mengecilkan string ke bentuk akhir, berikut kriteria ini:

Jika string Anda adalah 112112, ini berarti bahwa Anda harus mencetak 1, dua 1s dan 2, seperti ini: 1112. Ketika Anda akan melakukan operasi lagi Anda harus mencetak 1 dan 2. Anda dapatkan 12. Kemudian Anda mencetak satu 2, dapatkan 2. Ini adalah bentuk final, karena string ini tidak akan berubah lagi. Kode Anda akan ditampilkan 3, karena Anda memerlukan 3 langkah untuk sampai ke bentuk akhir.

Peraturan Lainnya

  • Jika string memiliki panjang yang tidak rata, angka terakhir tetap tidak tersentuh.

  • Setiap string yang tidak dapat diubah lagi (seperti 222222) dianggap sebagai bentuk akhir.

  • Anda tidak dapat menggunakan sumber eksternal apa pun.

  • Kode Anda harus bekerja dengan setiap string dari 1dan 2.

  • Kode terpendek menang, karena kode-golf.

  • Kode Anda harus mencetak setiap langkah.

  • Setiap metode input akan baik-baik saja.

Contohnya

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: Sangat diedit. Maaf soal itu.

Vereos
sumber
3
"Jika string Anda adalah 112112, ini berarti Anda harus mencetak 1, dua 1, dan 2, seperti ini: 1112." Saya tidak mengerti.
Fabinout
7
Cobalah untuk membacanya dengan keras. Ini "satu satu", "dua yang" dan "satu dua". Maksud saya, "1 kali 1", "2 kali 1" dan "1 kali 2".
Vereos
5
Jika regex "bahkan tidak berguna", mengapa Anda melarangnya?
JB
1
Pembatasan regex dihapus.
Vereos
1
@ProgramFOX "satu 1, dua 1s, dan 2": 1 11 2. Setiap dua angka adalah pasangan: angka pertama dari pasangan mengatakan berapa kali untuk membuat angka kedua dalam pasangan. Digit ganjil akhir tanpa pasangan pasangan diberikan apa adanya.
apsillers

Jawaban:

7

Ruby 1.9+, 73 karakter

Saya melihat aturan no-regex sebagai konyol dan sewenang-wenang, jadi inilah solusi berbasis regex dengki :

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

Uji coba:

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

Baris terakhir adalah jumlah langkah.

Sunting: Pembatasan regex telah dihapus oleh Vereos.

daniero
sumber
3

C - 156 154

Golf kode pertamaku di sini!

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);}

Uji:

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

Keluaran:

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

GolfScript: 69 karakter

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

Setiap iterasi dari loop dalam menemukan 2 angka pertama dalam string, dan menggunakannya untuk membentuk blok formulir {num1 num2 '' + *}. Ketika blok ini dievaluasi, kita mendapatkan bacaan yang diinginkan dari angka-angka itu. Ulangi ini sampai tidak ada karakter lagi. Kemudian, ulangi loop itu sambil melacak jumlah iterasi dan pencetakan.

Sampel:

echo '12211122211222221' | ruby golfscript.rb g.gs
"12211122211222221"
"21112211222221"
"111221222211"
"121122221"
"2122221"
"1122221"
"122221"
"22211"
"22111"
"2211"
"221"
10
Ben Reich
sumber
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

Ini tidak mencetak nilai input. Jika perlu, maka pindah print s;ke kanan sebelumnyan="";

Catatan: Anda mengatakan "fungsi", jadi ini adalah fungsi. Ini adalah versi yang bukan fungsi (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

(Jika saya dapat meminta pengguna menempelkan angka di kemudian 118 (tempel data di antara tanda kutip di baris pertama)):

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

Contoh dijalankan:

211222111111222
11222111222
122111222
2111222
111222
1222
222
7

Sebagai bonus, masing-masing solusi ini berfungsi untuk string yang berisi angka lebih besar (hingga 9), tetapi beberapa string menghasilkan output yang lebih besar dan lebih besar (misalnya, 99)

Justin
sumber
1

JavaScript, 107

(memerlukan dukungan fungsi panah, misalnya di Firefox)

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 adalah string input

  • Setiap putaran, kami menggunakan regex .?.?untuk meledak smenjadi array string dua karakter, kemudian mapstring tersebut ke bentuk tereduksi dan merekatkan array kembali bersama-sama

  • r menyimpan hasil putaran saat ini untuk perbandingan dengan yang sebelumnya s

  • k adalah konter bulat

  • Kami sangat menyalahgunakan prompt(alias p) sebagai mekanisme input dan output, karena dapat menyajikan pesan kepada pengguna


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)
apsillers
sumber
1

Perl - 50 (+2) byte

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

Membutuhkan -plsakelar baris perintah.

Penggunaan sampel:

$ 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
primo
sumber
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;}?>

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

211222111111222
11222111222
122111222
2111222
111222
1222
222
7

Saya agak buruk di codegolf ._. Mungkin saya seharusnya tidak hanya menggunakan Java dan PHP (dan saya harus berpikir lebih rumit)

Leo Pflug
sumber
1
CodeGolf bukan tentang menemukan solusi yang paling rumit, tetapi yang paling sederhana.
Primo
Anda tidak perlu melakukannya str_splitkarena Anda dapat mengakses karakter individu dalam sebuah string seperti halnya array di PHP.
Gareth
Ya, setelah beberapa waktu saya berpikir sendiri, tetapi saya terlalu malas untuk mengeditnya. Tapi sekarang saya mengubahnya.
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)

Contoh:

122122122121212212

211222111111222
11222111222
122111222
2111222
111222
1222
222
Steps: 7
Sven Hohenstein
sumber
0

MATHEMATICA, 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
Murta
sumber
0

POWERSHELL, 2

Berdasarkan tanggapan Vereos, "Anda dapat menggunakan metode input apa pun yang lebih pendek kode Anda" untuk pertanyaan saya di komentar OP, skrip berikut mencapai hasil:

$a

Contoh jalankan untuk "122122122121212212":

# 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

Jelas ini bukan entri serius - tujuannya adalah untuk mengilustrasikan poin saya bahwa mengizinkan metode input apa pun dapat meremehkan kode aktual yang diperlukan untuk menghasilkan jawaban. Oleh karena itu metode input perlu ditentukan dengan lebih teliti.

pengguna2460798
sumber
0

J, 41 karakter

Sebagai fungsi (ew paren! Tidak terlalu senang tentang mereka):

(,":@#)@}:@(([:;_2&(<@((".@[#])/)\))^:a:)
Tampilan meledak
                _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)
Contoh dijalankan
   (,":@#)@}:@(([:;_2&(<@((".@[#])/)\))^:a:) '1121121'
1121121
11121  
121    
21     
11     
5      
   (,":@#)@}:@(([:;_2&(<@((".@[#])/)\))^:a:) '122122122121212212'
122122122121212212
211222111111222   
11222111222       
122111222         
2111222           
111222            
1222              
7                 
FireFly
sumber
0

Perl, 107 karakter

Kode perl lainnya jelas mengalahkan ini, tetapi untuk apa nilainya, ini dia. Saya menggunakan -l switch dengan mengorbankan karakter tambahan:

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

Versi yang lebih mudah dibaca:

$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}
skibrianski
sumber