เครื่องหมายดอกจัน viral


9

ด้วยจำนวนเต็มบวกN ("virality") โปรแกรมของคุณควรสร้างภาพวาด ASCII-art ของต้นไม้ที่มีความยาวสองสาขาNขยายลงและ / หรือขวาจากมุมบนซ้าย

ทิศทางของแต่ละสาขาหลังจากเครื่องหมายดอกจันแรกอาจเป็นไปทางขวาหรือลงและตัวเลือกนี้ควรทำแบบสุ่ม1ในทุกขั้นตอนถัดไป

ตัวอย่างเช่นเมื่อได้รับอินพุต 5 เอาต์พุตอาจมีลักษณะดังนี้:

***
* ***
**
 **

กิ่งทั้งสองได้รับอนุญาตให้สัมผัส (อยู่ในเซลล์ที่อยู่ติดกัน) แต่ไม่ทับซ้อนกัน (อยู่ในเซลล์เดียวกัน) ดังนั้นสิ่งต่อไปนี้จะไม่ได้รับอนุญาต:

***
* *
*****
  *
  *

ตัวอย่าง

สำหรับอินพุต1เอาต์พุตที่เป็นไปได้เท่านั้นคือ:

**
*

(สิ่งนี้จะปรากฏในเอาต์พุตที่ถูกต้องทั้งหมดเนื่องจากการที่กิ่งทั้งสองใช้เส้นทางเดียวกันจะทำให้พวกมันทับซ้อนกัน)

เอาต์พุตที่เป็นไปได้สำหรับอินพุต3รวม:

***
* *
**
**
***
*
*

สำหรับอินพุต7:

****
*  **
*   **
*
***
  *

สำหรับอินพุต10:

****
*  *      
*********
  *
  *****

นี่คือ ดังนั้นคำตอบที่ถูกต้องที่สั้นที่สุด (เป็นไบต์) จะชนะ

1. สิ่งนี้ควรสุ่มอย่างสม่ำเสมอ (เช่นโอกาส 50/50 ของแต่ละทิศทาง) หรือใกล้เคียงกับการสุ่มอย่างสม่ำเสมอเท่าที่คุณจะได้รับบนฮาร์ดแวร์ปกติ


โปรดแสดงความคิดเห็นหากคุณมีปัญหาใด ๆ กับการโพสต์ที่ยาวนานของฉัน - บางทีฉันสามารถย่อบางสิ่งบางอย่าง (ฉันจะลอง)
nicael

3
เพียงแค่เรียนรู้ที่จะคาดหวังว่า บางครั้งมันก็ยุ่งเหมือนห่า บางครั้งมันเงียบเหมือนตอนนี้ อย่าลืมว่ามันเป็นวันอีสเตอร์ด้วย
Zacharý

ฉันไม่แน่ใจจริงๆว่าเกิดอะไรขึ้นกับโพสต์ของฉัน คนที่ลงคะแนนจะอธิบายอย่างนั้นได้ไหม
nicael

1
IMO Nมีการอธิบายที่ดีขึ้นเมื่อเวลา: P
ASCII-only

1
เราสามารถคืนเมทริกซ์ของ0s และ1s แทนช่องว่างและดอกจันได้หรือไม่?
dylnan

คำตอบ:


5

CJam , 58 51 ไบต์

