ทำอาร์เรย์ให้เรียบง่าย


22

อินพุต

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

เอาท์พุต

อาร์เรย์นี้เรียบง่าย

วิธีการรับรองอาร์เรย์

เราจะใช้อาร์เรย์[1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]]เป็นตัวอย่างของเรา

ก่อนอื่นเราจะตรวจสอบว่าค่าเหล่านี้ซ้อนอยู่ลึกแค่ไหน นี่คือความลึกและตัวเลขที่ระดับความลึกเหล่านั้น:

0  1
1  2 3 9
2  4 7
3  5 6
5  8

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

ดังนั้นผลลัพธ์ของเราคือ [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]]

ตัวอย่าง

[1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]] -> [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]]
[[[1]], [2, [3]], 4, [5, [6, [7, [8], [9, [[10]]]]]]] -> [4, [2, 5], [[1, 3, 6]], [[[7]]], [[[[8, 9]]]], [[[[[[10]]]]]]]
[1] -> [1]
[1, [2], [[3]], [[[4]]], [[[[5]]]]] -> [1, [2], [[3]], [[[4]]], [[[[5]]]]]
[1, [[[[2], 3]]] [[4]]] -> [1, [[4]], [[[3]]], [[[[2]]]]]

เอาต์พุตยืดหยุ่นหรือไม่? ชอบตัวเลขในบรรทัดที่แตกต่างกันโดยที่แต่ละบรรทัดมีหนึ่งระดับ หรือตัวคั่น / ตัวคั่นอาร์เรย์อื่น ๆ
Luis Mendo


@ LuisMendo ใช่มันยืดหยุ่น
Daniel

คุณจะหายไปทั้งคู่วงเล็บหนึ่งรอบที่บรรทัด8 So, our output is.....อย่างไรก็ตามคุณได้ทำการแก้ไขในตัวอย่างข้อมูล
sbisit

2
คำตอบบางคำสั่งให้ส่งบรรทัดว่างสำหรับระดับการซ้อนโดยไม่มีองค์ประกอบ ในกรณีเช่นนี้คุณสามารถส่งคืนอาเรย์ที่ว่างเปล่าได้[1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[]]]], [[[[[8]]]]]]หรือไม่ตัวอย่างเช่นคุณเป็นคนแรก?
nimi

คำตอบ:


1

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

fFṄḟ@;/ß

เอาต์พุตคือหนึ่งระดับต่อบรรทัดโดยมีบรรทัดว่างสำหรับระดับที่ไม่มีอิลิเมนต์ ลองออนไลน์!

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

fFṄḟ@;/ß  Main link. Argument: A (array)

 F        Flat; yield all integers (at any level) in A.
f         Filter; intersect A with the integers, yielding those at level 0.
  Ṅ       Print the filtered array and a linefeed. Yields the filtered array.
     ;/   Reduce by concatenation.
          This decreases the levels of all integers at positive levels by 1.
   ḟ@     Swapped filter-false; remove the integers at level 0 in A from the array
          with decreased levels.
       ß  Recursively call the main link on the result.
          The program stops once A is empty, since ;/ will result in an error.

3

JavaScript (ES6), 139 109 ไบต์

f=(a,v=b=>a.filter(a=>b^!a[0]))=>a[0]?v().concat((a=f([].concat(...v(1))),b=v())[0]?[b]:[],v(1).map(a=>[a])):[]

คำอธิบายการใช้อินพุตตัวอย่าง: vเป็นเมธอดตัวช่วยซึ่งส่งคืนอาร์เรย์ (พร้อมพารามิเตอร์1) หรือค่า (โดยไม่มีพารามิเตอร์) เราเริ่มต้นด้วยa = [1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]]ซึ่งไม่ว่างเปล่า [1]เรากรองอาร์เรย์ให้ จากนั้นเราจะเรียกตัวเองซ้ำบนอาร์เรย์ตัดแบ่งกันซึ่งเป็นผลที่เป็นอยู่[2, 3, [4], [[5, 6], 7, [[[8]]]], 9] [2, 3, 9, [4, 7], [[5, 6]], [[[[8]]]]]เรากรองอาร์เรย์อีกครั้งซึ่งทำให้เราได้ระยะที่สองของเอาต์พุตของเรา[2, 3, 9]อย่างไรก็ตามเราต้องระวังไม่ให้แทรกอาร์เรย์ว่างที่นี่ พวกเขายังคงห่ออาร์เรย์[4, 7], [[5, 6]], [[[[8]]]]ภายในอาร์เรย์และผนวกเข้ากับผลลัพธ์ที่เกิด[1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]]ขึ้น


