ลองทำ“ enciph5r47g” กันบ้าง


35

นี่คือสิ่งที่ตรงกันข้ามของLet's do "deciph4r4ng"


ในความท้าทายนี้งานของคุณคือการเข้ารหัสสตริง โชคดีที่อัลกอริทึมนั้นค่อนข้างง่าย: การอ่านจากซ้ายไปขวาอักขระการเขียนทั่วไปแต่ละตัว (ASCII ช่วง 32-126) จะต้องถูกแทนที่ด้วยตัวเลขN (0-9) เพื่อระบุว่ามันเหมือนกับตัวอักษรN + 1ตำแหน่งก่อนหน้า ข้อยกเว้นคือเมื่อตัวละครไม่ปรากฏภายใน 10 ตำแหน่งก่อนหน้าในสตริงเดิม ในกรณีนี้คุณควรพิมพ์อักขระอีกครั้ง อย่างมีประสิทธิภาพคุณควรจะสามารถย้อนกลับการดำเนินการจากความท้าทายเดิม

ตัวอย่าง

สตริงอินพุต"Programming"จะถูกเข้ารหัสด้วยวิธีนี้:

example1

"Prog2am0in6"ดังนั้นการส่งออกที่คาดว่าจะเป็น

คำอธิบายและกฎ

  • สตริงอินพุตจะมีอักขระ ASCII ในช่วง 32 - 126 เท่านั้น คุณสามารถสันนิษฐานได้ว่ามันจะไม่มีวันว่างเปล่า
  • สายเดิมรับประกันว่าจะไม่มีตัวเลขใด ๆ
  • เมื่อตัวละครได้รับการเข้ารหัสมันอาจจะถูกอ้างอิงโดยตัวเลขที่ตามมา ยกตัวอย่างเช่นควรได้รับการเข้ารหัสเป็น"alpaca""alp2c1"
  • การอ้างอิงจะไม่ล้อมรอบสตริง: สามารถอ้างอิงอักขระก่อนหน้าเท่านั้น
  • คุณสามารถเขียนโปรแกรมเต็มรูปแบบหรือฟังก์ชั่นซึ่งพิมพ์หรือส่งออกผลลัพธ์
  • นี่คือรหัสกอล์ฟดังนั้นคำตอบที่สั้นที่สุดเป็นไบต์ชนะ
  • ช่องโหว่มาตรฐานเป็นสิ่งต้องห้าม

กรณีทดสอบ

Input : abcd
Output: abcd

Input : aaaa
Output: a000

Input : banana
Output: ban111

Input : Hello World!
Output: Hel0o W2r5d!

Input : this is a test
Output: this 222a19e52

Input : golfing is good for you
Output: golfin5 3s24o0d4f3r3y3u

Input : Programming Puzzles & Code Golf
Output: Prog2am0in6 Puz0les7&1Cod74G4lf

Input : Replicants are like any other machine. They're either a benefit or a hazard.
Output: Replicants 4re3lik448ny3oth8r5mac6in8.8T64y'r371it9376a1b5n1fit7or2a1h2z17d.

6
ฉันเห็นว่ากรณีทดสอบของคุณใช้ตัวเลขต่ำสุดที่เป็นไปได้เสมอสำหรับการทดแทนใด ๆ สิ่งนี้เป็นพฤติกรรมที่ต้องการหรือเราสามารถใช้ตัวเลขที่สูงขึ้นเช่นกันเมื่อมีความเป็นไปได้มากกว่าหนึ่ง
ลีโอ

@Leo คุณสามารถใช้ตัวเลขหลักเดียวที่คุณต้องการ 0-9 ตราบเท่าที่ยังใช้ได้อยู่
Engineer Toast

นี่เป็นเหมือนเครื่องเปลี่ยนรหัสแบบไปด้านหน้ายกเว้นไม่มีการเคลื่อนไหว :)
ไปป์

คำตอบ:


6

05AB1E , 20 19 18 ไบต์

-2 ขอบคุณEmigna

õ¹vDyåiDykëy}?yìT£

ลองออนไลน์!

