เรียงลำดับรายการซ้อนกัน


23

คุณต้องเขียนโปรแกรมหรือฟังก์ชั่นที่เรียงลำดับรายการซ้อนกัน นี่คือกฎสำหรับการเรียงลำดับรายการซ้อนกัน:

ลองทำรายการนี้เป็นตัวอย่าง:

((5, 2), 2, 7, (2, 1, (3, 4)), 9)

แต่ละองค์ประกอบในรายการนี้มี "ลำดับความสำคัญ" องค์ประกอบนับเป็นตัวเลขหรือรายการย่อย ขั้นแรกรับลำดับความสำคัญของแต่ละองค์ประกอบที่ความลึกเท่ากัน หากองค์ประกอบเป็นเพียงตัวเลขลำดับความสำคัญของมันจะเหมือนกับตัวเอง หากองค์ประกอบเป็นรายการย่อยลำดับความสำคัญของมันคือผลรวมของตัวเลขทั้งหมดในนั้นไม่รวมรายการย่อยใด ๆ

ดังนั้นลำดับความสำคัญขององค์ประกอบทั้งหมดของความลึก1คือ:

 (  7 )  2  7  (    3       )  9
((5, 2), 2, 7, (2, 1, (3, 4)), 9)

จัดเรียงแต่ละองค์ประกอบตามลำดับความสำคัญ หากมีการเสมอกันคุณจะต้องรักษาลำดับเดียวกันกับรายการเดิม

 2  (     3      )  (  7 )  7  9
(2, (2, 1, (3, 4)), (5, 2), 7, 9) 

ทำซ้ำสำหรับทุกรายการย่อย ดังนั้นในรายการย่อยนี้

(2, 1, (3, 4))

ลำดับความสำคัญของเราดูเหมือนว่า:

 2  1  (  7  )
(2, 1, (3, 4))

เรียงลำดับแล้วดูเหมือนว่า:

(1, 2, (3, 4))

(3, 4)เรียงแล้วดังนั้นเราเสร็จแล้ว ทำซ้ำเพื่อให้ได้(5, 2)ผลลัพธ์(2, 5)และเราจะเสร็จสิ้น! รายการสุดท้ายของเราคือ:

(2, (1, 2, (3, 4)), (2, 5), 7, 9) 

กฎ:

  • น่าสงสัยอย่างมาก แต่ในกรณีที่ Mathematica มีบางอย่างสำหรับสิ่งนี้ไม่อนุญาตให้สร้างการเรียงลำดับรายการซ้อนกัน ฟังก์ชั่นการเรียงลำดับปกติจะได้รับอนุญาต

  • I / O สามารถอยู่ในรูปแบบที่เหมาะสม

  • ทุกรายการย่อยจะมีหมายเลขหรือรายการอย่างน้อยหนึ่งรายการ นอกจากนี้รายการย่อยสามารถซ้อนหลายระดับได้ ยกตัวอย่างเช่นในมีลำดับความสำคัญของ 0, เพราะมันมีรายการย่อยเฉพาะในมัน (1, 2, (((3))))(((3)))

  • รายการที่ไม่ถูกต้อง (วงเล็บที่ไม่ตรงกัน, ที่ไม่ใช่ตัวเลข, ประเภทของวงเล็บที่ไม่ถูกต้อง, จำนวนลบ, ฯลฯ ) ส่งผลให้เกิดพฤติกรรมที่ไม่ได้กำหนด

ทดสอบ I / O:

(1, 2, 3) ---> (1, 2, 3)

(1, 2, 6, 3, 9, 8) ---> (1, 2, 3, 6, 8, 9)

(4, 3, (2), (1)) ---> ((1), (2), 3, 4)

(4, 3, (2), ((1))) ---> (((1)), (2), 3, 4)

(5, (1, 2, (9, 8))) ---> ((1, 2, (8, 9)), 5)

(3, (1, 2), (2, 1)) ---> (3, (1, 2), (1, 2))

(3, (1, 2, (99)), (2, 1, (34))) ---> (3, (1, 2, (99)), (1, 2, (34)))

(7, 2, (1, (9, 12)), (4, 3, 2, (1, 2))) ---> ((1, (9, 12)), 2, 7, (2, 3, (1, 2), 4))

คำตอบที่สั้นที่สุดในการชนะไบต์


เราสามารถสมมติว่าตัวเลขเป็นจำนวนเต็มได้หรือไม่?
isaacg

@isaacg ใช่คุณทำได้
DJMcMayhem

คำตอบ:


5

เยลลี่ขนาด 13 ไบต์