filterอาจจะสามารถบันทึกไม่กี่ไบต์โดยการนามแฝงไป อาจเริ่มต้นด้วยF=(x,y)=>x.filter(y)
Cyoce

@Cyoce กลายเป็น 30 ในที่สุด!
Neil

คุณมีสนามกอล์ฟเหลือให้ทำเช่นนี้ ฉันคิดว่าคุณสามารถแทนที่ได้อย่างปลอดภัย[].concat(...v(1))ด้วยv(1)การบันทึก 14 ไบต์ อาจมีบางสิ่งอื่น ๆ เช่นกัน แต่ฉันมีเวลายากในการติดตามวงเล็บซ้อนกันในหัวของฉัน
Patrick Roberts

1
@PatrickRoberts [].concat(...v(1))เป็นสัตว์ร้ายที่แตกต่างกันมากv(1)ไม่งั้นฉันจะไม่ทำ! สำหรับตัวอย่างง่ายๆพิจารณาa = [2, [3], [[4]]]แล้วแต่v(1) = [[3], [[4]]] [].concat(...v(1)) = [3, [4]]
Neil

@ Neil โอ้ว้าวฉันควรจะทดสอบข้อเสนอแนะของฉันก่อนที่จะเปิดปากของฉัน ฉันรู้สึกว่าควรจะมีวิธีการที่สั้นกว่าในการทำเช่นนี้ ..
Patrick Roberts

2

05AB1E , 27 26 25 21 ไบต์

D˜gFvyydi„ÿ ?}}¶?.gG«

ลองออนไลน์! (แก้ไขเล็กน้อยเนื่องจาก.gยังไม่ได้ใช้ TIO)

คำอธิบาย

D˜gF                    # flattened input length times do
    vy                  # for each y current level of list
      ydi„ÿ ?}          # if y is a digit, print with space
              }         # end v-loop
               ¶?       # print newline
                 .g     # calculate length of stack (this should be .g but I can't test)
                   G«   # length stack times, concatenate items on stack

กลยุทธ์หลักคือการวนซ้ำในแต่ละระดับที่เป็นไปได้ของอาร์เรย์ที่ซ้อนกันและพิมพ์ตัวเลขใด ๆ ในหนึ่งแถวในขณะที่รักษาตัวเลขที่ไม่ใช่ตัวเลข (รายการ) ในรายการหนึ่งระดับที่ซ้อนกันน้อยลง


2

Perl, 52 ไบต์

เพียงรูทีนย่อยแบบเรียกซ้ำ (ผิดปกติสำหรับคำตอบ Perl ฉันรู้ .. )

sub f{say"@{[grep!ref,@_]}";@_&&f(map/A/?@$_:(),@_)}

เรียกมันว่า:

$ perl -E 'sub f{say"@{[grep!ref,@_]}";@_&&f(map/A/?@$_:(),@_)}f(1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9])'
1
2 3 9
4 7
5 6

8

แต่ละบรรทัดของเอาต์พุตสอดคล้องกับระดับความลึกของอาร์เรย์ (ดังนั้นบรรทัดว่างในตัวอย่างด้านบน)

มันสามารถเปลี่ยนเป็นโปรแกรมเต็มรูปแบบได้เพียงไม่กี่ไบต์: เพิ่ม-nแฟล็กและeval(ภายใน@{ }เพื่อแปลงอินพุตให้เป็นอาร์เรย์และไม่ใช่อาร์เรย์) เพื่อเปลี่ยนอินพุตให้เป็นอาร์เรย์ Perl:

perl -nE 'sub f{say"@{[grep!ref,@_]}";@_&&f(map/A/?@$_:(),@_)}f(@{+eval})' <<< "[1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]]"

วิธีก่อนหน้าของฉันยาวกว่าเล็กน้อย (65 ไบต์) แต่ก็ยังน่าสนใจดังนั้นฉันจะปล่อยไว้ที่นี่:

perl -nE '/\d/?push@{$;[$d-1]},$_:/]/?$d--:$d++for/\[|]|\d+/g;say"@$_"for@' <<< "[1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]]"

2

JavaScript (ES6) 121 144 152

แก้ไขมีการแก้ไขมาก 1 ไบต์บันทึกขอบคุณ Patrick Roberts และอีก 21 คนเพียงตรวจสอบรหัส