õ                  # Push an empty string
 ¹v y              # For each character in input
   D               # Duplicate the string on the stack (call this S)
     åi            # If this character is in S
       Dyk         #   Push the index of that that character 
          ë }      # Else
           y       #   Push the character 
             ?     # Print without newline
              yì   # Prepend this character to S
                T£ # Remove all but the first 10 elements from S

ฉันคิดว่า)¹vDyåiDykëy}?y¸ìT£ทำงานได้ดี
Emigna

อันที่จริงแล้วการรวมคำตอบของคุณกับของõIvDyåiDykëy}?yìT£
ฉันนั้น

@Emigna อย่าลังเลที่จะอัพเดทของคุณด้วย :) :)
Riley

ฉันจะไม่คิดถึงมันถ้าไม่ใช่เพื่อคำตอบของคุณดังนั้นคุณควรมีมัน เยี่ยมมาก!
Emigna

@Emigna ฉันคิดว่ามันยุติธรรม ขอบคุณ!
Riley

12

เรติน่า24 24ไบต์

(.)(?<=\1(.{0,9}).)
$.2

ลองออนไลน์!

การทดแทน regex ค่อนข้างง่าย เราจับคู่แต่ละอักขระและพยายามค้นหาสำเนาของอักขระ 0-9 ก่อนหน้า หากเราพบมันเราจะแทนที่ตัวละครด้วยจำนวนตัวอักษรที่เราต้องจับคู่เพื่อไปที่สำเนา

ผลลัพธ์ไม่ตรงกับกรณีทดสอบมากนักเนื่องจากตัวเลขนี้ใช้ตัวเลขที่ใหญ่ที่สุดที่เป็นไปได้แทนที่จะเป็นตัวเลขที่เล็กที่สุด


4
ความยาวที่เปลี่ยนแปลงได้คือการโกง: p
Dada

8
@Dada lookbehind ความยาวผันแปรเป็นวิธีการตรัสรู้
Martin Ender

น่าเศร้าที่ ... ถ้าคุณรู้สึกเบื่อคุณสามารถนำไปใช้ใน Perl ได้!
Dada

ตามความคิดเห็นของ OP เกี่ยวกับงานดั้งเดิม "คุณสามารถใช้ตัวเลขหลักเดียวที่คุณต้องการ 0-9 ตราบใดที่มันถูกต้อง" ... ที่ใหญ่ที่สุดที่เป็นไปได้ควรจะถูกต้อง
Doktor J

@DoktorJ ใช่ฉันเปลี่ยนหลังจาก OP เพิ่มคำอธิบายนั้น
Martin Ender

8

JavaScript (ES6), 74 57 54 ไบต์

บันทึก 3 ไบต์ด้วย ETHproductions ที่ยอดเยี่ยมp=/./gแทนที่จะเป็นp={}(ได้รับแรงบันดาลใจจาก Neil)

s=>s.replace(p=/./g,(c,i)=>(i=p[c]-(p[c]=i))>-11?~i:c)

กรณีทดสอบ


เนื่องจากสตริงรับประกันว่าจะไม่มีตัวเลขคุณสามารถใช้sแทนได้pหรือไม่?
Neil

(ฉันสามารถเอาชนะfindเวอร์ชันต้นฉบับของคุณได้โดยใช้lastIndexOfซึ่งน่าแปลกใจเล็กน้อยเนื่องจากมีความยาว 11 ตัวอักษร .... )
Neil

@ ไม่มีฉันไม่ได้อยู่หน้าคอมพิวเตอร์ แต่ตอนนี้ฉันไม่คิดว่ามันจะใช้ได้เพราะสตริง JS นั้นไม่เปลี่ยนรูป
Arnauld

2
ฉันสามารถยืนยันได้ว่าการตั้งค่าคุณสมบัติตามตัวอักษรสตริงไม่ทำงาน แต่ ... ดูเหมือนว่าจะทำงานกับ regex ดังนั้นฉันคิดว่าคุณสามารถทำได้s=>s.replace(p=/./g,(c,i)=>(i=p[c]-(p[c]=i))>-10?~i:c)เพื่อประหยัด 3 ไบต์
ETHproductions

