Сократить числовую строку

12

Учитывая строку 1и 2любой длины, написать код (не должен быть функцией больше, все будет просто отлично) , который вычисляет , сколько шагов это нужно сжать строку в окончательной форме, следуя этому критерию:

Если строка 112112, это означает , что вы должны напечатать A 1, два 1s и 2, как это: 1112. Когда вы снова выполните операцию, вам придется распечатать 1 и 2. Вы получите 12. Затем вы печатаете один 2, получив 2. Это окончательная форма, так как эта строка больше не будет меняться. Ваш код будет выведен 3, так как вам нужно 3 шага, чтобы добраться до окончательной формы.

Другие правила

  • Если строка имеет неравномерную длину, последний номер остается нетронутым.

  • Каждая строка, которая больше не может изменяться (например 222222), считается окончательной формой.

  • Вы не можете использовать любой внешний источник.

  • Ваш код должен работать с каждой строкой 1и 2.

  • Самый короткий код выигрывает, так как это код-гольф.

  • Ваш код должен печатать каждый шаг.

  • Каждый метод ввода будет в порядке.

Примеры

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

РЕДАКТИРОВАТЬ: Сильно отредактировано. Извините за это.

Vereos
источник
3
«Если ваша строка 112112, это означает, что вы должны напечатать 1, две 1 и 2, например: 1112.« Я не понимаю.
Fabinout
7
Попробуйте прочитать это громко. Это «один один», «два один» и «один два». Я имею в виду «1 раз 1», «2 раза 1» и «1 раз 2».
Vereos
5
Если регулярные выражения "даже не полезны", почему вы их запрещаете?
JB
1
Ограничение регулярных выражений снято.
Vereos
1
@ProgramFOX "один 1, два 1s, и 2": 1 11 2. Каждые два числа являются парой: первое число в паре говорит, сколько раз визуализировать второе число в паре. Любая последняя нечетная цифра без парного партнера отображается как есть.
Апсиллеры

Ответы:

7

Ruby 1.9+, 73 символа

Я считаю правило без регулярных выражений глупым и произвольным, так что вот злобное решение на основе регулярных выражений:

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

Тестовый забег:

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

Последняя строка - это количество шагов.

Редактировать: ограничение регулярных выражений было снято Vereos.

daniero
источник
3

С - 156 154

Мой первый код гольф здесь!

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

Тестовое задание:

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

Выход:

12211122211222221
21112211222221
111221222211
121122221
21222211
1122221
122221
22211
22111
2211
221
10
ТИА
источник
2

GolfScript: 69 символов

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

Каждая итерация внутреннего цикла находит первые 2 числа в строке и использует их для формирования блока формы {num1 num2 '' + *}. Когда этот блок оценивается, мы получаем желаемое чтение этих чисел. Повторяйте это, пока не останется больше персонажей. Затем повторите этот цикл, отслеживая количество итераций и печатая.

Образец:

echo '12211122211222221' | ruby golfscript.rb g.gs
"12211122211222221"
"21112211222221"
"111221222211"
"121122221"
"2122221"
"1122221"
"122221"
"22211"
"22111"
"2211"
"221"
10
Бен Райх
источник
2

Питон - 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

Это не печатает входное значение. Если нужно, то двигайтесь print s;вправо, прежде чемn="";

Примечание: вы сказали «функция», так что это функция. Вот версия, которая не является функцией (127 символов):

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

(Если я могу сделать так, чтобы пользователь вставил число в число 118 (вставьте данные между кавычками в первой строке)):

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

Образец прогона:

211222111111222
11222111222
122111222
2111222
111222
1222
222
7

В качестве бонуса каждое из этих решений работает для строк, содержащих большие числа (до 9), но некоторые строки выдают все большие и большие выходные данные (например, 99)

Джастин
источник
1

JavaScript, 107

(требуется поддержка функции стрелки, например, как в 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 это строка ввода

  • В каждом раунде мы используем регулярное выражение, .?.?чтобы взорваться sв массив двухсимвольных строк, затем mapэти строки в их уменьшенные формы и склеить массив обратно

  • r сохраняет результат текущего раунда для сравнения с предыдущим s

  • k это круглая стойка

  • Мы ужасно злоупотребляем prompt(псевдонимом 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)
apsillers
источник
1

Perl - 50 (+2) байтов

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

Требуются -plключи командной строки.

Пример использования:

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

Пример: http://skyleo.de/codegolf.php?i=211222111111222

211222111111222
11222111222
122111222
2111222
111222
1222
222
7

Я немного плох в Codegolf. Может быть, я не должен использовать только Java и PHP (и я должен думать более сложным)

Лео Пфлуг
источник
1
CodeGolf - это не самое сложное решение, а самое простое.
Прим
На самом деле вам это не нужно, str_splitпоскольку вы можете обращаться к отдельным символам в строке, как к массиву в PHP.
Гарет
Да, через некоторое время я сам так подумал, но мне было лень это редактировать. Но теперь я изменил это.
Лео Пфлуг,
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)

Пример:

122122122121212212

211222111111222
11222111222
122111222
2111222
111222
1222
222
Steps: 7
Свен Хоэнштейн
источник
0

МАТЕМАТИКА, 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

Основываясь на ответе Вереоса «Вы можете использовать любой метод ввода, сокращающий ваш код» на мой вопрос в комментариях ОП, следующий сценарий достигает результата:

$a

Пример выполнения для "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

Очевидно, что это не серьезная запись - ее цель состоит в том, чтобы проиллюстрировать мою мысль о том, что разрешение любого метода ввода может тривиализировать фактический код, необходимый для получения ответа. Следовательно, метод ввода должен быть более точным.

user2460798
источник
0

J, 41 символ

Как функция (ew parens! Не очень довольна ими):

(,":@#)@}:@(([:;_2&(<@((".@[#])/)\))^:a:)
В разобранном виде
                _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)
Пробный прогон
   (,":@#)@}:@(([:;_2&(<@((".@[#])/)\))^:a:) '1121121'
1121121
11121  
121    
21     
11     
5      
   (,":@#)@}:@(([:;_2&(<@((".@[#])/)\))^:a:) '122122122121212212'
122122122121212212
211222111111222   
11222111222       
122111222         
2111222           
111222            
1222              
7                 
Светляк
источник
0

Perl, 107 символов

Другой Perl-код явно превосходит это, но за это он стоит. Я использовал ключ -l за счет дополнительного символа:

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

Более разборчивая версия этого:

$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
источник