ฟังก์ชั่นวนซ้ำทำงานบนอาร์เรย์ในอินพุตและเอาต์พุต ฉันไม่ชอบการร้องขอของการมีองค์ประกอบที่ระดับความลึก 1 เป็นองค์ประกอบเดียวในอาร์เรย์เอาท์พุท (ในขณะที่ระดับสูงจะถูกจัดกลุ่มเป็นองค์ประกอบหนึ่ง) [l1,l1, [l2...], [[l3...]] ]ไปนี้: ขณะนี้จะตรงกว่า:[ [l1...], [[l2...]], [[[l3...]]] ]

f=(l,d=0,r=[])=>l.map(v=>v[0]?f(v,d+1,r):r[d]=[...r[d]||[],v])
r.reduce((r,v,d)=>d?[...r,(n=d=>d-->1?[n(d)]:v)(d)]:v,[])

เพิ่มบรรทัดใหม่เพื่อให้สามารถอ่านได้

หมายเหตุบางประการ: บรรทัดที่ 2 ได้รับการประเมินอีกครั้งและอีกครั้งในการโทรซ้ำแต่ละครั้ง แต่การทำซ้ำครั้งสุดท้ายเมื่อสิ้นสุดการเรียกซ้ำนั้นมีประโยชน์
การจัดการพิเศษเมื่อd==0อยู่ในบรรทัดที่ 2 จะดูแลความผิดปกติสำหรับองค์ประกอบระดับ 1 ฟังก์ชันเวียนจัดการอาร์เรย์ทำรังในการส่งออก
n

ทดสอบ

f=(l,d=0,r=[])=>l.map(v=>v[0]?f(v,d+1,r):r[d]=[...r[d]||[],v])
&&r.reduce((r,v,d)=>d?[...r,(n=d=>d-->1?[n(d)]:v)(d)]:v,[])

console.log=x=>O.textContent+=x+'\n'

test=[
 [ 
   [1, [2,3], 4], /* -> */ [1, 4, [2,3]]
 ]
,[
   [1, [2, 3], [[4]], [[[5, 6], 7, [[[8]]]], 9]], 
   // ->
   [1, [2, 3, 9], [[4, 7]], [[[5, 6]]], [[[[[8]]]]]]
 ]
,[
  [[[1]], [2, [3]], 4, [5, [6, [7, [8], [9, [[10]]]]]]],
  // ->
  [4, [2, 5], [[1, 3, 6]], [[[7]]], [[[[8, 9]]]], [[[[[[10]]]]]]] 
 ]
,[  
  [1], /* -> */ [1]
 ]
,[  
  [1, [2], [[3]], [[[4]]], [[[[5]]]]],
  // ->
  [1, [2], [[3]], [[[4]]], [[[[5]]]]]
 ]
,[  
  [1, [[[[2], 3]]], [[4]]],
  [1, [[4]], [[[3]]], [[[[2]]]]]
]]

test.forEach(t=>{
  var i=t[0], k=t[1], r=f(i),
      si=JSON.stringify(i),
      sr=JSON.stringify(r),
      sk=JSON.stringify(k)
  
  console.log((sr==sk?'OK ':'KO ')+si + " => " + sr)
})
<pre id=O></pre>


1
ระบุว่ามีเพียงอาร์เรย์ที่ซ้อนกันและจำนวนเต็มบวกและมีการระบุว่าไม่มีอาร์เรย์ใดในอินพุตที่ว่างเปล่าการทดสอบที่ง่ายขึ้นสำหรับผู้ประกอบการที่จะเป็นผู้v[0]แทนของv.mapคุณ บันทึก 1 ไบต์
Patrick Roberts



1

PHP, 145 ไบต์

<?function c($r){$n=[];foreach($r as$k=>$v)if(is_array($v)){$n=array_merge($n,$v);unset($r[$k]);}if($n)$r[]=c($n);return$r;}print_r(c($_GET[a]));

ทำให้พังถล่ม

function c($r){
  #usort($r,function($x,$y){return is_array($x)<=>is_array($y)?:$x<=>$y;}); 
#no need to sort and a simple sort($r); do it sort array after scalar
  $n=[];
  foreach($r as$k=>$v)if(is_array($v)){$n=array_merge($n,$v);unset($r[$k]);} # put arrays on the same depth together
  if($n)$r[]=c($n); # recursive if an array exists
  return$r; #return changes
}
print_r(c($_GET[a])); #Output and Input

1

Pyth, 19 16 ไบต์

W=Qsf!&sITp+TdQk

ลองออนไลน์ ชุดทดสอบ