1
@YOU ฉันไม่รู้จริงๆว่าเกิดอะไรขึ้นที่นี่ แต่ปรากฎว่าฉันแนะนำข้อผิดพลาดสำหรับเบราว์เซอร์ทั้งหมดในการแก้ไขครั้งล่าสุดของฉัน ตอนนี้ได้รับการแก้ไขแล้ว ขอบคุณที่สังเกต!
Arnauld

7

Haskell , 72 66 ไบต์

ขอบคุณLaikoniสำหรับการเล่นกอล์ฟ 6 ไบต์!

(a:r)%s=last(a:[n|(n,b)<-zip['0'..'9']s,b==a]):r%(a:s)
e%s=e
(%"")

ลองออนไลน์!

ฟังก์ชั่น%เก็บสตริงที่ประมวลผลบางส่วนในสิ่งที่ตรงกันข้ามในอาร์กิวเมนต์ที่สองดังนั้นจึงสามารถค้นหา 10 องค์ประกอบแรกของสตริงนี้สำหรับการเกิดขึ้นของตัวละครมันกำลังตรวจสอบ การส่งประกอบด้วยฟังก์ชั่นที่ไม่มีชื่อ(%"")ซึ่งเรียกใช้ฟังก์ชั่นก่อนหน้านี้กับสตริงที่ว่างเปล่าเป็นอาร์กิวเมนต์ที่สอง


f(a:s)=f s++(last$[a]:[show n|(n,b)<-zip[0..9]s,b==a])บันทึกสองไบต์
Laikoni

เดี๋ยวก่อนf(a:s)=f s++[last$a:[n|(n,b)<-zip['0'..'9']s,b==a]]ประหยัดมากยิ่งขึ้น
Laikoni

การย้อนกลับในระหว่างเดินทางแทนที่จะใช้reverseช่วยประหยัดอีกหนึ่งไบต์: ลองออนไลน์!
Laikoni

@Laikoni ขอบคุณมากมันเยี่ยมมาก!
Leo


3

Perl 5 , 36 ไบต์

35 ไบต์ของรหัส + -pธง

s/(\D)(.{0,9})\K\1/length$2/e&&redo

ลองออนไลน์!

คำอธิบายบางอย่าง:
เป้าหมายคือการแทนที่ตัวละครที่ไม่ใช่ตัวเลข ( \Dแต่มันสอดคล้องกับ backreference \1ใน regex ของฉัน) ที่นำหน้าด้วยน้อยกว่า 10 ตัวอักษร ( .{0,9}) และตัวละครเดียวกัน ( (\D)... \1) ด้วยความยาวของ.{0,9}กลุ่ม ( length$2) และredoในขณะที่ตัวละครได้รับการแทนที่


เห็นได้ชัดว่า.*ไม่จำเป็นต้องใช้ตัวอักษรใด ๆ ที่ถูกต้องในช่วงก่อนที่ตัวเลขที่ถูกแทนที่นั้นจะใช้ได้
colsw

@ConnorLSW Yup ฉันเพิ่งเห็นการปรับปรุงความท้าทายและแก้ไขคำตอบของฉันขอบคุณที่ชี้ให้เห็น
Dada


3

Japt , 18 ไบต์

£¯Y w bX s r"..+"X

ลองออนไลน์!

คำอธิบาย

£   ¯  Y w bX s r"..+"X
mXY{s0,Y w bX s r"..+"X}
                          // Implicit: U = input string
mXY{                   }  // Replace each char X and index Y in U by this function:
    s0,Y                  //   Take U.slice(0,Y), the part of U before this char.
         w bX             //   Reverse, and find the first index of X in the result.
                          //   This gives how far back this char last appeared, -1 if never.
              s           //   Convert the result to a string.
                r"..+"X   //   Replace all matches of /..+/ in the result with X.
                          //   If the index is -1 or greater than 9, this will revert to X.
                          // Implicit: output result of last expression


2

05AB1E , 20 ไบต์

