พิมพ์หมายเลขที่ปลอดภัยต่อการหมุน


29

พื้นหลัง

คุณกำลังทำงานให้กับผู้ผลิตเกมกระดานบางเกมและจำเป็นต้องผลิตแผ่นไม้ที่มีตัวเลขตั้งแต่ 0 ถึงn ที่สลักไว้สำหรับเกมบางเกม แต่ไม่ต้องกังวลใจต่อกระเบื้องบางส่วนจะกลายเป็นแยกไม่ออกเช่นและ6 9เพื่อหลีกเลี่ยงนี้คุณมีเพื่อให้ตัวเลขที่จะสับสนกับคนอื่น ๆ (และเฉพาะผู้) มีจุด disambiguating เช่นคุณจะมีกระเบื้องเหมือนหรือ9.6089.

น่าเสียดายที่คุณต้องใช้อุปกรณ์แกะสลักไม้แบบเก่า แต่ยังสามารถตั้งโปรแกรมได้ซึ่งอินเทอร์เฟซเสียจนคุณต้องเข้ารหัสตัวละครทุกตัวของโปรแกรมด้วยมือในกระบวนการที่น่าเบื่ออย่างไม่น่าเชื่อ โชคดีที่อุปกรณ์เข้าใจภาษาการเขียนโปรแกรมที่มีอยู่ทั้งหมด ดังนั้นคุณกำลังมองหาโปรแกรมที่สั้นที่สุดที่จะพิมพ์กระเบื้องดังกล่าว

งานจริง

เขียนโปรแกรมสั้นที่สุดที่:

  • รับจำนวนเต็มบวกnเป็นอินพุต การอ่านอินพุตนั้นขึ้นอยู่กับคุณอย่างไร
  • พิมพ์ตัวเลขแต่ละตัวตั้งแต่ 0 ถึงn (รวม 0 และn ) หนึ่งครั้งตามลำดับที่คุณเลือกโดยคั่นด้วยอักขระช่องว่างเดียว (รวมถึงบรรทัดใหม่) ตัวเลขจะถูกพิมพ์โดยไม่มีศูนย์นำหน้า
  • ผนวกจุด (.) กับทุกหมายเลขที่เปลี่ยนเป็นตัวเลขอื่นหมายเลขที่ถูกต้องเมื่อหมุนโดยπ (180 °) แม้ว่าจำนวนนั้นจะมากกว่าn แบบอักษรของคุณ 0 และ 8 คือการหมุนแบบสมมาตรและ 9 คือการหมุน 6 แบบที่ 2 และ 5 นั้นแตกต่างกันตามการหมุน 1 ไม่ใช่การหมุนแบบสมมาตร ตัวเลขที่มีเลขศูนย์นำหน้าไม่ถูกต้อง

ตัวอย่าง

แต่ละหมายเลขต่อไปนี้ต้องพิมพ์ด้วยวิธีนี้

  • 2
  • 4
  • 5
  • 6.
  • 8
  • 9.
  • 16
  • 60
  • 66.
  • 68.
  • 69
  • 906
  • 909.
  • 8088.
  • 9806.
  • 9886
  • 9889.

ไม่ควร60จะเป็น60.?
red-X

2
@ red-X "ตัวเลขที่มีเลขศูนย์นำหน้าไม่ถูกต้อง"
Sp3000

2
@ เหตุผล: มีช่องโหว่มาตรฐานสำหรับสิ่งนี้ (นอกจากนี้สิ่งนี้จะไม่สมเหตุสมผลเนื่องจากคุณต้องสอนเครื่องนั้นภาษานั้น) ไม่ว่าด้วยวิธีใดฉันก็เพิ่มสิ่งที่มีอยู่
Wrzlprmft

2
@rationalis สิ่งที่เกิดขึ้นโดยทั่วไปคือเฉพาะรุ่นภาษาที่มีอยู่ก่อนการโพสต์ของความท้าทายเท่านั้นที่มีสิทธิ์ได้รับโปรแกรมที่ชนะ เวอร์ชันที่สร้างขึ้นหลังจากนั้นยังสามารถโพสต์เพื่อความสนุกสนานได้ แต่ควรระบุไว้ในโพสต์ว่าพวกเขาไม่ได้โต้แย้ง ดังนั้นใช่คุณสามารถกำหนดภาษาดังกล่าว แต่มันจะไม่เหมาะสมและน่าจะได้รับไม่ดีเนื่องจากเป็นช่องโหว่มาตรฐาน (ดังกล่าวข้างต้น)
Sp3000

3
ฉันคิดว่ามันจะเป็นประโยชน์หากคุณรวม8088.ตัวอย่างของคุณเป็นหมายเลขที่ไม่ปลอดภัยและไม่มี 6 หรือ 9
El'endia Starman

คำตอบ:


6

Pyth - 34 38