สังเกตพื้นที่ชั้นนำ เอาต์พุตระดับบนแถวเช่นคำตอบ Perl

คำอธิบาย

  • Qการป้อนข้อมูลนัยใน
  • fรายการ ilter TของQเมื่อ:
    • ตรวจสอบว่าsหนอIเปิดอยู่Tหรือไม่
    • ถ้ามันเป็น (มันเป็นตัวเลข), print Tบวกพื้นที่...+d
    • ถ้าไม่ใช่ (เป็นอาร์เรย์) ให้เก็บไว้
  • sอืมรายการ สิ่งนี้จะเป็นการลบเลเยอร์ของอาร์เรย์ออกจากแต่ละรายการ หากไม่มีสิ่งใดเหลือ0อยู่
  • กำหนดผลให้=Q
  • While ผลลัพธ์ไม่ว่างพิมพ์สตริงว่างkและขึ้นบรรทัดใหม่

1

Haskell, 124 123 ไบต์

data L=I Int|R[L]
d#R l=((d+1)#)=<<l
d#i=[(d::Int,i)]
[]!_=[]
l!1=l
l!d=[R$l!(d-1)]
h l=R$do d<-[1..];[i|(e,i)<-0#l,d==e]!d

ในฐานะที่เป็น Haskell ไม่สนับสนุนรายการผสม (จำนวนเต็มและรายชื่อของจำนวนเต็ม) Lโดยค่าเริ่มต้นฉันกำหนดประเภทรายการที่กำหนดเอง ตัวอย่างการใช้งาน:

*Main> h (R[I 1, R[I 2, I 3], R[ R[I 4]], R[ R[ R[I 5, I 6], I 7, R[R[R[I 8]]]], I 9]])
R [I 1,R [I 2,I 3,I 9],R [R [I 4,I 7]],R [R [R [I 5,I 6]]],R [R [R [R [R [I 8]]]]]]

หมายเหตุ: ใช้เวลาสักครู่ในการรันเนื่องจากมันวนรอบ Ints เชิงบวกทั้งหมด (32 หรือ 64 บิต) เพื่อค้นหาระดับรังที่ลึก นอกจากนี้: ประเภทรายการที่กำหนดเองไม่สามารถพิมพ์ได้ตามค่าเริ่มต้นดังนั้นหากคุณต้องการดูผลลัพธ์ดังตัวอย่างข้างต้นคุณจะต้องเพิ่มderiving Showการdataประกาศ (-> data L=I Int|R[L] deriving Show) เนื่องจากไม่จำเป็นสำหรับการส่งคืน L-list จากฟังก์ชันฉันจึงไม่นับไบต์

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

data L=I Int|R[L]               -- custom list type L, which is either an Int
                                -- (-> I Int) or a list of some L (-> R [L]) 

d#R l=((d+1)#)=<<l              -- # makes a list of (depth, I-number) pairs from
d#i=[(d::Int,i)]                -- a given L-list, e.g.
                                -- 0 # (R[I 1,R[I 2,I 3],I 4]) -> [(1,I 4),(2,I 2),(2,I 3),(1,I 4)]
                                -- the type annotation ::Int makes sure that all
                                -- depths are bounded. Without it, Haskell
                                -- would use arbitrary large numbers of type
                                -- ::Integer and the program won't finish

[]!_=[]                         -- ! wraps a list of Is with (d-1) additional
l!1=l                           --  R constructors
l!d=[R$l!(d-1)]

h l=                            -- main function, takes a L-list
      do d<-[1..]               -- for each nest level d make
        [i|(e,i)<-0#l,d==e]     -- a list of all I where the depth is d
                           !!d  -- and wrap it again with d-1 Rs         
     R$                         -- wrap with a final R

แก้ไข @BlackCap บันทึกไบต์โดยสลับจาก>>=เป็นdoสัญกรณ์ ขอบคุณ!


หมายเหตุจะบันทึกไบต์h l=R$do d<-[1..];[i|(e,i)<-0#l,d==e]!d
BlackCap

0

JavaScript (ES6), 127 137 134 ไบต์

รับอาร์เรย์เป็นอินพุตและส่งคืนสตริง

f=(a,l=[],d=0,o='')=>`[${a.map(x=>x[0]?f(x,l,d+1,o+'['):l[d]=(l[d]?l[d]+',':o)+x),l.map((s,d)=>x+s+']'.repeat(d,x=','),x='').join``}]`

กรณีทดสอบ


@Shebang ขอบคุณสำหรับการสังเกต สิ่งนี้ควรได้รับการแก้ไข
Arnauld

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