[TT]{_2_m*\f.+{:-},mR}ri*]ee{~\)S*\{'*t}/}%::a:.+N*

ลองออนไลน์!

แนวคิดพื้นฐานคือเราเริ่มต้นด้วย[0 0]จากนั้นเพิ่ม 0 หรือ 1 ซ้ำ ๆ ในแต่ละองค์ประกอบ (ทำให้แน่ใจว่าจะไม่เท่ากันยกเว้นตอนเริ่มต้นเพื่อหลีกเลี่ยงการทับซ้อน) โดยรวบรวมผลลัพธ์ระดับกลางทั้งหมด

[[0 0] [0 1] [0 2] [0 2] [1 3]]

จากนั้นเราจะสร้างอาร์เรย์ขนาดใหญ่ที่แต่ละอาร์เรย์ย่อยมี*ดัชนีที่กำหนดโดยคู่ที่สอดคล้องกันในอาร์เรย์เดิมและช่องว่างทุกที่อื่น

["*"
 "**"
 "* *"
 "* * "
 " * * "]

สิ่งนี้ให้ผลเป็นเส้นทแยงมุมของเมทริกซ์เอาต์พุต (การเลื่อนจากซ้ายไปขวาสอดคล้องกับการเลื่อนบนขวาไปซ้ายล่างในเมทริกซ์จริง)

จากนั้นเราสามารถใช้::a:.+เพื่อ "ลดความทแยงมุม" และรับบรรทัดผลลัพธ์:

[ "**** "
  "*  *"
  "** "
  " *"
  ""     ]

3

ถ่าน , 31 24 ไบต์

F²«J⁰¦⁰F⊕θ«¿ι*↓*≔‽²ι¿KK↗

ลองออนไลน์! การเชื่อมโยงคือการใช้รหัสเวอร์ชันอย่างละเอียด เดิมทีฉันคิดว่ามันจะง่ายกว่าถ้าจะทำขั้นตอนแรกแบบสุ่ม แต่มันกลายเป็นนักกอล์ฟที่จะทำให้สาขาแรกสามารถคาดเดาได้ คำอธิบาย:

F²«

iห่วงสองครั้งใช้ตัวแปรดัชนี (สิ่งนี้ทำซ้ำในรายการโดยนัยดังนั้นจึงปลอดภัยที่จะกลายพันธุ์iภายในลูป)

J⁰¦⁰

ข้ามไปที่ต้นกำเนิดของผืนผ้าใบ

F⊕θ«

วนN+1ครั้ง

¿ι*↓*

พิมพ์แต่ปล่อยให้เคอร์เซอร์อย่างใดอย่างหนึ่งไปทางขวาหรือด้านล่างเคอร์เซอร์ขึ้นอยู่กับมูลค่าของ*i

‽²ι

สุ่มค่าของiการวนซ้ำถัดไปของลูปด้านใน

¿KK↗

ถ้าตัวละครในปัจจุบันคือ a *นี่หมายความว่าเราเป็นสาขาที่สองและเราลงไปแทนที่จะถูกต้องดังนั้นเลื่อนขึ้นไปทางขวาเพื่อแก้ไข (สาขาแรกเริ่มลงด้านล่างเสมอเพื่อให้สาขาที่สองอยู่เหนือซึ่งหมายความว่าเราจะต้องตรวจสอบการชนในแนวดิ่งเท่านั้น)


มันเป็นเรื่องที่ถูกต้องเกือบอย่างไรก็ตามมันไม่ได้พิมพ์Nสาขา -sized แต่N-1ขนาด :)
nicael

@nicael ขออภัยแก้ไขแล้ว
Neil

คุณอาจเคยเห็นมาแล้วหลายครั้ง แต่: 23 ไบต์
ASCII เท่านั้น

3

Java 10, 273 272 268 239 ไบต์

n->{var c=new char[++n][n];for(var d:c)java.util.Arrays.fill(d,' ');for(int i=0,j=0,k=0,l=0,r=0,s=0,t=0,u=0;n-->0;){c[i+=r][j+=s]=c[k+=t][l+=u]=42;do{r=t=2;r*=Math.random();t*=Math.random();s=r^1;u=t^1;}while(i+r==k+t&j+s==l+u);}return c;}

ลองออนไลน์ได้ที่นี่

ขอบคุณKevin Cruijssenสำหรับการเล่นกอล์ฟ 29 ไบต์

เวอร์ชันที่ไม่ถูกปรับแต่ง:

n -> { // lambda taking an int as argument
    var c = new char[++n][n]; // the output; increment the virality since the root does not count
    for(var d : c) // for every line
        java.util.Arrays.fill(d,' '); // initialize it with spaces
    for(int i = 0, j = 0, // coordinates of the first branch
            k = 0, l = 0, // coordinates of the second branch
            r = 0, s = 0, // offsets for the first branch, one will be 0 and the other 1 always except for the first '*' where the two branches overlap
            t = 0, u = 0; // offsets for the second branch, one will be 0 and the other 1 always except for the first '*' where the two branches overlap
        n-- > 0; ) { // decrement virality and repeat as many times
        c[i+=r][j+=s] = c[k+=t][l+=u] = 42; // move according to offsets and place an '*' for each branch, 42 is ASCII code
        do { // randomly pick offsets for both branches
            r = t = 2; // Math.random() provides results in [0,1)
            r *= Math.random(); // flip a coin for the first branch
            t *= Math.random(); // flip another coin for the second
            s = r^1; // set s to 0 if r=1, to 1 if r=0
            u = t^1; // set u to 0 if t=1, to 1 if t=0
        } while(i+r==k+t&j+s==l+u); // repeat if the branches overlap
    }
    return c; // return the output
}