VhQJ`N+J*\.&nJX_J`69`96&eN!-J"0689

ฉันต้องขอบคุณ @ Sp3000 ที่ช่วยฉันลบ 4 ไบต์ ฉันเดิมมีการตรวจสอบเพิ่มเติม&@JKซึ่งทำให้แน่ใจว่ามี 6 หรือ 9 ในจำนวน แต่หลังจากอ่านคำตอบก่อนโพสต์ฉันอ่านคำตอบของเขาและสังเกตเห็นว่าการแปลและการกลับรายการที่เหมือนกันของฉันได้รับการดูแลแล้ว

นอกจากนี้ยังต้องขอบคุณ @isaacg สำหรับการชี้ให้เห็นว่าสตริงนั้นเป็น iterables และคุณสามารถใช้ชุดการดำเนินการกับมันได้ นอกจากนี้สำหรับการสร้างรหัสปัจจุบัน)

คำอธิบาย:

                                    : (implicit) Q=eval(input())
VhQ                                 : for N in range(Q+1):
   J`N                              : J=str(N)
      +J*\.                         : J + "." * ...
           &nJX_J`69`96             : J!=translate(reversed(J),"69","96") and...
                       &eN          : N%10 and...
                          !-J"0689  : not(setwise_difference(J, "0689"))

ฉันไม่คิดว่าคุณต้องใช้รายการจำนวนเต็มKและJ- เพียงใช้สตริงแทน การสลับKไปที่ <backtick> 69 และJไปที่ <backtick> N จะบันทึกอักขระไม่กี่ตัวเช่นเดียวกับการฝังKในโปรแกรมที่ได้ สั้นที่สุดที่ฉันสามารถทำได้ภายใต้เทคนิคนั้นคือVhQJ``N+J*\.&nJX_J``69``96&eN!-J"068934 ตัวอักษร (สอง backticks เป็นหนึ่งเดียวจริงๆ)
isaacg

@isaacg ขอบคุณสำหรับเคล็ดลับ! ฉันคิดว่าด้วยเหตุผลบางอย่างที่ฉันลืมว่าการสร้างจำนวนตัวเลขนั้นสั้นมาก ๆ โดยใช้ ` อย่างไรก็ตามคุณสามารถเขียนบล็อกรหัสด้วย backticks โดยการหลบหนีด้วย \ ตัวอย่างเช่น:hell`o wo`rld
FryAmTheEggman

ในการอธิบายคุณดูเหมือนจะมีเป็นพิเศษก่อน_ `96
isaacg

@isaacg ขอบคุณคง
FryAmTheEggman

10

CJam, 46 44 43 42 ไบต์

l~),{_A%g1$s_6890s-!\_69s_W%erW%=!&&'.*N}/

ฉันคิดว่ามีห้องพักสำหรับการปรับปรุงบางอย่าง

ทดสอบที่นี่

คำอธิบาย

l~),{_A%g1$s_6890s-!\_69s_W%erW%=!&&'.*N}/
l~                                         "Read an eval input.";
  ),                                       "Get range from 0 to n.";
    {                                   }/ "For each...";
     _                                     "Get a copy of the integer.";
      A%g                                  "Ends with digit other than 0?";
         1$s_                              "Get another copy, convert to string, get a copy.";
             0689s-!                       "Contains rotation-safe digits?";
                    \                      "Swap with other copy.";
                     _                     "Get another copy.";
                      69s_W%er             "Swap 6 and 9.";
                              W%           "Reverse.";
                                =!         "Is different from original?";
                                  &&       "AND all three conditions.";
                                    '.*    "If true, push a period (else, an empty string).";
                                       N   "Push a newline.";

สิ่งนี้จะส่งกลับเมื่ออินพุทเป็น 8? (ฉันวางรหัสในอินพุตจากนั้นคลิกที่ปุ่ม Run แต่มีข้อผิดพลาดถูกเรียก)
DavidC

@DavidCarraher ใส่รหัสใน "Code" และnใน Input
Martin Ender

อินพุท 98 โปรแกรมของคุณกำหนดจุดถัดจาก 66 ซึ่งไม่ถูกต้อง
Sparr

3
@Sparr คุณควรรอให้ OP ตอบคำถามของคุณก่อนที่จะตอบว่าคำตอบนั้นไม่ถูกต้อง คำพูดของเขา: "แต่ละหมายเลขต่อไปนี้จะต้องถูกพิมพ์ด้วยวิธีนี้" ดูเหมือนจะขัดแย้งกับการตีความของคุณ
FryAmTheEggman

ฉันชอบความสวยงามของคำอธิบาย CJam
nyuszika7h


5

APL 66

∊' ',¨{a←⌽'0.....9.86'[⎕D⍳b←⍕⍵]⋄'.'∊a:b⋄('0'=⊃a)∨⍵=⍎a:b⋄b,'.'}¨0,⍳