fFSµ€Ụị߀µ¹<?

ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมด

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

fFSµ€Ụị߀µ¹<?  Main link. Input: A (list)

   µ€          Apply the chain to the left to each item B in A.
 F             Flatten B.
f              Filter; intersect B with flattened B, yielding a list.
               This returns the numbers in B if B is a list, [B] if B is a number.
  S            Compute the sum of the resulting list.
     Ụ         Sort the indices of A according to the computed sums.
       ߀      Recursively apply the main link to each B in A.
      ị        Retrieve the items of the list (right) at those indices (left).
         µ     Convert the preceding chain into a single link.
            ?  If:
           <     A compared with itself is truthy:
                   Execute the link to the left.
          ¹      Else, apply the identity function to A.

การเปรียบเทียบ ( <) ตัวเลขที่มีตัวเองให้ผลเป็น0 (เท็จ) แต่การเปรียบเทียบรายการที่ไม่ว่างกับตัวเองจะให้รายการ0 (ความจริง) ดังนั้นจึง<สามารถใช้แยกแยะตัวเลขออกจากรายการได้


0 เป็นเท็จ แต่กล่อง 0 เป็นจริง แต่กล่องว่างเปล่าเป็นเท็จ น่าสนใจว่า Python ทำงานอย่างไร : P
cat

ดูเหมือนว่า 25 ไบต์ (เมื่อเข้ารหัสใน UTF-8) สำหรับฉัน
Rotsor

@Rotsor นั่นฟังดูถูก อย่างไรก็ตาม Jelly ใช้หน้ารหัสที่กำหนดเองซึ่งเข้ารหัสอักขระทั้งหมด 256 ตัวที่เข้าใจเป็นไบต์เดียว
Dennis

17

Python 2, 114 101 78 73 62 ไบต์

k=lambda t:t*(t<[])or t.sort(key=k)or sum(z for z in t if[]>z)

ฉันรู้ว่ามีวิธีที่ดีกว่าในการกรองรายการออก

เรียงลำดับรายการหลาม (และรายการย่อย) ในสถานที่

https://eval.in/540457 ขอบคุณ @tac สำหรับการแจ้งให้เราทราบว่าโซลูชันในสถานที่เป็นที่ยอมรับและ @xnor + @feersum สำหรับการปรับแต่งเพิ่มเติม!


1
การเพิ่มประสิทธิภาพบางอย่างเพิ่มเติม: k=lambda t:t*(t<[])or sum(z for z in t if[t.sort(key=k)]>z).
xnor

@xnor ผมคิดว่าการแก้ปัญหาที่ไม่ถูกต้องมาก: eval.in/540447 สำหรับตัวอย่างนี้เราจะเก็บเงินคืนไปยังรายการย่อยแรกและคว้าค่าเริ่มต้นzจากรายการนั้น 5 จากนั้นตามเงื่อนไขเราเรียงลำดับรายการที่เราทำซ้ำ (!) ดังนั้นเมื่อเราคว้า z ถัดไปมันคือ ALSO 5 นำไปสู่ผลรวมของ 10 จากนั้นเราเรียงลำดับรายการภายนอกด้วยปุ่มเหล่านี้และรับ [6, [1, 5]] ซึ่งไม่ถูกต้องเป็น "ถ้ามีการเสมอกันคุณจะต้องรักษาลำดับเดียวกันกับรายการเดิม " สิ่งที่น่าสนใจคือเราโทรหาsortทั้งสองรายการดังนั้นสิ่งนี้จะเกิดขึ้นกับคีย์ที่เท่ากัน: หากรายการย่อยมีน้อยมันจะเรียงลำดับกลับ
Orez

จับดี. มันตลกที่การวนซ้ำจะดำเนินต่อไปด้วยรายการที่เรียงลำดับแล้ว ฉันรู้สึกว่าควรจะมีวิธีที่สั้นกว่าในการNoneเอาท์พุทของt.sort(key=k)แต่ฉันไม่เห็นมัน
xnor

Falseคือ 0 สำหรับวัตถุประสงค์ของและนามสกุล+ sumไม่สามารถคิดได้ว่าจะประหยัดจำนวนไบต์ได้อย่างไร
CalculatorFeline

@CatsAreFluffy list.sortผลตอบแทนไม่ได้None False
Dennis

4

Lua, 172 ไบต์

function p(a)if type(a)~="table"then return a end s(a)local t=0 for i,v in next,a do t=t+p(v)end return t end
function s(t)table.sort(t,function(a,b)return p(a)<p(b)end)end