239 ไบต์ (ฉันเพิ่งเปลี่ยนสิ่งต่าง ๆ ภายในdo{}เล็กน้อย (และวาง ints ไว้ในส่วนแรกของ for-loop) PS: ในคำตอบเริ่มต้นของคุณคุณ0.5สามารถเล่นกอล์ฟได้.5เช่นกัน
Kevin Cruijssen

@KevinCruijssen ดูเหมือนว่าฉันต้องทำงานกับคณิตศาสตร์ของฉัน ขอบคุณ :-)
OOBalance

3

Perl 5 , 208 124 122 118 ไบต์

118 ไบต์โดยไม่มีบรรทัดใหม่การเยื้องและความคิดเห็น รับNจาก stdin:

@b=1..2;                            #number of branches is 2
for(1..<>){                         #add length <> (the input) to each branch
  ($x,$y)=@$_                       #get where current branch has its tip now
 ,.5>rand?$x++:$y++                 #increase either x or y
 ,$o[$y][$x]++&&redo                #try again if that place is already occupied
 ,$_=[$x,$y]                        #register new tip of current branch
   for@b                            #...and do all that for each branch 
}
say map$_||!$i++?'*':$",@$_ for@o;  #output the branches

ลองออนไลน์!


ดี แต่มันพิมพ์สาขา 1 ดอกจันสั้นกว่าที่ควรจะเป็น :)
nicael

โปรดดูตัวอย่างในคำถามของฉันอีกครั้ง :)
nicael

โอ้ตอนนี้ฉันได้เปลี่ยน2..$Nไป1..shiftแล้วและได้ตัดออกไปสองสามไบต์
Kjetil S.

1
คำตอบที่ดี! คุณสามารถบันทึกไม่กี่ไบต์โดยใช้<>และป้อนข้อมูลแทนshiftและขัดแย้งเช่นเดียวกับการสั่งซื้อซ้ำอีกครั้งที่คุณโทรหาrandเพื่อหลีกเลี่ยงการล้อเลียน คุณไม่ควรจะต้องตัดการมอบหมายของคุณไป@oอย่างใดอย่างหนึ่ง ฉันลองใช้@b=([],[]);ซึ่งดูเหมือนว่าจะใช้งานได้ แต่ฉันไม่ได้ทดลองมากเกินไปดังนั้นฉันอาจพลาดกรณีที่มี หวังว่าพวกเขาช่วยนิดหน่อย!
Dom Hastings

1
เคล็ดลับสำหรับการเล่นกอล์ฟในหน้า Perlมีคำแนะนำที่ดีบางอย่างให้แน่ใจว่าได้ตรวจสอบออก! ขอให้โชคดีและสนุก!
Dom Hastings



1

PHP, 118 ไบต์

for($r="*",$w=$argn+2;$argn--;$r[$q+=rand(0,$r[$q+1]<"*")?:$w]=$r)$r[$p+=rand(!$i++,1)?:$w]=$r;echo wordwrap($r,$w-1);

ต้องการ PHP 5.4 หรือใหม่กว่าสำหรับผู้ดำเนินการ Elvis แทนที่?:ด้วย?1:สำหรับ PHP รุ่นเก่า

ทำงานเป็นท่อที่มี-nRหรือลองออนไลน์


1
ฉันจะตรวจสอบด้วยอินพุตที่ต่างกันได้อย่างไร
nicael

@nicael: คุณสามารถเปลี่ยนการโต้แย้งในบรรทัด$argBak=$argn=
Galen Ivanov

ตกลง! ไม่แน่ใจว่านี่เป็นวิธีที่ดีหรือไม่ "ยอมรับ" การป้อนข้อมูลด้วยวิธีนี้ แต่ให้ชุมชนตัดสินใจด้วยการลงคะแนน
nicael