คำอธิบาย:

¨0,⍳           applies the function to each number 0-n
a←⌽'0.....9.86'[⎕D⍳b←⍕⍵] inverts 6s and 9s, leaving 8s and 0s, and replacing other numbers with dots. Reverses vector after substitution.
'.'∊a          if there is a dot in the number....
('0'=⊃a)       .. or if the number starts with 0...
⍵=⍎a           or if the (inverted) number is the same as original
:b             then print the original number
b,'.'          else print a dot in the end
∊' ',¨        Finally to give the result in the asked format i add a single space after each result and join them all 

ลองใช้กับtryapl.org

โปรดทราบว่าในล่ามออนไลน์ฟังก์ชั่น doesn't ไม่ทำงานดังนั้นฉันจึงต้องแทนที่ด้วย2⊃⎕VFIซึ่งทำเช่นเดียวกันในกรณีนี้เรียกใช้งานและส่งกลับหมายเลขรับสตริง


ดูเหมือนผิด: 60, 69, 90 และ 96 ต้องไม่มีจุด
ngn

ขอบคุณ @ngn ฉันแก้ไขมันฉันคิดว่ามันทำงานได้อย่างถูกต้องแล้ว
Moris Zucca

2
ทำได้ดีมาก :) แทนที่จะเป็น⊃,/หรือ,/คุณสามารถใช้ด้านหน้า
ngn

โอ้ใช่! ฉันมักจะไม่ทำงานใน ml1 ดังนั้นฉันลืมเกี่ยวกับ ∊
Moris Zucca

4

Perl 5, 53 ไบต์

say$_,"."x(!/[1-57]|0$/&&reverse!=y/96/69/r)for 0..<>

การสาธิตออนไลน์

ใช้คุณสมบัติ Perl 5.10+ sayดังนั้นจึงต้องเปิดใช้งานด้วยperl -M5.010(หรือperl -E) เพื่อเปิดใช้งาน (ดูที่หัวข้อนี้เมตา ) อ่านอินพุตจาก stdin พิมพ์ไปยัง stdout


4

Python 2, 130 116 113 ไบต์

def f(n):S=`n`;n and f(n-1);print S+"."*all([n%10,set(S)<=set("0689"),(u""+S[::-1]).translate({54:57,57:54})!=S])

กำหนดฟังก์ชั่นfที่พิมพ์ตัวเลขไปที่ STDOUT ตามลำดับจากน้อยไปหามาก

ครั้งนี้ฉันคิดว่าฉันจะละทิ้งจากหนังสือของ @ feersum ด้วย.translate:)

ขยาย:

def f(n):
 S=`n`        
 n and f(n-1)                                      # Recurse if not 0                                     
 print S+"."*all([n%10,                            # Not divisible by 10
                  set(S)<=set("0689"),             # Consists of 0689
                  (u""+S[::-1]).translate
                  ({54:57,57:54})!=S])             # When rotated is not itself

โซลูชันก่อนหน้า:

def f(n):S=`n`;print S+"."*all([n%10,set(S)<=set("0689"),eval("S[::-1]"+".replace('%s','%s')"*3%tuple("6a96a9"))!=S]);n and f(n-1)

ขอบคุณ @xnor ที่แสดง.replaceกลอุบายให้ฉันมานานแล้ว


คุณสามารถใช้แทน(u''+S[::-1]) unicode(S[::-1])นอกจากนี้หากคุณสลับprintและการโทรซ้ำหมายเลขจะออกมาตามลำดับที่เพิ่มขึ้น
ngn

@ngn Ah ขอบคุณฉันไม่คิดว่าu""+จะใช้งานได้จริง
Sp3000

เห็นฉันคิดว่านี่ควรเล็กกว่านี้ไม่ใช่ความผิดของคุณที่พิมพ์ถูกต้องไม่ใช่ "p" พูด แต่ถ้าคุณเขียน "p = print" และไม่นับเป็นไบต์ในการส่ง "เป็นทางการ" ของคุณ สั้นลง!
Alec Teal

4

C #, 343 309 ตัวอักษร

วิธีที่ยาวเกินไป แต่อย่างไรก็ตาม:

namespace System.Linq{class C{static void Main(){int n=int.Parse(Console.ReadLine());for(int i=0;i<=n;i++){var b=i+"";var c=b.Replace("6","9");Console.Write(b+(b.All(x=>x=='0'|x=='8'|x=='6'|x=='9')&!b.EndsWith("0")&!(b.Count(x=>x=='6')==b.Count(x=>x=='9')&new String(c.Reverse().ToArray())==c)?". ":" "));}}}}

