पिरामिड स्कीम कोड जनरेट करें


32

पिरामिड स्कीम @ ConorO'Brien द्वारा विकसित की जा रही भाषा है । पिरामिड योजना में, आपके द्वारा लिखा गया कोड इस तरह दिखता है:

      ^         ^
     / \       /3\
    /   \      ---
   /  +  \
  ^-------^
 /9\     /3\
/123\    ---
-----

अब, उस कोड के दो स्पष्ट गुण हैं: पार्स करना मुश्किल है, और लिखना मुश्किल है। कॉनर ने पहले वाले को हल कर लिया है, हालांकि उस दूसरे मुद्दे को हल करना आपका काम होगा।


उपरोक्त कोड इस तरह से एक नेस्टर्ड स्ट्रिंग सरणी में पिरामिडसिमेह दुभाषिया द्वारा संसाधित किया जाता है:

[["+", ["9123", "3"]], "3"]

आपका कार्य एक प्रोग्राम या फ़ंक्शन लिखना है, जिसने स्ट्रिंग, आउटपुट या फिर से बनाए गए PyramidSchemes कोड का नेस्टेड सरणी दिया गया है। आप मान सकते हैं कि इनपुट सरणी हमेशा मान्य होगी।

एक पिरामिड एक समद्विबाहु त्रिभुज है। शीर्ष है ^, पक्ष तिरछे ढलान के साथ दूर /और \, और नीचे है -। दो निचले कोने या तो खाली हैं या उनमें अन्य पिरामिडों की शुरुआत है, जो तर्क हैं। लाइन के टूटने को अनदेखा करते हुए बीच को पिरामिड के नाम से भरा गया है।

यहां बताया गया है कि कैसे पार्सर कोड को एक प्रयोग करने योग्य प्रारूप में परिवर्तित करता है। सबसे पहले, यह एक शीर्ष-स्तरीय पिरामिड के लिए स्कैन करता है। यदि यह कोई तर्क नहीं लेता है, तो यह एक स्ट्रिंग के साथ इसका प्रतिनिधित्व करता है और आगे बढ़ता है। अन्यथा, यह एक सरणी के रूप में ["name",[arg1,arg2]]या का प्रतिनिधित्व करता है ["name",[arg1]]। तर्क पिरामिड के निचले बाएँ और नीचे दाईं ओर पिरामिड हैं, जो ऊपर वर्णित स्ट्रिंग या अधिक सरणियाँ हो सकते हैं। आप देख सकते हैं कि यह कुछ हद तक लिस्प से मिलता-जुलता है, जिस स्थिति में आपने भाषा के नाम का भयानक वाक्य भी देखा होगा। पिरामिड का पूरी तरह से प्रतिनिधित्व करने के बाद, पार्सर अगले एक पर चला जाता है।

यह , सबसे छोटा कोड जीतता है!

परीक्षण मामले: ये केवल मान्य आउटपुट नहीं हैं, ये मान्य आउटपुट का उदाहरण हैं।

[["+", ["9123", "3"]], "3"]

      ^         ^
     / \       /3\
    /   \      ---
   /  +  \
  ^-------^
 /9\     /3\
/123\    ---
-----

[["out", [["chr", ["72"]], ["chr", ["101"]]]], ["out", [["chr", ["108"]]]], ["out", [["chr", ["108"]]]], ["out", [["chr", ["111"]]]]]

        ^      ^     ^     ^
       / \    / \   / \   / \
      /out\  /out\ /out\ /out\
     ^-----^ -----^----- -----^
    / \   / \    / \         / \
   /chr\ /chr\  /chr\       /chr\
  ^----- -----^ -----^     ^-----
 / \         / \    / \   / \
/72 \       /101\  /108\ /111\
-----       -----  ----- -----

[ ["+", [ ["asdfghjkl"], ["do", [ "1" ]] ]] ]

       ^
      / \
     / + \
    /     \
   ^-------^
  /a\     /d\
 /sdf\   /o  \
/ghjkl\ ^-----
-------/1\
       ---

दूसरे परीक्षण मामले में सूचना, दूसरे और तीसरे outपिरामिड में दोनों ["chr", ["108"]]एक पैरामीटर के रूप में होते हैं, जो दो शीर्ष-स्तरीय लोगों द्वारा साझा किए गए एक पिरामिड स्टैक में ढह जाता है। यह एक वैध अनुकूलन है जो आपका कोड समर्थन कर सकता है, लेकिन यह पूरी तरह से वैकल्पिक है; स्कोरिंग आपके आउटपुट की लंबाई पर आधारित नहीं है।