@nicael $argnในติ้วเพียงแค่เปลี่ยนค่าสำหรับ ในสภาพแวดล้อมที่แท้จริง$argnมาจาก STDIN -Rถ้าคุณเรียกใช้เป็นท่อด้วย จากนั้นจะรันรหัสสำหรับแต่ละบรรทัดของการป้อนข้อมูล (แต่ฉันค่อนข้างแน่ใจว่า PHP ไม่ได้ตั้งค่าตัวแปรในระหว่างนั้นดังนั้นการรันที่ต่อเนื่องกันอย่างชัดเจนมีแนวโน้มที่จะหลีกเลี่ยงความประหลาดใจที่ไม่ดี)
Titus

0

สีแดง , 195 190 ไบต์

func[n][g: func[s][i: 0 d: s while[i < n][b/(d): #"*"until[r: 1 if 1 = random 2[r: n + 1]b/(d + r) =#" "]d: d + r
i: i + 1]]b:""loop n[loop n[append b" "]append b"^/"]b/1: #"*"g n + 2 g 2 b]

ลองออนไลน์!

อ่านได้:

f: func[n][
    g: func[s][
        i: 0
        d: s
        while[i < n][
            b/(d): #"*"
            until[
                r: 1 if 1 = random 2[r: n + 1]
                b/(d + r) = #" "
            ]
            d: d + r
            i: i + 1
        ]
    ]
    b: ""
    loop n[loop n[append b " "]append b "^/"]
    b/1: #"*"
    g n + 2
    g 2
    b
]

0

เจลลี่ , 50 43 41 ไบต์

2ḶẊ⁸С+\‘Ṗ
⁸ÇU;Ǥ⁻Q$¿
‘,þ`⁼€þÇS+»þ`Ị$ị⁾* 

ลองออนไลน์!

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

หลังจากที่ผมโพสต์นี้ฉันรู้ว่าฉันสามารถใช้แทน,þ`aþ,""oþ`Ɗ


0

R , 148 142 ไบต์

n=scan();`~`=sample;o=r=k=1;l=c(1,n);for(i in 1:n){r=r+l~1;t=l~1;k=k+"if"(k+t-r,t,l[l!=t]);o=c(o,r,k)};write(c(" ","*")[1:n^2%in%o+1],1,n,,"")

ลองออนไลน์!

นอกจากนี้แม้ว่าจะไม่ตรงตามข้อกำหนดของเอาต์พุต แต่คุณสามารถแยกความแตกต่างระหว่างสองสาขา: ลองออนไลน์!

คำอธิบาย:

เริ่มต้นจากดัชนี1เราสุ่มเลือกย้ายขวาหรือซ้ายสำหรับสาขาrโดยการเพิ่มnหรือ1ตามลำดับ จากนั้นเราเลือกการย้ายขวาหรือซ้ายอีกสาขาkและถ้ามันจะตัดกันว่าrจะไปไหนเราจะเลือกทิศทางอื่น จากนั้นเราจะใช้rและkเป็นดัชนีเข้าสู่การตั้งค่าเหล่านั้นเป็นm "*"ทำซ้ำn-1ครั้งแล้วเราพิมพ์ผล


0

เจลลี่ , 39 38 ไบต์

ḣ2+\€Ẏ
2Rd¤ṗẊÇ⁻Q$$¿Ç0,0ṭ‘Ṭ€×þ/$€Sị⁾* Y

ลองออนไลน์!

แม้ว่าจะดูเหมือนไม่เกี่ยวข้อง แต่dก็มีประโยชน์ที่นี่เพื่อบันทึกไบต์ (มากกว่าวิธีก่อนหน้าของฉัน)


0

Python 2 , 191 187 176 ไบต์

from random import*
n=input()
p,q=c=1,1j;s={p,q,0}
exec'z=choice(c);q,p=p+[z,1+1j-z][p+z in s],q;s|={q};'*2*~-n
R=range(n+1)
for y in R:print''.join(' *'[y+x*1jin s]for x in R)

ลองออนไลน์!

งูหลามมีการสนับสนุนพื้นเมืองสำหรับตัวเลขที่ซับซ้อนของรูปแบบa+bj; สิ่งนี้ทำให้เกิดปัญหา 2 มิติบางอย่างที่สามารถจัดการได้ง่ายขึ้น ...

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