มันทำงานยังไง? หากต้องการเพิ่มจุดในจำนวนนั้นจะต้องตรงกับข้อกำหนดต่อไปนี้:

  • ประกอบด้วยเดียวของ0, 8, และ69
  • ไม่ได้ลงท้ายด้วยศูนย์
  • ไม่ใช่หมายเลขเดียวกันเมื่อคุณหมุน:
    • หากตัวเลขมีจำนวน6s และ9s เท่ากันและ
    • if c= ตัวเลขที่มี6s ทั้งหมดแทนที่ด้วย9s
    • และตรงกันข้ามc== c,
    • ดังนั้น: หมายเลขที่หมุนแล้วจะเหมือนกับหมายเลขนั้น

ตัวเลขถูกคั่นด้วยช่องว่าง

รหัสด้วยการเยื้อง:

namespace System.Linq
{
    class C
    {
        static void Main()
        {
            int n = int.Parse(Console.ReadLine());
            for (int i = 0; i <= n; i++)
            {
                var b = i + "";
                var c = b.Replace("6", "9");
                Console.Write(b +
                    (b.All(x => x == '0' | x == '8' | x == '6' | x == '9') &
                    !b.EndsWith("0") &
                    !(b.Count(x => x == '6') == b.Count(x => x == '9') &
                    new String(c.Reverse().ToArray()) == c) ? ". " : " "));
            }
        }
    }
}

1
คำตอบของฉันยาวขึ้น;) ฉันดูเหมือนจะเล่นโบว์ลิ่งที่สนามกอล์ฟ
Digital Trauma

1
แล้ว 8808 ล่ะ มันไม่มี 6s หรือ 9 ใด ๆ แต่เป็น 8088 เมื่อหมุน
El'endia Starman

1
@ El'endiaStarman ขอบคุณมาก! ในขณะที่แก้ไขการส่งของฉันฉันบันทึกตัวละครจริง ๆ :)
ProgramFOX

4

M (MUMPS) - 72 70

R n F i=0:1:n W !,i S r=$TR($RE(i),69,96) W:r=+r*r'=i*'$TR(i,0689) "."

คำสั่งและฟังก์ชั่นในตัวส่วนใหญ่ใน M มีเวอร์ชั่นย่อ ฉันใช้ชื่อเต็มด้านล่าง

READ n - อ่านสตริงจากคีย์บอร์ดและเก็บไว้ใน nอ่านสตริงจากแป้นพิมพ์และเก็บไว้ใน

FOR i=0:1:n- วนซ้ำจากศูนย์ถึงการnเพิ่มขึ้นiซ้ำ 1 ครั้งในแต่ละครั้ง (ส่วนที่เหลือของบรรทัดถือเป็นเนื้อความของลูป)

WRITE !,i - พิมพ์บรรทัดใหม่ตามด้วยค่าของ iพิมพ์ขึ้นบรรทัดใหม่ตามค่าของ

SET r=$TRANSLATE($REVERSE(i),69,96))- ย้อนกลับแทนที่ด้วยเก้าแต้มและแต้มกับเก้าและร้านค้าที่อยู่ในir

WRITE:r=+r*r'=i*'$TRANSLATE(i,0689) "."

  • : - หมายถึงนิพจน์ postconditional ดังนั้น WRITEคำสั่งจะถูกดำเนินการเฉพาะในกรณีที่r=+r*r'=i*'$TRANSLATE(i,0689)ประเมินเป็นค่าจริง
  • r=+r - ตรวจสอบว่า rไม่มีศูนย์นำหน้า ตัวดำเนิน+การunary แปลงสตริงให้เป็นตัวเลขซึ่งจะนำแถบเลขศูนย์นำหน้าถ้ามี
  • *- ผู้ประกอบการคูณ M ไม่มีคำสั่งของการดำเนินงาน ตัวดำเนินการไบนารีทั้งหมดจะถูกประเมินตามลำดับที่ปรากฏจากซ้ายไปขวา
  • r'=i- ตรวจสอบว่าiไม่เหมือนกันกับเวอร์ชั่นที่พลิกrจะไม่เหมือนกับที่มันพลิกรุ่น
  • '$TRANSLATE(i,0689)- ลบเลขศูนย์, หก, แปดและเก้าออกจากiนั้นตรวจสอบว่าไม่มีอะไรเหลือ ( 'เป็นตัวดำเนินการปฏิเสธเชิงตรรกะ)
  • "."- ในที่สุดอาร์กิวเมนต์ไปยังWRITEคำสั่ง (สตริงตัวอักษร)

แก้ไข:ทำให้สั้นลงเล็กน้อยโดยใช้โอเปอเรเตอร์การคูณ รุ่นก่อนหน้า:

R n F i=0:1:n W !,i S r=$TR($RE(i),69,96) I '$TR(i,0689),i'=r,r=+r W "."

3

APL, 53 ตัวอักษร

∊{⍵,'. '↓⍨∨/(3≡⊃i)(5∊i),⍵≡'9608x'[i←⌽'6908'⍳⍵]}∘⍕¨0,⍳

