ลดขนาดสตริงตัวเลข


12

เมื่อกำหนดสตริง1และ2ความยาวใด ๆ ให้เขียนโค้ดบางส่วน (ไม่จำเป็นต้องมีฟังก์ชั่นอีกต่อไปทุกอย่างจะใช้ได้) ที่คำนวณว่าจำเป็นต้องใช้หลายขั้นตอนในการย่อขนาดสตริงเป็นแบบฟอร์มสุดท้ายโดยทำตามเกณฑ์นี้:

ถ้าสายของคุณเป็น112112วิธีที่คุณจะต้องพิมพ์ 1 สอง 1s และ 2 1112เช่นนี้ เมื่อคุณจะดำเนินการอีกครั้งคุณจะต้องพิมพ์ 1 และ 2. 12คุณจะได้รับ จากนั้นคุณพิมพ์หนึ่ง 2 ได้2มา นี่เป็นรูปแบบสุดท้ายเนื่องจากสตริงนี้จะไม่เปลี่ยนแปลงอีกต่อไป รหัสของคุณจะถูกส่งออก3เนื่องจากคุณต้องการ 3 ขั้นตอนเพื่อไปยังแบบฟอร์มสุดท้าย

กฎอื่น ๆ

  • หากสตริงมีความยาวไม่สม่ำเสมอตัวเลขสุดท้ายจะไม่ถูกแตะต้อง

  • สตริงทุกตัวที่ไม่สามารถเปลี่ยนแปลงได้อีกต่อไป (เช่น222222) จะถือว่าเป็นรูปแบบสุดท้าย

  • คุณไม่สามารถใช้แหล่งภายนอก

  • รหัสของคุณต้องทำงานกับสตริงของทุกและ12

  • รหัสที่สั้นที่สุดชนะเพราะมันเป็นรหัสกอล์ฟ

  • รหัสของคุณควรพิมพ์ทุกขั้นตอน

  • ทุกวิธีการป้อนข้อมูลจะถูกปรับ

ตัวอย่าง

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

แก้ไข: แก้ไขอย่างหนัก ขอโทษที่เกี่ยวกับเรื่องนั้น


3
"ถ้าสตริงของคุณคือ 112112 นั่นหมายความว่าคุณต้องพิมพ์ 1, 2 1 และ 2 เช่นนี้: 1112" ฉันไม่เข้าใจ
Fabinout

7
ลองอ่านเสียงดัง มันคือ "หนึ่งหนึ่ง", "สองคน" และ "หนึ่งสอง" ฉันหมายถึง "1 ครั้ง 1", "2 ครั้ง 1" และ "1 ครั้ง 2"
Vereos

5
หาก regexes เป็น "ไม่มีประโยชน์" ทำไมคุณถึงห้ามแบน
JB

1
นำการ จำกัด Regex ออกแล้ว
Vereos

1
@ProgramFOX "หนึ่ง 1 สอง 1s และ 1 11 22": หมายเลขสองคู่ทุกคู่เป็นคู่: หมายเลขแรกของคู่บอกว่ากี่ครั้งที่จะแสดงหมายเลขที่สองในคู่ เลขคี่สุดท้ายสุดท้ายที่ไม่มีคู่พันธมิตรจะแสดงผลตามสภาพ
apsillers

คำตอบ:


7

Ruby 1.9+, 73 ตัวอักษร

ฉันเห็นว่ากฎ no-regex นั้นโง่และไม่มีข้อ จำกัด ดังนั้นนี่คือโซลูชันที่ใช้ 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

C - 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

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

นี่ไม่ได้พิมพ์ค่าอินพุต ถ้าจำเป็นให้ย้ายprint s;ไปทางขวาก่อนn="";

หมายเหตุ: คุณพูดว่า "function" ดังนั้นนี่คือฟังก์ชั่น นี่คือรุ่นที่ไม่ใช่ฟังก์ชั่น (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 คือสตริงอินพุต

  • ในแต่ละรอบเราใช้ regex .?.?เพื่อกระจาย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 ไม่ได้เกี่ยวกับการหาทางออกที่ซับซ้อนที่สุด แต่เป็นวิธีที่ง่ายที่สุด
primo

คุณไม่จำเป็นต้องทำstr_splitเพราะคุณสามารถเข้าถึงอักขระแต่ละตัวในสตริงเช่นเดียวกับอาร์เรย์ใน PHP
Gareth

ใช่บางครั้งฉันก็คิดว่าตัวเอง แต่ฉันขี้เกียจเกินกว่าจะแก้ไขได้ แต่ตอนนี้ฉันเปลี่ยนมัน
Leo Pflug


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

จากการตอบกลับของ Vereos "คุณสามารถใช้วิธีการป้อนข้อมูลใดก็ได้ทำให้รหัสของคุณสั้นลง" สำหรับคำถามของฉันในความคิดเห็นของ OP สคริปต์ที่ตามมาจะได้ผลลัพธ์ดังนี้:

$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 ตัวอักษร

รหัสเพิร์ลอื่น ๆ เต้นอย่างชัดเจน แต่สำหรับสิ่งที่คุ้มค่านี่คือ ฉันใช้สวิตช์ -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}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.