นับถอยหลังและรีไซเคิล


14

นับถอยหลัง

เป้าหมายของคุณสำหรับการแข่งขันกอล์ฟรหัสคือการนับถอยหลังและรีไซเคิลหมายเลข ให้ฉันอธิบาย

ก่อนอื่นแอปพลิเคชันของคุณจะอ่านตัวเลขไม่ว่าจะเป็นอาร์กิวเมนต์ของโปรแกรมหรือการใช้ stdin ต่อไปคุณจะต้องนับถอยหลังเช่นนี้: 10 9 8 7 6( ตามลำดับจากมากไปน้อย )

แต่เดี๋ยวก่อนมีอีกมาก!

รีไซเคิล

มีสถานการณ์ที่เราสามารถพิมพ์ได้ทุกหมายเลข แต่ไม่แสดงรายการทุกหมายเลขเราสามารถรีไซเคิลได้! ขอยกตัวอย่างง่ายๆ:

Input: 110

Output:   11091081071061051041031021010099... etc
Recycled:  10                        1

เราได้ในขณะนี้ยังคงแสดงตัวเลขทั้งหมด, 110, 109, 108, แต่เราได้รีไซเคิล0และ1

ตัวอย่างอื่น:

Input: 9900

Output:   9900989989897989698959894... etc
Recycled:        9 98  

ความท้าทายของรหัส - กอล์ฟ

  • อ่านตัวเลข (อาร์กิวเมนต์หรือ stdin)
  • การส่งออกนับถอยหลังในลงมาเพื่อการรีไซเคิลในขณะที่ทุกตัวเลขที่เป็นไปได้ (ที่ stdout หรือแฟ้ม)
  • หยุดเมื่อคุณไปถึง 1 หรือช่วงเวลาที่คุณรีไซเคิล 0 ถึง 9 (ไม่ว่าจะเกิดอะไรขึ้นก่อน)

ตัวอย่างง่ายๆ (จนถึง 1 ถึง):

Input: 15
Output: 15141312110987654321

(Notice the 110 instead of 1110)

ตัวอย่างขั้นสูงเพิ่มเติม (รีไซเคิลทั้งหมด):

Input: 110
Output:   110910810710610510410310210100998979695949392919089887868584838281807978776757473727170696867665646362616059585756554535251504948474645443424140393837363534332313029282726252423221
Recycled:  10                            9                    8                    7                    6                    5                    4                    3                    2

