リストの「再帰サイズ」を見つける


20

リストの「ラップされていないサイズ」を見つけます

RS長さ(含まれるアイテムの数)としてリストを含まないリストの再帰サイズ、および長さとそれらのリストの再帰サイズの合計としてリストを含むリストの再帰サイズを定義します。

チャレンジ

特定のリストの再帰サイズを可能な限り少ないバイト数で出力するプログラムまたは関数を作成します。

入力はリストであり、数字、文字列(言語に含まれている場合)、および同様のリストを含めることができます。


例えば:

RS([]) = 0

RS([[]]) = 1

RS([4, 5, 6]) = 3
RS(["four", "five", "six"]) = 3
RS(["[[[[]]]]", "[][][][][]", "][][[[]]][]["]) = 3

RS([[4, 5, 6]]) = 4
RS([["four", "five", "six"]]) = 4
RS([["[[[[]]]]", "[][][][][]", "][][[[]]][]["]]) = 4

RS([[4], [5], [6]]) = 6
RS([["four"], ["five"], ["six"]]) = 6
RS([["[[[[]]]]"], ["[][][][][]"], ["][][[[]]][]["]]) = 6

RS([[[[[[[[[]]]]]]]]]) = 8

RS([[],[],[],[],[],[],[],[]]) = 8

RS([[],[],[[]],[[[[]]]]]) = 8

RS([0,[-1],[2.3,-4.3],[5,[6]],[7,[8,9,[10,11,[12,13,14]]]]]) = 22

言語に文字列がなく、文字のリストがある場合、"strings"上記を含む例は実際には文字のリストであり、より大きな結果になる可能性があることに注意してください。例として:

RS([['f','o','u','r'], ['f','i','v','e'], ['s','i','x']]) = 14

これはであるため、バイト単位の最短回答が優先されます。いつものように面白いビジネスはありません。

リスト以外の入力は、任意の出力を生成する場合があります。
I / Oはいつものように柔軟です。



要素は文字列、数字、再帰リストになりますか?
-xnor

注:いくつかの議論の後、リストの内容を制限しました。これを反映するように質問を編集しました。入力してくれた@xnorに感謝します!
ジョナサンアラン

2
文字列を考慮せずに、これがより良い挑戦になると思います。それだけでいくつかの言語にバイトをIMO追加しています
コナー・オブライエン

@ ConorO'Brienか、文字列をリストとして扱いたいかどうかを答えたい人は、回答者に任せるべきだったでしょう。残念ながら、コミュニティに「追加する必要のあるエッジケースはありますか?」と「定義の明確化が必要ですか?」そして、9日間にわたってサンドボックスで応答がありませんでした...そして今、私はそのような質問が重複するだろうと思いますか?
ジョナサンアラン

回答:


5

ゼリー、8 バイト

߀-ŒḊ?‘S

オンラインでお試しください!

使い方

߀-ŒḊ?‘S  Main link. Argument: x

   ŒḊ?    If x has non-zero depth:
߀          Recursively map the main link over its elements.
  -         Else, yield -1.
      ‘   Increment all integers in the result.
       S  Compute the sum of the result.
          If x is an array, incrementing before adding is equivalent to computing
          the sum of the elements and the length.
          If x is an integer/character, incrementing -1 yields 0, as desired.

13

Python、42バイト

f=lambda x:x*0==[]and len(x)+sum(map(f,x))

非リストの場合、出力0。リストの場合、その長さとその要素の再帰出力の合計を出力します。

リストは、Python 2の順序で数字より上、文字列より下にあり、を必要とし[]<=x<''ます。代わりに、数値または文字列x*0==[]の結果に対してをチェックします。0''


6

JavaScript(ES6)、39 37バイト

@ edc65のおかげで2バイト節約

f=a=>a.map&&a.map(x=>a-=~f(x),a=0)&&a

38バイト:f=a=>a.map?a.reduce((s,x)=>s+f(x),0):0
Sethi

@Sethi入力に対して0を返しませんか?あなたは1どこかにそこに入れなければなりません。
ETHproductions