0,⍳N        numbers 0..N
{...}∘⍕¨    format each number as a string and do the thing in curly braces
                inside the braces ⍵ is the current string
'6908'⍳⍵    encode '6' as 1, '9' as 2, '0' as 3, '8' as 4, and all others as 5
⌽           reverse
'9608x'[A]  use each element of A as an index in '9608x':
                effectively: swap '9'←→'6', preserve '08', mask other digits
⍵≡          does it match the original string?
                this is the first boolean condition, two more to come
5∊i         did we have a digit other than '0689'?
3≡⊃i        is the first of i (that is, the last of ⍵) a '0' (encoded as 3)?
∨/          disjunction ("or") over the three conditions, returns 0 or 1
'. '↓⍨      drop 0 or 1 elements from the beginning of the string '. '
⍵,          prepend ⍵
∊           flatten the results to obtain a single output string

3

C # 205 209

C # ไม่จำเป็นต้องยาว ...
มากกว่าหรือน้อยกว่าคำตอบ JavaScript ของฉัน

class P{static void Main(string[]a){for(int n=int.Parse(a[0]);n>=0;--n){string p="",u=n+p;int e=n%10;foreach(var d in u)p=(d<56?d!=54?d>48?e=0:0:9:120-d-d)+p;System.Console.WriteLine(e!=0&p!=u?u+".":u);}}}

Ungolfed

class P 
{
    static void Main(string[] a)
    {
        for (int n = int.Parse(a[0]); n >= 0; --n)
        {
            string p = "", u = n + p;
            int e = n % 10;
            foreach (var d in u) p = (d < 56 ? d != 54 ? d > 48 ? e = 0 : 0 : 9 : 120 - d - d) + p;
            System.Console.WriteLine(e != 0 & p != u ? u + "." : u);
        }
    }
}

2

ทับทิม, 81

?0.upto(*$*){|x|puts x.reverse.tr('69','96')!=x&&x=~/^[0689]+$/&&/0$/!~x ?x+?.:x}

อินพุตถูกนำมาจากบรรทัดคำสั่ง

สร้างรายการของStringS จากไป0 nมันวนซ้ำและพิมพ์ออกมา มันจะเพิ่มจุดถ้าเงื่อนไขทั้งหมดเป็นที่พอใจ:

  • ย้อนกลับจำนวนและแทนที่6ด้วย9 s จะไม่ให้ผลดั้งเดิม
  • จำนวนเท่านั้นประกอบด้วยตัวเลข0, 6,8และ9
  • ตัวเลขไม่ได้ลงท้ายด้วย 0

2

JavaScript (ES6) 101 104 106 109

ฟังก์ชั่นที่มี n เป็นอาร์กิวเมนต์, เอาต์พุตผ่าน console.log
แก้ไขโดยใช้% 10 เพื่อทดสอบการปรับโครงสร้างองค์กรชั้นนำ 0
แก้ไข 2 forฉันไม่ต้องการความเข้าใจของอาเรย์หลังจาก
แก้ไขทั้งหมด3แก้ไข (อีกครั้ง) ตรวจสอบเพื่อนำ 0

F=n=>{
   for(;e=~n;console.log(e*l&&p-n?n+'.':n),--n)
     for(d of(p='')+n)p=(l=d<8?d-6?-d?e=0:0:9:24-d-d)+p
}

Ungolfedและง่ายต่อการทดสอบ

F=n=>
{
  o = '';
  for( ; ~n; --n) // loop on n decreasing to 0 (~n is 0 when n==-1)
  {
    e = ~n; // init to a nonzero value, zero will mark 'invalid digit'
    p = ''; // build rotated number in p
    for(d of '' + n)
    {
      // l is the current digit, on exit will be the first digit of p
      l = d < 8 ?
            d != 6 ?
              d != 0 ?
                e = 0 // invalid char found, no matter what
                : 0 
              : 9 // 6 become 9
            : 24 - d - d; // calc 8 => 8, 9 => 6
      p = l + p;
    }       
    // e==0 if invalid char, l==0 if leading 0
    o += ' ' + ( e * l && p-n ? n+'.' : n);
  }
  console.log(o);
}

F(100)

เอาท์พุต

100 99. 98. 97 96 95 94 93 92 91 90 89. 88 87 86. 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 69 68. 67 66. 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9. 8 7 6. 5 4 3 2 1 0

มีชื่อสำหรับการก่อสร้างด้วย for for loop ภายในเครื่องหมายวงเล็บ[]หรือไม่? ฉันกำลังมองหาเอกสารเพราะฉันเพิ่งรู้เรื่องนี้จากหลามจนถึงตอนนี้
ข้อบกพร่อง

1
ฉันคิดว่าคุณสามารถประหยัดได้มากในบรรทัดใหม่ที่นี่
britishtea