(We've recycled all 0-9)


2
มันไม่เกี่ยวข้องกับปัญหา "แหวนเดียวที่จะปกครองพวกเขาทั้งหมด" เลย
จะ

@RoyvanRijn คุณไม่ได้พูดถึงสิ่งใดเกี่ยวกับการเรียงลำดับจากน้อยไปหามากในคำถามของคุณ - ถ้าฉันไม่ลงคะแนนใกล้เคียงกับซ้ำฉันจะมี "ไม่ชัดเจนเกี่ยวกับสิ่งที่คุณถาม" หากตัวเลขต้องเรียงลำดับจากน้อยไปมากแล้ว 10 (ในตัวอย่างที่สองของคุณ) จะเป็นอย่างไรในตอนเริ่มต้นของลำดับ
ภูมิใจ haskeller

1
@proudhaskeller ไม่ได้ระบุคำถามลงมาเพื่อ? "count down" ถูกเข้าใจเพื่อหมายถึงลำดับจากมากไปน้อย
จะ

1
รอยฉันไม่ได้ลงคะแนนให้ปิดเหมือนซ้ำ แต่การพูดถึงคำถามที่เกี่ยวข้องอย่างชัดเจนจะเป็นการเสริมระบบคาดเดาคำถามที่เกี่ยวข้องโดยอัตโนมัติ @ แน่นอนว่ามันเกี่ยวข้องกัน ลบเงื่อนไขการหยุดก่อนกำหนดและคำถามนี้ขอให้คุณใช้กลยุทธ์ที่ไม่เหมาะสมโดยเฉพาะสำหรับ "หนึ่งสตริงเพื่อปกครองทั้งหมด"
Peter Taylor

คำตอบ:


11

T-SQL - 291 277 267 217 199 191 166 158 153 145 142 128 117

หลังจากที่เข้าใกล้สิ่งนี้ในรูปแบบใหม่ฉันสามารถลงไปที่ 145 (142 หลังจากการปรับแต่งเล็กน้อยสองครั้ง) ไม่โทรมเกินไป นั่นหมายความว่าฉันอาจจะสามารถชิงเงินหรือทองสัมฤทธิ์ได้ ^^

DECLARE @ INT=100;WITH N AS(SELECT 1A UNION ALL SELECT A+1FROM N WHERE A<@)SELECT LEFT(A,LEN(A)-1+A%11)FROM N ORDER BY-A

นี่ไม่ได้พิมพ์รายการ แต่จะเลือกผลลัพธ์ คำถามไม่เคยให้รายละเอียดเกี่ยวกับผลลัพธ์ดังนั้นควรจะดี สิ่งนี้ยังคงมีขีด จำกัด อยู่ที่ 100 ในอินพุตส่วนหนึ่งเป็นเพราะฉันใช้ความจริงที่ว่าทุกคำที่ 11 ต่ำกว่า 100 สูญเสียอักขระและส่วนหนึ่งเป็นเพราะขีด จำกัด การเรียกซ้ำ 100 ครั้งบนนิพจน์ตารางทั่วไป

DECLARE @ INT=100;

WITH N AS
(
    SELECT 1A
    UNION ALL
    SELECT A+1
    FROM N
    WHERE A<@
)

SELECT LEFT(A,LEN(A)-1+A%11)
FROM N
ORDER BY-A

1
ฮ่า ๆ ๆ T-SQL สุดยอดจริงๆ!
Roy van Rijn

7

Python 143 147

def t(n):
 p=o='';r=0 # p is previous string, o is output string, r is recycled bitmap
 while n and r<1023: # 1023 is first 10 bits set, meaning all digits have been recycled
    s=`n`;i=-1 # s is the current string representation of n
       # i is from end; negative offsets count backwards in strings
    while p.endswith(s[:i])-1:i-=1 # find common ending with prev; s[:0] is '',
       # which all strings end with
    for j in s[:i]:r|=1<<int(j) # mark off recycled bits
    o+=s[i:];p=s;n-=1 # concatenate output, prepare for next number
 print o # done

เยื้องระดับแรกคือพื้นที่และระดับที่สองคือแท็บถ่าน


2
ถ่านมาตรฐานบางตัวประหยัด: ใส่สิ่งต่าง ๆ เช่นp=o=''params เผื่อเลือกไปยังฟังก์ชัน คุณสามารถใช้*สำหรับandในn and r<1023หรือแม้กระทั่งr<1023*n; while x-1:สามารถโกนพื้นที่while~-xได้ นอกจากนี้อาจใช้เวลาสั้นลงในการใช้ชุดตัวเลขแทนที่จะเป็นบิตมาสก์เพื่อเก็บตัวเลขที่ใช้ไปแล้ว
xnor

5

Haskell, 154 149 147 145 128 120 119 117 ไบต์

import Data.List
(r%x)n|n>0&&r<":"=[(r\\t)%(x++(show n\\t))$n-1|t<-tails x,isPrefixOf t$show n]!!0|0<1=x
h=['0'..]%""

การเพิ่มในการตรวจสอบการรีไซเคิลมีจำนวนมากของตัวละคร ... ถอนหายใจ

golfed เล็กน้อยโดยการจดจำตัวเลขที่ยังไม่ได้นำกลับมาใช้ใหม่และหยุดเมื่อรายการว่างเปล่า จากนั้นไปเล่นกอล์ฟอีกเล็กน้อยโดยการย้ายไปยังการเรียกซ้ำอย่างชัดเจนและลูกเล่นอีกเล็กน้อย

เอาท์พุทตัวอย่าง:

*Main> h 110
"110910810710610510410310210100998979695949392919089887868584838281807978776757473727170696867665646362616059585756554535251504948474645443424140393837363534332313029282726252423221"

5

Python 2: 119 117

ทำเครื่องหมายนี้เป็นวิกิพีเดียชุมชนเพราะมันเป็นเพียงรุ่นแข็งแรงเล่นกอล์ฟมากขึ้นของคำตอบของวิล

n=input()
d=s,={''}
exec"t=`n`;i=len(t)\nwhile(s*i)[-i:]!=t[:i]:i-=1\ns+=t[i:];d|=set(t[:i]);n-=len(d)<11;"*n
print s

! ที่ยอดเยี่ยม วิธีการที่ไม่d=s,={''}ทำงานหรือไม่
จะ

2
@Will เทียบเท่ากับd=s,={''} ใช้การเปิดกล่องข้อมูลตามลำดับซึ่งเป็นคุณสมบัติที่ใช้บ่อยในข้อความสั่งต่าง ๆ เช่นแต่คุณยังสามารถใช้เพื่อแยกองค์ประกอบเดียวจากลำดับองค์ประกอบเดียว d={''}; s,={''}s,={''}a, b = (b, a)
flornquake

1
@ flornquake โอ้ความผิดพลาดของฉัน ฉันคิดว่าคุณยังสามารถทำได้len(d)%11*nแต่ดูเหมือนว่ามันจะเข้าข่ายกับคุณโดยใช้วนรอบ exec
xnor

1
@ Will เนื่องจากเบื้องหลังว่าทำไมเคล็ดลับที่ชาญฉลาดนี้จึงมีประสิทธิภาพมากขึ้นมันจึงยิ่งทำให้ชุดที่ว่างเปล่าเสียset()กว่าชุดชุดองค์ประกอบ{x}เดียว ดังนั้น flornquake จะเริ่มต้นด้วยสมาชิกฟิลเลอร์และตรวจสอบว่ามันมีสิบหลักโดยดูว่ามันมีองค์ประกอบสิบเอ็ด เนื่องจากสตริงว่างต้องถูกกำหนดค่าเริ่มต้นsจึงถูกใช้เพื่อทำหน้าที่เป็นสมาชิกฟิลเลอร์นี้รวมการเริ่มต้นเหล่านี้เพื่อบันทึกตัวอักษร
xnor

1
@ จะใช่len(d)%11*nก็คงจะดี :)
flornquake