õIv¹N£RT£©yåi®ykëy}J

ลองออนไลน์!

คำอธิบาย

õ                     # push an empty string
 Iv                   # for each [index,char] [N,y] in input
   ¹N£                # push the first N characters of input
      R               # reverse
       T£             # take the first 10 characters of this string
         ©            # save a copy in register
          yåi         # if y is in this string
             ®yk      #   push the index of y in the string in register
                ë     # else 
                 y    #   push y
                  }   # end if
                   J  # join stack as one string


2

C (tcc) , 113 ไบต์

เนื่องจากฟังก์ชั่นสร้างสำเนาของสายป้อนข้อมูลขนาดสูงสุดของการป้อนข้อมูลคือ 98 ตัวอักษร (เกินพอที่จะใส่แบบทดสอบที่ยาวที่สุด) แน่นอนสิ่งนี้สามารถเปลี่ยนเป็นค่าอื่น ๆ

i,j;f(char*s){char n[99];strcpy(n,s);for(i=1;s[i];i++)for(j=i-1;j>-1&&i-j<11;j--)if(n[i]==n[j])s[i]=47+i-j;j=-1;}

ลองออนไลน์!

แก้ไข

-15 ไบต์ ขอบคุณโจฮา du Toit


Agh! จำกัด อินพุตที่ 98 ตัวอักษรและช่วยตัวคุณเองด้วยไบต์
ท่อ

วิธีแก้ปัญหาที่ดี แต่คุณสามารถบันทึกอีก 15 ไบต์: i,j;f(char*s){char n[99];strcpy(n,s);for(i=1;s[i];i++)for(j=i-1;j>-1&&i-j<11;j--)if(n[i]==n[j])s[i]=47+i-j,j=-1;}
Johan du Toit

@JohanduToit ขอบคุณ! ฉันมีหนึ่งคำถาม. s [i] ทำงานอย่างไรเป็นเงื่อนไขของ for loop? ฉันเคยเห็นหลายครั้งในคำตอบของผู้อื่นในเว็บไซต์นี้
Maxim Mikhaylov

@ Max Lawnboy เดิมคุณมีสิ่งต่อไปนี้: 's [i] ^' \ 0 '' ซึ่งย่อมาจาก 's [i]! =' \ 0 '' ตัวอักษร '\ 0' ตามตัวอักษรมีค่าเท่ากับศูนย์เพื่อให้คุณสามารถเขียนเช่นนี้: 's [i]! = 0' คำสั่ง if ใน C จะทดสอบว่าค่าประเมินเป็นศูนย์หรือไม่เป็นศูนย์เท่านั้นดังนั้นไม่จำเป็นต้องใช้ '! = 0'
Johan du Toit


2

Java 7, 102 101 ไบต์

void a(char[]a){for(int b=a.length,c;--b>0;)for(c=b;c-->0&c+11>b;)if(a[c]==a[b])a[b]=(char)(b-c+47);}

ลองออนไลน์!

-1 ขอบคุณไบต์เควิน Cruijssen ฉันสนุกกับข้อแก้ตัวเสมอในการใช้ตัวดำเนินการไปที่


ทำไม--c>=0? คุณสามารถแทนที่ด้วยc-->0เพื่อบันทึกไบต์
Kevin Cruijssen

@KevinCruijssen ฉันมีอยู่ในหัวของฉันว่าฉันต้องการ preecrement มิฉะนั้นการคำนวณจริงจะผิด ... จับได้ดี!
โผล่

1

MATL, 31 30 ไบต์

&=R"X@@f-t10<)l_)t?qV}xGX@)]&h

ลองที่MATL Online!

คำอธิบาย

        % Implicitly grab input as a string
&=      % Perform element-wise comparison with automatic broadcasting.
R       % Take the upper-triangular part of the matrix and set everything else to zero
"       % For each column in this matrix
X@      % Push the index of the row to the stack
@f      % Find the indices of the 1's in the row. The indices are always sorted in
        % increasing order
-       % Subtract the index of the row. This result in an array that is [..., 0] where
        % there is always a 0 because each letter is equal to itself and then the ...
        % indicates the index distances to the same letters
