พิมพ์ชุดคันทอร์


19

ความท้าทาย

สร้าง N-เลื่อนระดับต้นเสียงชุด

ชุดที่ประกอบไปด้วยคันทอร์ถูกสร้างขึ้นโดยการลบกลางเปิดที่สามของชุดของส่วนบรรทัด

โปรแกรมได้รับหนึ่งพารามิเตอร์N(ตัวเลขจำนวนเต็ม) จากนั้นพิมพ์ (ในคอนโซลหรือในลักษณะที่คล้ายกัน) ชุดคันทอร์ของระดับ N การพิมพ์สามารถมี_ตัวอักษรundescore ( ) และ whithe ช่องว่างเท่านั้น พารามิเตอร์สามารถเป็นบวกหรือลบและเครื่องหมายบ่งชี้ทิศทางการก่อสร้างชุดคันทอร์: หากN > 0ชุดคันทอร์ถูกสร้างขึ้นด้านล่างและหากN < 0ชุดคันทอร์ถูกสร้างขึ้น ถ้าN = 0โปรแกรมนั้นพิมพ์บรรทัดเดียว ( _)

ตัวอย่างเช่น:

N = 2

_________
___   ___
_ _   _ _

N = -2

_ _   _ _
___   ___
_________

N = 3

___________________________
_________         _________
___   ___         ___   ___
_ _   _ _         _ _   _ _

N = -3

_ _   _ _         _ _   _ _
___   ___         ___   ___
_________         _________
___________________________

เกณฑ์การชนะ

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

แก้ไข: แก้ไข 0 อินพุตโดยคำแนะนำของ ugoren


ทำไมไม่มีอะไรพิมพ์เมื่อ N = 0 สิ่งนี้ทำให้เป็นกรณีพิเศษ 0 และทำให้ยากต่อการใช้การเรียกซ้ำ การจัดการทั่วไปคือการพิมพ์ครั้งเดียว_(แต่พิมพ์ลงเมื่อรับ -0)
ugoren

ขวา. ฉันได้แก้ไขรายละเอียดแล้ว
Averroes

คำตอบ:


10

GolfScript, 49 42 40 ตัวอักษร

