การนับ Quipu: ฐาน 10 ในโลกใหม่


41

Quipusเป็นอุปกรณ์โบราณที่ใช้โดย Inca ในยุค Precolumbian เพื่อบันทึกตัวเลขในระบบฐานสิบตำแหน่งของนอตบนสายซึ่งทำงานดังนี้:

แต่ละกลุ่มของนอตเป็นตัวเลขและมีสามประเภทหลักนอต: นอตฟาดง่าย; "นอตยาว" ประกอบด้วยปมฟาดหนึ่งหรือมากกว่านั้นอีกรอบ; และนอตรูปแปด

  • พลังของสิบจะแสดงตามตำแหน่งตามสายอักขระและตำแหน่งนี้อยู่ในแนวเดียวกันระหว่างเส้นต่อเนื่อง
  • ตัวเลขในตำแหน่งสำหรับ 10 และอำนาจที่สูงกว่าจะถูกแสดงด้วยกลุ่มของนอตง่าย (เช่น 40 เป็นสี่นอตง่าย ๆ ในแถวในตำแหน่ง "สิบ")
  • ตัวเลขในตำแหน่ง "คน" จะแสดงโดยนอตยาว (เช่น 4 เป็นปมที่มีสี่รอบ) เนื่องจากวิธีการผูกปมตัวเลข 1 จึงไม่สามารถแสดงด้วยวิธีนี้และแสดงในตำแหน่งนี้ด้วยปมรูปแปดแปด
  • ศูนย์แสดงโดยไม่มีปมในตำแหน่งที่เหมาะสม

รายละเอียด

สำหรับความท้าทายนี้แต่ละเส้นของ quipu แสดงหมายเลขเดียว (แม้ว่าตามบทความของ Wikipedia คุณสามารถแสดงตัวเลขจำนวนมากบนหนึ่งสายในการท้าทายนี้เราจะไม่)

นอต

ปมแต่ละอันจะถูกแสดงด้วยอักขระ ASCII เดียว

  • . หมายถึงปมที่เรียบง่าย
  • : หมายถึงหนึ่งเทิร์นของปมยาว
  • 8 หมายถึงปมแปดรูป
  • | แสดงถึงการขาดปมเช่นเดียวกับตัวคั่นระหว่างตัวเลข

การสร้าง Quipus

Quipu สร้างขึ้นตามกฎเหล่านี้

  1. เส้นที่เรียงลำดับจากบนลงล่างตามลำดับของตำแหน่ง (เช่นในหน่วยหลักจะอยู่ที่ด้านล่างสุดของเส้น) ตัวเลขตามเส้นจะถูกคั่นด้วยอักขระ ( |)
  2. กำลังของตัวเลข 10 หลักนั้นถูกกำหนดโดยตำแหน่งของมันในแนวเดียวกับที่กำลังของเลข 10 นั้นจะถูกคำนวณโดยใช้ดัชนีในตัวเลขด้วยระบบตัวเลขของเรา นั่นคือ24ด้วยหนึ่ง2ในสถานที่สิบและหนึ่ง4ในสถานที่หน่วยจะถูกแสดงด้วยสองนอตตัวคั่น ( |) แล้วสี่นอต
  3. ตัวเลขในตำแหน่งเดียวกันจะถูกจัดตำแหน่งไปทางด้านล่างของสาระ หากหนึ่งหลักในตำแหน่งจะมีปมน้อยกว่าตัวเลขอื่น ๆ ของตัวเลขอื่น ๆ ในตำแหน่งเดียวกันการขาดปมเหล่านั้นจะถูกแทนด้วย ( |)
  4. Knots อย่างต่อเนื่อง ( .) แสดงถึงค่าในตำแหน่งของพวกเขา
  5. ทุกหลักจะแสดงด้วยอักขระอย่างน้อย 1 ตัว เมื่อค่าตัวเลขเป็น 0 สำหรับตัวเลขทั้งหมดใน quipu ค่าจะถูกแทนด้วย knot ( |)
  6. สถานที่หน่วยได้รับการปฏิบัติเป็นพิเศษ หนึ่งในสถานที่หน่วยจะถูกแสดงด้วยปมแปดรูป ( 8) ค่าของสองหน่วยขึ้นไปในสถานที่หน่วยจะแสดงด้วยนอตยาวต่อเนื่อง ( :)
  7. เมื่อหน่วยหลักคือ 0 สำหรับตัวเลขทั้งหมดใน quipu การไม่มีปมจะไม่ถูกพิมพ์ แต่ตัวคั่นต่อท้ายสำหรับหลักสิบจะถูกเก็บรักษาไว้
  8. ไม่มีตัวคั่นตามหลักหน่วย

กฎระเบียบ

  • การป้อนข้อมูลจะประกอบด้วยรายการที่ไม่ว่างเปล่าของจำนวนเต็มไม่เป็นลบที่อาจได้รับผ่านวิธีการป้อนข้อมูลเริ่มต้นใดๆ คุณอาจจะคิดว่าจำนวนเต็มเหล่านี้ทั้งหมดน้อยกว่าหรือเท่ากับหรือ2147483647 2^31-1ในขณะที่กรณีทดสอบเป็นแบบมีการเว้นวรรคพื้นที่รูปแบบการป้อนข้อมูลของคุณสามารถแยกอินพุตด้วยวิธีใดก็ได้ที่สะดวกสำหรับภาษาของคุณไม่ว่าจะคั่นด้วยเครื่องหมายจุลภาคคั่นด้วยบรรทัดใหม่ในอาร์เรย์และอื่น ๆ
  • เอาต์พุตประกอบด้วย Quipu เดี่ยวที่สร้างขึ้นตามกฎที่อธิบายไว้ข้างต้น การส่งออกอาจได้รับผ่านวิธีการเริ่มต้นใด
  • รหัสของคุณควรเป็นโปรแกรมหรือฟังก์ชั่นแม้ว่ามันจะไม่จำเป็นต้องเป็นฟังก์ชั่นที่มีชื่อ
  • นอตใช้เวลาในการผูกเพื่อประหยัดเวลารหัสของคุณสั้นที่สุด

เช่นเคยหากปัญหายังไม่ชัดเจนโปรดแจ้งให้เราทราบ ขอให้โชคดีและการเล่นกอล์ฟที่ดี!

ตัวอย่าง

การป้อนข้อมูล:

5 3 1 0

เอาท์พุท:

:|||
:|||
::||
::||
::8|

การป้อนข้อมูล:

50 30 10 0

เอาท์พุท:

.|||
.|||
..||
..||
...|
||||

การป้อนข้อมูล:

330

เอาท์พุท:

.
.
.
|
.
.
.
|

การป้อนข้อมูล:

204 1

เอาท์พุท:

.|
.|
||
||
||
:|
:|
:|
:8

การป้อนข้อมูล:

201 0 100 222

เอาท์พุท:

.||.
.|..
||||
|||.
|||.
||||
|||:
8||:

การป้อนข้อมูล:

1073741823 2147483647

เอาท์พุท:

|.
..
||
|.
||
.|
.|
.|
..
..
..
..
||
|.
|.
|.
|.
..
..
..
||
.|
.|
.|
..
..
..
..
||
|.
|.
|.
|.
..
..
..
..
||
|.
|.
..
||
.|
.|
..
..
..
..
..
..
||
|.
|.
..
..
||
|:
|:
|:
|:
::
::
::

การป้อนข้อมูล:

0

เอาท์พุท:

|

กรณีทดสอบอีกต่อไป

อ่านเพิ่มเติม


คำตอบ:


3

Pyth, 64 ไบต์