t10<)   % Discard the index differences that are > 9
l_)     % Grab the next to last index which is going to be the smallest value. If the index
        % array only contains [0], then modular indexing will grab that zero
t?      % See if this is non-zero...
  qV    % Subtract 1 and convert to a string
}       % If there were no previous matching values
  x     % Delete the item from the stack
  GX@)  % Push the current character
]       % End of if statement
&h      % Horizontally concatenate the entire stack
        % Implicit end of for loop and implicit display

คุณอาจจะปิดนิด แต่ผมสุดไม่สามารถบอกได้ว่า การป้อนข้อมูลที่this is a testอัตราผลตอบแทนแทนthis 222a1te52 this 222a19e52ที่สองจะไม่แปลงเป็นt 9
Engineer Toast

@EngineerToast ฮ่าฮ่าขอบคุณ ฉันจะดู
Suever

1

PHP, 104 ไบต์

ส่งต่อการแก้ปัญหา

for($i=0;$i<strlen($a=&$argn);$f[$l]=$i++)$a[$i]=is_int($f[$l=$a[$i]])&($c=$i-$f[$l]-1)<10?$c:$l;echo$a;

โซลูชั่นย้อนหลัง

รุ่นออนไลน์

PHP, 111 ไบต์

for(;++$i<$l=strlen($a=&$argn);)!is_int($t=strrpos($argn,$a[-$i],-$i-1))?:($p=$l-$i-$t-1)>9?:$a[-$i]=$p;echo$a;

PHP, 112 ไบต์

for(;++$i<$l=strlen($a=&$argn);)if(false!==$t=strrpos($argn,$a[-$i],-$i-1))($p=$l-$i-$t-1)>9?:$a[-$i]=$p;echo$a;

เวอร์ชั่นออนไลน์


1

REXX, 124 125 ไบต์

a=arg(1)
b=a
do n=1 to length(a)
  m=n-1
  c=substr(a,n,1)
  s=lastpos(c,left(a,m))
  if s>0&m-s<=9 then b=overlay(m-s,b,n)
  end
say b

คุณอาจจะออกไปเล็กน้อย ผมไม่ทราบว่า REXX แต่ผมเข้าใจข้อผิดพลาดอยู่ในสายที่ 7 ก็มีs<9แทนหรือs<10 s<=9การป้อนข้อมูลที่this is a testอัตราผลตอบแทนแทนthis 222a1te52 this 222a19e52ที่สองจะไม่แปลงเป็นt ลองออนไลน์9
วิศวกรขนมปังปิ้ง

ขอบคุณมันเป็นความพยายามที่โง่เขลาที่จะกำจัดหนึ่งไบต์ รหัสได้รับการแก้ไขแล้ว
idrougge

1

C (gcc) , 117 103 ไบต์

i,j;f(char*s){for(i=strlen(s)-1;s[i];i--)for(j=i-1;s[j]&&i-j<11;j--)if(s[i]==s[j]){s[i]=47+i-j;break;}}

ลองออนไลน์!

103 ไบต์โดยไม่ต้องสตริง h นำเข้าทำงานโดยมีคำเตือน หากสิ่งนี้ขัดกับกฎฉันจะดึงมัน

พริตตี้รหัส:

i,j;
f(char *s) {
    // Chomp backwards down the string
    for(i=strlen(s)-1; s[i]; i--)
        // for every char, try to match the previous 10
        for(j=i-1; s[j] && i-j < 11; j--)
            // If there's a match, encode it ('0' + (i-j))
            if (s[i] == s[j]) {
                s[i] = 47+i-j;
                break;
            }
}

การแก้ไข:

  • เปลี่ยนจาก LLVM เป็น gcc เพื่ออนุญาตการประกาศ i, j, การนำเข้า lib ที่ถูกลบ
  • เพิ่มฟังก์ชั่นกระดาษห่อสำหรับการปฏิบัติตาม

แนะนำ(i=strlen(s);s[--i];)แทน(i=strlen(s)-1;s[i];i--)
ceilingcat
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.