ฟังก์ชั่นsเรียงลำดับตาราง Lua (โครงสร้างข้อมูลที่ทำหน้าที่เป็นรายการท่ามกลางสิ่งอื่น ๆ ใน Lua) ในสถานที่ตามกฎ


ฉันชอบที่type(a)จะคืนค่าสตริง
แมว

ในที่สุดคำตอบโดยใช้ Lua
Leun Nun

3

Mathematica ขนาด 50 ไบต์

#0/@SortBy[#,Tr@Cases[#,_Integer,{0,1}]&]~Check~#&

วิธี recursive SortByง่ายๆที่ใช้ ละเว้นข้อความ


3

Haskell, 160 151 135 ไบต์

import Data.List
data T=N Int|T[T]deriving Show
p(N x)=x
p(T t)=sum$[x|N x<-t]
f(N x)=N x
f(T t)=T$sortBy((.p).compare.p)$map f$t

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

ดังนั้นก่อนอื่นเราต้องกำหนดประเภทข้อมูลสำหรับต้นไม้กุหลาบ:

data T = N Int | T [T]

(อย่างเคร่งครัดderiving Showเป็นสิ่งที่จำเป็นเท่านั้นถ้าคุณต้องการที่จะเห็นผล. แต่นั่นเป็นวิชา.) ที่มีความหมายในที่นี้เราสามารถเขียนรายการเช่น(1, 2, (3, 4))เป็น

T [N 1, N 2, T [N 3, N 4]]

ซึ่งอ่านได้น้อยกว่ามาก แต่อะไรก็ตาม เป็นการแปลเชิงกลเล็กน้อย คำนำหน้าจำนวนกับทุกคนและทุกทรีย่อยด้วยNT

ตอนนี้เราต้องคำนวณลำดับความสำคัญ นี่จะเป็นเรื่องง่ายถ้าลำดับความสำคัญของทรีย่อยนั้นง่ายกว่าผลรวมขององค์ประกอบทั้งหมดที่มี นั่นจะเป็นการวนซ้ำแบบซ้ำซาก แต่เนื่องจากมันไม่ได้เป็นเราจึงจำเป็นต้องกำหนดสองฟังก์ชั่น: หนึ่งที่ซ้ำซากและที่ไม่

p (N x) = x
p (T t) = sum $ map q t

q (N x) = x
q _     = 0

หากเราจะรวมองค์ประกอบย่อยทั้งหมดแล้วqก็ไม่จำเป็นต้องมีอยู่ช่วยตัวละครจำนวนมาก โอ้ดี!

แก้ไข: อันที่จริงหลาย commentors ชี้ให้เห็นว่าคุณสามารถหลีกเลี่ยงการใช้ความเข้าใจรายการ:q [ x | N x <- t]โทรดีนะ!

(อันที่จริงแล้วpไม่จำเป็นต้องมีอยู่เช่นกันเราอาจมีคอมไพเลอร์อัตโนมัติสร้างOrdอินสแตนซ์ให้เราด้วยอักขระจำนวนหนึ่งและการใช้งานเริ่มต้นนี้จะตรงกับข้อมูลจำเพาะ)

ในที่สุดเราจำเป็นต้องเรียกซ้ำต้นไม้ย่อยทั้งหมดและจัดเรียง:

f (N x) = N x
f (T t) = T $ sortBy (\ x y -> compare (p x) (p y)) $ map f $ t

นั่นคือfเรียงลำดับต้นไม้โดยใช้ตัวเองซ้ำกับองค์ประกอบทั้งหมด ( map f) แล้วเรียกใช้sortByฟังก์ชันเพื่อเรียงลำดับระดับบนสุด บรรทัดแรกบอกว่าการเรียงลำดับหมายเลขไม่ได้ทำอะไรเลยและจำเป็นต้องยกเลิกการสอบถามซ้ำ


2
sortBy (\ x y -> compare (p x) (p y))sortOn pเป็นเพียง ใช้รุ่นมัดของแผนที่ใน:p sum$q<$>t
nimi

@nimi มีการsortOnกำหนดไว้ที่ไหน? ฉันอยากรู้อยู่เสมอ ...
MathematicalOrchid


2
คุณยังสามารถโกนบาง 16 ไบต์กับรายการความเข้าใจเคล็ดลับและp(T t)=sum[x|N x<-t] data T=N Int|T[T]deriving Show:)
Will Ness

1
คุณรวม 2 ไบต์สำหรับแต่ละบรรทัดในการนับของคุณหรือไม่ ผมคิดว่าเราได้รับอนุญาตให้นับพวกเขาเป็นซิงเกิ้ล นอกจากนี้ยังไม่มีความจำเป็นในการใน$ sum$[x|N x<-t]ดังนั้น 135-5-1 = 129 :)
Will Ness