1
@britishtea ขึ้นบรรทัดใหม่และเพิ่มการเยื้องเพื่อให้สามารถอ่านได้และไม่นับ มันเป็นบรรทัดเดียว
edc65



1

sed, 467

นานกว่า C # ...

ฉันค่อนข้างทำสิ่งนี้เสร็จสมบูรณ์เมื่อ @ edc65 ชี้ให้เห็นว่าคำตอบต้องประมวลผลตัวเลข 0-n และไม่ใช่แค่ n การเพิ่มรหัส sed เพื่อเพิ่ม 0-n เพิ่มรหัสอีกมากเนื่องจากงานนี้ไม่เหมาะกับ sed เลขคณิตน้อย

:l
/^[0689]*$/{
h
s/$/:/
:x
s/([0-9]):(.*)/:\2\1/
tx
s/://
y/69/96/
G
/^([0-9]+)\n\1/be
s/^[^0].*/&./
:e
s/.*\n//
}
p
s/\.//
s/[0-9]/<&/g
s/0//g;s/1/_/g;s/2/__/g;s/3/___/g;s/4/____/g;s/5/_____/g
s/6/______/g;s/7/_______/g;s/8/________/g;s/9/_________/g
:t
s/_</<__________/
tt
s/<//g
s/_//
:b
s/__________/</g
s/<([0-9]*)$/<0\1/
s/_________/9/;s/________/8/;s/_______/7/;s/______/6/
s/_____/5/;s/____/4/;s/___/3/;s/__/2/;s/_/1/
s/</_/g
tb
s/^$/0/
/^0$/by
bl
:y
c\
0
p

ตาม OP การสั่งซื้อไม่สำคัญดังนั้นเราจึงลดระดับลงจาก n เป็น 0

เอาท์พุท:

$ sed -rnf rotproof.sed <<< 100 | grep "\."
99.
98.
89.
86.
68.
66.
9.
6.
$ 

1

AWK: 120

{a[a[6]=9]=6;a[8]=8;for(j=a[0]=0;j<=$0;++j){r="";for(i=j;i;i=int(i/10))r=r a[i%10];print(j~/[^0689]|0$/||j==r)?j:j"."}}

อ่านค่า n จาก stdin

ทดสอบ:

C: \ AWK> gawk -f revnum.awk | grep \.
100
^ Z
6.
9.
66.
68.
86.
89.
98.
99


1

Rebol - 195

