Verkleinere eine Zahlenfolge

12

Bei einer Reihe von 1und 2in beliebiger Länge, schreiben einige Code (nicht zu sein braucht Funktion mehr, alles wird in Ordnung sein) , dass berechnet , wie viele Schritte braucht es den String in eine endgültige Form zu schrumpfen, nach diesem Kriterium:

Wenn Ihr String ist 112112, bedeutet dies , dass Sie ein 1 zwei 1s drucken müssen und 2, wie folgt aus : 1112. Wenn Sie den Vorgang erneut ausführen, müssen Sie eine 1 und eine 2 drucken 12. Dann drucken Sie eine 2 und erhalten 2. Dies ist eine endgültige Form, da sich diese Zeichenfolge nicht mehr ändern wird. Ihr Code wird ausgegeben 3, da Sie 3 Schritte benötigt haben, um zum endgültigen Formular zu gelangen.

Andere Regeln

  • Wenn die Saite ungerade lang ist, bleibt die letzte Zahl unangetastet.

  • Jede Zeichenfolge, die sich nicht mehr ändern kann (wie 222222), wird als endgültige Form betrachtet.

  • Sie können keine externe Quelle verwenden.

  • Ihr Code muss mit jeder Zeichenfolge von 1und funktionieren 2.

  • Der kürzeste Code gewinnt, da es sich um Code-Golf handelt.

  • Ihr Code sollte jeden Schritt drucken.

  • Jede Eingabemethode wird in Ordnung sein.

Beispiele

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: Stark bearbeitet. Es tut mir Leid.

Vereos
quelle
3
"Wenn Ihre Zeichenfolge 112112 ist, bedeutet dies, dass Sie eine 1, zwei Einsen und eine 2 wie folgt drucken müssen: 1112." Ich verstehe es nicht.
Fabinout
7
Versuchen Sie es laut zu lesen. Es ist "eins eins", "zwei eins" und "eins zwei". Ich meine "1 mal 1", "2 mal 1" und "1 mal 2".
Vereos
5
Wenn reguläre Ausdrücke "nicht einmal nützlich" sind, warum verbieten Sie sie?
JB
1
Regex-Einschränkung entfernt.
Vereos
1
@ProgramFOX "one 1 zwei 1s, und ein 2": 1 11 2. Alle zwei Zahlen sind ein Paar: Die erste Zahl des Paares gibt an, wie oft die zweite Zahl im Paar gerendert werden soll. Jede letzte ungerade Ziffer ohne Partnerpaar wird unverändert wiedergegeben.
Apsillers

Antworten:

6

Ruby 1.9+, 73 Zeichen

Ich sehe das nicht-regex Regel als dumm und willkürlich, so ist hier eine gehässige regex - basierte Lösung:

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

Testlauf:

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

Die letzte Zeile gibt die Anzahl der Schritte an.

Bearbeiten: Die Regex-Einschränkung wurde von Vereos entfernt.

daniero
quelle
3

C - 156 154

Mein erster Code Golf hier!

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

Prüfung:

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

Ausgabe:

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

GolfScript: 69 Zeichen

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

Bei jeder Iteration der inneren Schleife werden die ersten beiden Zahlen in der Zeichenfolge gefunden und zum Bilden eines Formularblocks verwendet {num1 num2 '' + *} . Wenn dieser Block ausgewertet wird, erhalten wir das gewünschte Lesen dieser Zahlen. Wiederholen Sie diesen Vorgang, bis keine Zeichen mehr vorhanden sind. Wiederholen Sie diese Schleife, während Sie die Anzahl der Iterationen und des Druckvorgangs verfolgen.

Stichprobe:

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

Der Eingabewert wird nicht gedruckt. Wenn es sein muss, dann gehe print s;vorher nach rechtsn="";

Hinweis: Sie haben "Funktion" gesagt, dies ist also eine Funktion. Hier ist eine Version, die keine Funktion ist (127 Zeichen):

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

(Wenn der Benutzer die Nummer in dann 118 einfügen kann (Daten zwischen Anführungszeichen in der ersten Zeile einfügen)):

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

Probelauf:

211222111111222
11222111222
122111222
2111222
111222
1222
222
7

Als Bonus kann jede dieser Lösungen für Zeichenfolgen verwendet werden, die größere Zahlen (bis zu 9) enthalten. Einige Zeichenfolgen erzeugen jedoch immer größere Ausgaben (z. B. 99).

Justin
quelle
1

JavaScript, 107

(erfordert Pfeilfunktionsunterstützung, zB wie in 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 ist die Eingabezeichenfolge

  • In jeder Runde wird der reguläre Ausdruck verwendet .?.?, um sein Array aus Zeichenfolgen mit zwei Zeichen zu erstellen. Anschließend werden mapdiese Zeichenfolgen in ihre reduzierten Formen gebracht und das Array wieder zusammengeklebt

  • r Speichert das Ergebnis der aktuellen Runde zum Vergleich mit der vorherigen Runde s

  • k ist der runde Zähler

  • Wir missbrauchen prompt(mit Alias p) schrecklich als Eingabe- und Ausgabemechanismus, da er dem Benutzer eine Nachricht präsentieren kann


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
quelle
1

Perl - 50 (+2) Bytes

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

Erfordert -plBefehlszeilenoptionen.

Beispielnutzung:

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

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

211222111111222
11222111222
122111222
2111222
111222
1222
222
7

Ich bin ein bisschen schlecht im Codegolf. Vielleicht sollte ich nicht nur Java und PHP verwenden (und ich sollte komplizierter denken)

Leo Pflug
quelle
1
Bei CodeGolf geht es nicht darum, die komplizierteste, sondern die einfachste Lösung zu finden.
Primo
Sie brauchen das nicht wirklich zu tun, str_splitda Sie auf einzelne Zeichen in einem String zugreifen können, genau wie auf ein Array in PHP.
Gareth
Ja, nach einiger Zeit habe ich das selbst gedacht, aber ich war zu faul, um es zu bearbeiten. Aber jetzt habe ich es geändert.
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)

Beispiel:

122122122121212212

211222111111222
11222111222
122111222
2111222
111222
1222
222
Steps: 7
Sven Hohenstein
quelle
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
quelle
0

POWERSHELL, 2

Basierend auf Vereos 'Antwort "Sie können jede Eingabemethode verwenden, die Ihren Code verkürzt" auf meine Frage in den Kommentaren des OP, erzielt das folgende Skript das Ergebnis:

$a

Beispiellauf für "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

Offensichtlich ist dies kein ernstzunehmender Eintrag - er soll meinen Standpunkt verdeutlichen, dass das Zulassen einer Eingabemethode den tatsächlichen Code, der zur Erzielung der Antwort benötigt wird, trivialisieren kann. Daher muss die Eingabemethode genauer spezifiziert werden.

user2460798
quelle
0

J, 41 Zeichen

Als eine Funktion (ew parens! Nicht schrecklich glücklich über sie):

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

Perl, 107 Zeichen

Der andere Perl-Code schlägt dies eindeutig, aber für das, was es wert ist, ist es hier. Ich habe den Schalter -l auf Kosten eines zusätzlichen Zeichens verwendet:

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

Eine besser lesbare Version davon:

$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
quelle