=QjRTQjCmj\|+:R"[8:]"\.PdedCmm+*\|-h.MZdk*?tk\:\8kdC.[L0h.MZlMQQ

ลองออนไลน์!

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

=QjRTQ   Converts each number in input to decimal (as a list)
         123 becomes [1,2,3]

----

jCmj\|+:R"[8:]"\.PdedCmm+*\|-h.MZdk*?tk\:\8kdC.[L0h.MZlMQQ

                                              .[L0       Q  0-leftpad each #
                                                  h.MZlMQ   (max length) times

                                             C              transpose

                      mm                    d    for each digit:
                        +                        [convert to] sum of
                         *\|                     "|" repeated
                            -                    the difference of
                             h.MZd               maximum digit in same row
                                  k              and itself.. that many times
                                   *?tk\:\8      and (digit > 1 then ":" or "8") repeated
                                           k     itself many times


the list:
[11,23,52]
->[[1,1],[2,3],[5,2]]
->[[1,2,5],[1,3,2]]
->[["||||8","|||::",":::::"],["||8",":::","|::"]]

                     C      transpose

->[["||||8","||8"],["|||::",":::"],[":::::","|::"]]

  m                          for each number
      +                      [convert to] sum of
                 Pd          every element but the last
       :R"[8:]"\.            with "8" and ":" replaced by "."
                   ed        and the last element
   j\|                       joined with "|"

  C                          transpose
 j                           join (with newlines)

นี่คือคำตอบที่ยอดเยี่ยมยกเว้นสำหรับปัญหาเดียว ปมสุดท้ายไม่ใช่ปมรูปแปด8เสมอไป ในความเป็นจริงมันเป็นเพียง8ปมเมื่อหลักสุดท้ายคือ 1 (ดูกฎ 6) คุณกำลังแปลงนอตสุดท้ายทั้งหมดและไม่ตรงกับข้อมูลจำเพาะ ลองเล่นออนไลน์กับคุณ! ลิงก์มีรหัสที่แตกต่างจากที่โพสต์ไว้ที่นี่
Sherlock9

22

อ่านไม่ได้ , 3183 3001 ไบต์

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

รุ่นแรกของรุ่นนี้คือ 4844 ไบต์เพื่อให้คุณทราบว่าฉันเล่นกอล์ฟนี้มากแค่ไหน

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

' '' '' ''' "" ' ''' "" ' ''' " ' '' ' ' '' ''"'' ''' "" ' ''' "" '"' "" ' ''' "" ' ''' "" ' ''' "" "" "" ' ''' "" ' ''' "" ' ''' "" '' " '"' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" '"" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" ' ''' "" "" "" "" "" "" "" " ' '' ' ' '''' ' ' '''' ' ' '''' '' '' ' '"'' '''" " ' '''"' "" ' ''' "" ' ''' " ' '' ' ' '' '' ' ' '' ''"'' '''' '' '' '' "' '' ''"" "" '' ' ' '' '' '''' '' '' ''" ' '' ' ' ''''"' '' '' '' "" '' '' '' '' ' '' ' ' '' '' ' ' '''' '' '' ' ' '''' ' '"'' '''' '' '' '' ''" ' '' ''' "" "" "" ' ''' " ' ''"' '' '' '' ' ' '''' ' ' '''' ' ' '''' " ''" """" "" "" "" ' '' '' ''' "" "" "" '"' "" " ' '''" "" "" "" '"' "" "" '' ' '' '' ' ' '' '' '''' ' '"'' ''' "" "" "" """ '' '' '' ' ' '''' " ''" ' '' '' ''' "" ' ''' " ' '' ' ' '' '' '' '''' '' '' ''' "" ' ''' """""" ' '' '' ''' "" "" " ' '' ' ' '' '' '' '''' '' '' ''' "" "" ''" " '' '' " ' '' ' ' '' '' '' '''' ''' "" "" "" ' '''" ' '' "' '' '' "" '' '' ''" ' '' '' '' ' ' '' ' ' '' '' "'' '''' '' '' ''"' '' '' '' "" ''"" ''"" " ' '' ''"'" "" ' ''' "" "" "" "" '' ' ' '' '''' '' '' ' ' ''''" " '' ' '' ' ' '' '' '' '''' ''' "" "" " ' '' '' '' '''" "" "" "" '' '' ''"" '' " ' '''" "" "" "" ' '' '' '' "' '' "" '' '' '' ''" ' '' '' '' '' "' ''"" "" "" '' '' ''"" '' ' ' '' ' ' '' '' '' '' ' ' '''' '' '' '''' '''' '' ' '' '' '' ''' "" " ' '' '''" "" " ' '' '' '''" " '' ' ' '''' ' ' ''''" "" ' ''' "" '"' "" "" '' ''" " '' '' '' ' ' '' '' ''''" '' ' ' ''''"" "" "" '"' "" " ' '' '''" """ " '' '' ' ' '' '' '''' ' ' '''' ' ' '''' " ' '''" " '' ' ' '' '' '''' ' ' '''' ' '"'' '' "" "" "" "" ' '' '' "' " ' '' ' ' '''' '' '' '''" ' '' "' '' "" '' ''" ' '' '' '' "' '' ''"" '"'" "" ' '' '' '' ''' "" "" "" " '"'" "" ' '' '' '' '' "' '' '' ''" "" '' '' '' ' ' '' '' '''' ' ' '''' ' ' '''' ' ' '''' ' '' "' '' '' '' '' ' '' '' '' ' ' '''' ' ' '''' ' ' '''' ' '"'' ''' "" "" "" """ " '' ''"" "" ' '' '' '' ''' "" "" "" "" '' '' ''" ' ''"' '' '' '' '' "" '' '' '' " ' '''" " '"'" "" ' '' '' ''' "" ' ''' "" '"' "" """ ' '' '' '' ''"' "" ' '' '' '' ' ' '' '' '' ' '"'' '''' '' '' '' ''' "" ' ''' "" """"" ' '' '' '' ' '"'' ''' "" "" ' '' '' ''' "" "" "" " '"'" "" " '' ''" "" "" ' '' '' '' '' ' ' '''' '' '' ''' "" "" ''"" '' '' '' '' ' ' '''' " "" "" "" "" '' '' ''" ' ''"' '' "" '' '' '' '' ' ' '''' ' ' '''' ''""" " ' '' '' '' ' '"'' '''" "" ' '' '' '' ''' "" " ' '''" "" "" """ ''" "" "" '"' "" " ' '' '' '' '''" "" "" "" "" ''" ' '' '' '' "' '' '' '' '' ' '' "' '' '' '' '' "" '' '' ''" ' '' '' '' "' '' "" '' '' '' ''" " ''' '' '' '' "' ''" " '' '' '' ' ' '''' ' ' '''' ' ' '''' ' '' ' ' ''''"' " "" "" "" ' ''' "" ' ''' "" '"' "" " ' '' '' '' ' ' '' '' '' '''' '''" "" "" "" ' ''' "" ' ''' "" '"' "" " ' '' '''" "" "" "" """ '' '' '' ''"' ''' "" "" " ' '' '' '' ' ' '' '' '''' ' '"'' '''" "" "" """ " '' '' '' " ' '''" " '' ' ' '' '' '''' '' '' ''""" '' ' ' '' '' '' '''' '' '' '' ' '' '' '' ' '"'' ''' "" "" '' '' '' ''" " '' '' '' ' ' '''' ' ' ''''" ' '''" "" "" "" ' ''' " ' ''"' '' ' ' '' '' '' '' ' ' '''' '' '' '''' " " '' ' ' '' '' '' '''' ''"" "" "" " ' '' '' '' ' '"'' '''" "" "" "" "' "" "" "" " ' '' '' '' ' '"'' '''" "" ' '' ''"' '' '' '' "" '' '' ''' ''' " ' '' ' ' '''' '' '' ''' "" '"' "" "" '' ' ' '' '''' ''"" '' '' " ' '' '' '''" "" "" "" '"' "" " ' '' '' '' '''" "" "" "" ' '' '' ''"' " " '' ' ' '' '' '''' '' '' ' ' '''' ' '' ' ' '' '' '' '''' '' '' ''"'" '"'" "" ' ''"' '' '' ' ' '' '' '' ' ' '' '' '''' ' '"'' ''''" '' " "" "" ' ''' " ' '' ' ' '' '' '''' '' '' '''" ' '' ' ' '''' '' '' ''' "" "" "" " '"'" "" ' '' '' '' '' ' ' '''' '' '' ''' "" " ' '' '' "'" """" "" " ' '' '' '' '''" "" "" "" " ' '' '' '' '''" "" "" "" ' ''' "" ''" " ''" '' "" ''" ' '' '' '' ''"' '' '' "" '' '' '' ' ' '' '' ''''" ''" ' ''' "" "" "" " '"'" """ '' '' '' ' ' '''' ' ' '''' " '' "" ''" """" "" "" "" ' '' '' '' ' ' '''' ' '"'' '''" " '' '' '' ' ' '' '' '' '''' " ' ''"' '' '' '' '' ' ' '' '' '' '''' '' '' '' ' ' '' '' '' '''' '' '' " "" '' '' ''"" '' " ' '' '' '' '' ' ' '' '' '' ' ' '''' ' '"'' '''''"" ' ''' "" ' ''' "" ' ''' "" ' ''' "" '' " ' '' ' ' '' '' '''' '' '' ''' "" " ' '' '' '' '''" "" "" " ' '''" " '"'" "" ' '' ''"' '' '' '' "" ''" "" " ' '''" " '' ' ' '' '' '' '''' '' '' ''"" " '"'" "" ' '' '' "'"" "" "" " ' '' ' ' '' '' '' '''' '' '' '''" "" "" "" ' '' "' ''"

คำอธิบาย

ฉันจะแนะนำคุณเกี่ยวกับวิธีการทำงานของโปรแกรมโดยแสดงให้คุณเห็นว่ามันประมวลผลอินพุตเฉพาะ202,100,1อย่างไร

ในการเริ่มต้นเราสร้างค่าบางอย่างที่เราต้องการในภายหลัง - ส่วนใหญ่เป็นรหัส ASCII ของตัวละครที่เราจะส่งออก

ป้อนคำอธิบายรูปภาพที่นี่

อย่างที่คุณเห็น'8'และ'.'มีอยู่แล้ว '|'อย่างไรก็ตามเป็น 124 จริงๆไม่ใช่ 14 เราใช้ a while loop เพื่อเพิ่มค่าชั่วคราวสองครั้งใน slot # 1 ลงไปเพื่อรับ 124 (ซึ่งคือ 14 + 55 × 2 เนื่องจากขณะที่ loop ทำงาน 56−1 = 55 ซ้ำ) สิ่งนี้ช่วยประหยัดบางไบต์เนื่องจากตัวอักษรจำนวนเต็มขนาดใหญ่เช่น 124 มีความยาวจริง ๆ ในแผนภาพต่อไปนี้ฉันจะแสดงตำแหน่งของตัวแปรทุกตัวที่โปรแกรมใช้

ป้อนคำอธิบายรูปภาพที่นี่

ต่อไปเราต้องการใส่อักขระทั้งหมดและเก็บไว้ในเทปเริ่มต้นที่เซลล์ # 12 ( pเป็นตัวชี้การทำงานสำหรับสิ่งนี้) ในเวลาเดียวกันเราต้องการทราบว่าจำนวนที่ยาวที่สุดคือเท่าใด เพื่อให้บรรลุนี้เราให้รวมการทำงานในเอก leftwards จะเริ่มต้นที่เซลล์ # -1 (เราใช้Qเป็นตัวชี้ทำงาน) หลังจากป้อนหมายเลขแรก ( 202) เทปจะมีลักษณะดังนี้:

ป้อนคำอธิบายรูปภาพที่นี่

คุณจะสังเกตเห็นว่าตัวเลขนั้นถูกปิดด้วย 4 ทีนี้เมื่อเราใส่พวกมันครั้งแรกพวกเขาคือค่า ASCII ดังนั้นพวกเขาจึง“ ปิด” 48 และเครื่องหมายจุลภาคคือ 44 สำหรับตัวละครแต่ละตัวเราคัดลอก 46 จาก'.'เป็นrแล้วลบออกด้วย a while loop (ซึ่งลบ 45) จากนั้นเราบวก 1 เราทำเช่นนั้นเครื่องหมายจุลภาค (ตัวคั่นของเรา) คือ 0 ดังนั้นเราสามารถใช้เงื่อนไขเพื่อจดจำมัน

นอกจากนี้คุณจะสังเกตเห็นว่าเราออกจากเซลล์ # 11 ที่ 0 เราจำเป็นต้องรู้ขอบเขตของหมายเลขแรก

ตัวละครต่อไปจะเป็นเครื่องหมายจุลภาคเพื่อให้เราเก็บ 0 ใน # 15 แต่แน่นอนเวลานี้เราทำไม่ได้ล่วงหน้าQ แต่เราตั้งค่าคิวกลับเป็น 0 และเริ่ม“ เขียนทับ” 1s ที่เราได้วางไว้แล้ว

หลังจากประมวลผลอักขระที่เหลือทั้งหมดแล้วเราจะได้รับสิ่งนี้:

ป้อนคำอธิบายรูปภาพที่นี่

อย่างที่คุณเห็นตอนนี้1s ที่เขียนโดยqจะแสดงความยาวของตัวเลขที่ยาวที่สุด

ขณะนี้เราใช้ในขณะที่วงจะย้ายคิวไปทางซ้ายมากแล้ววางตัวชี้มีอีกซึ่งผมจะเรียกr2 วัตถุประสงค์ของr2จะชัดเจนในภายหลัง

ป้อนคำอธิบายรูปภาพที่นี่

ณ จุดนี้ให้ฉันชี้แจงคำศัพท์ที่ฉันจะใช้ตลอดนี้

  • ตามตัวเลขฉันหมายถึงหนึ่งในหมายเลขอินพุตที่คั่นด้วยเครื่องหมายจุลภาค ในตัวอย่างของเราคือ 202, 100 และ 1
  • โดยหลักผมหมายถึงตัวเลขหลักเดียวในหนึ่งที่เฉพาะเจาะจงของตัวเลขที่ หมายเลขแรกมี 3 หลัก
  • ตามสถานที่ฉันหมายถึงสถานที่หนึ่งที่สิบสถานที่หลายร้อย ฯลฯ ดังนั้นถ้าฉันพูดว่า "ตัวเลขในสถานที่ปัจจุบัน" และสถานที่ปัจจุบันคือสถานที่ที่หนึ่งตัวเลขเหล่านั้นเป็น 2, 0 และ 1 ในที่ ใบสั่ง.

กลับไปที่รายการปกติของเรา ส่วนที่เหลือทั้งหมดของโปรแกรมเป็นลูปขนาดใหญ่ที่เลื่อนคิวไปข้างหน้าจนกว่าจะถึงเซลล์ # 0 แต่ละเซลล์ที่อยู่ระหว่างทางแสดงถึงสถานที่โดยที่ที่อยู่ทางด้านขวาสุดและqจะเริ่มต้นที่จุดสำคัญที่สุด ในตัวอย่างของเรานั่นคือสถานที่นับร้อย

เราดำเนินการต่อโดยการเพิ่มจุดqของเซลล์ที่ (นั่นคือ* q )

ป้อนคำอธิบายรูปภาพที่นี่

ตอนนี้เราอยู่ที่“ เวที 2” สำหรับสถานที่หลายร้อยแห่ง ในขั้นตอนนี้เราจะค้นหาว่าตัวเลขที่ใหญ่ที่สุดคือตัวเลขใดในหลักร้อย เราใช้เคล็ดลับการนับ unary เดียวกันสำหรับสิ่งนี้ยกเว้นเวลานี้ตัวชี้เรียกว่าrและตัวชี้r2ทำเครื่องหมายตำแหน่งเริ่มต้นซึ่งเราจำเป็นต้องรีเซ็ตทุกครั้งที่เราไปยังหมายเลขถัดไป

เริ่มจากตัวเลขแรกกันก่อน เราเริ่มต้นด้วยการตั้งค่าpเป็น 11 (ตำแหน่งเริ่มต้นฮาร์ดโค้ดของตัวเลขทั้งหมด) จากนั้นเราใช้ a while loop เพื่อค้นหาจุดสิ้นสุดของตัวเลขและตั้งค่าp2 ที่นั่นเพื่อทำเครื่องหมายตำแหน่ง ในเวลาเดียวกันเราก็ตั้งค่าq2เป็น 0:

ป้อนคำอธิบายรูปภาพที่นี่

อย่าสับสนกับข้อเท็จจริงที่ว่าq2ชี้ไปที่ vars เราไม่มีช่องว่างภายในเซลล์ว่างเปล่าเพราะเราสามารถตรวจจับเซลล์ # 0 เพียงเพราะมันเป็นศูนย์

ต่อไปเราจะผ่านจำนวนปัจจุบันโดยการลดค่าpและq2ด้วยกันจนกระทั่ง* pเป็นศูนย์ ในแต่ละสถานที่คุณค่าของ* q2บอกเราว่าเราต้องทำอะไร 1 หมายถึง“ ไม่ทำอะไรเลย” ดังนั้นเราจะดำเนินต่อไป ในที่สุดเราก็พบกับ 2 ในเซลล์ # −3 ทุกครั้งที่* q2ไม่เท่ากับ 1, q2จะเท่ากับqเสมอ

ป้อนคำอธิบายรูปภาพที่นี่

ดังที่ฉันได้กล่าวไปแล้วขั้นตอนที่ 2 คือ“ กำหนดตัวเลขที่ใหญ่ที่สุดในสถานที่แห่งนี้” ดังนั้นเราจึงตั้งค่าrเป็นr2ใช้ while loop เพื่อลดค่า* pแล้วเลื่อนrไปทางซ้ายแล้วเติมเทปด้วย 1s จากนั้นใช้อีกอันในขณะที่ loop เพื่อเลื่อนrกลับไปทางขวาและเพิ่ม* pอีกครั้งเพื่อเรียกคืนค่า โปรดจำไว้ว่าในขณะที่ลูปทำงานด้วยการวนซ้ำน้อยกว่าค่าที่เราใช้ ด้วยเหตุนี้จำนวน 1s ที่เขียนจะเท่ากับ 3 (มากกว่า 4 มากกว่า) มากกว่าค่าตัวเลขและค่าสุดท้ายที่เก็บไว้ใน* pจะเพิ่มอีก 2 ดังนั้นสิ่งนี้จึงลดลงอย่างมีประสิทธิภาพ* p 2

หลังจากนั้นเราตั้งค่าpเป็นค่าของp2แล้วเราทำทั้งหมดอีกครั้ง เป็นครั้งที่สองตั้งค่าq2เป็น 0 ค้นหาจุดสิ้นสุดของตัวเลขโดยเลื่อนpไปทางขวาจากนั้นผ่านตัวเลขของตัวเลขนี้โดยการลดค่าpและq2ด้วยกัน อีกครั้งหนึ่งที่เราจะได้พบกับ 2 ในเซลล์ # -3 และเขียนว่า 1s หลายด้านซ้ายของR *

ในกรณีของตัวเลขที่สามเราไม่ต้องทำอะไรเพราะมันไม่มีที่นับร้อย ( q2จึงไม่ถึงq ) แต่ก็ไม่เป็นไรเพราะมันไม่มีผลต่อการคำนวณค่าตัวเลขสูงสุด

ป้อนคำอธิบายรูปภาพที่นี่

นอกจากนี้เรายังตั้งค่าเซลล์* (r - 4)ซึ่งฉันได้ทำเครื่องหมายด้วยลูกศรที่ไม่มีป้ายกำกับที่นี่เป็น 1 (แม้ว่าจะอยู่ที่ 1) ฉันจะไม่บอกคุณว่าทำไมยัง แต่คุณอาจเดาได้แล้ว?

การเพิ่ม* qครั้งต่อไปจะนำเราไปสู่สเตจ 3 ซึ่งเป็น“ ลบตัวเลขสูงสุดจากตัวเลขทั้งหมดในตำแหน่งปัจจุบัน” ก่อนหน้านี้เรารีเซ็ตpเป็น 11 และq2เป็น 0 จากนั้นทำตัวเลขทั้งหมดเหมือนที่เราทำในขั้นตอนก่อนหน้า ยกเว้นเวลานี้* q = 3 แทน 2 ทุกครั้งที่q2ตรงกับqและpอยู่ในหลายร้อยแห่งเราใช้ a while loop เพื่อลดค่า* pหลาย ๆ ครั้งเนื่องจากมี 1 วินาทีในบล็อกด้านซ้ายของ* r2 (5 ในตัวอย่างของเรา) โดยใช้rเป็นตัวชี้การทำงาน เราจะลดมันอีกครั้งเพื่อให้ตัวเลขที่ใหญ่ที่สุดสิ้นสุดที่ −2 ด้วยเหตุผลที่ชัดเจนในภายหลัง:

ป้อนคำอธิบายรูปภาพที่นี่

หลังจากที่เราประมวลผลตัวเลขทั้งหมดแล้วตอนนี้เราจะถึงจุดสิ้นสุดของขั้นตอนที่ 3 ที่นี่เราแสดงสองสิ่งที่แปลกประหลาด

  • อันดับแรกเรายังลบขนาดของr -block (บวก 1) จาก* qแต่ใช้ตัวชี้r2ซึ่งปล่อยไว้ทางซ้าย * qกลายเป็นลบด้วยวิธีนี้ ในกรณีของเราr -block มีห้า 1 วินาทีดังนั้น* qกลายเป็น −3
  • ประการที่สองเราตั้งค่าตัวแปรออกเป็นค่าที่ไม่ใช่ศูนย์เพื่อบ่งชี้ว่าตอนนี้เรากำลังเข้าสู่ขั้นตอนการส่งออก (โดยทางเทคนิคแล้วความจริงที่ว่า* qนั้นเป็นค่าลบแสดงถึงขั้นตอนการส่งออกแล้ว แต่นี่เป็นเรื่องยากเกินไปที่จะตรวจสอบดังนั้นจึงเป็นตัวแปรพิเศษ)

ตอนนี้คุณเข้าใจว่าเราให้ไปผ่านตัวเลขค้นหาสถานที่ปัจจุบัน (แสดงโดยค่าที่ไม่ใช่ 1 ของQ * ) ภายในแต่ละหมายเลขและทำบางสิ่งบางอย่างขึ้นอยู่กับมูลค่าของQ * เราเห็นว่า* qถูกเพิ่มครั้งแรกเป็น 2 (= คำนวณค่าตัวเลขสูงสุดสูงสุด) จากนั้น 3 (ลบค่าตัวเลขสูงสุดจากทุกตำแหน่งในตำแหน่งนี้) จากนั้นเราลบออกเพื่อให้มันเป็นค่าลบ จากนั้นจะเพิ่มขึ้นเรื่อย ๆ จนกว่าจะถึง 1 ดังนั้นจะเรียกคืนค่าที่หมายถึง "ไม่ทำอะไรเลย" ณ จุดนั้นเราย้ายไปยังสถานที่ต่อไป

ตอนนี้เมื่อ* qเป็นลบเราจะแสดงผล * qเป็นค่าที่ถูกต้องดังนั้นเราจะส่งออกจำนวนแถวของอักขระที่ถูกต้องก่อนที่จะถึง 1; ถ้าตัวเลขที่ใหญ่ที่สุดคือ 2 เราต้องเอาท์พุท 3 แถว มาดูกันว่าเกิดอะไรขึ้นกับแต่ละค่าของ* q :

  • * q = −2:
    • สำหรับหมายเลขแรก* pคือ −2 ซึ่งบ่งชี้ว่าเราจำเป็นต้องส่งออก a '.'(จุด) หรือ a ':'(โคลอน) เราตัดสินใจที่โดยดูที่Q : ถ้ามัน -1 เราอยู่ในสถานที่ที่คนเพื่อการส่งออก':'(ซึ่งเราจะคำนวณเป็น'8'2) '.'มิฉะนั้น
    • สำหรับหมายเลขที่สอง* pคือ −3 อะไรก็ตามที่ไม่ใช่ −2 หมายถึงเราส่งออก'|'(ไปป์) แล้วเพิ่มค่า วิธีนี้จะไปถึง −2 ในตำแหน่งที่ถูกต้องจากนั้นเราจะส่งออก'.'s / ':'s สำหรับส่วนที่เหลือของตัวเลขนั้น
    • ในแต่ละกรณีเรายังตั้งตัวแปรpdเป็น 0 ก่อนที่เราจะประมวลผลจำนวนและตั้งค่าpd (=“ พิมพ์”) เป็นค่าที่ไม่เป็นศูนย์เพื่อระบุว่าเราได้พิมพ์ตัวอักษรแล้ว
    • สำหรับหมายเลขที่สามจะไม่มีการประมวลผลเกิดขึ้นเนื่องจากหมายเลขที่สามไม่มีจำนวนร้อย ในกรณีนี้pdจะยังคงเป็น 0 หลังจากประมวลผลหมายเลขซึ่งระบุว่าเรายังคงต้องส่งออก a '|'(แต่ถ้าออกไม่ใช่ศูนย์เพราะมิฉะนั้นเรายังอยู่ในขั้นตอนที่ 2 หรือ 3)
    • หลังจากการประมวลผลตัวเลขทั้งหมดถ้าออกมาเป็นที่ไม่ใช่ศูนย์ส่งออกขึ้นบรรทัดใหม่ โปรดทราบว่าเราต้องการตัวแปรoutเพื่อที่เราจะได้ไม่ต้องขึ้นบรรทัดใหม่ในระยะที่ 2 หรือ 3
  • * q = −1:เหมือนเมื่อก่อนยกเว้นว่า * pคือ −2 สำหรับทั้งสองหมายเลขแรกดังนั้นทั้งสองเอาท์พุต'.'(และเอาท์พุตที่สามเป็น'|'เหมือนก่อนหน้า)
  • * q = 0:เมื่อ * qเป็น 0 นี่หมายความว่า "ไม่ต้องทำอะไรถ้าเราอยู่ในที่เดียวกันมิฉะนั้นให้ส่งออกแถว'|'s โดยไม่คำนึงถึง * p " วิธีนี้เราจะได้ช่องว่างระหว่างตัวเลข

ทีนี้เราก็เพิ่มคิวเพื่อย้ายไปยังตำแหน่งถัดไป, หลักสิบและเพิ่ม* q ที่นั่น ที่จุดเริ่มต้นของระยะที่ 2 เทปจะมีลักษณะดังนี้:

ป้อนคำอธิบายรูปภาพที่นี่

จากนั้นเราก็ขึ้นเวที 2 เหมือนเมื่อก่อน โปรดจำไว้ว่าการลบ 2 อย่างมีประสิทธิภาพจากทุกหลักในสถานที่นี้และปล่อยให้หมายเลข unary ที่เหลือของ* r2แสดงถึงจำนวนสูงสุด เราปล่อยให้หมายเลขเอกนารีก่อนหน้าเพียงอย่างเดียวและขยายเทปไปทางซ้ายเรื่อย ๆ มันจะเสียค่าใช้จ่ายรหัสพิเศษที่ไม่จำเป็นเพื่อ "ล้าง" เมื่อเราเสร็จแล้วและเราเพิ่มขึ้น* qในตอนเริ่มต้นของเวที 3 เทปตอนนี้:

ป้อนคำอธิบายรูปภาพที่นี่

จริงๆแล้วนี่เป็นเรื่องโกหก โปรดจำไว้ว่าก่อนหน้านี้ที่ฉันบอกว่าเราตั้ง* (r - 4)เป็น 1 และฉันไม่ได้บอกคุณว่าทำไม? ตอนนี้ฉันจะบอกคุณว่าทำไม สำหรับกรณีเช่นนี้ซึ่งตัวเลขที่ใหญ่ที่สุดในความเป็นจริง 0 หมายถึงตัวเลขทั้งหมดในสถานที่นี้คือ 0 การตั้งค่า* (r - 4) ที่ระบุโดยลูกศรที่ไม่มีป้ายกำกับด้านบนถึง 1 ขยายหมายเลขเอกนัมเบอร์โดย 1 แต่เฉพาะในกรณีพิเศษนี้ ด้วยวิธีนี้เราทำท่าราวกับว่าตัวเลขที่ใหญ่ที่สุดคือ 1 ซึ่งหมายความว่าเราจะส่งออกหนึ่งแถวพิเศษ

หลังจากขั้นตอนที่ 3 (ลบตัวเลขสูงสุดจากตัวเลขทั้งหมดในตำแหน่งปัจจุบัน) รวมถึงขั้นตอนพิเศษที่ทำให้* q เป็นลบเทปจะมีลักษณะเช่นนี้ ครั้งที่แล้วตัวเลขที่ใหญ่ที่สุดถูกแสดงด้วย −2 ในบล็อก* pแต่ครั้งนี้พวกเขาทั้งหมด −3 เพราะพวกเขาทั้งหมดเป็นศูนย์จริง ๆ แต่เราแสร้งทำเป็นว่าตัวเลขสูงสุดคือ 1

ป้อนคำอธิบายรูปภาพที่นี่

ตอนนี้เรามาดูกันว่าเกิดอะไรขึ้นเมื่อ* qไปยัง 1:

  • เมื่อ* q = −1 ค่า* pคือ −3 ทั้งหมดซึ่งหมายความว่าเราส่งออก'|'s และเพิ่มพวกเขา
  • เมื่อ* Q = 0 เราส่งออก'|'เพราะที่สิ่งที่เรามักจะทำเมื่อQ * = 0 โดยไม่คำนึงถึง* p

ดังนั้นเราจึงได้รับท่อสองแถว

ในที่สุดเราย้าย* qไปยังสถานที่หนึ่ง อันนี้น่าสนใจเพราะเราต้องเอาท์พุท':'s หากตัวเลขจริงคืออะไรนอกจาก 1 แต่'8'ถ้าเป็น 1 ลองดูว่าโปรแกรมดำเนินไปอย่างไร ก่อนอื่นเราเพิ่ม* qเพื่อเริ่มขั้นตอนที่ 2:

ป้อนคำอธิบายรูปภาพที่นี่

หลังจากขั้นตอนที่ 2 (“ คำนวณค่าตัวเลขสูงสุด”) เราจะเหลือสิ่งนี้:

ป้อนคำอธิบายรูปภาพที่นี่

หลังจากขั้นตอนที่ 3 (“ ลบค่าตัวเลขสูงสุดจากตัวเลขทั้งหมดในตำแหน่งปัจจุบัน”) เทปจะมีลักษณะดังนี้:

ป้อนคำอธิบายรูปภาพที่นี่

ทีนี้ลองทำซ้ำแต่ละ* qกัน:

  • * q = −2:
    • หมายเลขแรก: อยู่ที่ −2 ดังนั้นให้ส่งออก a ':'(แทนที่จะเป็น'.'เพราะq = −1)
    • หมายเลขที่สอง: ที่ −4 ดังนั้นเอาท์พุท a '|'และส่วนเพิ่ม
    • จำนวนที่สาม: ที่ -3 '|'เพื่อการส่งออก อย่างไรก็ตามในครั้งนี้แทนที่จะเป็นตัวพิมพ์ใหญ่จะทำให้เกิดกรณีพิเศษ เฉพาะในกรณีที่เราส่งออกสถานที่สุดท้าย ( q = −1) และเราอยู่ในแถวที่สองสุดท้ายสำหรับ ( * q = −2) และหลักคือ 1 ( * p = −3) , แล้วแทนการเพิ่มมันถึง -2 เราตั้งค่าให้ -1 ในคำอื่น ๆ ที่เราใช้ -1 เป็นค่าพิเศษที่จะแสดงให้เห็นว่าในการย้ำต่อไปเราจะต้องส่งออกแทน'8'':'
  • * q = −1:
    • จำนวนแม่: แล้วที่ -2 ':'เพื่อการส่งออก
    • จำนวนสอง: ที่ -3 '|'เพื่อการส่งออก เงื่อนไขพิเศษไม่เปิดใช้งานเพราะ* qไม่มีอีกต่อไป −2 ดังนั้นการเพิ่มขึ้น
    • จำนวนที่สาม: -1 '8'เพื่อการส่งออก
  • * q = 0:โดยปกติแล้วเราจะส่งออกแถว padding ของ'|'ที่นี่ แต่ในกรณีพิเศษที่เราอยู่ในสถานที่ที่ ( q = −1) เราข้ามมัน

หลังจากนี้qจะเพิ่มขึ้นเป็น 0 และใหญ่ขณะที่ลูปสิ้นสุด

ตอนนี้คุณรู้วิธีการป้อนข้อมูลเหมือน202,100,1งาน อย่างไรก็ตามมีอีกหนึ่งกรณีพิเศษที่เรายังไม่ได้ครอบคลุม คุณอาจจำได้ว่าในขณะที่เรากำลังประมวลผลสถานที่สุดท้ายเมื่อ* pเป็น −3 เราตั้งค่าเป็น −1 สำหรับ1(แทนที่จะเพิ่มขึ้นเป็น −2) เพื่อให้การทำซ้ำครั้งถัดไป'8'แทน สิ่งนี้ใช้งานได้เพราะเรามีการทำซ้ำที่* pคือ −3 และเราทำการตัดสินใจว่าจะเพิ่มขึ้นหรือตั้งเป็น −1 เราไม่ได้เช่นการทำซ้ำถ้าทั้งหมดของตัวเลขในสถานที่ที่เป็น 0 หรือ 1 ในกรณีเช่นนี้ทั้งหมด* pค่า 1s จะเริ่มต้นที่ -2; ไม่มีโอกาสตัดสินใจที่จะตั้งเป็น −1มากกว่าที่จะเพิ่มขึ้นได้จาก -3 ด้วยเหตุนี้จึงมีเงื่อนไขพิเศษอีกอย่างหนึ่งในขั้นตอนที่ 3 (“ ลบตัวเลขสูงสุดจากทุกหลักในสถานที่ปัจจุบัน”) ฉันอ้างว่าหลังจากลบค่าตัวเลขสูงสุดจากทุกหลัก (ณ จุดที่ตัวเลขสูงสุดคือ −1) เราก็ลดมันอีกครั้ง แต่จริงๆแล้วมีเงื่อนไขว่าจะไปดังนี้:

หากตัวเลขที่เราดูมีค่าเท่ากับตัวเลขสูงสุดในสถานที่นี้ ( * p = −1) และสถานที่นี้คือตำแหน่งที่หนึ่ง ( q = −1) และตัวเลขสูงสุดคือ 1 ( * (r + 5) = 0, คือบล็อกยูนารีที่ด้านซ้ายสุดมีความยาวเพียง 5 เซลล์เท่านั้น , จากนั้นเราจะปล่อย* pที่ −1 เพื่อระบุว่าการวนซ้ำของเอาต์พุตเท่านั้นที่จะต้องส่งออก'8'และ ในกรณีอื่น ๆ เราจะลดมันอีกครั้ง

เสร็จสิ้น สวัสดีปีใหม่!

  • แก้ไข 1 (3183 → 3001):มีความสุขปีใหม่กอล์ฟ! ฉันจัดการเพื่อกำจัดตัวแปรp2และr2โดยสิ้นเชิง! พีตอนนี้แข่งไปมาเพื่อให้การหาจุดเริ่มต้นและจุดสิ้นสุดของตัวเลข แต่ดูเหมือนว่าจะสั้นลงในรหัส ฉันพยายามกำจัดq2ด้วย แต่ฉันไม่สามารถทำให้รหัสสั้นลงได้

    ฉันยังพบสถานที่อีกไม่กี่แห่งที่ฉันสามารถใช้เทคนิคการตีกอล์ฟทั่วไปที่อ่านไม่ได้เช่นการใช้ค่าสุดท้ายของลูปอีกครั้ง เพื่อให้คุณเป็นตัวอย่างแทน

    while *(++p) { 1 }         // just increment p until *p is 0; the 1 is a noop
    if (pd) { x } else { y }   // where pd is a variable
    

    ฉันสามารถบันทึก'""""(ทำครั้งแรกจากนั้นสอง) และ'"""(คงที่ 1) โดยการเขียนในลักษณะที่เป็นเช่น

    if (while *(++p) { pd }) { x } else { y }
    

    แน่นอนมันใช้งานได้ก็ต่อเมื่อฉันรู้ว่าขณะที่ลูปจะทำงานอย่างน้อยหนึ่งรอบ แต่ถ้าเป็นเช่นนั้นค่าส่งคืนจะเป็นpdดังนั้นฉันจึงสามารถใช้มันเป็นเงื่อนไขสำหรับ if ได้


"อ่านไม่ได้" เป็นชื่อที่เหมาะเจาะ ...
อเล็กซ์ A.

9
-1 ไม่เพียงพอคำอธิบาย
The Guy with The Hat

7

Javascript (ES6) 750 744 690 604 498 346 245 234 ไบต์

ฉันใหม่สำหรับ PPCG และคิดว่าฉันจะลองดูสิว่ามันค่อนข้างง่าย ฉันเป็นคนผิด !! ฉันทำงานมาระยะหนึ่งแล้วและฉันก็มีหลายอย่างที่ต้องทำ ...
มีข้อเสนอแนะให้กำลังใจ! - แม้ว่าการทำความเข้าใจกับสิ่งนี้จะไม่ใช่เรื่องง่าย

เชือกขาออกเมื่อเข้าเป็นอาร์เรย์ของตัวเลข (เช่น: [204, 1])

a=>(o=m=s="",l=a.map(n=>(s+="|",l=(n+"").length)>m?m=l:l),h=[],a=a.map((n,i)=>[..."0".repeat(m-l[i])+n].map((d,j)=>d<h[j]?d:h[j]=d)),h.map((n,i)=>{i?o+=s+`
`:0;for(j=n;j--;o+=`
`)a.map(d=>o+="|.:8"[d[i]-j<1?0:i<m-1?1:d[i]-1?2:3])}),o)

คำอธิบาย

a=>(

  o=m=s="",                      // m = max number of digits in a number, s = separator string         
  l=a.map(n=>(                   // l = lengths of each number
      s+="|",                    // set the separator string
      l=(n+"").length                 // convert each number to a string
    )>m?m=l:l                    // get max length
  ),
  h=[],
  a=a.map((n,i)=>
    [..."0".repeat(m-l[i])+n]    // add leading 0s to make all same length
    .map((d,j)=>d<h[j]?d:h[j]=d) // set each digit of h to max
  ),

  h.map((n,i)=>{
    i?o+=s+`
`:0;
    for(j=n;j--;o+=`
`)
      a.map(d=>
        o+=
          "|.:8"[
            d[i]-j<1?0
            :i<m-1?1
            :d[i]-1?2:
            3
          ]
      )
  }),
  o
)

ตัวอย่าง

อินพุต:อาร์เรย์ของตัวเลข: [4,8,15,16,23,42]
เอาต์พุต:

|||||.
|||||.
||||..
||....
||||||
|:||||
|:||||
|:|:||
|:::||
::::||
:::::|
::::::
::::::

+1 สนามกอล์ฟที่น่าประทับใจ คุณจะรวมตัวอย่างกับอินพุตและเอาต์พุตหรือไม่
DavidC

@DavidC ขอบคุณ! และตัวอย่างรวมอยู่ด้วย เรียกใช้จากคอนโซลและส่งคืนสตริง :)
Aᴄʜᴇʀᴏɴғᴀɪʟ

7

Python 3, 624 598 595 574 561 535 532 527 525 426 345 328 324 294 288 286 283 283 280 267 265 255 251 245 238 235 234 230 228 ไบต์

z=input().split();v=max(map(len,z));d=''.join(i.zfill(v)for i in z);x=['']*len(z)
for k,c in enumerate(d):j=k%v;m=int(max(d[j::v]));c=int(c);x[k//v]+="|"*(m-c+0**m+(j>0))+":8."[(c<2)|-(j<v-1)]*c
for r in zip(*x):print(*r,sep='')

"204 1"ดีเนื่องจากคำถามนี้จำเป็นคำตอบผมได้ให้ที่นี่ที่ป้อนข้อมูลที่ควรจะเป็นสตริงพื้นที่แยกออกจากกันของตัวเลขเช่น บอยมันยาวไหม คำแนะนำการเล่นกอล์ฟ (หรือคำตอบที่ดีกว่า) ยินดีต้อนรับ

แก้ไข:ไบต์ที่บันทึกโดยการผสมแท็บและช่องว่าง

แก้ไข:ฉันบันทึกไบต์จำนวนมากโดยการเปลี่ยนวิธีรับตัวเลข (ทำรายการจากสตริง zero-padded ของตัวเลขจากนั้นในเนื้อความของรหัสทรานส์เพื่อรับตัวเลขหลายหลักสิบหลัก ฯลฯ .)

แก้ไข:และฉันบันทึกบางส่วนเพิ่มเติมโดยการรวม:8ลูปสุดท้ายนั้นเข้ากับลูปหลัก quipu ทีนี้ถ้ามีเพียงฉันเท่านั้นที่สามารถรู้ได้ว่าทำไมb=d[j*v+i]==m(d[i::v])ไม่ทำงาน คิดออกและการแก้ปัญหาใช้เวลามากเกินไปไบต์ (เช่นจำนวนไบต์ลดลงเนื่องจากแท็บหันกลับไปเป็นช่องว่างสี่ช่องซึ่งอาจเป็นรูปแบบการบล็อกโค้ดในไซต์นี้)

แก้ไข:ฉันจัดระเบียบใหม่ว่าทำ quipus ตอนนี้มันจะสร้างหนึ่งเส้นในเวลาเดียวกันจากนั้นสลับเพื่อการพิมพ์

แก้ไข:เปลี่ยนคำตอบของฉันกลับไปเป็นโปรแกรม Python 3 เพื่อบันทึกไบต์เพิ่มเติม

แก้ไข:ฉันพบข้อบกพร่องในรหัสของฉันที่สร้างขึ้นเพื่อไม่ให้พิมพ์เลขศูนย์ตรงกลางของตัวเลขอย่างถูกต้อง (ดูกรณีทดสอบ204 1ด้านบน) ในการแก้ไขปัญหานี้ฉันจัดการกับกอล์ฟ :)

แก้ไข:ฉันเปลี่ยนการพิมพ์เพื่อประหยัด 10 ไบต์ และฉันก็นับจำนวนไบต์เก่าทั้งหมดกลับเพราะ

แก้ไข: Golfed การกำหนดvใช้mapสี่ไบต์ เครดิตCarpetPythonที่ผมมีความคิดจากคำตอบของพวกเขาที่นี่

แก้ไข:เปิดตรงกลาง "สำหรับลูปภายในสำหรับลูป" เป็นเพียงหนึ่งสำหรับลูปสำหรับหกไบต์

แก้ไข:enumerateตอนนี้ใช้ l=len(z)ไม่ใช้ เปลี่ยนไตรภาคif-elseให้เป็นรายการประกอบไปด้วย ดูรายละเอียดด้านล่าง

แก้ไข: Sp3000 แนะนำการแก้ไขprintและการแก้ไขเงื่อนไขที่ประกอบไปด้วยที่บันทึกไบต์แต่ละรายการ

Ungolfed:

s = input()
z = s.split()
v = max(map(len, z))                # the amount of digits of the largest number
d = ''.join(i.zfill(v) for i in z)  # pad zeroes until every number is the same length
                                     # then join the numbers into one string
x = ['']*len(z)                     # a list of strings for the output, one for each number

for k,c in enumerate(d):          # for every digit in every number
    i,j = divmod(k, v)            # i is the index of the number we're on
                                   # j is the index of the digit of the number we're on
    m = int(max(d[j::v]))         # the largest of all the digits in the j-th place
    c = int(c)                    # the digit in j-th place of the i-th number
    x[i] += "|"*(m-c+0**m+(j>0))  # pad | to size m-c, until the knots are correctly spaced
                                  # add a | if m<1, all j-th place digits are 0
                                  # add a | if j>0, if it's not at the start, as delimiters
    x[i] += ":8."[(c<2)|-(j<v-1)] * c
    # this is essentially the following code
    # if j<v-1:
    #     x[i] += "."*c      # . knots if not in the units place
    # else:
    #     if c == 1:
    #         x[i] += "8"*c  # 8 knots for ones in the units place
    #     else:
    #         x[i] += ":"*c  # : knots for something else is in the units place

for r in zip(*x):       # transpose so all the rows (the quipu strings) now hang down
    print(*r, sep='')    # join the strings together at each knot
                         # and print each on a separate line

มีอะไรพิเศษใน Python 3ไหม? หากไม่มีการแปลงเป็น Python 2 สามารถบันทึกได้ไม่กี่ไบต์
Cyoce

@Cyoce ไม่มีอะไรพิเศษเช่น Python 3 ฉันเพิ่งเริ่มต้นใน Python 3 เพราะเป็นรุ่นที่ฉันมี ฉันจะทดสอบ Python 2 ในรูปแบบของ ideone หรือบางอย่าง
Sherlock9

@Maltysen ที่ไม่ได้ทำงานกับปัจจัยการผลิตที่เริ่มต้นด้วยเช่น0 0 12 4
Sherlock9

คุณสามารถบันทึกบางไบต์โดยสลับแท็บและช่องว่างสำหรับการเยื้องใน Python 2 ฉันเชื่อว่าตัวละครแท็บ 1 == 8 ช่องว่างตาม
parson

for r in zip(*x):print(''.join(r))->print(''.join(r)for r in zip(*x))
Leun Nun

4

C, 238 235 ไบต์

ใช้ตัวประมวลผลล่วงหน้า C อย่างหนักเพื่อทำให้รหัสสั้นที่สุดเท่าที่จะเป็นไปได้ ในฐานะที่เป็นผลข้างเคียงก็ทำให้อ่านไม่ได้

#define l strlen(a[i])
#define d l<k||a[i][l-k]-48
#define m(e) for(i=1;a[i];e<=r?i++:r++);
#define p(e) {m(!putchar(e?'|':k>1?46:d<2?56:58))puts("");}
k,r;main(int i,char**a){m(l)for(k=r,r=1;k;r=k>1){m(d)for(;r;r--)p(d<r)if(--k)p(1)}}

บน Ubuntu 14.04 คุณสามารถคอมไพล์โค้ดได้อย่างตรงไปตรงมาgcc quipu.c(โปรดเพิกเฉยต่อคำเตือน) ตัวอย่างของการรันโปรแกรมที่รันได้:

$ ./a.out 1 2 3 2 1
||:||
|:::|
8:::8

ทดสอบกับกรณีทดสอบของ OP ทั้งหมด

รหัสแหล่งที่มาไม่ถูกปรับแต่ง:

// Standard library; leaving out the includes still gives executable code despite the warnings.
#include <stdio.h>
#include <string.h>

// 4 preprocessor macros.
// Note: some of these actually make use of the fact that parentheses have been left out

// l: length of argument i
#define l     strlen(a[i])

// d: shorthand for a digit
#define d     l<k || a[i][l-k]-'0'

// m: loop across all arguments; calculates r as the maximum of expression e
#define m(e)  for (i=1; a[i]; e<=r ? i++ : r++);

// p: prints one line of output
// note: intentionally does not use the r++ code branch of m;
//       putchar always returns a non-zero number here, so !putchar is zero,
//       which is always <=r (because r is never negative)
// note: the semicolon after m(...) is redundant;
//       the definition of m already contains a semicolon
// note: puts("") outputs a newline
#define p(e)  { m(!putchar(e ? '|' : k > 1 ? '.' : d < 2 ? '8' : ':')); puts(""); }

// k: knot position; 1 for units, 2 for tens, 3 for hundreds...
int k;

// r: input and output value for m
// note: the first time we call m, we need r to be zero;
//       by defining it outside main, it is automatically initialized as such
int r;

// function main
// note: parameter i (normally named argc by convention) is not needed
//       (the last element of argv is known; it is followed by a NULL pointer)
//       but we cannot leave it out (otherwise we cannot access argv)
//       so it serves as a local variable (to loop through arguments; see m)
// note: parameter a (normally named argv by convention)
//       is the array of arguments (starting from index 1)
int main(int i, char **a)
{
    // Determine the longest argument; store its length in r.
    // This is the number of knot positions to consider.
    m(l)

    // Iterate k through the knot positions from top to bottom.
    // Note: k > 0 has been abbreviated to k.
    // Note: for each iteration, we also initialize r with either 0 or 1.
    //       0 = suppress printing when all knots are zero
    //       1 = always print, even when all knots are zero
    for (k = r, r = 1; k > 0; r = k > 1)
    {
        // Determine the highest digit at this knot position.
        // Note: due to the absence of parentheses, d mixes up with <=r into:
        // (l < k) || (a[i][l-k]-'0' <= r)
        m(d)

        // Count the digits down.
        for (; r; r--)
        {
            // Print a single line of output.
            // When d (the digit in the current strand) is less than the counter,
            // then print a '|', otherwise print a knot.
            p(d < r)
        }

        // Decrement k (go to next knot position).
        // If this was not the last iteration...
        if (--k > 0)
        {
            // Print separator line.
            p(1)
        }
    }

    // Return exit code zero; redundant.
    return 0;
}

ขอแสดงความยินดี! เนื่องจากคำตอบที่สั้นที่สุดที่โพสต์ภายในระยะเวลาเงินรางวัลคุณได้รับค่าตอบแทน +50 ตัวแทนของฉัน คำตอบที่ดี! :)
Alex A.

4

Mathematica 436 453 357 352 347 ไบต์

t=Transpose;y=ConstantArray;a=Table;
g@j_:=(s=t[PadLeft[#,Max[Length/@i]]&/@(i=IntegerDigits@#)]&;p_~u~o_:=(m=Max@p;c=If[o==-2,":","."];w=If[o==-2,"8","."];p//.{0->a["|",Max@{1,m}],1->Join[a["|",{m-1}],{w}],n_/;MemberQ[2~Range~9,n]:>Join[y["|",m-n ],c~y~n]});t[Join@@@t@Join[u[#,0]&/@Most@#,u[#,-2]&/@{#[[-1]]}]]&[Riffle[(s@j),{a[0,Length@j]}]]//Grid)

ข้างบน

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

ตัวอย่าง

g[Range[0, 50]]

ห้าสิบ


Transpose@Join? ที่ควรจะเป็นใช่มั้ย
CalculatorFeline

ใช่. ขอบคุณที่รับสิ่งนี้
DavidC

ช่องว่างก่อนหน้านั้น
CalculatorFeline

1

R - 446 444

ฉันเห็นว่ายังไม่มีวิธีแก้ปัญหา R ดังนั้นนี่คือวิธีแก้ปัญหา ฟังก์ชันนี้ใช้เวกเตอร์ที่มีจำนวนเต็ม

function(x){r=nchar(max(x));c=length(x);m=matrix(0,r,c);for(i in 1:c){t=as.numeric(strsplit(as.character(x[i]),"")[[1]]);m[(r+1-length(t)):r,i]=t};Q=c();for(i in 1:r){d=m[i,];z=ifelse(max(d)>0,max(d),1);q=matrix("|",z,c);for(j in 1:c){v=m[i,j];if(i==r){if(v==1)q[z,j]=8;if(v>1)q[(z-v+1):z,j]=rep(":",v)};if(i<r){if(v>0)q[(z-v+1):z,j]=rep(".",v)}};if(i!=1&sum(d)>0)q=rbind(rep("|",c),q);Q=rbind(Q,q)};for(i in 1:nrow(Q))cat(Q[i,],sep="",fill=T)}

Ungolfed

# Some test data
test <- c(201, 0, 100, 222, 53)

# Define function
quipu <- function (x) {

    # Create matrix with a row for each digit and a column for each number
    r=nchar(max(x));c=length(x);m <- matrix(0,r,c)
    for(i in 1:c) {
        t=as.numeric(strsplit(as.character(x[i]),"")[[1]])
        m[(r+1-length(t)):r,i]=t
    }

    # Loop through each row (digit) starting at the top of the quipu
    Q=c() # Empty matrix to store quipu 
    for(i in 1:r){

        d=m[i,]
        z=ifelse(max(d)>0,max(d),1)
        q=matrix("|",z,c)

        # Loop through each column (number in the vector) starting at the leftmost quipu
        for(j in 1:c){

            # The digit
            v=m[i,j]

            # If it is the last segment of the quipu
            if(i==r){
                if(v==1){q[z,j]=8} # If unit digit =1
                if(v>1){q[(z-v+1):z,j]=rep(":",v)} # If unit digit >1               
            }

            # If it is not the last segment of the quipu
            if(i<r){
                if(v>0){q[(z-v+1):z,j]=rep(".",v)} # If non-unit digit >0   
            }
        }

        # Add segment to Q
        if(i!=1 & sum(d)>0){q=rbind(rep("|",c),q)}
        Q=rbind(Q,q)    
    }

    # Print quipu
    for(i in 1:nrow(Q)) {cat(Q[i,], sep="", fill=T)}
}

# Test
quipu(test)

คุณต้องการประโยคif(v>0)ของคุณif(i<r)หรือไม่? R ยอมรับช่วงเช่นไรz+1:zเมื่อv==0ใด ถ้าเป็นเช่นนั้นq[z+1:z,j]จะไม่ได้รับผลกระทบเลยฉันจะคิด นอกจากนี้ R มีelseคำหลักและคำหลักบางประเภทelse ifหรือไม่ ถ้าเป็นเช่นนั้นคุณจะสามารถเล่นกอล์ฟเงื่อนไขเหล่านี้ได้
Sherlock9

if(v>0) เป็นสิ่งจำเป็นเพราะถ้า v=0ดัชนีจะไม่อยู่ในขอบเขต (เช่นพยายามรับแถว nrow + 1) R มีelseและฉันลองใช้ข้อเสนอแนะของคุณจริงและใช้elseเท่าที่จะทำได้ แต่กลับกลายเป็นว่ามีจำนวนไบต์เท่ากัน
Loris ช้า
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.