for n 0 do input 1[b: copy a: form n d: c: 0 parse reverse a[any[m:"6"(change m"9"++ c)|"9"(change m"6"++ c)|"0"|"8"| skip(++ d)]]print rejoin [b either all[d = 0 c > 0 a != b a/1 != #"0"]"."{}]]

Ungolfed + คำอธิบายประกอบบางส่วน:

for n 0 do input 1 [
    b: copy a: form n
    d: c: 0

    ; reverse number and rotate "6" & "9"
    ; and do some counts (c when "6" or "9" and d when != "0689")
    parse reverse a [
        any [
            m:
              "6" (change m "9" ++ c)
            | "9" (change m "6" ++ c)
            | "0"
            | "8"
            | skip (++ d)
        ]
    ]

    print rejoin [
        b either all [
            d = 0               ; only has 0689 digits
            c > 0               ; must have at least one "6" or "9"
            a != b              ; not same when reversed
            a/1 != #"0"         ; does not "end" with zero
        ]
        "." {}                  ; if ALL then print "." else blank {}
    ]
]

1

bc, 158

หลังจากทำสิ่งนี้อย่างหมดจดโดยใช้การดำเนินการสตริงและ regex ทั้งหมดโดยไม่มีเลขคณิตพื้นเมืองฉันอยากรู้ว่าสิ่งนี้จะมีลักษณะอื่น ๆ เช่นการดำเนินการทางคณิตศาสตร์และตรรกะทั้งหมดและไม่มีสตริง / regex:

for(i=read();i+1;r=0){p=1
for(x=i;x;x/=A){d=x%A
if(x==i&&!d)p=0
if(d==6||d==9)d=F-d else if(d%8)p=0
r=r*A+d}
if(r==i)p=0
print i--
if(p)print "."
print "\n"}

เอาต์พุตถูกเรียงลำดับจากมากไปน้อย

เอาท์พุท:

$ bc rotproof.bc <<< 100 | grep "\."
99.
98.
89.
86.
68.
66.
9.
6.
$ 

1

Python - 152

for i in range(input()+1):print`i`+("."*all([j in"0689"for j in`i`])and`i`[-1]!="0"and`i`!=`i`.replace("9","x").replace("6","9").replace("x","6")[::-1])

+1 ดูดี ... หากคุณต้องการเรียนรู้เคล็ดลับในการทำให้สั้นลงจะมีคำตอบอีกอย่างหนึ่งใน python 2 ที่ใช้การแปลแทนการแทนที่และในประวัติการแก้ไข มีประโยชน์สำหรับคำถามในอนาคต ...
trichoplax

2
ความคืบหน้าดี! นอกเหนือจากข้างต้นนี่คือบางส่วนของสนามกอล์ฟเพิ่มเติม: "."if a[i]else"" -> "."*a[i], int(raw_input()) -> input()(ซึ่งเป็นจริง ๆ เท่านั้นeval(raw_input()))
Sp3000

บาง golfes: (1) ในหลาม 2 คุณสามารถแทนที่ด้วยstr(i) `i`(2) คุณใช้aเพียงครั้งเดียวดังนั้นทำไมจึงกำหนดให้กับตัวแปร
Wrzlprmft

ฉันจะใช้คำแนะนำที่สองของคุณ แต่ฉันจะใช้str(i)หลายครั้ง ฉันจะแทนที่อันiไหนได้ด้วย
KSFT

1
ไม่ได้iแต่iกับ backticks repr(i)ซึ่งเป็นความหมายเหมือนกันไป คุณสามารถใช้มันได้str(i)ทุกที่แม้ว่าจะมีstr(i)หลายครั้งที่อาจสั้นกว่าเพื่อกำหนดให้กับตัวแปรและใช้นอกเหนือจากการใช้ backticks (เช่นx=`i`; (do stuff with x))
Sp3000

1

JavaScript - 168 129 119 113 111 108

F=n=>{for(;~n;n--){r='';for(c of""+n)r=(c-6?c-9?c:6:9)+r;console.log(r-n&&!/[1-57]/.test(r)&&n%10?n+".":n)}}

4 5 6. 8 9. 16 60 66. 68. 69 906 909. 6090 9806. 9886 9889

หรือเวอร์ชันที่อ่านได้:

F=n=>{for(;~n;n--){
    r='';for(c of ""+n)r=(c-6?c-9?c:6:9)+r; // rotate
    console.log( // output, new-line is added
        // original number, and
        // append dot only if number is different than its rotated version and no un-rotatable digit is present and there is no zero at the end
        r-n && !/[1-57]/.test(r) && n%10
           ?n+".":n
    )}}

ฉันไม่ได้มีความสุขมากกับ regex ความคิดใด ๆ

แก้ไข : เรียนรู้เคล็ดลับที่เรียบร้อยด้วย~และfor (... of ...)จาก @ edc65
Edit2 : เงื่อนไขที่จัดระเบียบใหม่
Edit3 : คำแนะนำที่ใช้โดย @ edc65


นักเรียนไม่ดี :) i=n+"";for(c of i)=> for(c of i=n+"")บันทึก 2 ไบต์
edc65

... และc==6?A:B=> c!=6=>B:A=>c-6?B:A
edc65

นอกจากนี้โดยปกติแล้ว Regexp.test (String) สามารถใช้แทน String.match (Regexp) สั้นลง 1 ไบต์
edc65

6 ไบต์เป็นผลรวมขอบคุณ :) for(c of i=n+"")ค่อนข้างสมเหตุสมผลเมื่อฉันเห็นมัน แต่ฉันจะไม่คิดถึงมัน c-6?B:Aพระเจ้าห้ามไม่ให้ฉันใส่สิ่งนี้ลงในรหัสการผลิต
zabalajka

แนวคิดเกี่ยวกับ regexp: คุณต้องตรวจสอบถ่านที่ไม่ถูกต้อง 1 ตัวไม่ใช่แร่อีก 1 อันดังนั้นไม่จำเป็นต้องใช้ '+' ถ้าคุณเล่นซอฟท์แวร์ด้วย console.log ของคุณคุณสามารถบันทึกได้ 8 ไบต์ ... แต่ฉันคิดว่าคำตอบของคุณ จะสั้นเกินไป
edc65

1

05AB1E , 38 37 30 29 ไบต์

ÝεÐSUT%ĀiŽR!XåPiÐ69‡RÊi'.«]»

ลองออนไลน์

คำอธิบาย:

Ý                # Inclusive 0-based range: [0, (implicit) input]
 ε               # Map each integer to:
  Ð              #  Triplicate the current integer
  SU             #  Convert it to a list of digits, and pop and store it in variable `X`
    Ti         #  If the current integer contains no trailing zeros
    ŽR!XåPi      #  And if the current integer only consists of the digits [0689]
    Ð69‡RÊi     #  And if the current integer is not the same when its 6s and 9s
                 #  are swapped and then the total is reversed
             '.« #   Concat a '.'
                 #  Implicit else: use the top of the stack (the duplicate current integer)
]                # Close all three ifs and the map
 »               # Join the resulting list by newlines (and output implicitly)

คำอธิบายเพิ่มเติมสำหรับบางส่วน:

