ネストされたリストを並べ替える


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は、妥当な形式であれば何でもかまいません。

  • すべてのサブリストには、少なくとも1つの番号またはリストが含まれます。また、サブリストは、いくつかのレベルの深さにネストできます。たとえば、に(1, 2, (((3))))(((3)))サブリストのみがあるため、優先度は0です。

  • 無効なリスト(括弧の不一致、非数値、間違った括弧タイプ、負の数値など)は、未定義の動作を引き起こします。

テスト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(falsy)を、それ自体で、非空のリストを比較するリスト得0、「S(truthy)のように<リストから番号を区別するために使用することができます。


0はFalseですが、0のボックスはTrueですが、空のボックスはFalseです。興味深いPythonの仕組み。:P

私には25バイト(UTF-8でエンコードされている場合)のように見えます。
ローター

@Rotsorそうですね。ただし、Jellyは、シングルバイトとして認識される256文字すべてをエンコードするカスタムコードページを使用します。
デニス

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)

私は知っていて、フィルタリストへのより良い方法がありました。

Pythonリスト(およびそのサブリスト)をインプレースでソートします。

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。この例では、最初のサブリストまで再帰し、その最初のサブリスト5を取得しzます。その後、条件で、繰り返し処理するリストをソートします(!)。合計10になります。次に、これらのキーで外側のリストをソートし、[6、[1、5]]を取得します。 」おもしろいのはsort、両方のリストを2回呼び出すことです。したがって、これは等しいキーでのみ発生します。
オレズ

良いキャッチ。ソートが今ソートされたリストで繰り返されるのは面白いです。のNone出力を維持するためのもっと短い方法があるべきだと思いますがt.sort(key=k)、私はそれを見ていません。
xnor

False目的上+および拡張のために0ですsum。しかし、それがどのようにバイトを節約するのか考えることができません。
電卓

@CatsAreFluffy list.sortはを返しますがNone、ではありませんFalse
デニス

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を使用した回答。
リーキー修道女

3

Mathematica、50バイト

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

を使用する単純な再帰的メソッドSortBy。メッセージを無視します。


3

Haskell、160 151135バイト

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]]

これはかなり読みにくいです。しかし、何でも。些細な機械翻訳です。すべての数字の接頭辞Nとすべてのサブツリーの接頭辞T

次に、優先順位を計算する必要があります。これは、サブツリーの優先度が単純で、サブツリーに含まれるすべての要素の合計であれば簡単です。それは些細な再帰ループになります。しかし、そうではないので、2つの関数を定義する必要があります。1つは再帰する関数、もう1つは定義しない関数です。

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

q (N x) = x
q _     = 0

すべてのサブ要素を合計qする場合、存在する必要はなく、膨大な数の文字を節約できます。しかたがない!

編集:実際、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です。infixバージョンのmapを使用し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。:)
ウィルネス

1
カウントに改行ごとに2バイトを含めましたか?私たちはそれらをシングルとして数えることが許されていると思います。また、は必要ありません$ではsum$[x|N x<-t]。したがって、135-5-1 = 129。:)
ウィルネス

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を呼び出します。

私はLisp初心者です。私を殺さないでください^^


ハハ、誰かがLispでそれをすることを望んでいた!
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に渡される前に、ネストされたリストが最初にソートされます。これらの値は、ソート時にリスト内でコンパレータが位置を決定する方法です。

ここで試してみてください


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();}
アンドレアス・

絞るにはもっとたくさんあると思います。
アンドレアス

しかし、夫婦の問題があります:あなたは明示的に変換することはできませんObjectするintことが好きで、そして挑戦は、リストが出力されている必要のようです。
TNT

instanceofを変更してIntegerではなくListをチェックすることにより、実際に1バイトを保存します。整数は中括弧なしの7バイトですが、リストは6バイトです。
ブルー

@TNT java 1.7以降では、オブジェクトをプリミティブにキャストできます。もちろん、オブジェクトがnullの場合、npeを取得します。リストを適切に並べ替えても問題は見られません。課題は問題に直接言及しているようには見えません。
アンドレアス

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.