1
37: f=a=>a.map&&a.map(x=>a-=~f(x),a=0)&&a-=~1文字未満である+=1+と、整数にブール値を変換し、それを別の文字に切断します。再利用aグローバル変数を避けるためにt
edc65

@ edc65ありがとう、それは素晴らしい!
ETHproductions

5

Mathematica、20バイト

Length@Level[#,∞]&

匿名関数。入力として式を取り、出力として数値を返します。Unicode文字は、U + 221E INFINITY for \[Infinity]です。Level[#,∞]入力の部分式のリストを提供し、Length@それらをカウントします。


ブーム!スラムは私の答えに浸った。しかし、私は何か新しいことを学びました:)
グレッグマーティン

5

Mathematica、14バイト

LeafCount@#-1&

私の前の答えのわずかな変更。LeafCount既に説明したように、ネストされたアトミック値はすでに処理されていますが、結果から減算する必要がある最も外側のリストもカウントします。


4

Perl、34バイト

再帰関数!はい、Perlには正規表現だけでなく、関数もあります!

sub f{@_+f(map ref?@$_:(),@_)if@_}

テストする場合は、次のように実行できます。

perl -pE 'sub f{@_+f(map ref?@$_:(),@_)if@_}$_=f@{+eval}' <<< '[["four"], ["five"], ["six"]]'

3

Mathematica、32バイト

Length@#+Tr[#0/@#~Select~ListQ]&

名前のない再帰関数。抜粋#0/@#~Select~ListQは、リストである入力の各要素で関数を再度呼び出し、Trそれらの値を合計します。幸いなことに、Mathematicaは空のリストの長さを取得し、空のリストから修飾要素を検索するので問題ありません。したがって、基本ケースは必要ありません。


2

Haskell、52バイト

data L a=E a|N[L a]
r(N n)=1+sum(r<$>n)
r _=1
pred.r

使用例:

*Main> pred.r $ N[E 0,N[E(-1)],N[E 2.3,E(-4.3)],N[E 5,N[E 6]],N[E 7,N[E 8,E 9,N[E 10,E 11,N[E 12,E 13,E 14]]]]] 
22

Haskellは混合リスト(たとえば、IntとIntのリスト)をサポートしていません。そのため、カスタムリストタイプLを使用します。カスタムリストタイプは、タイプa(-> E a)または他のLのリスト(-> N[L a])です。RSの計算は、Eカウント1N1にその要素の再帰サイズの合計を加算する単純な再帰です。合計は1オフなので、を介して減算しpredます。

サイドノート:要素の正確な型と値はアルゴリズムにとって重要ではないため、抽象要素のみを扱うポリモーフィズムを削除してに進むことができdata L=E|N[L]ます。


2

係数、105バイト

再帰関数g。

: g ( o -- l ) [ dup [ sequence? ] [ string? not ] bi and [ [ g ] map sum 1 + ] [ drop 1 ] if ] map sum ;

Ungolfed(ちょっと):

: g ( o -- l ) 
[ dup 
  [ sequence? ] 
  [ string? not ] 
  bi and 
  [ [ g ] map sum 1 + ] 
  [ drop 1 ] 
  if 
] map sum ;

length組み込みの長さを使用する代わりにdrop 1、文字列と非シーケンスに実装されているため、への呼び出しがないことがわかります。


2

Mathematica、18バイト

(c=-1;++c&//@#;c)&

さらに別のMathematicaアプローチ。ビルトインを使用するほど短くはありませんLeafCountが、それでもかなり簡潔です。これは、式のすべてのノードで関数を呼び出すMapAll演算子//@を使用し、その関数を使用してcounterをインクリメントしますc。以下のようにLeafCount、我々はからカウンターを開始するので、それは、同様に外側のリストの先頭がカウントされるため場合、これは、より多くの私たちが必要とするよりも、1を提供します-1


2

C#(Visual C#Interactive Compiler)、50バイト

int f(Array a)=>a.Length+a.OfType<Array>().Sum(f);

オンラインでお試しください!

以前に送信されたJava回答と同じ手法を使用しますが、LINQを活用して回答の長さを減らします。

説明:

// f is a method that a accepts
// an array of any underlying type
int f(Array a)=>
  // include the length of the
  // current array in the total
  a.Length+
  // filter the current list to elements
  // that are also arrays
  a.OfType<Array>()
    // recursively call f on each child
    // array and add to cumulative total
    .Sum(f);

2

05AB1E(レガシー)、22 17 バイト

"ε¼D¸D˜Êi®.V"©.V¾

オンラインそれを試してみたり、すべてのテストケースを確認してください

説明:

この課題には、05AB1Eで克服すべき複数の課題があります。

  1. 05AB1EにはElixirの書き換え(λ)以来再帰関数がありますが、整数シーケンスにのみ有用です。05AB1E再帰関数の例として、私の答えを以下に示します。そのため、コードの一部を文字列に入れて、その文字列を05AB1Eコードとして再帰的に実行することで、再帰呼び出しを行う代替手段を見つける必要がありました。
  2. isList05AB1Eにはコマンドもありません。そのため、リストへの折り返し、深い平坦化、および同等性のチェックを利用して、いくつかの回避策を使用してこれを確認する必要がありました。
  3. そして第三に、多次元リストの1レベルだけをフラット化することはできません。flatten関数˜は、すべてのレイヤーを削除し、多次元リストをすべての最も内側の値を持つ単一のリストにするディープフラットンです。(つまりに[[1,2],[[[3]],4]]なります[1,2,3,4])。

上記の3つの問題すべてを克服するために、コードを最上部に配置しました。3つの主要な部分に分かれています。まず、次のものがあります。

"..."        # Create a string with 05AB1E code
     ©       # Save this string in the register (without popping)
      .V     # Execute the string as 05AB1E code

文字列には次のコードが含まれます。

ε            # Map each value in the given list by:
             # (this uses the input-list implicitly with the initial call)
 ¼           #  Increase the counter_variable by 1
 D           #  Duplicate the map-value
             #   i.e. STACK "A" becomes "A","A"
             #   i.e. STACK [["B","C"]] becomes [["B","C"]],[["B","C"]]
  ¸          #  Wrap it into a list
             #   i.e. "A" → ["A"]
             #   i.e. [["B","C"]] → [[["B","C"]]]
   D         #  Duplicate that again
             #   i.e. STACK "A",["A"] becomes "A",["A"],["A"]
             #   i.e. STACK [["B","C"]],[[["B","C"]]]
             #    becomes [["B","C"]],[[["B","C"]]],[[["B","C"]]]
    ˜        #  Flatten it
             #   i.e. ["A"] → ["A"]
             #   i.e. [[["B","C"]]] → ["B","C"]
     Ê       #  Check if the wrapped and wrapped+flattened lists are NOT equal
             #   i.e. ["A"] and ["A"] → 0 (falsey)
             #   i.e. [[["B","C"]]] and ["B","C"] → 1 (truthy)
      i      #  If they are:
       ®     #   Push the string from the register
        .V   #   Execute it as 05AB1E code
             #   (this is basically our recursive call, mapping the current value
             #    we duplicated initially again)

マップには暗黙的なyがあり、foreach-loopには明示的なが必要なので、foreach-loopの代わりにマップが使用されyます。counter_variableしかし、私たちは気にするだけです。

最後に、すべてのマップと内部マップが完了したら、次のことを行います。

¾           # Push the counter_variable (which is output implicitly as result)


1

C、 174の 167 152バイト

再帰関数 fメモリをリークする(152):

#include"object.h"
size_t f(array_t*a){size_t t=0,i=0;for(;i<array_length(a);i++){object_t*o=array_get_copy(a,i,0);t+=o->type==6?f(o->ary):1;}return t;}

再帰的 f参照を使用して、167でリークしない:

#include"object.h"
size_t f(array_t*a){size_t t=0,i=0;for(;i<array_length(a);i++){object_t**o=array_get_ref(a,i,0);t+=*o->type==t_array?f(*o->ary):1;}return t;}

ゴルフをしていない:

size_t get_recursize (const array_t* const a) {
  pfn();

  object_failnull(a);

  size_t out = 0;

  for (size_t i = 0; i < array_length(a); i++) {

    object_t** o = array_get_ref(a, i, NULL);

    if ( (*o)->type == t_array ) {

      out += get_recursize((*o)->ary);

    } else {
      ++out;
    }
  }
  return out;
}

「しかし、Cでこれに答えることはできますか?確かに、Cにはマネージドアレイはなく、異種アレイを実際に持つことはできません...」

「あは」と答えます。「(GNU-ish)C11およびISO C ++ 11の「オブジェクト」の単純なシステムに取り組んできたからです」。

この機能の完全なデモプログラムは次のとおりです。

#include "../calc/object/object.h"

size_t get_recursize (const array_t* const a);

define_array_new_fromctype(ssize_t);

int main (void) {

  size_t len = 6;

  static const ssize_t h[6] = { -1, 3, -5, 7, -9, 11 };

  array_t* a = array_new_from_ssize_t_lit(h, len, t_realint);

  size_t rsize = get_recursize(a);

  printf("Recursive size of a: %zu\n", rsize);

  object_t* asobj = object_new(t_array, a);
  array_destruct(a);

  array_t* b = array_new(NULL, -1);

  for (size_t j = 0; j < 10; j++) {
    array_append(b, asobj);
  }

  object_destruct(asobj);

  rsize = get_recursize(b);

  printf("Recursive size of b: %zu\n", rsize);

  asobj = object_new(t_array, b);
  array_destruct(b);

  array_t* c = array_new(NULL, -1);

  for (size_t i = 0; i < 100; i++) {
    array_append(c, asobj);
  }

  object_destruct(asobj);

  rsize = get_recursize(c);

  printf("Recursive size of c: %zu\n", rsize);

  array_destruct(c);

  return EXIT_SUCCESS;
}

size_t get_recursize (const array_t* const a) {
  pfn();

  object_failnull(a);

  size_t out = 0;

  for (size_t i = 0; i < array_length(a); i++) {

    object_t** o = array_get_ref(a, i, NULL);

    if ( (*o)->type == t_array ) {

      out += get_recursize((*o)->ary);

    } else {
      ++out;
    }
  }
  return out;
}

今、ここに住んでいますありを使用するにはそのリポジトリが必要です。

またlibfnv、プラットフォーム用にコンパイルされたFowler-Noll-Voハッシュライブラリが必要です。それはそのリポジトリにあり、ここから取得することもできます

その後、あなたはできる cc -DNODEBUG size.c path/to/libfnv.a -o size

実装は必ずしも効率的ではありません。

$ valgrind --leak-check=full --track-origins=yes --show-leak-kinds=all ./size
==24127== Memcheck, a memory error detector
==24127== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==24127== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==24127== Command: ./size
==24127== 
Recursive size of a: 6
Recursive size of b: 60
Recursive size of c: 6000
==24127== 
==24127== HEAP SUMMARY:
==24127==     in use at exit: 0 bytes in 0 blocks
==24127==   total heap usage: 22,900 allocs, 22,900 frees, 615,584 bytes allocated
==24127== 
==24127== All heap blocks were freed -- no leaks are possible
==24127== 
==24127== For counts of detected and suppressed errors, rerun with: -v
==24127== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

しかし、それは機能します!マスターへの最後のコミット(このプログラムがコンパイルされた)は2日前でした。つまり、この送信は有効です。


1

公理118バイト

RS(a:Union(List(Any),Any)):INT==(a case List(Any)=>(g:List(Any):=a;leaf? g=>0;r:=#g;for i in g repeat r:=r+RS(i);r);0)

食べない

RS(a:Union(List(Any),Any)):INT==
  a case List(Any)=>
          g:List(Any):=a
          leaf? g=>0
          r:=#g
          for i in g repeat r:=r+RS(i)
          r
  0

結果

(25) -> RS([])=0
   (25)  0= 0
                                        Type: Equation NonNegativeInteger
(26) -> RS([[]]) = 1
   (26)  1= 1
                                           Type: Equation PositiveInteger
(27) -> RS([4, 5, 6]) = 3
   (27)  3= 3
                                           Type: Equation PositiveInteger
(28) -> RS(["four", "five", "six"]) = 3
   (28)  3= 3
                                           Type: Equation PositiveInteger
(29) -> RS(["[[[[]]]]", "[][][][][]", "][][[[]]][]["]) = 3
   (29)  3= 3
                                           Type: Equation PositiveInteger
(30) -> RS([[4, 5, 6]]) = 4
   (30)  4= 4
                                           Type: Equation PositiveInteger
(31) -> RS([["four", "five", "six"]]) = 4
   (31)  4= 4
                                           Type: Equation PositiveInteger
(32) -> RS([["[[[[]]]]", "[][][][][]", "][][[[]]][]["]]) = 4
   (32)  4= 4
                                           Type: Equation PositiveInteger
(33) -> RS([[4], [5], [6]]) = 6
   (33)  6= 6
                                           Type: Equation PositiveInteger
(34) -> RS([["four"], ["five"], ["six"]]) = 6
   (34)  6= 6
                                           Type: Equation PositiveInteger
(35) -> RS([["[[[[]]]]"], ["[][][][][]"], ["][][[[]]][]["]]) = 6
   (35)  6= 6
                                           Type: Equation PositiveInteger
(36) -> RS([[[[[[[[[]]]]]]]]]) = 8
   (36)  8= 8
                                           Type: Equation PositiveInteger
(37) -> RS([[],[],[],[],[],[],[],[]]) = 8
   (37)  8= 8
                                           Type: Equation PositiveInteger
(38) -> RS([[],[],[[]],[[[[]]]]]) = 8
   (38)  8= 8
                                           Type: Equation PositiveInteger
(39) -> RS([0,[-1],[2.3,-4.3],[5,[6]],[7,[8,9,[10,11,[12,13,14]]]]]) = 22
   (39)  22= 22
                                           Type: Equation PositiveInteger
(40) -> RS([['f','o','u','r'], ['f','i','v','e'], ['s','i','x']]) = 14
   (40)  14= 14
                                           Type: Equation PositiveInteger

1

APL(NARS)、24文字、48バイト

{⍬≡⍵:0⋄×≡⍵:(≢⍵)++/∇¨⍵⋄0}

これは、ここでの '私の'公理の答えの散文的な翻訳になります... APLでは、voidリストは '⍬' Zildeになります。 1 2 3´は ´[1,2,3]´ eccいくつかのテスト:

  RS←{⍬≡⍵:0⋄×≡⍵:(≢⍵)++/∇¨⍵⋄0}
  RS ⍬
0
  RS ⊂⍬
1
  RS  4 5 6
3
  RS ("four")("five")("six")
14
  RS ('f' 'o' 'u' 'r') ('f' 'i' 'v' 'e') ('s' 'i' 'x')
14
  RS ("(((())))")("()()()()()")(")()((()))()(")
33
  RS (⊂4 5 6)
4
  RS (⊂("four")("five")("six")) 
15
  RS (⊂("(((())))")("()()()()()")(")()((()))()(") )
34
  RS (,4) (,5) (,6)
6
  RS ⊂¨("four")("five")("six")
17
  RS ⊂¨("(((())))")("()()()()()")(")()((()))()(") 
36
  RS ⊂⊂⊂⊂⊂⊂⊂⊂⍬
8
  RS ⍬⍬⍬⍬⍬⍬⍬⍬
8
  RS ⍬⍬(⊂⍬)(⊂(⊂(⊂⍬)))
8
  RS 0(,¯1)(2.3 ¯4.3)(5 (,6))(7 (8 9 (10 11 (12 13 14))))  
22     

他のタイプの結果を印刷するために、演習では別の関数が必要であると提案しています(演習では関数RSとRの両方が適切である必要があります)

  Rs←{⍬≡⍵:0⋄(''≡0↑⍵)∨0=≡⍵:0⋄(≢⍵)++/∇¨⍵}
  Rs ("four")("five")("six")
3
  Rs ("(((())))")("()()()()()")(")()((()))()(")
3
  Rs (⊂("four")("five")("six"))
4
  Rs (⊂("(((())))")("()()()()()")(")()((()))()(") )
4
  Rs ⊂¨("four")("five")("six")
6
  Rs ⊂¨("(((())))")("()()()()()")(")()((()))()(")
6
  Rs 0(,¯1)(2.3 ¯4.3)(5 (,6))(7 (8 9 (10 11 (12 13 14))))
22
  Rs ('f' 'o' 'u' 'r') ('f' 'i' 'v' 'e') ('s' 'i' 'x')
3

入力をどのように表示するかを確認するには、o関数を使用します。

  o←⎕fmt
  o 0(,¯1)(2.3 ¯4.3)(5 (,6))(7 (8 9 (10 11 (12 13 14))))
┌5─────────────────────────────────────────────────────────┐
│  ┌1──┐ ┌2────────┐ ┌2─────┐ ┌2──────────────────────────┐│
│0 │ ¯1│ │ 2.3 ¯4.3│ │  ┌1─┐│ │  ┌3──────────────────────┐││
│~ └~──┘ └~────────┘ │5 │ 6││ │7 │    ┌3────────────────┐│││
│                    │~ └~─┘2 │~ │8 9 │      ┌3────────┐││││
│                    └∊─────┘ │  │~ ~ │10 11 │ 12 13 14│││││
│                             │  │    │~~ ~~ └~────────┘2│││
│                             │  │    └∊────────────────┘3││
│                             │  └∊──────────────────────┘4│
│                             └∊──────────────────────────┘5
└∊─────────────────────────────────────────────────────────┘

このプリントジルデ、および1つの8ジルデリスト:

  o ⍬
┌0─┐
│ 0│
└~─┘
  o ⍬⍬⍬⍬⍬⍬⍬⍬
┌8──────────────────────────────────────┐
│┌0─┐ ┌0─┐ ┌0─┐ ┌0─┐ ┌0─┐ ┌0─┐ ┌0─┐ ┌0─┐│
││ 0│ │ 0│ │ 0│ │ 0│ │ 0│ │ 0│ │ 0│ │ 0││
│└~─┘ └~─┘ └~─┘ └~─┘ └~─┘ └~─┘ └~─┘ └~─┘2
└∊──────────────────────────────────────┘

1

Java、96バイト

int c(Object[]a){int r=a.length;for(var i:a)r+=i instanceof Object[]?c((Object[])i):0;return r;}

オンラインでお試しください。

説明:

int c(Object[]a){  // Recursive method with Object-array parameter and integer return-type
  int r=a.length;  //  Result-sum, starting at the size of the input-array
  for(var i:a)     //  Loop over the input-array:
    r+=            //   Increase the result-sum by:
       i instanceof Object[]?
                   //    If the current item is an array:
        c((Object[])i) 
                   //     A recursive call with this item
       :           //    Else:
        0;         //     0 (so leave the result-sum the same)
  return r;}       //  Return the result-sum


1

Clojure、79 77 51バイト

入力はベクトルではなくリストでなければなりません。両方を使用してサポートされsequential?ます。

(defn f[i](if(seq? i)(apply +(count i)(map f i))0))

前:

(defn f[i](if(seq? i)(if(some seq? i)(apply +(count i)(map f i))(count i))0))

-1

Python、72バイト

l=lambda a:0if len(a)==0else len(a)+sum(l(i)for i in a if type(i)==list)

あなたはそこにいくつかのスペースを削除することができます
ブルー

具体的には、 0 and if0and else、および)andの間for
ザカリー16

2
チャットボットアカウントの担当者が必要な場合は、サイトに有意義な貢献をすることを検討してください。これにより、既存の42バイトのPythonの回答に何も追加されません。
デニス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.