Ti       # Check if the integer contains no trailing zeros:
T          #  Push 10 (T is a builtin for 10)
 %         #  Modulo
  Ā        #  Trutified: 0 remains 0 (falsey), everything else becomes 1 (truthy)
           #   i.e. 12 % 10 → 2 → 1 (truthy)
           #   i.e. 68 % 10 → 8 → 1 (truthy)
           #   i.e. 70 % 10 → 0 → 0 (falsey) (70 remains as is)
           #   i.e. 609 % 10 → 9 → 1 (truthy)
           #   i.e. 808 % 10 → 8 → 1 (truthy)

ŽR!XåPi    # Check if the integer only consists of the digits 0, 6, 8 and/or 9:
ŽR!        #  Push 6890 (Ž is a builtin for 2-char compressed integers, where R! is 6890)
   X       #  Push variable `X` (the list of digits)
    å      #  Check for each of these digits if they're in "6890"
     P     #  Take the product of that list
           #   i.e. [1,2] → [0,0] → 0 (falsey) (12 remains as is)
           #   i.e. [6,8] → [1,1] → 1 (truthy)
           #   i.e. [6,0,9] → [1,1,1] → 1 (truthy)
           #   i.e. [8,0,8] → [1,1,1] → 1 (truthy)

Ð69‡RÊi   # Check if the integer with 6s and 9s swapped and then reversed isn't unchanged:
Ð          #  Triplicate the integer
 69        #  Push 69
   Â       #  Bifurcate (short for Duplicate & Reverse)
          #  Transliterate (in `a` replace all characters `b` with characters `c`)
     R     #  Reverse
      Ê    #  Check for inequality
           #   i.e. 68 → "68" → "98" → "89" → 68 != "89" → 1 (truthy) (68 becomes "68.")
           #   i.e. 609 → "609" → "906" → "609" → 609 != "609" → 0 (falsey) (609 remains as is)
           #   i.e. 808 → "808" → "808" → "808" → 808 != "808" → 0 (falsey) (808 remains as is)


0

Powershell, 111 102 ไบต์

param($s)$s+'.'*!($s-match'[1-57]|0$|'+-join$(switch -r($s[($s.Length-1)..0]){'0|8'{$_}'6'{9}'9'{6}}))

สคริปต์ทดสอบที่อธิบาย:

$f = {

param($s)           # input string
$l=$s.Length        # length of the string
$c=$s[($l-1)..0]    # chars of the string in the reversed order
$d=switch -r($c){   # do switch with regex cases for each char
    '0|8'{$_}       # returns the current char if it equal to 8 or 0
    '6'{9}          # returns 9 if the current char is 6
    '9'{6}          # returns 6 if the current char is 9
}                   # returns array of new chars (contains 0,6,8,9 only)
$s+'.'*!(            # returns s. Add '.' if not...
    $s-match'[1-57]|0$|'+-join$d
                    # $s contains chars 1,2,3,4,5,7 or
                    # ends with 0 or
                    # equal to string of $d
)

}

@(
    ,('2'    ,'2'   )
    ,('4'    ,'4'   )
    ,('5'    ,'5'   )
    ,('6.'   ,'6'   )
    ,('7'    ,'7'   )
    ,('9.'   ,'9'   )
    ,('16'   ,'16'  )
    ,('60'   ,'60'  )
    ,('66.'  ,'66'  )
    ,('68.'  ,'68'  )
    ,('69'   ,'69'  )
    ,('906'  ,'906' )
    ,('909.' ,'909' )
    ,('8088.','8088')
    ,('9806.','9806')
    ,('9886' ,'9886')
    ,('9889.','9889')
) | % {
    $e,$s = $_
    $r = &$f $s
    "$($r-in$e): $r"
}

เอาท์พุท:

True: 2
True: 4
True: 5
True: 6.
True: 7
True: 9.
True: 16
True: 60
True: 66.
True: 68.
True: 69
True: 906
True: 909.
True: 8088.
True: 9806.
True: 9886
True: 9889.

0

Stax , 27 ไบต์

Ç▒≈♣▌╬"÷╜─B↓«âpø←╚S☼ì>♫è;&╛

เรียกใช้และแก้ไขข้อบกพร่อง

คลายกล่อง ungolfed และแสดงความคิดเห็นมันมีลักษณะเช่นนี้

0p      print 0 with no line break
F       for each [1 .. n] execute the rest of the program, where n is the input
  zP    print a newline
  q     peek and print the iterating variable without newline
  A%!C  modulo 10, and cancel iteration if zero (this cancels for multiples of 10)
  _$cc  convert iterating value to string and duplicate it twice on the stack
  7R6-$ construct the string "123457"
  |&C   if the character intersection is truthy, cancel the iteration
  r     reverse string
  69$:t map 6 and 9 characters to each other
  =C    if this rotated string is equal to the original, cancel iteration
        print "." with no newline 
        (this comment precedes the instruction because it's an unterminated literal)
  ".

เรียกใช้อันนี้

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