~.abs.3\?'_'*\{.3%..,' '*\++}*](0>2*(%n*

ด้วยต้องขอบคุณhammarสำหรับ 42-> 40

ความพยายามที่ดีที่สุดของฉันเมื่อใช้วิธีการทางทฤษฎีมากกว่าจำนวนมากยิ่งขึ้นไปอีก:

~.abs:^3\?,{3^)?+3base(;1+1?.'_'*^@-)' '*+}%zip\0>2*(%n*

หรือ

~.abs 3\?:^,{6^*+3base.1+1?.('_'*@,@-' '*+}%zip\0>2*(%n*

และฉันสงสัยว่าความยาวของมันbaseและzipจะทำให้มันเป็นไปไม่ได้ที่จะตามทัน


~.abs.@/\.3\?'_'*\{.3%..,' '*\++}*](%n*39 ตัวอักษร 0แต่เกิดความผิดพลาดในการป้อนข้อมูล :-(
Ilmari Karonen

@IlmariKaronen ใช่หารด้วยศูนย์อาการปวดสำหรับการดำเนินงาน C ที่ผมเขียนเกินไปเพราะมันหมายความว่าคุณไม่สามารถทำที่จะได้รับn/abs(n) signum(n)
ปีเตอร์เทย์เลอร์

6

Python 116 113 104 103 ตัวอักษร

n=input()
d=n>0 or-1
for i in range(n*d+1)[::d]:
 s='_'*3**i
 while i<n*d:s+=len(s)*' '+s;i+=1
 print s

อัลกอริทึมที่เก่ากว่ามีจำนวนอักขระสูงสุด 113 ตัว

r=input()
u='_'
l=[u]
for _ in abs(r)*u:o=len(l[0]);l=[s+o*' '+s for s in l]+[u*o*3]
print'\n'.join(l[::r>0 or-1])

5

ทับทิม (97)

อ้างอิงจากเวอร์ชั่น Python ของ Steven Rumbalski:

n,r=$*[0].to_i,[?_]
n.abs.times{z=r[0].size;r=r.map{|s|s+' '*z+s}+[?_*z*3]}
puts n<0?r:r.reverse

ความพยายามก่อนหน้าทั้งความยาวเท่ากัน (112)

สร้างเส้นจากชิ้นส่วน:

c=->x,n{n<1??_*x :(z=c[s=x/3,n-1])+' '*s+z}
r=(0..m=(n=$*[0].to_i).abs).map{|i|c[3**m,i]}
puts n<0?r.reverse: r

เริ่มต้นด้วยหนึ่งบรรทัดทำหลุมใน:

r=[?_*3**a=(n=$*[0].to_i).abs]
a.times{|c|r<<r[-1].gsub((x=?_*o=3**(a-c-1))*3,x+' '*o+x)}
puts n<0?r.reverse: r

3

Perl, 93 ตัวอักษร

@x=($t=$x=_ x 3**($a=abs($n=<>)),map$x.=$"x($x=~s/(.)../$1/g).$x,1..$a);say for$n<0?sort@x:@x

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


2

เสียงกระเพื่อมสามัญ217 210 ตัว

(defun m(x)(flet((c(n v)(if(= n 0)`((,v))(cons(substitute v nil(make-list(expt 3 n)))(mapcar #'append(c(1- n)v)(c(1- n)" ")(c(1- n)v))))))(format t "~{~{~a~}~%~}"(let((r(c(abs x)'_)))(if(< x 1)(reverse r)r)))))

ขยาย:

(defun m(x)
  (flet((c(n v)
    (if(= n 0)
       `((,v))
       (cons(substitute v nil(make-list(expt 3 n)))
            (mapcar #'append
                    (c(1- n)v)
                    (c(1- n)" ")
                    (c(1- n)v))))))
   (format t "~{~{~a~}~%~}"(let((r(c(abs x)'_)))(if(< x 1)(reverse r)r)))))

ฉันคิดว่ารหัส LISP สามารถจัดการกับการนับจำนวนเริ่มต้นสำหรับภาษาอื่น (C, 219) ฉันตกลงแล้ว :)


2

C ( 163 161 ตัวอักษร)

i,l,N;f(n,m,s){if(n){s=--n<l?m:s;f(n,m,s);f(n,s,s);f(n,m,s);}else
putchar(m);}main(n,v)int**v;{for(i=N=abs(n=atoi(1[v]));i+1;i--)l=n<N?N-i:i,f(N,95,32),f(0,10);}

ยืมอุบายสองสามอย่างจากคำตอบของ ugorenแต่ตรรกะหลักแตกต่างกันมาก ฉันไม่สามารถติดตามลูปของเขาได้ดังนั้นอาจเป็นไปได้ที่จะผสมและบันทึกอีกสองสามข้อ


2

C, 219 193 179 143 136 131 ตัวอักษร

ติดตามความคิดเห็นของ Petyer Taylor อีกครั้งรวมถึงการปรับปรุงของฉันเองช่วยอีก 6 คน
บูรณาการเคล็ดลับบางอย่างจาก @PeterTaylor รวมทั้งคัดลอกฟังก์ชั่นหลักของเขาด้วยการเปลี่ยนแปลงเล็กน้อยซึ่งบันทึกตัวละคร (มันยุติธรรมที่จะคัดลอกหรือไม่เนื่องจากพวกเราทั้งคู่ไม่ได้รับรางวัลนี้ฉันคิดว่ามันไม่เลวร้ายเกินไป)
ฉันคิดว่าการปรับปรุงที่สำคัญในการทำงานของการเรียกคืนของฉันและหลังจากเห็นคำตอบของ Peter Taylor ฉันได้ใช้มันเพื่อนำกลับคืนมา เมื่ออ่านคำตอบของเขาอีกครั้งฉันเห็นว่าฉันทำสิ่งที่เขาทำ ดังนั้นนี่จึงเป็นเหมือนไฮบริดที่เขาแนะนำ
ลดความซับซ้อนของลูปในmainทำให้ความยาวเท่ากัน
และใช้เคล็ดลับของปีเตอร์ในการพิมพ์บรรทัดใหม่แทนputs("")- บันทึกอักขระ

ลบออกintจากการประกาศตัวแปร - คำเตือน แต่บันทึก 4 ตัวอักษร
อัลกอริทึมใหม่ไม่คำนวณล่วงหน้า 3 ^ x แต่ใช้การวนซ้ำครั้งเดียวเพื่อพิมพ์อักขระ 3 ^ x
สามารถประหยัดได้อีกหนึ่งโดยการกำหนดint*vแต่ 64 บิตจะไม่ทำงาน
จำนวนตัวอักษรไม่รวมช่องว่าง (ซึ่งสามารถลบออกได้)

o,i,n;
p(c) {
    n-- ?
        p(c),p(o>n?c:32),p(c)
    :
        putchar(c);
    n++;
}
main(c,v)int**v; {
    for(n=abs(c=atoi(v[1]));i<=n;i++)o=c+n?n-i:i,p(95),puts("");
}

อัลกอริทึมรุ่นเก่า, 219 ตัวอักษร:

p(l,o,i,m,c,j) {
    for(;i<(m=l);i++)
        for(j=0,c=95;m/o||!putchar(c);j++)
            i/m%3-1||(c=32),m/=3;
    puts("");
}
main(c,v,n,i,l,o)int**v;{
    (n=atoi(v[1]))<0?n=-n:(c=0);
    for(i=n,l=1;i;i--)l*=3;
    o=c?1:l;
    for (;i<=n;i++)p(l,o,0),c?o*=3:(o/=3);
}

@PeterTaylor ฉันไม่สามารถลบพารามิเตอร์เพราะใช้ทั่วโลกจะยุ่งเกี่ยวกับi จะยุ่งเกี่ยวกับและฉันจะต้องแทนที่ด้วย(ดังนั้นทำไมฉันเขียนมันราวกับว่ามันเป็นสิ่งที่ไม่ดี?) ฉันสามารถคัดลอกคุณซึ่งง่ายกว่าและสั้นกว่าของฉัน mainl--o>=l>main
ugoren

@ PeterTaylor คุณพูดถูกi- ฉันพลาดความจริงที่ว่าฉันไม่ได้ใช้งานอีกต่อไป (ฉันคิดว่าคุณหมายความว่าฉันไม่ผ่านมัน)
ugoren

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

@ PeterTaylor ฉันคิดว่าเราถึงจุดจบ pตอนนี้ดูเหมือนว่าฉันจะดีที่สุดแล้วและคุณmainก็ดีขึ้น (ฉันไม่แน่ใจว่ามันดีที่สุด แต่ไม่สามารถปรับปรุงเพิ่มเติมได้อีก) ดังนั้นสำหรับโครงสร้างโปรแกรมใหม่ที่ชาญฉลาดวิธีเดียวที่จะไปคือเราคนใดคนหนึ่งกำลังคัดลอกโค้ดของอีกฝ่าย
ugoren

BTW คุณนับตัวละครของคุณอย่างไร? เพราะฉันทำรุ่นล่าสุดของคุณ 138 ตัวอักษรไม่ใช่ 136
Peter Taylor

2

J, 44 39 38 37 ไบต์

' _'{~0&>_&(]|.)(,:1)1&(,],.0&*,.])~|

ใช้การวนซ้ำเพื่อสร้างชุดถัดไปที่เริ่มต้นด้วย 1 (แทน_) ในขั้นต้น

การใช้

   f =: ' _'{~0&>_&(]|.)(,:1)1&(,],.0&*,.])~|
   f 0
_
   f 1
___
_ _
   f _1
_ _
___
   f 2
_________
___   ___
_ _   _ _
   f _2
_ _   _ _
___   ___
_________
   f 3
___________________________
_________         _________
___   ___         ___   ___
_ _   _ _         _ _   _ _
   f _3
_ _   _ _         _ _   _ _
___   ___         ___   ___
_________         _________
___________________________

คำอธิบาย

' _'{~0&>_&(]|.)(,:1)1&(,],.0&*,.])~|  Input: integer n
                                    |  Absolute value of n
                (,:1)                  The array [1]
                     1&(          )~   Repeat abs(n) times starting with x = [1]
                                 ]       Identity function, gets x
                            0&*          Multiply x by 0
                               ,.        Join the rows together
                         ]               Identity function, gets x
                          ,.             Join the rows together
                     1  ,                Prepend a row of 1's and return
      0&>                              Test if n is negative, 1 if true else 0
         _&(   )                       If n is negative
             |.                          Reverse the previous result
            ]                            Return that
                                       Else pass the previous result unmodified
' _'                                   The string ' _'
    {~                                 Select from the string using the result
                                       as indices and return

ดี! ฉันไม่ได้ลองเป็นการส่วนตัว แต่ฉันชอบใช้ระเบียบวาระการประชุม - @.บางทีมัน$:อาจจะรวมกับบางอย่างอาจใช้ที่นี่บ้าง เช่นสิ่งที่ต้องการหรือแม้กระทั่งอาจจะ(zero case)`(positive case)`(negative case)@.* ":@_:`(positive case)`(|."1@$:)@.*
Conor O'Brien

ฉันไม่ได้พยายามแก้ปัญหาแบบเรียกซ้ำ แต่ก็ลองได้
ไมล์

2

R , 141 139 137 137 ไบต์

m=abs(n<-scan());write("if"(n<m,rev,c)(c(" ","_")[Reduce(`%x%`,rep(list(matrix(c(1,1,1,1,0,1),3)),m),t(1))[,1+2^m-2^(m:0)]+1]),1,3^m,,"")

ลองออนไลน์!

-15 ไบต์ขอบคุณเช่นกัน Giuseppe ใช้'('เป็นฟังก์ชันตัวตน; writeแทนที่จะcatพิมพ์ออก; %x%ฉลาดใช้

-2 ไบต์ขอบคุณ Kirill L. โดยใช้cแทน'('ฟังก์ชันตัวตน


ผลิตภัณฑ์ Kronecker สามารถทำงานที่นี่ได้หรือไม่ %x%? อาจจะมีบางประเด็นที่มีการสลับแถวบางที ...
จูเซปเป้

@Giuseppe ฉันลองสร้างคำตอบ "สร้าง" H "ของคุณจากคำตอบ" H "ขนาดเล็ก ... ฉันจะลองอีกครั้ง
JayCe

อาคุณเป็นคนที่โหวตว่า นั่นเป็นเหตุผลเดียวที่ฉันคิดkronเช่นกัน! ฉันคิดว่ามันน่าจะลงไปถึง 125 ไบต์ได้ถ้าเราหาวิธีที่ถูกต้อง
Giuseppe

คุณสามารถใช้`(`เป็นฟังก์ชันข้อมูลประจำตัวเพื่อให้คุณสามารถใช้writeโดยตรงแทนcatและforวนซ้ำ 141 bytes
Giuseppe

@iuseppe ฉันไม่มีความคิดเลยที่(จะใช้วิธีนี้หรือif อาจใช้เพื่อเลือกจากสองฟังก์ชั่น และฉันจะเริ่มต้นใช้การเขียน ... บันทึกจำนวนมาก "\ n"
JayCe

1

Python, 177 164 ตัวอักษร

N=input()
n=abs(N)
c=lambda x:0if x<1 else x%3==1or c(x/3)
r=["".join([["_"," "][c(x/3**i)]for x in range(3**n)])for i in range(n+1)]
print"\n".join(r[::N>0 or-1])

เนื่องจากคุณกำลังใช้งูหลาม 2 คุณไม่จำเป็นที่จะโยนผลของการเป็นinput intสองบรรทัดสุดท้ายของคุณอาจถูกตัดให้สั้นลงprint"\n".join(r[::N>0 or-1])
Steven Rumbalski

@Steven ฉันทำการเปลี่ยนแปลง ขอขอบคุณ.
Ante

1

Perl, 113 ตัวอักษร

$i=abs($I=<>);@w=$_='_'x3**$i;while($i--){$x=3**$i;s/(__){$x}/'_'x$x.' 'x$x/eg;push@w,$_}say for$I>0?reverse@w:@w

ขยาย:

$i=abs($I=<>);
@w=$_='_'x3**$i;
while($i--){
    $x=3**$i;
    s/(__){$x}/'_'x$x.' 'x$x/eg;
    push@w,$_
}
say for$I>0?reverse@w:@w

1

จาวาสคริปต์ 121 ไบต์

ฟังก์ชั่นเรียกซ้ำภายในจากนั้นดูแลเอาต์พุตย้อนหลังหากจำเป็น

n=>(f=(n,t=n&&f(n-1),r=t[0])=>n?[r+r+r,...t.map(x=>x+t[n]+x)]:['_',' '],f=f(n<0?-n:n),f.pop(),n<0?f.reverse():f).join`\n`

น้อย golfed

n=>{
  var f = n => { // recursive function
    var t = n && f(n-1), r = t[0]
    return n 
      ? [r+r+r, ...t.map(x => x+t[n]+x)]
      : ['_',' ']
  };
  f = f(n < 0 ? -n : n);
  f.pop(); // last row is all blanks
  if (n<0) f.reverse();
  return f.join`\n`
}

ทดสอบ

var F=
n=>(f=(n,t=n&&f(n-1),r=t[0])=>n?[r+r+r,...t.map(x=>x+t[n]+x)]:['_',' '],f=f(n<0?-n:n),f.pop(),n<0?f.reverse():f).join`\n`

function go()
{
  var n=+I.value
  O.textContent = F(n)
}

go()
<input id=I type=number value=3 oninput='go()'>
<pre id=O></pre>


1

แบตช์, 265 262 242 236 235 ไบต์

@echo off
set/pn=
set c=%n%,-1,0
if %n% lss 0 set c=0,1,%n:-=%
for /l %%i in (%c%)do call:l %%i
exit/b
:l
set s=_
for /l %%j in (1,1,%n:-=%)do call:m %1 %%j
echo %s%
:m
set t=%s%
if %1 lss +%2 set t=%s:_= %
set s=%s%%t%%s%

แก้ไข: บันทึกแล้ว12 19 ไบต์ขอบคุณ @ l4m2 บันทึก 8 ไบต์ด้วยการลบ%a%ตัวแปรที่ไม่จำเป็นออก


สิ่งนี้มีขนาด 247 ไบต์
Conor O'Brien

@ ConorO'Brien ลองคิดดูว่ามันจะเป็น 261 ถ้าฉันนับ CRs ทั้งหมดรวมถึง LFs (ซึ่งฉันแน่ใจว่าคุณไม่จำเป็นต้องทำ แต่ฉันขี้เกียจแบบนี้)
Neil

ดังนั้นคุณไม่ได้ลบ CR จากรหัสของคุณใช่ไหม แม้ว่าจะไม่จำเป็นต้องใช้ไฟล์. BAT และถูกปล้นโดย SE แต่อย่างใด : P
Conor O'Brien

@ ConorO'Brien มันเป็นโทษที่ฉันยอมรับว่าใช้ Notepad เพื่อเขียนไฟล์แบตช์
Neil

คุณสามารถทำอะไรได้set c=%n%,-1,0 [LF] if %n% lss 0 set c=0,1,%a% [LF] for /l %%i in (%c%)do call:l %%iบ้าง
l4m2




0

PowerShellขนาด 111 ไบต์

filter f{if($s=[math]::Sign($_)){($x=$_-$s|f|%{$_+' '*($l=$_|% Le*)+$_})|?{$s-1};'_'*3*$l;$x|?{$s+1}}else{'_'}}

ลองออนไลน์!

หักกอล์ฟ:

filter f{
    if($sign=[math]::Sign($_)){
        $x=$_-$sign|f|%{
            $_+' '*($length=$_|% Length)+$_
        }
        $x|?{$sign-1}  # output $x if $_ is negative
        '_'*3*$length
        $x|?{$sign+1}  # output $x if $_ is positive
    }
    else{
        '_'
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.