Стиснути рядковий номер


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

EDIT: Сильно відредагований. Тож шкода про це.


3
"Якщо ваш рядок становить 112112, це означає, що ви повинні надрукувати 1, два 1s і 2, як це: 1112." Я не розумію.
Fabinout

7
Спробуйте прочитати його голосно. Це "один", "два" і "один два". Я маю на увазі "1 раз 1", "2 рази 1" і "1 раз 2".
Вереос

5
Якщо регулярні вирази "навіть не корисні", чому ви забороняєте їх?
JB

1
Обмеження Regex знято.
Вереос

1
@ProgramFOX "один 1, два 1s, і 2": 1 11 2. Кожні два числа - це пара: перше число пари говорить про те, скільки разів виводити друге число в парі. Будь-яка остаточна непарна цифра без парного партнера надається такою, якою є.
апспіллери

Відповіді:


7

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

Я вважаю, що правило no-regex є дурним і довільним, тому ось злобне рішення на основі регулярних виразів:

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

Пробіг:

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

Останній рядок - кількість кроків.

Редагувати: обмеження Regex видалено компанією Vereos.


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)

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

МОЖЛИВОСТІ, 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

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


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}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.