4

Ruby, 145 139 130 ไบต์

n=gets.to_i
d=*?0..?9
s=''
n.times{|i|j=(t=(n-i).to_s).size;j-=1 while s[-j,j]!=u=t[0,j];d-=u.chars;s=t;$><<t[j..-1];exit if[]==d}

วิธีที่คล้ายกับ Will's ยกเว้นฉันไม่ได้ใช้ bit mask แต่เป็นชุดตัวเลขที่ไม่ได้ใช้แทนชุด อินพุตคือผ่าน STDIN

มีรุ่นอื่นที่ใช้whileแทนtimesแต่สิ่งที่ฉันลองจำนวนไบต์เหมือนกัน:

n=gets.to_i
d=*?0..?9
s=''
(j=(t=n.to_s).size;j-=1 while s[-j,j]!=u=t[0,j];d-=u.chars;s=t;$><<t[j..-1];exit if[]==d;n-=1)while 0<n

3

CJam, 80 77 65 57 54 ตัวละคร

อาจจะไม่ได้รับการปรับให้เหมาะสมเลย แต่หลังจากการปรับแต่งและแก้ไขจุดบกพร่องจำนวนมากที่นี่คือการแปลงคำตอบ ES6 ของฉันโดยตรงใน CJam:

Mr{s:C_,{:H<M_,H->=!_CH@-@}g:T>+:MCT<_O@-+:O,A<Ci(*}h;

ลองมันออนไลน์ได้ที่นี่ ฟังก์ชั่นนี้ใช้หมายเลขเป็น STDIN และส่งออกการนับถอยหลังที่นำกลับมาใช้ใหม่ซึ่งจะหยุดหากการรีไซเคิลเสร็จสิ้น

ฉันจะลองกอล์ฟต่อไป

มันทำงานอย่างไร:

แนวคิดพื้นฐานคือสำหรับแต่ละหมายเลขนับถอยหลัง C ตรวจสอบว่า H หลักแรกนั้นเท่ากับตัวเลข H สุดท้ายของสตริงผลลัพธ์หรือไม่โดยที่ H ไปจากจำนวนหลักใน C ถึง 0

Mr                                    "Put an empty string and input on stack";
  { ... }h;                           "Run while top element of stack is true, pop when done";
s:C                                   "Store string value of top stack element in C"
   _,                                 "Put the number of characters in C to stack";
     { ... }g                         "Run while top element of stack is true";
:H<                                   "Store the digit iteration in H and slice C";
   M                                  "M is the final output string in making";
    _,H-                              "Take length of M and reduce H from it";
        >                             "Take that many digits of M from end and..."
         =!_                          "Compare with first H digits of C, negate and copy";
            CH@                       "Put C and H on stack and bring the above result to top of stack";
               -                      "Reduce H if the matched result was false";
                @                     "Bring the matched result on top in order continue or break the loop"
             :T                       "Store top stack element in T after the loop";
               >+:M                   "Take everything but first T digits of C and add it to M and update M";
                   CT<_               "Take first T digits of C and copy them";
                       O@             "Put saved digits on stack, and rotate top three elements";
                         -            "Remove all occurence of first T digits of C from O";
                          +:O         "Add first T digits of C to O and update O";
                             ,A<      "Compare number of saved digits with 10";
                                Ci(   "Decrement integer value of C and put it on stack";
                                   *  "If number of saved digits greater than 9, break loop";

2

JavaScript ES6, 149 146 ตัวอักษร

verbose ดังกล่าวตัวละครมากว้าว

C=n=>{s=c='';while(n>0&s.length<10){j=1;while(t=(n+'').slice(0,-j++))if(c.endsWith(t)){s+=~s.search(t)?'':t;break}c+=(n--+'').slice(1-j)}return c}

เรียกใช้ในคอนโซลเว็บล่าสุดของ Firefox

หลังจากรันแล้วจะสร้างวิธีการCที่คุณสามารถใช้เช่น

C(12)
12110987654321

UPDATE : บางครั้งเก่าธรรมดาreturnสั้นกว่าฟังก์ชั่นลูกศรปิด :)


ไม่ควรส่งออกตัวเลขที่ถูกนำกลับมาใช้ใหม่เฉพาะลำดับการนับถอยหลังหลังจากการรีไซเคิล
ภูมิใจ haskeller

Oh! คือว่า ? ตัวอย่างทั้งหมดของเขาก็แสดงผลออกมาเช่นกัน
เครื่องมือเพิ่มประสิทธิภาพ

@proudhaskeller โอ้ฉันส่งออกตัวอักษรรีไซเคิลด้วย ขอบคุณที่จะช่วยฉันประหยัดบางตัวอักษร
PenutReaper
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.