जिज्ञासु के लिए, पहला मामला 9126 3टॉपलैव पिरामिड, दूसरे एक प्रिंट की अंतर्निहित छपाई के कारण प्रदर्शित होता है Hello, और अंतिम एक वाक्यविन्यास त्रुटि है, इसमें सिर्फ इसलिए शामिल है क्योंकि इसमें एक साफ संरचना है।


आप मान सकते हैं कि इनपुट केवल प्रिंट योग्य ASCII, को छोड़कर रिक्त स्थान, शामिल हैं ^, /, \, और -। इनपुट हमेशा मान्य होगा, और कम से कम एक पिरामिड शामिल होगा। सरणी या इनपुट स्ट्रिंग्स के आकार की कोई सीमा नहीं है, हालांकि आप अपना कोड लिख सकते हैं जैसे कि आपकी भाषा का डिफ़ॉल्ट पूर्णांक प्रकार अनंत सटीक था और आपके कंप्यूटर की मनमानी स्मृति है। यदि एकल स्ट्रिंग के रूप में इनपुट लेते हैं, तो आप कुछ भी उचित (अल्पविराम, स्थान इत्यादि) का उपयोग कर सकते हैं, जब तक कि यह प्रिंट करने योग्य एएससीआई और नहीं "या नहीं []) को सीमांकित करने के लिए हो। आपको पूरी चीज़ के चारों ओर कोष्ठक शामिल करने की आवश्यकता नहीं है, और इसके बजाय अपने सीमांकक द्वारा अलग किए गए कई सरणियों को लें।

आपके आउटपुट को गोल्फ होने की ज़रूरत नहीं है, आप अतिरिक्त स्थान डाल सकते हैं या अपने पिरामिड को आवश्यकता से अधिक बड़ा बना सकते हैं। टॉपलेवल पिरामिड पहली पंक्ति में होना चाहिए । आउटपुट न्यूलाइन्स या स्ट्रिंग्स की सूची के साथ एक स्ट्रिंग होना चाहिए।

जो कोई भी अपने कोड के एक संस्करण को शामिल करता है जो कि पिरामिड को आसानी से गोल्फ देता है उसे अपवोट्स / बाउंटी (लेकिन शायद सिर्फ अपवोट्स) के रूप में कुछ प्रतिनिधि मिल सकता है।


8
Sierpinski को यह भाषा पसंद आएगी।
mbomb007

4
पूरी तरह से इस चुनौती को पोस्ट नहीं किया क्योंकि मैं त्रिकोण को ठीक से प्रारूपित करने के लिए बहुत आलसी हूं ...
पावेल

@KodosJohnson इनपुट एक देशी सरणी हो सकती है।
पावेल

आप दो से अधिक तर्कों के साथ कैसे कार्य कर सकते हैं?
विनाशकारी नींबू

@DestructibleWatermelon इनपुट में एक सरणी नहीं होगी, जिसमें पिरामिड के लिए दो तर्क पारित करने की आवश्यकता होगी, क्योंकि यह पिरामिड स्कीम में असंभव है।
पावेल

जवाबों:


26

आम लिस्प - 2524 1890 बाइट्स