2

CLISP, 380 ไบต์

(defun q(L)(if(null L)L(append(append(q(car(s(cdr L)(car L))))(list(car L)))(q(cadr(s(cdr L)(car L))))))))(defun s(L E)(if(not(atom(car L)))(setq L(cons(q(car L))(cdr L))))(cond((null L)'(nil nil))((<(v(car L))E)(list(cons(car L)(car(s(cdr L)E)))(cadr(s(cdr L)E))))(T(list(car(s(cdr L)E))(cons(car L)(cadr(s(cdr L)E)))))))(defun v(L)(if(atom L)L(apply'+(remove-if-not #'atom L))))

เรียกใช้ฟังก์ชัน q พร้อมกับรายการ

ฉันเป็นคนพูดไม่คล่องโปรดอย่าฆ่าฉันเลย ^^


ฮ่าฮ่าฉันหวังว่าจะมีคนทำมันในกระเพื่อม!
DJMcMayhem

1

Pyth, 15 ไบต์

L?sIbbossI#NyMb

ชุดทดสอบ

ฟังก์ชั่นวนซ้ำซึ่งทำงานดังนี้:

L?sIbbossI#NyMb
L                  define y(b):
 ?sIb              If b is an integer:          (invariant under the s function)
     b             Return it.
            yMb    Else, apply y recursively to all of the elements of b,
      o            Then sort b by
        sI#N       For each element, the elements of that list that are integers.
                   This is luckily a nop on integers.
       s           Summed.

1

Java, 219 ไบต์

import java.util.*;List f(List l){l.sort(Comparator.comparing(o->{if(o instanceof Integer)return(Integer)o;f((List)o);return((List) o).stream().filter(i->i instanceof Integer).mapToInt(i->(Integer)i).sum();}));return l;}

ด้วยตัวแบ่งบรรทัด:

import java.util.*;
List f(List l){
    l.sort(Comparator.comparing(o -> {
        if (o instanceof Integer)
            return (Integer) o;
        f((List) o);
        return ((List) o).stream().filter(i -> i instanceof Integer).mapToInt(i -> (Integer) i).sum();
    }));
    return l;
}

มีการคัดเลือกนักแสดงมากมายที่เกิดขึ้นจริงนับจำนวนไบต์ : P

ค่าจำนวนเต็มจะถูกป้อนเข้าสู่ Comparator และรายการที่ซ้อนกันจะถูกเรียงลำดับก่อนก่อนที่จะรวมเฉพาะค่าจำนวนเต็มที่มอบให้กับ Comparator ค่าเหล่านี้เป็นวิธีที่ Comparator กำหนดตำแหน่งภายในรายการเมื่อเรียงลำดับ

ลองมันนี่


1
นี่เป็นเทคนิคเดียวกันที่ 154 ไบต์int f(List l){l.sort(Comparator.comparing(o->o instanceof Integer?(int)o:f((List)o)));return l.stream().mapToInt(o->o instanceof Integer?(int)o:0).sum();}
Andreas

ฉันคิดว่ามันมีอะไรอีกมากมายที่จะบีบเหมือนกัน
Andreas

แต่มีปัญหาอยู่สองสามข้อ: คุณไม่สามารถแปลงObjectเป็นintแบบนั้นได้อย่างชัดเจนและความท้าทายดูเหมือนว่าจะต้องมีรายการผลลัพธ์
TNT

คุณบันทึก 1 ไบต์จริงโดยการเปลี่ยนอินสแตนซ์ของการตรวจสอบรายชื่อแทนจำนวนเต็ม จำนวนเต็มคือ 7 ไบต์โดยไม่มีเครื่องหมายปีกกา แต่รายการคือ 6 ไบต์
Blue

@TNT คุณสามารถส่ง Object ไปเป็นแบบดั้งเดิมใน java 1.7 หรือสูงกว่า แน่นอนถ้า Object เป็นโมฆะคุณจะได้รับ npe ฉันไม่เห็นปัญหาใด ๆ กับการเรียงลำดับรายการความท้าทายดูเหมือนจะไม่พูดกับปัญหาโดยตรง
Andreas

0

JavaScript (ES6), 86 ไบต์

f=a=>a.map?a.map(f).sort((a,b)=>p(a)-p(b),p=a=>a.map?a.map(a=>t+=a.map?0:a,t=0)|t:a):a

การตรวจสอบอาร์เรย์ทั้งหมด :-(


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