(defun f(i)(let((s(loop as r in i collect(g r)))(n())(output""))(loop until n do(setf n T)(loop as r in s do(if(cdr r)(progn(setf output(c output(e r))(cdr r)(cdr(cdr r)))(setf n()))(setf output(c output(b(car r))))))(setf output(c output(format()"~%"))))output))(defun g(r)(if(stringp r)(d(m(length r))r)(if(<(length r)2)(d(m(length(car r)))(car r))(if(=(length(e r))1)(let((h(g(car(e r))))(p(d(m(length(car r)))(car r))))(let((o(+ 1(position #\^(e h))))(parent_length(car p)))(if(<(-(car h)o)parent_length)(l(cons(+ o parent_length)())(loop as n in(butlast(cdr p))collect(c(b o)n))(cons(c(subseq(e h)0 o)(car(last p)))())(loop as n in(cdr(cdr h))collect(c n(b (- parent_length(-(car h)o))))))(let((i(-(- o 1)parent_length)))(l(cons(car h)())(loop as n in(butlast(cdr p))collect(c(b o)n(b i)))(cons(c(subseq(nth 1 h)0 o)(car(last p))(b i))())(cddr h))))))(let((l-h(g(car(e r))))(r-h(g(e(e r)))))(let((ll(position #\^(e l-h)))(rl(position #\^(e r-h))))(let((lr(-(car l-h)ll 1))(rr(-(car r-h)rl 1)))(let((p(d(max(m(length(car r)))(ceiling(+ lr rl)2))(car r))))(let((m-pad(if(>(car p)(+ lr rl))(-(car p)lr rl)0)))(l(cons(+ ll 1(car p)1 rr)())(loop as n in(butlast(cdr p))collect(c(b(+ 1 ll))n(b(+ 1 rr))))(cons(c(subseq(e l-h)0(+ 1 ll))(car(last p))(subseq(e r-h)rl))())(loop as y in(append(cddr l-h)(make-list(length l-h):initial-element(b(car l-h))))as z in(append(cdr(cdr r-h))(make-list(length r-h):initial-element(b(car r-h))))collect(c y(b m-pad)z))))))))))))(defun d(r n)(cons(+(* 2 r)1)(l(cons(c(b r)"^"(b r))())(loop as i from 1 to r collect(c(b(- r i))"/"(subseq(c n(b(expt i 2)))(expt(- i 1)2)(expt i 2))"\\"(b(- r i))))(cons(make-string(+ 1(* 2 r)):initial-element #\-)()))))(defun m(l)(+ 1(floor(sqrt l))))(defun b(n)(make-string n :initial-element #\space))(defun c(&rest a)(apply 'concatenate 'string a))(defun l(&rest a)(apply 'concatenate 'list a))(defun e(tree)(nth 1 tree))

कई गोल्‍फ ट्रिक के लिए @coredump को धन्‍यवाद। सवाल से नमूना उत्पादन:

> (f '(("out" (("chr" ("72")) ("chr" ("101")))) ("out" (("chr" ("108")))) ("out" (("chr" ("108")))) ("out" (("chr" ("111"))))))
          ^               ^          ^          ^  
         /o\             /o\        /o\        /o\ 
        /ut \           /ut \      /ut \      /ut \
       /     \         ^-----     ^-----     ^-----
      /       \       /c\        /c\        /c\    
     ^---------^     /hr \      /hr \      /hr \   
    /c\       /c\   ^-----     ^-----     ^-----   
   /hr \     /hr \ /1\        /1\        /1\       
  ^-----    ^-----/08 \      /08 \      /11 \      
 /7\       /1\    -----      -----      -----      
/2  \     /01 \                                    
-----     -----                                    










> (f '( ("+" ( ("asdfghjkl") ("do" ( "1" )) )) ))
          ^        
         /+\       
        /   \      
       /     \     
      /       \    
     /         \   
    ^-----------^  
   /a\         /d\ 
  /sdf\       /o  \
 /ghjkl\     ^-----
/       \   /1\    
---------  /   \   
           -----   








> (f '(("+" ("9123" "3")) "3"))
       ^        ^  
      /+\      /3\ 
     /   \    /   \
    /     \   -----
   ^-------^       
  /9\     /3\      
 /123\   /   \     
/     \  -----     
-------            

यहाँ मूल है, (अधिकतर) अनगुल्ड संस्करण:

(defun f (input)
    (let ((trees (loop for tree in input collect (g tree)))
          (done nil)
          (output ""))
        (loop while (not done)
            do  (setf done T) 
                (loop for tree in trees
                    do  (if (cdr tree)
                            (progn
                                (setf output (conStr output (car (cdr tree))))
                                (setf (cdr tree) (cdr (cdr tree)))
                                (setf done nil))
                            (setf output (conStr output (blank (car tree))))))
                (setf output (conStr output  (format nil "~%"))))
        output))

;creates a single tree
;output is a list, first element is the length of each line, the rest are the lines of text
(defun g (tree)
    (if (stringp tree)
        ;strings should be drawn as just the pyramid for the name
        (draw-body (min-rows (length tree)) tree)

        (if (< (length tree) 2)
            ;lists with no arguments should be drawn as just the pyramid for the name
            (draw-body (min-rows (length (car tree))) (car tree))
            (if (= (length (car (cdr tree))) 1)
                ;single child
                (let ((child (g (car (car (cdr tree))))) (parent (draw-body (min-rows (length (car tree))) (car tree))))
                    (let ((parent_offset (+ 1 (position #\^ (first-line child)))) (parent_length (car parent)))
                        (if (< (- (car child) parent_offset) parent_length)
                            (let ((child-fill (- parent_length (- (car child) parent_offset))))
                                (concatenate 'list 
                                    (cons (+ parent_offset parent_length) nil)
                                    (loop for line in (butlast (cdr parent))
                                        collect (conStr (blank parent_offset) line))
                                    (cons (conStr (subseq (nth 1 child) 0 parent_offset) (car (last parent))) nil)
                                    (loop for line in (cdr (cdr child))
                                        collect (conStr line (blank child-fill)))))
                            (let ((parent-fill (- (- parent_offset 1) parent_length)))
                                (concatenate 'list 
                                    (cons (car child) nil)
                                    (loop for line in (butlast (cdr parent))
                                        collect (conStr (blank parent_offset) line (blank parent-fill)))
                                    (cons (conStr (subseq (nth 1 child) 0 parent_offset) (car (last parent)) (blank parent-fill)) nil)
                                    (cdr (cdr child)))))))
                ;two children
                (let ((l-child (g (car (car (cdr tree))))) (r-child (g (car (cdr (car (cdr tree)))))))
                    (let ((lc-l-width (position #\^ (first-line l-child))) (rc-l-width (position #\^ (first-line r-child))))
                        (let ((lc-r-width (- (car l-child) lc-l-width 1)) (rc-r-width (- (car r-child) rc-l-width 1)))
                            (let ((parent (draw-body (max (min-rows (length (car tree))) (ceiling (+ lc-r-width rc-l-width) 2)) (car tree))))
                                (let ((m-pad (if (> (car parent) (+ lc-r-width rc-l-width))
                                            (- (car parent) lc-r-width rc-l-width)
                                            0)))
                                    (concatenate 'list
                                        (cons (+ lc-l-width 1 (car parent) 1 rc-r-width) nil)
                                        (loop for line in (butlast (cdr parent))
                                            collect (conStr (blank (+ 1 lc-l-width)) line (blank (+ 1 rc-r-width))))
                                        (cons (conStr (subseq (first-line l-child) 0 (+ 1 lc-l-width)) (car (last parent)) (subseq (first-line r-child) rc-l-width)) nil)
                                        (loop for left in (append (cdr (cdr l-child)) (make-list (length l-child) :initial-element (blank (car l-child))))
                                            for right in (append (cdr (cdr r-child)) (make-list (length r-child) :initial-element (blank (car r-child))))
                                            collect (conStr left (blank m-pad) right))))))))))))


;create a single pyramid
; output is a list, first element is the length of each line, the rest are the lines of text
(defun draw-body (rows name)
    (print rows)
    (print name)
    (cons (+ (* 2 rows) 1)
        (concatenate 'list (cons (conStr (blank rows) "^" (blank rows)) nil)
            (loop for i from 1 to rows
                collect (conStr (blank (- rows i)) "/" (subseq (conStr name (blank (expt i 2))) (expt (- i 1) 2) (expt i 2)) "\\" (blank (- rows i))))
            (cons (make-string (+ 1 (* 2 rows)) :initial-element #\-) nil))))

(defun min-rows (l)
    (+ 1 (floor (sqrt l))))

(defun blank (n)
    (make-string n :initial-element #\space))

(defun conStr (&rest args)
    (apply 'concatenate 'string args))

(defun first-line (tree)
    (car (cdr tree)))

इसे ऑनलाइन आज़माएं!


आपको अनावश्यक रिक्त स्थान को हटाकर बहुत सारे बाइट्स को बंद करने में सक्षम होना चाहिए।
clismique

2
PPCG में आपका स्वागत है और पहला उत्तर अच्छा है!
कृतिका लिथोस

सीएल गोल्फिंग के लिए कुछ सुझाव: छोरों में, "के लिए" भी "के रूप में" लिखा जा सकता है; कोष्ठक और डबल-कोट्स से पहले और बाद में रिक्त स्थान हटा सकते हैं; आप NIL को बदल सकते हैं (); तुम भी पाठक चर का उपयोग कर सकते हैं, कभी कभी
coredump

... loop while (not x)है loop until x, (cdr (cdr x))है (cddr x), आदि की (setf a b c d)तुलना में कम (setf a b)है (setf c d), लेकिन यह पहले से ही एक अच्छा जवाब है
coredump

2
350 की कुल प्रतिष्ठा महत्वपूर्ण है ... लेकिन यह उत्तर इसके योग्य है। एक आम लिस्प एक लिस्प बोली के लिए सवालों के निर्माण के बारे में एक सवाल का जवाब ... वाह।
wizzwizz4
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.